emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] feature/tramp-thread-safe c8ca97a 2/2: Merge remote-tracki


From: Michael Albinus
Subject: [Emacs-diffs] feature/tramp-thread-safe c8ca97a 2/2: Merge remote-tracking branch 'origin/master' into feature/tramp-thread-safe
Date: Sat, 29 Sep 2018 09:46:36 -0400 (EDT)

branch: feature/tramp-thread-safe
commit c8ca97af3851188acd5934968672462d7ca7d926
Merge: 853ade4 ce0da8a
Author: Michael Albinus <address@hidden>
Commit: Michael Albinus <address@hidden>

    Merge remote-tracking branch 'origin/master' into feature/tramp-thread-safe
---
 CONTRIBUTE                             |   2 +-
 INSTALL                                |   5 +-
 Makefile.in                            |   6 +-
 build-aux/config.guess                 |   4 +-
 build-aux/config.sub                   | 894 ++++++++++++++++-----------------
 doc/emacs/Makefile.in                  |   4 +-
 doc/emacs/custom.texi                  |  11 +-
 doc/emacs/kmacro.texi                  |   4 +
 doc/emacs/maintaining.texi             |  16 +-
 doc/emacs/programs.texi                |   4 +
 doc/lispintro/Makefile.in              |   4 +-
 doc/lispref/Makefile.in                |   4 +-
 doc/lispref/abbrevs.texi               |   4 +-
 doc/lispref/commands.texi              |  67 ++-
 doc/lispref/control.texi               |   2 +-
 doc/lispref/customize.texi             |  11 +-
 doc/lispref/display.texi               |  48 +-
 doc/lispref/elisp.texi                 |   1 -
 doc/lispref/files.texi                 |  25 +-
 doc/lispref/help.texi                  |  30 +-
 doc/lispref/intro.texi                 |   2 +-
 doc/lispref/keymaps.texi               |   2 +-
 doc/lispref/lists.texi                 |   2 +-
 doc/lispref/minibuf.texi               |  64 ++-
 doc/lispref/os.texi                    |  19 +-
 doc/lispref/processes.texi             | 130 -----
 doc/man/emacsclient.1                  |   2 +-
 doc/misc/Makefile.in                   |   8 +-
 doc/misc/auth.texi                     |  39 +-
 doc/misc/calc.texi                     |  17 +-
 doc/misc/dired-x.texi                  |   5 +-
 doc/misc/efaq.texi                     |   5 +-
 doc/misc/emacs-mime.texi               |   9 +-
 doc/misc/eshell.texi                   |   7 +-
 doc/misc/gnus.texi                     |   6 +-
 doc/misc/org.texi                      |   4 +-
 doc/misc/reftex.texi                   |   2 +-
 doc/misc/sieve.texi                    |   2 +-
 doc/misc/srecode.texi                  |   2 +-
 doc/misc/tramp.texi                    |   2 +-
 doc/misc/url.texi                      |   2 +-
 doc/misc/vhdl-mode.texi                |   2 +-
 etc/NEWS                               |  63 ++-
 etc/NEWS.1-17                          | 622 +++++++++++------------
 etc/NEWS.18                            | 394 +++++++--------
 etc/NEWS.26                            |   6 +
 etc/PROBLEMS                           |   9 +
 etc/refcards/Makefile                  |   2 +-
 lib-src/Makefile.in                    |   4 +-
 lib-src/profile.c                      |   7 +-
 lib/Makefile.in                        |   2 +-
 lib/dtotimespec.c                      |  10 +-
 lib/fcntl.c                            | 190 ++++++-
 lib/gettime.c                          |  29 +-
 lib/intprops.h                         |   4 +-
 lib/limits.in.h                        |  44 +-
 lib/mktime-internal.h                  |  16 +
 lib/mktime.c                           | 122 ++---
 lib/stat-time.h                        |   8 +-
 lib/strtol.c                           |  29 --
 lib/timegm.c                           |  32 +-
 lib/timespec-add.c                     |   6 +-
 lib/timespec-sub.c                     |   6 +-
 lib/timespec.h                         |  28 +-
 lib/utimens.c                          |   4 +-
 lisp/abbrev.el                         |  85 ++--
 lisp/auth-source.el                    |   6 +-
 lisp/autorevert.el                     |   9 +-
 lisp/bs.el                             |   4 +-
 lisp/calc/calc-misc.el                 |  16 +-
 lisp/calc/calc.el                      |   4 +-
 lisp/calculator.el                     |   2 +-
 lisp/calendar/icalendar.el             |   4 +-
 lisp/calendar/parse-time.el            |  10 +-
 lisp/cedet/ede/files.el                |   2 +-
 lisp/cedet/ede/pconf.el                |   4 +-
 lisp/cedet/semantic/db-file.el         |   4 +-
 lisp/cedet/semantic/db-mode.el         |   5 +-
 lisp/cedet/semantic/db.el              |   8 +-
 lisp/cedet/srecode/table.el            |   4 +-
 lisp/cus-start.el                      |   3 +-
 lisp/dabbrev.el                        |   4 +-
 lisp/delsel.el                         |   8 -
 lisp/desktop.el                        |  11 +-
 lisp/dired-aux.el                      |  55 +-
 lisp/dired-x.el                        |  11 +-
 lisp/dired.el                          |  20 +-
 lisp/dos-w32.el                        |   2 +-
 lisp/emacs-lisp/advice.el              | 114 ++---
 lisp/emacs-lisp/autoload.el            |  23 +-
 lisp/emacs-lisp/generator.el           |  15 +-
 lisp/emacs-lisp/shadow.el              |   4 +-
 lisp/emulation/viper-cmd.el            |   4 +-
 lisp/emulation/viper-keym.el           |   6 +-
 lisp/emulation/viper-macs.el           |  13 +-
 lisp/emulation/viper-util.el           |  61 +--
 lisp/emulation/viper.el                | 102 ----
 lisp/epg.el                            |   8 +-
 lisp/erc/erc.el                        |   5 +-
 lisp/eshell/em-dirs.el                 |  10 +-
 lisp/eshell/em-ls.el                   |  38 +-
 lisp/eshell/em-pred.el                 |  14 +-
 lisp/eshell/em-unix.el                 |  52 +-
 lisp/eshell/esh-util.el                |   4 +-
 lisp/files-x.el                        |  35 +-
 lisp/files.el                          |  80 +--
 lisp/filesets.el                       |   3 +-
 lisp/find-dired.el                     |   2 +-
 lisp/find-lisp.el                      |  24 +-
 lisp/gnus/deuglify.el                  |   8 +-
 lisp/gnus/gnus-agent.el                |  54 +-
 lisp/gnus/gnus-cache.el                |  11 +-
 lisp/gnus/gnus-cloud.el                |   3 +-
 lisp/gnus/gnus-score.el                |   3 +-
 lisp/gnus/gnus-start.el                |  16 +-
 lisp/gnus/gnus-sum.el                  |   9 +-
 lisp/gnus/gnus-util.el                 |   7 +-
 lisp/gnus/mail-source.el               |   8 +-
 lisp/gnus/nneething.el                 |  21 +-
 lisp/gnus/nnfolder.el                  |   2 +-
 lisp/gnus/nnheader.el                  |   4 +-
 lisp/gnus/nnmail.el                    |   3 +-
 lisp/gnus/nnmaildir.el                 |  48 +-
 lisp/gnus/nnmh.el                      |  18 +-
 lisp/gnus/nnml.el                      |   3 +-
 lisp/gnus/spam-stat.el                 |  21 +-
 lisp/ibuf-ext.el                       |  45 +-
 lisp/ibuf-macs.el                      |  65 ++-
 lisp/ido.el                            |   9 +-
 lisp/image-dired.el                    |  12 +-
 lisp/imenu.el                          |   8 +-
 lisp/info.el                           |   6 +-
 lisp/leim/quail/latin-post.el          |  48 ++
 lisp/leim/quail/latin-pre.el           |  48 ++
 lisp/ls-lisp.el                        |  55 +-
 lisp/mail/blessmail.el                 |   6 +-
 lisp/mail/feedmail.el                  |  94 ++--
 lisp/mail/mailabbrev.el                |   6 +-
 lisp/mail/mspools.el                   |   2 +-
 lisp/mail/rmail.el                     |   4 +-
 lisp/mail/sendmail.el                  |   3 +-
 lisp/menu-bar.el                       |  10 +-
 lisp/mh-e/mh-alias.el                  |   3 +-
 lisp/mouse.el                          |   2 +-
 lisp/multifile.el                      | 217 ++++++++
 lisp/net/ange-ftp.el                   |  21 +-
 lisp/net/dbus.el                       |   9 +-
 lisp/net/eudcb-mab.el                  |   3 +-
 lisp/net/eww.el                        |   2 +-
 lisp/net/netrc.el                      |   6 +-
 lisp/net/newst-backend.el              |   3 +-
 lisp/net/nsm.el                        |  53 +-
 lisp/net/shr.el                        |   6 +-
 lisp/net/tramp-adb.el                  |   8 +-
 lisp/net/tramp-cache.el                |   5 +-
 lisp/net/tramp-compat.el               |  14 +-
 lisp/net/tramp-gvfs.el                 |   2 +-
 lisp/net/tramp-sh.el                   |  55 +-
 lisp/net/tramp-smb.el                  |  31 +-
 lisp/net/tramp.el                      |  80 +--
 lisp/nxml/rng-loc.el                   |   2 +-
 lisp/obsolete/fast-lock.el             |   3 +-
 lisp/obsolete/vc-arch.el               |   7 +-
 lisp/org/ob-eval.el                    |   2 +-
 lisp/org/org-attach.el                 |   2 +-
 lisp/org/org-macro.el                  |   3 +-
 lisp/org/org.el                        |   9 +-
 lisp/org/ox-html.el                    |   3 +-
 lisp/org/ox-publish.el                 |   9 +-
 lisp/pcmpl-gnu.el                      |   2 +-
 lisp/pcmpl-rpm.el                      |   3 +-
 lisp/play/bubbles.el                   |  96 ++--
 lisp/play/cookie1.el                   |   6 +-
 lisp/progmodes/ada-mode.el             |  22 +-
 lisp/progmodes/cc-engine.el            | 116 +++--
 lisp/progmodes/cmacexp.el              |   3 +-
 lisp/progmodes/etags.el                | 299 ++++-------
 lisp/progmodes/gdb-mi.el               |   5 +-
 lisp/progmodes/idlw-shell.el           | 211 ++++----
 lisp/progmodes/js.el                   |  35 +-
 lisp/progmodes/project.el              |  46 +-
 lisp/progmodes/prolog.el               |   6 -
 lisp/progmodes/xref.el                 |  20 +-
 lisp/ps-bdf.el                         |  10 +-
 lisp/replace.el                        |  35 +-
 lisp/rfn-eshadow.el                    |   4 +-
 lisp/saveplace.el                      |  12 +-
 lisp/server.el                         |   6 +-
 lisp/simple.el                         |  13 +-
 lisp/speedbar.el                       |  21 +-
 lisp/subr.el                           |  10 +-
 lisp/textmodes/flyspell.el             |   9 +-
 lisp/thingatpt.el                      |  27 +-
 lisp/thread.el                         |   6 +-
 lisp/thumbs.el                         |   4 +-
 lisp/time.el                           |  38 +-
 lisp/url/url-auth.el                   |   4 +-
 lisp/url/url-cache.el                  |  10 +-
 lisp/url/url-file.el                   |   2 +-
 lisp/vc/diff-mode.el                   |   2 +-
 lisp/vc/pcvs-info.el                   |   3 +-
 lisp/vc/vc-bzr.el                      |  12 +-
 lisp/vc/vc-cvs.el                      |  15 +-
 lisp/vc/vc-git.el                      |  18 +-
 lisp/vc/vc-hg.el                       |  17 +-
 lisp/vc/vc-hooks.el                    |   2 +-
 lisp/vc/vc-rcs.el                      |   9 +-
 lisp/vc/vc-svn.el                      |   6 +-
 lisp/vc/vc.el                          |   9 +-
 lisp/wdired.el                         |  25 +-
 lisp/window.el                         |  81 +--
 lisp/xdg.el                            |   4 +-
 lwlib/Makefile.in                      |   2 +-
 m4/limits-h.m4                         |  16 +-
 m4/stddef_h.m4                         |  29 +-
 oldXMenu/Makefile.in                   |   2 +-
 src/Makefile.in                        |   6 +-
 src/alloc.c                            |  16 +-
 src/atimer.c                           |  15 +-
 src/bignum.c                           |  44 +-
 src/bignum.h                           |   1 +
 src/buffer.c                           |  34 +-
 src/charset.c                          |   2 +-
 src/data.c                             |  12 +-
 src/dired.c                            |  20 +-
 src/editfns.c                          |  71 ++-
 src/emacs-module.c                     |  12 +-
 src/eval.c                             |  14 +-
 src/fileio.c                           |  12 +-
 src/floatfns.c                         |  35 +-
 src/gnutls.c                           |  49 +-
 src/gtkutil.c                          |   2 +-
 src/json.c                             |  14 +-
 src/keyboard.c                         |   4 +-
 src/keymap.c                           |  18 +-
 src/lisp.h                             |   4 +-
 src/lread.c                            |  20 +-
 src/process.c                          |  27 +-
 src/sysdep.c                           |  28 +-
 src/systime.h                          |  26 +-
 src/thread.h                           |   1 -
 src/w32common.h                        |   1 +
 src/xdisp.c                            |   9 +
 src/xfns.c                             |   2 +-
 test/Makefile.in                       |   2 +-
 test/lisp/autorevert-tests.el          |   5 +-
 test/lisp/calendar/icalendar-tests.el  |  11 +-
 test/lisp/calendar/parse-time-tests.el |  62 ++-
 test/lisp/emacs-lisp/timer-tests.el    |   6 +-
 test/lisp/net/tramp-tests.el           |  28 +-
 test/lisp/subr-tests.el                |  12 +
 test/lisp/thingatpt-tests.el           |  72 +--
 test/src/buffer-tests.el               |  19 +
 test/src/data-tests.el                 |  10 +
 test/src/floatfns-tests.el             |  25 +
 test/src/json-tests.el                 |   8 +
 256 files changed, 4077 insertions(+), 3249 deletions(-)

diff --git a/CONTRIBUTE b/CONTRIBUTE
index c4f424c..0b68052 100644
--- a/CONTRIBUTE
+++ b/CONTRIBUTE
@@ -97,7 +97,7 @@ Otherwise do not mark it.
 If your change requires updating the manuals to document new
 functions/commands/variables/faces, then use the proper Texinfo
 command to index them; for instance, use @vindex for variables and
address@hidden for functions/commands.  For the full list of predefine indices, 
see
address@hidden for functions/commands.  For the full list of predefined 
indices, see
 
https://www.gnu.org/software/texinfo/manual/texinfo/html_node/Predefined-Indices.html
 or run the shell command 'info "(texinfo)Predefined Indices"'.
 
diff --git a/INSTALL b/INSTALL
index ab2e800..0c56fff 100644
--- a/INSTALL
+++ b/INSTALL
@@ -202,8 +202,9 @@ The names of the packages that you need varies according to 
the
 GNU/Linux distribution that you use, and the options that you want to
 configure Emacs with.  On Debian-based systems, you can install all the
 packages needed to build the installed version of Emacs with a command
-like 'apt-get build-dep emacs24'.  On Red Hat systems, the
-corresponding command is 'yum-builddep emacs'.
+like 'apt-get build-dep emacs' (on older systems, replace 'emacs' with
+eg 'emacs25').  On Red Hat-based systems, the corresponding command is
+'dnf builddep emacs' (on older systems, use 'yum-builddep' instead).
 
 
 DETAILED BUILDING AND INSTALLATION:
diff --git a/Makefile.in b/Makefile.in
index 4d7627b..c6b2cfa 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -192,7 +192,7 @@ address@hidden@
 desktopdir=$(datarootdir)/applications
 
 # Where the etc/emacs.appdata.xml file is to be installed.
-appdatadir=$(datarootdir)/appdata
+appdatadir=$(datarootdir)/metainfo
 
 # Where the etc/emacs.service file is to be installed.
 # The system value (typically /usr/lib/systemd/user) can be
@@ -839,7 +839,7 @@ $(foreach dir,$(clean_dirs),$(eval $(call 
submake_template,$(dir),clean)))
 clean: $(clean_dirs:=_clean)
        $(MAKE) -C admin/charsets $@
        [ ! -d test ] || $(MAKE) -C test $@
-       -rm -f *.tmp etc/*.tmp*
+       -rm -f ./*.tmp etc/*.tmp*
        -rm -rf info-dir.*
 
 ### 'bootclean'
@@ -926,7 +926,7 @@ $(foreach dir,$(extraclean_dirs),$(eval $(call 
submake_template,$(dir),extraclea
 extraclean: $(extraclean_dirs:=_extraclean)
        ${top_maintainer_clean}
        -rm -f config-tmp-*
-       -rm -f *~ \#*
+       -rm -f ./*~ \#*
 
 # The src subdir knows how to do the right thing
 # even when the build directory and source dir are different.
diff --git a/build-aux/config.guess b/build-aux/config.guess
index d4fb321..b33c9e8 100755
--- a/build-aux/config.guess
+++ b/build-aux/config.guess
@@ -2,7 +2,7 @@
 # Attempt to guess a canonical system name.
 #   Copyright 1992-2018 Free Software Foundation, Inc.
 
-timestamp='2018-08-02'
+timestamp='2018-08-29'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -838,7 +838,7 @@ EOF
     *:BSD/OS:*:*)
        echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
        exit ;;
-    arm*:FreeBSD:*:*)
+    arm:FreeBSD:*:*)
        UNAME_PROCESSOR=`uname -p`
        set_cc_for_build
        if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
diff --git a/build-aux/config.sub b/build-aux/config.sub
index 49b1673..b51fb8c 100755
--- a/build-aux/config.sub
+++ b/build-aux/config.sub
@@ -2,7 +2,7 @@
 # Configuration validation subroutine script.
 #   Copyright 1992-2018 Free Software Foundation, Inc.
 
-timestamp='2018-08-24'
+timestamp='2018-08-29'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -639,194 +639,162 @@ case $1 in
                ;;
 esac
 
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
 case $basic_machine in
        # Here we handle the default manufacturer of certain CPU types.  It is 
in
        # some cases the only manufacturer, in others, it is the most popular.
-       craynv)
-               basic_machine=craynv-cray
-               os=${os:-unicosmp}
-               ;;
-       fx80)
-               basic_machine=fx80-alliant
-               ;;
        w89k)
-               basic_machine=hppa1.1-winbond
+               cpu=hppa1.1
+               vendor=winbond
                ;;
        op50n)
-               basic_machine=hppa1.1-oki
+               cpu=hppa1.1
+               vendor=oki
                ;;
        op60c)
-               basic_machine=hppa1.1-oki
-               ;;
-       romp)
-               basic_machine=romp-ibm
-               ;;
-       mmix)
-               basic_machine=mmix-knuth
-               ;;
-       rs6000)
-               basic_machine=rs6000-ibm
+               cpu=hppa1.1
+               vendor=oki
                ;;
-       vax)
-               basic_machine=vax-dec
-               ;;
-       pdp11)
-               basic_machine=pdp11-dec
-               ;;
-       we32k)
-               basic_machine=we32k-att
-               ;;
-       cydra)
-               basic_machine=cydra-cydrome
-               ;;
-       i370-ibm* | ibm*)
-               basic_machine=i370-ibm
-               ;;
-       orion)
-               basic_machine=orion-highlevel
+       ibm*)
+               cpu=i370
+               vendor=ibm
                ;;
        orion105)
-               basic_machine=clipper-highlevel
+               cpu=clipper
+               vendor=highlevel
                ;;
        mac | mpw | mac-mpw)
-               basic_machine=m68k-apple
-               ;;
-       microblaze | microblazeel)
-               basic_machine=$basic_machine-xilinx
+               cpu=m68k
+               vendor=apple
                ;;
        pmac | pmac-mpw)
-               basic_machine=powerpc-apple
-               ;;
-       xps | xps100)
-               basic_machine=xps100-honeywell
+               cpu=powerpc
+               vendor=apple
                ;;
 
        # Recognize the various machine names and aliases which stand
        # for a CPU type and a company and sometimes even an OS.
        3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-               basic_machine=m68000-att
+               cpu=m68000
+               vendor=att
                ;;
        3b*)
-               basic_machine=we32k-att
-               ;;
-       blackfin-*)
-               basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               os=linux
+               cpu=we32k
+               vendor=att
                ;;
        bluegene*)
-               basic_machine=powerpc-ibm
+               cpu=powerpc
+               vendor=ibm
                os=cnk
                ;;
-       c54x-*)
-               basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       c55x-*)
-               basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       c6x-*)
-               basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       c90)
-               basic_machine=c90-cray
-               os=${os:-unicos}
-               ;;
        decsystem10* | dec10*)
-               basic_machine=pdp10-dec
+               cpu=pdp10
+               vendor=dec
                os=tops10
                ;;
        decsystem20* | dec20*)
-               basic_machine=pdp10-dec
+               cpu=pdp10
+               vendor=dec
                os=tops20
                ;;
        delta | 3300 | motorola-3300 | motorola-delta \
              | 3300-motorola | delta-motorola)
-               basic_machine=m68k-motorola
-               ;;
-       dpx20 | dpx20-*)
-               basic_machine=rs6000-bull
-               os=${os:-bosx}
+               cpu=m68k
+               vendor=motorola
                ;;
        dpx2*)
-               basic_machine=m68k-bull
+               cpu=m68k
+               vendor=bull
                os=sysv3
                ;;
-       e500v[12])
-               basic_machine=powerpc-unknown
-               os=$os"spe"
-               ;;
-       e500v[12]-*)
-               basic_machine=powerpc-`echo "$basic_machine" | sed 
's/^[^-]*-//'`
-               os=$os"spe"
-               ;;
        encore | umax | mmax)
-               basic_machine=ns32k-encore
+               cpu=ns32k
+               vendor=encore
                ;;
        elxsi)
-               basic_machine=elxsi-elxsi
+               cpu=elxsi
+               vendor=elxsi
                os=${os:-bsd}
                ;;
        fx2800)
-               basic_machine=i860-alliant
+               cpu=i860
+               vendor=alliant
                ;;
        genix)
-               basic_machine=ns32k-ns
+               cpu=ns32k
+               vendor=ns
                ;;
        h3050r* | hiux*)
-               basic_machine=hppa1.1-hitachi
+               cpu=hppa1.1
+               vendor=hitachi
                os=hiuxwe2
                ;;
        hp3k9[0-9][0-9] | hp9[0-9][0-9])
-               basic_machine=hppa1.0-hp
+               cpu=hppa1.0
+               vendor=hp
                ;;
        hp9k2[0-9][0-9] | hp9k31[0-9])
-               basic_machine=m68000-hp
+               cpu=m68000
+               vendor=hp
                ;;
        hp9k3[2-9][0-9])
-               basic_machine=m68k-hp
+               cpu=m68k
+               vendor=hp
                ;;
        hp9k6[0-9][0-9] | hp6[0-9][0-9])
-               basic_machine=hppa1.0-hp
+               cpu=hppa1.0
+               vendor=hp
                ;;
        hp9k7[0-79][0-9] | hp7[0-79][0-9])
-               basic_machine=hppa1.1-hp
+               cpu=hppa1.1
+               vendor=hp
                ;;
        hp9k78[0-9] | hp78[0-9])
                # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
+               cpu=hppa1.1
+               vendor=hp
                ;;
        hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | 
hp9k893 | hp893)
                # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
+               cpu=hppa1.1
+               vendor=hp
                ;;
        hp9k8[0-9][13679] | hp8[0-9][13679])
-               basic_machine=hppa1.1-hp
+               cpu=hppa1.1
+               vendor=hp
                ;;
        hp9k8[0-9][0-9] | hp8[0-9][0-9])
-               basic_machine=hppa1.0-hp
+               cpu=hppa1.0
+               vendor=hp
                ;;
        i*86v32)
-               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+               cpu=`echo "$1" | sed -e 's/86.*/86/'`
+               vendor=pc
                os=sysv32
                ;;
        i*86v4*)
-               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+               cpu=`echo "$1" | sed -e 's/86.*/86/'`
+               vendor=pc
                os=sysv4
                ;;
        i*86v)
-               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+               cpu=`echo "$1" | sed -e 's/86.*/86/'`
+               vendor=pc
                os=sysv
                ;;
        i*86sol2)
-               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+               cpu=`echo "$1" | sed -e 's/86.*/86/'`
+               vendor=pc
                os=solaris2
                ;;
        j90 | j90-cray)
-               basic_machine=j90-cray
+               cpu=j90
+               vendor=cray
                os=${os:-unicos}
                ;;
        iris | iris4d)
-               basic_machine=mips-sgi
+               cpu=mips
+               vendor=sgi
                case $os in
                    irix*)
                        ;;
@@ -835,35 +803,23 @@ case $basic_machine in
                        ;;
                esac
                ;;
-       leon-*|leon[3-9]-*)
-               basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
-               ;;
-       m68knommu-*)
-               basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               os=linux
-               ;;
        miniframe)
-               basic_machine=m68000-convergent
+               cpu=m68000
+               vendor=convergent
                ;;
        *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
-               basic_machine=m68k-atari
+               cpu=m68k
+               vendor=atari
                os=mint
                ;;
-       mips3*-*)
-               basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
-               ;;
-       mips3*)
-               basic_machine=`echo "$basic_machine" | sed -e 
's/mips3/mips64/'`-unknown
-               ;;
-       ms1-*)
-               basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
-               ;;
        news-3600 | risc-news)
-               basic_machine=mips-sony
+               cpu=mips
+               vendor=sony
                os=newsos
                ;;
        next | m*-next)
-               basic_machine=m68k-next
+               cpu=m68k
+               vendor=next
                case $os in
                    nextstep* )
                        ;;
@@ -876,441 +832,437 @@ case $basic_machine in
                esac
                ;;
        np1)
-               basic_machine=np1-gould
+               cpu=np1
+               vendor=gould
                ;;
        op50n-* | op60c-*)
-               basic_machine=hppa1.1-oki
+               cpu=hppa1.1
+               vendor=oki
                os=proelf
                ;;
-       openrisc | openrisc-*)
-               basic_machine=or32-unknown
-               ;;
        pa-hitachi)
-               basic_machine=hppa1.1-hitachi
+               cpu=hppa1.1
+               vendor=hitachi
                os=hiuxwe2
                ;;
-       parisc-*)
-               basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               os=linux
-               ;;
        pbd)
-               basic_machine=sparc-tti
+               cpu=sparc
+               vendor=tti
                ;;
        pbb)
-               basic_machine=m68k-tti
+               cpu=m68k
+               vendor=tti
                ;;
-       pc532 | pc532-*)
-               basic_machine=ns32k-pc532
+       pc532)
+               cpu=ns32k
+               vendor=pc532
                ;;
-       pc98-*)
-               basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       pn)
+               cpu=pn
+               vendor=gould
                ;;
-       pentium | p5 | k5 | k6 | nexgen | viac3)
-               basic_machine=i586-pc
+       power)
+               cpu=power
+               vendor=ibm
                ;;
-       pentiumpro | p6 | 6x86 | athlon | athlon_*)
-               basic_machine=i686-pc
+       ps2)
+               cpu=i386
+               vendor=ibm
                ;;
-       pentiumii | pentium2 | pentiumiii | pentium3)
-               basic_machine=i686-pc
+       rm[46]00)
+               cpu=mips
+               vendor=siemens
                ;;
-       pentium4)
-               basic_machine=i786-pc
+       rtpc | rtpc-*)
+               cpu=romp
+               vendor=ibm
                ;;
-       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-               basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       sde)
+               cpu=mipsisa32
+               vendor=sde
+               os=${os:-elf}
                ;;
-       pentiumpro-* | p6-* | 6x86-* | athlon-*)
-               basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       simso-wrs)
+               cpu=sparclite
+               vendor=wrs
+               os=vxworks
                ;;
-       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-               basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       tower | tower-32)
+               cpu=m68k
+               vendor=ncr
                ;;
-       pentium4-*)
-               basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       vpp*|vx|vx-*)
+               cpu=f301
+               vendor=fujitsu
                ;;
-       pn)
-               basic_machine=pn-gould
+       w65)
+               cpu=w65
+               vendor=wdc
                ;;
-       power)  basic_machine=power-ibm
+       w89k-*)
+               cpu=hppa1.1
+               vendor=winbond
+               os=proelf
                ;;
-       ppc | ppcbe)    basic_machine=powerpc-unknown
+       none)
+               cpu=none
+               vendor=none
                ;;
-       ppc-* | ppcbe-*)
-               basic_machine=powerpc-`echo "$basic_machine" | sed 
's/^[^-]*-//'`
+       leon|leon[3-9])
+               cpu=sparc
+               vendor=$basic_machine
                ;;
-       ppcle | powerpclittle)
-               basic_machine=powerpcle-unknown
+       leon-*|leon[3-9]-*)
+               cpu=sparc
+               vendor=`echo "$basic_machine" | sed 's/-.*//'`
                ;;
-       ppcle-* | powerpclittle-*)
-               basic_machine=powerpcle-`echo "$basic_machine" | sed 
's/^[^-]*-//'`
+
+       *-*)
+               IFS="-" read -r cpu vendor <<EOF
+$basic_machine
+EOF
                ;;
-       ppc64)  basic_machine=powerpc64-unknown
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+               cpu=$basic_machine
+               vendor=pc
                ;;
-       ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 
's/^[^-]*-//'`
+       # These rules are duplicated from below for sake of the special case 
above;
+       # i.e. things that normalized to x86 arches should also default to "pc"
+       pc98)
+               cpu=i386
+               vendor=pc
                ;;
-       ppc64le | powerpc64little)
-               basic_machine=powerpc64le-unknown
+       x64 | amd64)
+               cpu=x86_64
+               vendor=pc
                ;;
-       ppc64le-* | powerpc64little-*)
-               basic_machine=powerpc64le-`echo "$basic_machine" | sed 
's/^[^-]*-//'`
+       # Recognize the basic CPU types without company name.
+       *)
+               cpu=$basic_machine
+               vendor=unknown
                ;;
-       ps2)
-               basic_machine=i386-ibm
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+       # Here we handle the default manufacturer of certain CPU types in 
cannonical form. It is in
+       # some cases the only manufacturer, in others, it is the most popular.
+       craynv-unknown)
+               vendor=cray
+               os=${os:-unicosmp}
                ;;
-       rm[46]00)
-               basic_machine=mips-siemens
+       c90-unknown | c90-cray)
+               vendor=cray
+               os=${os:-unicos}
                ;;
-       rtpc | rtpc-*)
-               basic_machine=romp-ibm
+       fx80-unknown)
+               vendor=alliant
                ;;
-       sb1)
-               basic_machine=mipsisa64sb1-unknown
+       romp-unknown)
+               vendor=ibm
                ;;
-       sb1el)
-               basic_machine=mipsisa64sb1el-unknown
+       mmix-unknown)
+               vendor=knuth
                ;;
-       sde)
-               basic_machine=mipsisa32-sde
-               os=${os:-elf}
+       microblaze-unknown | microblazeel-unknown)
+               vendor=xilinx
                ;;
-       sh5el)
-               basic_machine=sh5le-unknown
+       rs6000-unknown)
+               vendor=ibm
                ;;
-       sh5el-*)
-               basic_machine=sh5le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       vax-unknown)
+               vendor=dec
                ;;
-       simso-wrs)
-               basic_machine=sparclite-wrs
-               os=vxworks
+       pdp11-unknown)
+               vendor=dec
                ;;
-       spur)
-               basic_machine=spur-unknown
+       we32k-unknown)
+               vendor=att
                ;;
-       strongarm-* | thumb-*)
-               basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+       cydra-unknown)
+               vendor=cydrome
                ;;
-       tx39)
-               basic_machine=mipstx39-unknown
+       i370-ibm*)
+               vendor=ibm
                ;;
-       tx39el)
-               basic_machine=mipstx39el-unknown
+       orion-unknown)
+               vendor=highlevel
                ;;
-       tower | tower-32)
-               basic_machine=m68k-ncr
+       xps-unknown | xps100-unknown)
+               cpu=xps100
+               vendor=honeywell
                ;;
-       vpp*|vx|vx-*)
-               basic_machine=f301-fujitsu
+
+       # Here we normalize CPU types with a missing or matching vendor
+       dpx20-unknown | dpx20-bull)
+               cpu=rs6000
+               vendor=bull
+               os=${os:-bosx}
                ;;
-       w65)
-               basic_machine=w65-wdc
+
+       # Here we normalize CPU types irrespective of the vendor
+       amd64-*)
+               cpu=x86_64
                ;;
-       w89k-*)
-               basic_machine=hppa1.1-winbond
-               os=proelf
+       blackfin-*)
+               cpu=bfin
+               os=linux
                ;;
-       xscale-* | xscalee[bl]-*)
-               basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
+       c54x-*)
+               cpu=tic54x
                ;;
-       none)
-               basic_machine=none-none
+       c55x-*)
+               cpu=tic55x
                ;;
-
-       c54x)
-               basic_machine=tic54x-unknown
+       c6x-*)
+               cpu=tic6x
                ;;
-       c55x)
-               basic_machine=tic55x-unknown
+       e500v[12]-*)
+               cpu=powerpc
+               os=$os"spe"
                ;;
-       c6x)
-               basic_machine=tic6x-unknown
+       mips3*-*)
+               cpu=mips64
                ;;
-       leon | leon[3-9])
-               basic_machine=sparc-$basic_machine
+       ms1-*)
+               cpu=mt
                ;;
-       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70)
+       m68knommu-*)
+               cpu=m68k
+               os=linux
                ;;
-       ms1)
-               basic_machine=mt-unknown
+       m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+               cpu=s12z
                ;;
-       strongarm | thumb | xscale)
-               basic_machine=arm-unknown
+       openrisc-*)
+               cpu=or32
                ;;
-       xscaleeb)
-               basic_machine=armeb-unknown
+       parisc-*)
+               cpu=hppa
+               os=linux
                ;;
-
-       xscaleel)
-               basic_machine=armel-unknown
+       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+               cpu=i586
                ;;
-
-       # We use `pc' rather than `unknown'
-       # because (1) that's what they normally are, and
-       # (2) the word "unknown" tends to confuse beginning users.
-       i*86 | x86_64)
-               basic_machine=$basic_machine-pc
+       pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+               cpu=i686
                ;;
-       # These rules are duplicated from below for sake of the special case 
above;
-       # i.e. things that normalized to x86 arches should also default to "pc"
-       pc98)
-               basic_machine=i386-pc
+       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+               cpu=i686
                ;;
-       x64 | amd64)
-               basic_machine=x86_64-pc
+       pentium4-*)
+               cpu=i786
+               ;;
+       pc98-*)
+               cpu=i386
+               ;;
+       ppc-* | ppcbe-*)
+               cpu=powerpc
+               ;;
+       ppcle-* | powerpclittle-*)
+               cpu=powerpcle
+               ;;
+       ppc64-*)
+               cpu=powerpc64
+               ;;
+       ppc64le-* | powerpc64little-*)
+               cpu=powerpc64le
+               ;;
+       sb1-*)
+               cpu=mipsisa64sb1
+               ;;
+       sb1el-*)
+               cpu=mipsisa64sb1el
+               ;;
+       sh5e[lb]-*)
+               cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
+               ;;
+       spur-*)
+               cpu=spur
+               ;;
+       strongarm-* | thumb-*)
+               cpu=arm
+               ;;
+       tx39-*)
+               cpu=mipstx39
+               ;;
+       tx39el-*)
+               cpu=mipstx39el
+               ;;
+       x64-*)
+               cpu=x86_64
+               ;;
+       xscale-* | xscalee[bl]-*)
+               cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
                ;;
 
        # Recognize the cannonical CPU Types that limit and/or modify the
        # company names they are paired with.
-       amd64-*)
-               basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
-       cr16)
-               basic_machine=cr16-unknown
-               os=${os:-elf}
-               ;;
        cr16-*)
                os=${os:-elf}
                ;;
-       crisv32 | crisv32-* | etraxfs*)
-               basic_machine=crisv32-axis
+       crisv32-* | etraxfs*-*)
+               cpu=crisv32
+               vendor=axis
                ;;
-       cris | cris-* | etrax*)
-               basic_machine=cris-axis
+       cris-* | etrax*-*)
+               cpu=cris
+               vendor=axis
                ;;
        crx-*)
                os=${os:-elf}
                ;;
-       crx)
-               basic_machine=crx-unknown
-               os=${os:-elf}
-               ;;
-       m9s12z | m68hcs12z | hcs12z | s12z)
-               basic_machine=s12z-unknown
-               ;;
-       m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
-               basic_machine=s12z-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-               ;;
        neo-tandem)
-               basic_machine=neo-tandem
+               cpu=neo
+               vendor=tandem
                ;;
        nse-tandem)
-               basic_machine=nse-tandem
+               cpu=nse
+               vendor=tandem
                ;;
        nsr-tandem)
-               basic_machine=nsr-tandem
+               cpu=nsr
+               vendor=tandem
                ;;
        nsv-tandem)
-               basic_machine=nsv-tandem
+               cpu=nsv
+               vendor=tandem
                ;;
        nsx-tandem)
-               basic_machine=nsx-tandem
+               cpu=nsx
+               vendor=tandem
                ;;
-       s390 | s390-*)
-               basic_machine=s390-ibm
+       s390-*)
+               cpu=s390
+               vendor=ibm
                ;;
-       s390x | s390x-*)
-               basic_machine=s390x-ibm
+       s390x-*)
+               cpu=s390x
+               vendor=ibm
                ;;
        tile*-*)
                os=${os:-linux-gnu}
                ;;
-       tile*)
-               basic_machine=$basic_machine-unknown
-               os=${os:-linux-gnu}
-               ;;
-
-       # Recognize the cannonical CPU types that are allowed with any
-       # company name.
-       1750a-* | 580-* \
-       | a29k-* \
-       | aarch64-* | aarch64_be-* \
-       | abacus-* \
-       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-       | alphapca5[67]-* | alpha64pca5[67]-* \
-       | am33_2.0-* \
-       | arc-* | arceb-* \
-       | arm-*  | arm[lb]e-* | arme[lb]-* | armv*-* \
-       | avr-* | avr32-* \
-       | asmjs-* \
-       | ba-* \
-       | be32-* | be64-* \
-       | bfin-* | bs2000-* \
-       | c[123]* | c30-* | [cjt]90-* | c4x-* \
-       | c8051-* | clipper-* | craynv-* | csky-* | cydra-* \
-       | d10v-* | d30v-* | dlx-* | dsp16xx-* \
-       | e2k-* | elxsi-* | epiphany-* \
-       | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | ft32-* | fx80-* \
-       | h8300-* | h8500-* \
-       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-       | hexagon-* \
-       | i370-* | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
-       | ip2k-* | iq2000-* \
-       | k1om-* \
-       | le32-* | le64-* \
-       | lm32-* \
-       | m32c-* | m32r-* | m32rle-* \
-       | m5200-* | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* | 
v70-* | w65-* \
-       | m6811-* | m68hc11-* | m6812-* | m68hc12-* | m68hcs12x-* | nvptx-* | 
picochip-* \
-       | m88110-* | m88k-* | maxq-* | mb-* | mcore-* | mep-* | metag-* \
-       | microblaze-* | microblazeel-* \
-       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-       | mips16-* \
-       | mips64-* | mips64el-* \
-       | mips64octeon-* | mips64octeonel-* \
-       | mips64orion-* | mips64orionel-* \
-       | mips64r5900-* | mips64r5900el-* \
-       | mips64vr-* | mips64vrel-* \
-       | mips64vr4100-* | mips64vr4100el-* \
-       | mips64vr4300-* | mips64vr4300el-* \
-       | mips64vr5000-* | mips64vr5000el-* \
-       | mips64vr5900-* | mips64vr5900el-* \
-       | mipsisa32-* | mipsisa32el-* \
-       | mipsisa32r2-* | mipsisa32r2el-* \
-       | mipsisa32r6-* | mipsisa32r6el-* \
-       | mipsisa64-* | mipsisa64el-* \
-       | mipsisa64r2-* | mipsisa64r2el-* \
-       | mipsisa64r6-* | mipsisa64r6el-* \
-       | mipsisa64sb1-* | mipsisa64sb1el-* \
-       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
-       | mipsr5900-* | mipsr5900el-* \
-       | mipstx39-* | mipstx39el-* \
-       | mmix-* \
-       | mn10200-* | mn10300-* \
-       | moxie-* \
-       | mt-* \
-       | msp430-* \
-       | nds32-* | nds32le-* | nds32be-* \
-       | nfp-* \
-       | nios-* | nios2-* | nios2eb-* | nios2el-* \
-       | none-* | np1-* | ns16k-* | ns32k-* \
-       | open8-* \
-       | or1k*-* \
-       | or32-* \
-       | orion-* \
-       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | powerpcspe-* \
-       | pru-* \
-       | pyramid-* \
-       | riscv-* | riscv32-* | riscv64-* \
-       | rl78-* | romp-* | rs6000-* | rx-* \
-       | score-* \
-       | sh-* | sh[1234]-* | sh[24]a-* | sh[24]ae[lb]-* | sh[23]e-* | 
she[lb]-* | sh[lb]e-* \
-       | sh[1234]e[lb]-* |  sh[12345][lb]e-* | sh[23]ele-* | sh64-* | sh64le-* 
\
-       | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | 
sparclet-* \
-       | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
-       | spu-* \
-       | tahoe-* \
-       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-       | tron-* \
-       | ubicom32-* \
-       | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
-       | vax-* \
-       | visium-* \
-       | wasm32-* \
-       | we32k-* \
-       | x86-* | x86_64-* | xc16x-* | xgate-* | xps100-* \
-       | xstormy16-* | xtensa*-* \
-       | ymp-* \
-       | z8k-* | z80-*)
-               ;;
-
-       # Recognize the basic CPU types without company name.
-       # Some are omitted here because they have special meanings below.
-       1750a | 580 \
-       | a29k \
-       | aarch64 | aarch64_be \
-       | abacus \
-       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | 
alpha64pca5[67] \
-       | am33_2.0 \
-       | arc | arceb \
-       | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv6m | 
armv[78][arm] \
-       | avr | avr32 \
-       | asmjs \
-       | ba \
-       | be32 | be64 \
-       | bfin \
-       | c4x | c8051 | clipper | csky \
-       | d10v | d30v | dlx | dsp16xx \
-       | e2k | epiphany \
-       | fido | fr30 | frv | ft32 \
-       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-       | hexagon \
-       | i370 | i860 | i960 | ia16 | ia64 \
-       | ip2k | iq2000 \
-       | k1om \
-       | le32 | le64 \
-       | lm32 \
-       | m32c | m32r | m32rle | m68000 | m68k | m88k \
-       | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip \
-       | maxq | mb | mcore | mep | metag \
-       | mips | mipsbe | mipseb | mipsel | mipsle \
-       | mips16 \
-       | mips64 | mips64el \
-       | mips64octeon | mips64octeonel \
-       | mips64orion | mips64orionel \
-       | mips64r5900 | mips64r5900el \
-       | mips64vr | mips64vrel \
-       | mips64vr4100 | mips64vr4100el \
-       | mips64vr4300 | mips64vr4300el \
-       | mips64vr5000 | mips64vr5000el \
-       | mips64vr5900 | mips64vr5900el \
-       | mipsisa32 | mipsisa32el \
-       | mipsisa32r2 | mipsisa32r2el \
-       | mipsisa32r6 | mipsisa32r6el \
-       | mipsisa64 | mipsisa64el \
-       | mipsisa64r2 | mipsisa64r2el \
-       | mipsisa64r6 | mipsisa64r6el \
-       | mipsisa64sb1 | mipsisa64sb1el \
-       | mipsisa64sr71k | mipsisa64sr71kel \
-       | mipsr5900 | mipsr5900el \
-       | mipstx39 | mipstx39el \
-       | mn10200 | mn10300 \
-       | moxie \
-       | mt \
-       | msp430 \
-       | nds32 | nds32le | nds32be \
-       | nfp \
-       | nios | nios2 | nios2eb | nios2el \
-       | ns16k | ns32k \
-       | open8 | or1k | or1knd | or32 \
-       | pdp10 | pj | pjl \
-       | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
-       | pru \
-       | pyramid \
-       | riscv | riscv32 | riscv64 \
-       | rl78 | rx \
-       | score \
-       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | 
shbe | shle | sh[1234]le | sh[23]ele \
-       | sh64 | sh64le \
-       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | 
sparclite \
-       | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-       | spu \
-       | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
-       | ubicom32 \
-       | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-       | visium \
-       | wasm32 \
-       | x86 | xc16x | xstormy16 | xgate | xtensa* \
-       | z8k | z80)
-               basic_machine=$basic_machine-unknown
-               ;;
 
        *)
-               echo Invalid configuration \`"$1"\': machine 
\`"$basic_machine"\' not recognized 1>&2
-               exit 1
+               # Recognize the cannonical CPU types that are allowed with any
+               # company name.
+               case $cpu in
+                       1750a | 580 \
+                       | a29k \
+                       | aarch64 | aarch64_be \
+                       | abacus \
+                       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+                       | alpha64 | alpha64ev[4-8] | alpha64ev56 | 
alpha64ev6[78] \
+                       | alphapca5[67] | alpha64pca5[67] \
+                       | am33_2.0 \
+                       | arc | arceb \
+                       | arm  | arm[lb]e | arme[lb] | armv* \
+                       | avr | avr32 \
+                       | asmjs \
+                       | ba \
+                       | be32 | be64 \
+                       | bfin | bs2000 \
+                       | c[123]* | c30 | [cjt]90 | c4x \
+                       | c8051 | clipper | craynv | csky | cydra \
+                       | d10v | d30v | dlx | dsp16xx \
+                       | e2k | elxsi | epiphany \
+                       | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+                       | h8300 | h8500 \
+                       | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+                       | hexagon \
+                       | i370 | i*86 | i860 | i960 | ia16 | ia64 \
+                       | ip2k | iq2000 \
+                       | k1om \
+                       | le32 | le64 \
+                       | lm32 \
+                       | m32c | m32r | m32rle \
+                       | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | 
m68k | v70 | w65 \
+                       | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx 
| picochip \
+                       | m88110 | m88k | maxq | mb | mcore | mep | metag \
+                       | microblaze | microblazeel \
+                       | mips | mipsbe | mipseb | mipsel | mipsle \
+                       | mips16 \
+                       | mips64 | mips64el \
+                       | mips64octeon | mips64octeonel \
+                       | mips64orion | mips64orionel \
+                       | mips64r5900 | mips64r5900el \
+                       | mips64vr | mips64vrel \
+                       | mips64vr4100 | mips64vr4100el \
+                       | mips64vr4300 | mips64vr4300el \
+                       | mips64vr5000 | mips64vr5000el \
+                       | mips64vr5900 | mips64vr5900el \
+                       | mipsisa32 | mipsisa32el \
+                       | mipsisa32r2 | mipsisa32r2el \
+                       | mipsisa32r6 | mipsisa32r6el \
+                       | mipsisa64 | mipsisa64el \
+                       | mipsisa64r2 | mipsisa64r2el \
+                       | mipsisa64r6 | mipsisa64r6el \
+                       | mipsisa64sb1 | mipsisa64sb1el \
+                       | mipsisa64sr71k | mipsisa64sr71kel \
+                       | mipsr5900 | mipsr5900el \
+                       | mipstx39 | mipstx39el \
+                       | mmix \
+                       | mn10200 | mn10300 \
+                       | moxie \
+                       | mt \
+                       | msp430 \
+                       | nds32 | nds32le | nds32be \
+                       | nfp \
+                       | nios | nios2 | nios2eb | nios2el \
+                       | none | np1 | ns16k | ns32k \
+                       | open8 \
+                       | or1k* \
+                       | or32 \
+                       | orion \
+                       | pdp10 | pdp11 | pj | pjl | pn | power \
+                       | powerpc | powerpc64 | powerpc64le | powerpcle | 
powerpcspe \
+                       | pru \
+                       | pyramid \
+                       | riscv | riscv32 | riscv64 \
+                       | rl78 | romp | rs6000 | rx \
+                       | score \
+                       | sh | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | 
she[lb] | sh[lb]e \
+                       | sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | 
sh64le \
+                       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | 
sparclet \
+                       | sparclite \
+                       | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+                       | spu \
+                       | tahoe \
+                       | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+                       | tron \
+                       | ubicom32 \
+                       | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+                       | vax \
+                       | visium \
+                       | wasm32 \
+                       | we32k \
+                       | x86 | x86_64 | xc16x | xgate | xps100 \
+                       | xstormy16 | xtensa* \
+                       | ymp \
+                       | z8k | z80)
+                               ;;
+
+                       *)
+                               echo Invalid configuration \`"$1"\': machine 
\`"$cpu-$vendor"\' not recognized 1>&2
+                               exit 1
+                               ;;
+               esac
                ;;
 esac
 
 # Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-       *-digital*)
-               basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
+case $vendor in
+       digital*)
+               vendor=dec
                ;;
-       *-commodore*)
-               basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
+       commodore*)
+               vendor=cbm
                ;;
        *)
                ;;
@@ -1412,8 +1364,8 @@ case $os in
        # Remember, each alternative MUST END IN *, to match a version number.
                ;;
        qnx*)
-               case $basic_machine in
-                   x86-* | i*86-*)
+               case $cpu in
+                   x86 | i*86)
                        ;;
                    *)
                        os=nto-$os
@@ -1539,7 +1491,7 @@ case $os in
                # Until real need of OS specific support for
                # particular features comes up, bare metal
                # configurations are quite functional.
-               case $basic_machine in
+               case $cpu in
                    arm*)
                        os=eabi
                        ;;
@@ -1573,7 +1525,7 @@ else
 # will signal an error saying that MANUFACTURER isn't an operating
 # system, and we'll never get to this point.
 
-case $basic_machine in
+case $cpu-$vendor in
        score-*)
                os=elf
                ;;
@@ -1754,9 +1706,8 @@ fi
 
 # Here we handle the case where we know the os, and the CPU type, but not the
 # manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-       *-unknown)
+case $vendor in
+       unknown)
                case $os in
                        riscix*)
                                vendor=acorn
@@ -1825,11 +1776,10 @@ case $basic_machine in
                                vendor=stratus
                                ;;
                esac
-               basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
                ;;
 esac
 
-echo "$basic_machine-$os"
+echo "$cpu-$vendor-$os"
 exit
 
 # Local variables:
diff --git a/doc/emacs/Makefile.in b/doc/emacs/Makefile.in
index 1da2f15..54e173f 100644
--- a/doc/emacs/Makefile.in
+++ b/doc/emacs/Makefile.in
@@ -206,8 +206,8 @@ doc-emacsver:
 
 ## Temp files.
 mostlyclean:
-       rm -f *.aux *.log *.toc *.cp *.cps *.fn *.fns *.ky *.kys \
-         *.op *.ops *.pg *.pgs *.tp *.tps *.vr *.vrs
+       rm -f ./*.aux ./*.log ./*.toc ./*.cp ./*.cps ./*.fn ./*.fns ./*.ky 
./*.kys \
+         ./*.op ./*.ops ./*.pg ./*.pgs ./*.tp ./*.tps ./*.vr ./*.vrs
 
 ## Products not in the release tarfiles.
 clean: mostlyclean
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index 51e36ea..ddde5b22 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -1059,6 +1059,10 @@ local variable specifications; it automatically makes 
these variables
 local to the buffer, and sets them to the values specified in the
 file.
 
+  File local variables override directory local variables
+(@pxref{Directory Variables}), if any are specified for a file's
+directory.
+
 @menu
 * Specifying File Variables:: Specifying file local variables.
 * Safe File Variables::       Making sure file local variables are safe.
@@ -1309,7 +1313,12 @@ confirmation about processing @code{eval} variables.
   Sometimes, you may wish to define the same set of local variables to
 all the files in a certain directory and its subdirectories, such as
 the directory tree of a large software project.  This can be
-accomplished with @dfn{directory-local variables}.
+accomplished with @dfn{directory-local variables}.  File local
+variables override directory local variables, so if some of the files
+in a directory need specialized settings, you can specify the settings
+for the majority of the directory's files in directory variables, and
+then define file local variables in a few files which need the general
+settings overridden.
 
 @cindex @file{.dir-locals.el} file
   The usual way to define directory-local variables is to put a file
diff --git a/doc/emacs/kmacro.texi b/doc/emacs/kmacro.texi
index dac41fd..0151c81 100644
--- a/doc/emacs/kmacro.texi
+++ b/doc/emacs/kmacro.texi
@@ -49,15 +49,19 @@ intelligent or general.  For such things, Lisp must be used.
 
 @table @kbd
 @item @key{F3}
address@hidden C-x (
 Start defining a keyboard macro
 (@code{kmacro-start-macro-or-insert-counter}).
 @item @key{F4}
address@hidden C-x e
 If a keyboard macro is being defined, end the definition; otherwise,
 execute the most recent keyboard macro
 (@code{kmacro-end-or-call-macro}).
 @item C-u @key{F3}
address@hidden C-u C-x (
 Re-execute last keyboard macro, then append keys to its definition.
 @item C-u C-u @key{F3}
address@hidden C-u C-u C-x (
 Append keys to the last keyboard macro without re-executing it.
 @item C-x C-k r
 Run the last keyboard macro on each line that begins in the region
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 5c3017a..4527c23 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -1981,7 +1981,7 @@ table.
 @item M-x tags-query-replace @key{RET} @var{regexp} @key{RET} 
@var{replacement} @key{RET}
 Perform a @code{query-replace-regexp} on each file in the selected tags table.
 
address@hidden M-x tags-loop-continue
address@hidden M-x multifile-continue
 Restart one of the last 2 commands above, from the current location of point.
 @end table
 
@@ -2017,9 +2017,9 @@ you can follow its progress.  As soon as it finds an 
occurrence,
 @code{tags-search} returns.  This command requires tags tables to be
 available (@pxref{Tags Tables}).
 
address@hidden tags-loop-continue
address@hidden multifile-continue
   Having found one match with @code{tags-search}, you probably want to
-find all the rest.  @kbd{M-x tags-loop-continue} resumes the
+find all the rest.  @kbd{M-x multifile-continue} resumes the
 @code{tags-search}, finding one more match.  This searches the rest of
 the current buffer, followed by the remaining files of the tags table.
 
@@ -2042,10 +2042,10 @@ default is to use the same setting as the value of
 single invocation of @kbd{M-x tags-query-replace}.  But often it is
 useful to exit temporarily, which you can do with any input event that
 has no special query replace meaning.  You can resume the query
-replace subsequently by typing @kbd{M-x tags-loop-continue}; this
+replace subsequently by typing @kbd{M-x multifile-continue}; this
 command resumes the last tags search or replace command that you did.
 For instance, to skip the rest of the current file, you can type
address@hidden@kbd{M-> M-x tags-loop-continue}}.
address@hidden@kbd{M-> M-x multifile-continue}}.
 
   Note that the commands described above carry out much broader
 searches than the @code{xref-find-definitions} family.  The
@@ -2077,7 +2077,7 @@ Display a list of all known identifiers matching 
@var{regexp}.
 Display a list of the identifiers defined in the program file
 @var{file}.
 
address@hidden M-x next-file
address@hidden M-x tags-next-file
 Visit files recorded in the selected tags table.
 @end table
 
@@ -2116,8 +2116,8 @@ variable @code{tags-apropos-additional-actions}; see its 
documentation
 for details.
 @end ignore
 
address@hidden next-file
-  @kbd{M-x next-file} visits files covered by the selected tags table.
address@hidden tags-next-file
+  @kbd{M-x tags-next-file} visits files covered by the selected tags table.
 The first time it is called, it visits the first file covered by the
 table.  Each subsequent call visits the next covered file, unless a
 prefix argument is supplied, in which case it returns to the first
diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index c72558c..cfeb61e 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -274,6 +274,10 @@ Rescanning happens automatically if you set 
@code{imenu-auto-rescan} to
 a address@hidden value.  There is no need to rescan because of small
 changes in the text.
 
address@hidden imenu-auto-rescan-maxout
+  @code{imenu-auto-rescan} will be disabled in buffers that are larger
+than @code{imenu-auto-rescan-maxout} in bytes.
+
 @vindex imenu-sort-function
   You can customize the way the menus are sorted by setting the
 variable @code{imenu-sort-function}.  By default, names are ordered as
diff --git a/doc/lispintro/Makefile.in b/doc/lispintro/Makefile.in
index 71739fd..e2a1229 100644
--- a/doc/lispintro/Makefile.in
+++ b/doc/lispintro/Makefile.in
@@ -109,8 +109,8 @@ emacs-lisp-intro.ps: emacs-lisp-intro.dvi
 .PHONY: mostlyclean clean distclean bootstrap-clean maintainer-clean infoclean
 
 mostlyclean:
-       rm -f *.aux *.log *.toc *.cp *.cps *.fn *.fns *.ky *.kys \
-         *.op *.ops *.pg *.pgs *.tp *.tps *.vr *.vrs
+       rm -f ./*.aux ./*.log ./*.toc ./*.cp ./*.cps ./*.fn ./*.fns ./*.ky 
./*.kys \
+         ./*.op ./*.ops ./*.pg ./*.pgs ./*.tp ./*.tps ./*.vr ./*.vrs
 
 clean: mostlyclean
        rm -f $(DVI_TARGETS) $(HTML_TARGETS) $(PDF_TARGETS) $(PS_TARGETS)
diff --git a/doc/lispref/Makefile.in b/doc/lispref/Makefile.in
index 98ca90a..221f4f9 100644
--- a/doc/lispref/Makefile.in
+++ b/doc/lispref/Makefile.in
@@ -167,8 +167,8 @@ elisp.ps: elisp.dvi
 
 ## [12] stuff is from two-volume.make.
 mostlyclean:
-       rm -f *.aux *.log *.toc *.cp *.cps *.fn *.fns *.ky *.kys \
-         *.op *.ops *.pg *.pgs *.tp *.tps *.vr *.vrs
+       rm -f ./*.aux ./*.log ./*.toc ./*.cp ./*.cps ./*.fn ./*.fns ./*.ky 
./*.kys \
+         ./*.op ./*.ops ./*.pg ./*.pgs ./*.tp ./*.tps ./*.vr ./*.vrs
        rm -f elisp[12]* vol[12].tmp
 
 clean: mostlyclean
diff --git a/doc/lispref/abbrevs.texi b/doc/lispref/abbrevs.texi
index 087e694..4c9e653 100644
--- a/doc/lispref/abbrevs.texi
+++ b/doc/lispref/abbrevs.texi
@@ -122,7 +122,9 @@ System abbrevs are listed and identified as such.  
Otherwise the
 description is a Lisp expression---a call to @code{define-abbrev-table}
 that would define @var{name} as it is currently defined, but without
 the system abbrevs.  (The mode or package using @var{name} is supposed
-to add these to @var{name} separately.)
+to add these to @var{name} separately.)  If the Lisp expression would
+not define any abbrevs (i.e.@: it defines an empty abbrev table), this
+function inserts nothing.
 @end defun
 
 @node Defining Abbrevs
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 6cbda8f..fa64d07 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -1076,11 +1076,13 @@ the current Emacs session.  If a symbol has not yet 
been so used,
 @subsection Keyboard Events
 @cindex keyboard events
 
address@hidden character event
 There are two kinds of input you can get from the keyboard: ordinary
-keys, and function keys.  Ordinary keys correspond to characters; the
-events they generate are represented in Lisp as characters.  The event
-type of a character event is the character itself (an integer); see
address@hidden Events}.
+keys, and function keys.  Ordinary keys correspond to (possibly
+modified) characters; the events they generate are represented in Lisp
+as characters.  The event type of a @dfn{character event} is the
+character itself (an integer), which might have some modifier bits
+set; see @ref{Classifying Events}.
 
 @cindex modifier bits (of input character)
 @cindex basic code (of input character)
@@ -1124,7 +1126,7 @@ for @kbd{%} plus
 2**26
 @end ifnottex
 (assuming the terminal supports address@hidden
-control characters).
+control characters), i.e.@: with the 27th bit set.
 
 @item shift
 The
@@ -1134,8 +1136,8 @@ The
 @ifnottex
 2**25
 @end ifnottex
-bit in the character code indicates an @acronym{ASCII} control
-character typed with the shift key held down.
+bit (the 26th bit) in the character event code indicates an
address@hidden control character typed with the shift key held down.
 
 For letters, the basic code itself indicates upper versus lower case;
 for digits and punctuation, the shift key selects an entirely different
@@ -1147,7 +1149,7 @@ character with a different basic code.  In order to keep 
within the
 @ifnottex
 2**25
 @end ifnottex
-bit for those characters.
+bit for those character events.
 
 However, @acronym{ASCII} provides no way to distinguish @kbd{C-A} from
 @kbd{C-a}, so Emacs uses the
@@ -1168,7 +1170,7 @@ The
 @ifnottex
 2**24
 @end ifnottex
-bit in the character code indicates a character
+bit in the character event code indicates a character
 typed with the hyper key held down.
 
 @item super
@@ -1179,7 +1181,7 @@ The
 @ifnottex
 2**23
 @end ifnottex
-bit in the character code indicates a character
+bit in the character event code indicates a character
 typed with the super key held down.
 
 @item alt
@@ -1190,9 +1192,9 @@ The
 @ifnottex
 2**22
 @end ifnottex
-bit in the character code indicates a character typed with the alt key
-held down.  (The key labeled @key{Alt} on most keyboards is actually
-treated as the meta key, not this.)
+bit in the character event code indicates a character typed with the
+alt key held down.  (The key labeled @key{Alt} on most keyboards is
+actually treated as the meta key, not this.)
 @end table
 
   It is best to avoid mentioning specific bit numbers in your program.
@@ -1950,6 +1952,10 @@ Here are some examples:
 
 The modifiers list for a click event explicitly contains @code{click},
 but the event symbol name itself does not contain @samp{click}.
+Similarly, the modifiers list for an @acronym{ASCII} control
+character, such as @samp{C-a}, contains @code{control}, even though
+reading such an event via @code{read-char} will return the value 1
+with the control modifier bit removed.
 @end defun
 
 @defun event-basic-type event
@@ -2546,17 +2552,31 @@ right-arrow function key:
 @end defun
 
 @defun read-char &optional prompt inherit-input-method seconds
-This function reads and returns a character of command input.  If the
+This function reads and returns a character input event.  If the
 user generates an event which is not a character (i.e., a mouse click or
 function key event), @code{read-char} signals an error.  The arguments
 work as in @code{read-event}.
 
-In the first example, the user types the character @kbd{1} (@acronym{ASCII}
-code 49).  The second example shows a keyboard macro definition that
-calls @code{read-char} from the minibuffer using @code{eval-expression}.
address@hidden reads the keyboard macro's very next character, which
-is @kbd{1}.  Then @code{eval-expression} displays its return value in
-the echo area.
+If the event has modifiers, Emacs attempts to resolve them and return
+the code of the corresponding character.  For example, if the user
+types @kbd{C-a}, the function returns 1, which is the @acronym{ASCII}
+code of the @samp{C-a} character.  If some of the modifiers cannot be
+reflected in the character code, @code{read-char} leaves the
+unresolved modifier bits set in the returned event.  For example, if
+the user types @kbd{C-M-a}, the function returns 134217729, 8000001 in
+hex, i.e.@: @samp{C-a} with the Meta modifier bit set.  This value is
+not a valid character code: it fails the @code{characterp} test
+(@pxref{Character Codes}).  Use @code{event-basic-type}
+(@pxref{Classifying Events}) to recover the character code with the
+modifier bits removed; use @code{event-modifiers} to test for
+modifiers in the character event returned by @code{read-char}.
+
+In the first example below, the user types the character @kbd{1}
+(@acronym{ASCII} code 49).  The second example shows a keyboard macro
+definition that calls @code{read-char} from the minibuffer using
address@hidden  @code{read-char} reads the keyboard macro's
+very next character, which is @kbd{1}.  Then @code{eval-expression}
+displays its return value in the echo area.
 
 @example
 @group
@@ -2578,10 +2598,11 @@ the echo area.
 @end defun
 
 @defun read-char-exclusive &optional prompt inherit-input-method seconds
-This function reads and returns a character of command input.  If the
-user generates an event which is not a character,
+This function reads and returns a character input event.  If the
+user generates an event which is not a character event,
 @code{read-char-exclusive} ignores it and reads another event, until it
-gets a character.  The arguments work as in @code{read-event}.
+gets a character.  The arguments work as in @code{read-event}.  The
+returned value may include modifier bits, as with @code{read-char}.
 @end defun
 
   None of the above functions suppress quitting.
diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi
index 8a6cf73..0f7502f 100644
--- a/doc/lispref/control.texi
+++ b/doc/lispref/control.texi
@@ -791,7 +791,7 @@ Here are some important details about that usage.
 
 @enumerate
 @item When @var{symbol} occurs more than once in @var{seqpat},
-the second and subsequent occurances do not expand to re-binding,
+the second and subsequent occurrences do not expand to re-binding,
 but instead expand to an equality test using @code{eq}.
 
 The following example features a @code{pcase} form
diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi
index b3528b1..1cc7cb6 100644
--- a/doc/lispref/customize.texi
+++ b/doc/lispref/customize.texi
@@ -449,15 +449,14 @@ those other variables already have their intended values.
   It is useful to specify the @code{:require} keyword for an option
 that turns on a certain feature.  This causes Emacs to load the
 feature, if it is not already loaded, whenever the option is set.
address@hidden Keywords}.  Here is an example, from the library
address@hidden:
address@hidden Keywords}.  Here is an example:
 
 @example
-(defcustom save-place nil
-  "Non-nil means automatically save place in each file..."
+(defcustom frobnicate-automatically nil
+  "Non-nil means automatically frobnicate all buffers."
   :type 'boolean
-  :require 'saveplace
-  :group 'save-place)
+  :require 'frobnicate-mode
+  :group 'frobnicate)
 @end example
 
 If a customization item has a type such as @code{hook} or
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index ea9a305..9a6fb42 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5442,7 +5442,8 @@ Specifies a rotation angle in degrees.
 
 SVG (Scalable Vector Graphics) is an XML format for specifying images.
 If your Emacs build has SVG support, you can create and manipulate
-these images with the following functions.
+these images with the following functions from the @file{svg.el}
+library.
 
 @defun svg-create width height &rest args
 Create a new, empty SVG image with the specified dimensions.
@@ -5456,8 +5457,11 @@ The default width (in pixels) of any lines created.
 The default stroke color on any lines created.
 @end table
 
-This function returns an SVG structure, and all the following functions
-work on that structure.
address@hidden SVG object
+This function returns an @dfn{SVG object}, a Lisp data structure that
+specifies an SVG image, and all the following functions work on that
+structure.  The argument @var{svg} in the following functions
+specifies such an SVG object.
 @end defun
 
 @defun svg-gradient svg id type stops
@@ -5501,8 +5505,8 @@ gradient object.
 @end table
 
 @defun svg-rectangle svg x y width height &rest args
-Add a rectangle to @var{svg} where the upper left corner is at
-position @var{x}/@var{y} and is of size @var{width}/@var{height}.
+Add to @var{svg} a rectangle whose upper left corner is at
+position @var{x}/@var{y} and whose size is @var{width}/@var{height}.
 
 @lisp
 (svg-rectangle svg 100 100 500 500 :gradient "gradient1")
@@ -5510,24 +5514,24 @@ position @var{x}/@var{y} and is of size 
@var{width}/@var{height}.
 @end defun
 
 @defun svg-circle svg x y radius &rest args
-Add a circle to @var{svg} where the center is at @var{x}/@var{y}
-and the radius is @var{radius}.
+Add to @var{svg} a circle whose center is at @var{x}/@var{y} and whose
+radius is @var{radius}.
 @end defun
 
 @defun svg-ellipse svg x y x-radius y-radius &rest args
-Add a circle to @var{svg} where the center is at @var{x}/@var{y} and
-the horizontal radius is @var{x-radius} and the vertical radius is
+Add to @var{svg} an ellipse whose center is at @var{x}/@var{y}, and
+whose horizontal radius is @var{x-radius} and the vertical radius is
 @var{y-radius}.
 @end defun
 
 @defun svg-line svg x1 y1 x2 y2 &rest args
-Add a line to @var{svg} that starts at @var{x1}/@var{y1} and extends
+Add to @var{svg} a line that starts at @var{x1}/@var{y1} and extends
 to @var{x2}/@var{y2}.
 @end defun
 
 @defun svg-polyline svg points &rest args
-Add a multiple segment line to @var{svg} that goes through
address@hidden, which is a list of X/Y position pairs.
+Add to @var{svg} a multiple-segment line (a.k.a.@: ``polyline'') that
+goes through @var{points}, which is a list of X/Y position pairs.
 
 @lisp
 (svg-polyline svg '((200 . 100) (500 . 450) (80 . 100))
@@ -5541,12 +5545,12 @@ that describe the outer circumference of the polygon.
 
 @lisp
 (svg-polygon svg '((100 . 100) (200 . 150) (150 . 90))
-             :stroke-color "blue" :fill-color "red"")
+             :stroke-color "blue" :fill-color "red")
 @end lisp
 @end defun
 
 @defun svg-text svg text &rest args
-Add a text to @var{svg}.
+Add the specified @var{text} to @var{svg}.
 
 @lisp
 (svg-text
@@ -5565,9 +5569,9 @@ Add a text to @var{svg}.
 
 @defun svg-embed svg image image-type datap &rest args
 Add an embedded (raster) image to @var{svg}.  If @var{datap} is
address@hidden, @var{IMAGE} should be a file name; if not, it should be a
-binary string containing the image data.  @var{image-type} should be a
address@hidden image type, for instance @samp{"image/jpeg"}.
address@hidden, @var{image} should be a file name; otherwise it should be a
+string containing the image data as raw bytes.  @var{image-type} should be a
address@hidden image type, for instance @code{"image/jpeg"}.
 
 @lisp
 (svg-embed svg "~/rms.jpg" "image/jpeg" nil
@@ -5580,10 +5584,14 @@ binary string containing the image data.  
@var{image-type} should be a
 Remove the element with identifier @code{id} from the @code{svg}.
 @end defun
 
-Finally, the @code{svg-image} takes an SVG object as its parameter and
address@hidden svg-image svg
+Finally, the @code{svg-image} takes an SVG object as its argument and
 returns an image object suitable for use in functions like
address@hidden  Here's a complete example that creates and
-inserts an image with a circle:
address@hidden
address@hidden defun
+
+Here's a complete example that creates and inserts an image with a
+circle:
 
 @lisp
 (let ((svg (svg-create 400 400 :stroke-width 10)))
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 6d8529d..ec62ffb 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -1392,7 +1392,6 @@ Packing and Unpacking Byte Arrays
 
 * Bindat Spec::             Describing data layout.
 * Bindat Functions::        Doing the unpacking and packing.
-* Bindat Examples::         Samples of what bindat.el can do for you!
 
 Emacs Display
 
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 674ac82..85a2ce4 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -1319,28 +1319,27 @@ Alternate names, also known as hard links, can be 
created by using the
 @item
 The file's @acronym{UID}, normally as a string
 (@code{file-attribute-user-id}).  However, if it does not correspond
-to a named user, the value is a number.
+to a named user, the value is an integer.
 
 @item
 The file's @acronym{GID}, likewise (@code{file-attribute-group-id}).
 
 @item
-The time of last access, as a list of four integers
address@hidden(@var{sec-high} @var{sec-low} @var{microsec} @var{picosec})}
-(@code{file-attribute-access-time}).  (This is similar to the value of
address@hidden; see @ref{Time of Day}.)  The value is truncated
+The time of last access as a Lisp timestamp
+(@code{file-attribute-status-change-time}).  The timestamp is in the
+style of @code{current-time} (@pxref{Time of Day}) and is truncated
 to that of the filesystem's timestamp resolution; for example, on some
 FAT-based filesystems, only the date of last access is recorded, so
 this time will always hold the midnight of the day of the last access.
 
 @cindex modification time of file
 @item
-The time of last modification as a list of four integers (as above)
+The time of last modification as a Lisp timestamp
 (@code{file-attribute-modification-time}).  This is the last time when
 the file's contents were modified.
 
 @item
-The time of last status change as a list of four integers (as above)
+The time of last status change as a Lisp timestamp
 (@code{file-attribute-status-change-time}).  This is the time of the
 last change to the file's access mode bits, its owner and group, and
 other information recorded in the filesystem for the file, beyond the
@@ -1357,11 +1356,12 @@ The file's modes, as a string of ten letters or dashes, 
as in
 An unspecified value, present for backward compatibility.
 
 @item
-The file's inode number (@code{file-attribute-inode-number}).
+The file's inode number (@code{file-attribute-inode-number}),
+a nonnegative integer.
 
 @item
 The filesystem number of the device that the file is on
address@hidden).
address@hidden), an integer.
 This element and the file's inode number
 together give enough information to distinguish any two files on the
 system---no two files can have the same values for both of these
@@ -2938,7 +2938,7 @@ are included.
 This is similar to @code{directory-files} in deciding which files
 to report on and how to report their names.  However, instead
 of returning a list of file names, it returns for each file a
-list @code{(@var{filename} @var{attributes})}, where @var{attributes}
+list @code{(@var{filename} . @var{attributes})}, where @var{attributes}
 is what @code{file-attributes} returns for that file.
 The optional argument @var{id-format} has the same meaning as the
 corresponding argument to @code{file-attributes} (@pxref{Definition
@@ -3430,8 +3430,9 @@ between consecutive checks.  For example:
   (let ((remote-file-name-inhibit-cache
          (- display-time-interval 5)))
     (and (file-exists-p file)
-         (< 0 (nth 7 (file-attributes
-                       (file-chase-links file)))))))
+         (< 0 (file-attribute-size
+               (file-attributes
+                (file-chase-links file)))))))
 @end example
 @end defopt
 
diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi
index 6dd55d0..2688a2b 100644
--- a/doc/lispref/help.texi
+++ b/doc/lispref/help.texi
@@ -556,13 +556,15 @@ brackets.
 
 @defun text-char-description character
 This function returns a string describing @var{character} in the
-standard Emacs notation for characters that appear in text---like
address@hidden, except that control characters are
-represented with a leading caret (which is how control characters in
-Emacs buffers are usually displayed).  Another difference is that
address@hidden recognizes the 2**7 bit as the Meta
-character, whereas @code{single-key-description} uses the 2**27 bit
-for Meta.
+standard Emacs notation for characters that can appear in
+text---similar to @code{single-key-description}, except that the
+argument must be a valid character code that passes a
address@hidden test (@pxref{Character Codes}).  The function
+produces descriptions of control characters with a leading caret
+(which is how Emacs usually displays control characters in buffers).
+Characters with modifier bits will cause this function to signal an
+error (@acronym{ASCII} characters with the Control modifier are an
+exception, they are represented as control characters).
 
 @smallexample
 @group
@@ -571,19 +573,7 @@ for Meta.
 @end group
 @group
 (text-char-description ?\M-m)
-     @result{} "\xed"
address@hidden group
address@hidden
-(text-char-description ?\C-\M-m)
-     @result{} "\x8d"
address@hidden group
address@hidden
-(text-char-description (+ 128 ?m))
-     @result{} "M-m"
address@hidden group
address@hidden
-(text-char-description (+ 128 ?\C-m))
-     @result{} "M-^M"
+     @error{} Wrong type argument: characterp, 134217837
 @end group
 @end smallexample
 @end defun
diff --git a/doc/lispref/intro.texi b/doc/lispref/intro.texi
index f421f3b..197f54e 100644
--- a/doc/lispref/intro.texi
+++ b/doc/lispref/intro.texi
@@ -493,7 +493,7 @@ giving a prefix argument makes @var{here} address@hidden
 
 @defvar emacs-build-time
 The value of this variable indicates the time at which Emacs was
-built.  It is a list of four integers, like the value of
+built.  It uses the style of
 @code{current-time} (@pxref{Time of Day}), or is @code{nil}
 if the information is not available.
 
diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi
index 38e89c6..d9d213d 100644
--- a/doc/lispref/keymaps.texi
+++ b/doc/lispref/keymaps.texi
@@ -2443,7 +2443,7 @@ Next we define the menu items:
 
 @smallexample
 (define-key menu-bar-replace-menu [tags-repl-continue]
-  '(menu-item "Continue Replace" tags-loop-continue
+  '(menu-item "Continue Replace" multifile-continue
               :help "Continue last tags replace operation"))
 (define-key menu-bar-replace-menu [tags-repl]
   '(menu-item "Replace in tagged files" tags-query-replace
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index b7bb3cf..1548dd4 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -1755,7 +1755,7 @@ alist
 @defun assoc-delete-all key alist &optional test
 This function is like @code{assq-delete-all} except that it accepts
 an optional argument @var{test}, a predicate function to compare the
-keys in @var{alist}. If omitted or @code{nil}, @var{test} defaults to
+keys in @var{alist}.  If omitted or @code{nil}, @var{test} defaults to
 @code{equal}.  As @code{assq-delete-all}, this function often modifies
 the original list structure of @var{alist}.
 @end defun
diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi
index d091787..55fde74 100644
--- a/doc/lispref/minibuf.texi
+++ b/doc/lispref/minibuf.texi
@@ -26,7 +26,7 @@ argument.
 * Initial Input::             Specifying initial contents for the minibuffer.
 * Completion::                How to invoke and customize completion.
 * Yes-or-No Queries::         Asking a question with a simple answer.
-* Multiple Queries::          Asking a series of similar questions.
+* Multiple Queries::          Asking complex questions.
 * Reading a Password::        Reading a password from the terminal.
 * Minibuffer Commands::       Commands used as key bindings in minibuffers.
 * Minibuffer Windows::        Operating on the special minibuffer windows.
@@ -1776,12 +1776,9 @@ flag may be one of the following values.
 @table @code
 @item nil
 This specifies a @code{try-completion} operation.  The function should
-return @code{t} if the specified string is a unique and exact match;
-if there is more than one match, it should return the common substring
-of all matches (if the string is an exact match for one completion
-alternative but also matches other longer alternatives, the return
-value is the string); if there are no matches, it should return
address@hidden
+return @code{nil} if there are no matches; it should return @code{t}
+if the specified string is a unique and exact match; and it should
+return the longest common prefix substring of all matches otherwise.
 
 @item t
 This specifies an @code{all-completions} operation.  The function
@@ -2093,9 +2090,12 @@ Do you really want to remove everything? (yes or no)
 @end defun
 
 @node Multiple Queries
address@hidden Asking Multiple Y-or-N Questions
address@hidden multiple yes-or-no questions
address@hidden Asking Multiple-Choice Questions
 
+  This section describes facilities for asking the user more complex
+questions or several similar questions.
+
address@hidden multiple yes-or-no questions
   When you have a series of similar questions to ask, such as ``Do you
 want to save this buffer?'' for each buffer in turn, you should use
 @code{map-y-or-n-p} to ask the collection of questions, rather than
@@ -2189,6 +2189,52 @@ The return value of @code{map-y-or-n-p} is the number of 
objects acted on.
 @c FIXME  An example of this would be more useful than all the
 @c preceding examples of simple things.
 
+If you need to ask the user a question that might have more than just
+2 answers, use @code{read-answer}.
+
address@hidden read-answer question answers
address@hidden read-answer-short
+This function prompts the user with text in @var{question}, which
+should end in the @samp{SPC} character.  The function includes in the
+prompt the possible responses in @var{answers} by appending them to
+the end of @var{question}.  The possible responses are provided in
address@hidden as an alist whose elements are of the following form:
+
address@hidden
+(@var{long-answer} @var{short-answer} @var{help-message})
address@hidden lisp
+
address@hidden
+where @var{long-answer} is the complete text of the user response, a
+string; @var{short-answer} is a short form of the same response, a
+single character; and @var{help-message} is the text that describes
+the meaning of the answer.  If the variable @code{read-answer-short}
+is address@hidden, the prompt will show the short variants of the
+possible answers and the user is expected to type the single
+characters shown in the prompt; otherwise the prompt will show the
+long variants of the answers, and the user is expected to type the
+full text of one of the answers and end by pressing @key{RET}.  If
address@hidden is address@hidden, and this function was invoked
+by mouse events, the question and the answers will be displayed in a
+GUI dialog box.
+
+The function returns the text of the @var{long-answer} selected by the
+user, regardless of whether long or short answers were shown in the
+prompt and typed by the user.
+
+Here is an example of using this function:
+
address@hidden
+(let ((read-answer-short t))
+  (read-answer "Foo "
+     '(("yes"  ?y "perform the action")
+       ("no"   ?n "skip to the next")
+       ("all"  ?! "perform for the rest without more questions")
+       ("help" ?h "show help")
+       ("quit" ?q "exit"))))
address@hidden lisp
address@hidden defun
+
 @node Reading a Password
 @section Reading a Password
 @cindex passwords, reading
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 0b9dd1c..8ce5a5e 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -1423,7 +1423,8 @@ The year, an integer typically greater than 1900.
 The day of week, as an integer between 0 and 6, where 0 stands for
 Sunday.
 @item dst
address@hidden if daylight saving time is effect, otherwise @code{nil}.
address@hidden if daylight saving time is effect, @code{nil} if it is not
+in effect, and @minus{}1 if this information is not available.
 @item utcoff
 An integer indicating the Universal Time offset in seconds, i.e., the number of
 seconds east of Greenwich.
@@ -1735,17 +1736,26 @@ integer number stands for the number of seconds since 
the epoch.
 @defun time-less-p t1 t2
 This returns @code{t} if time value @var{t1} is less than time value
 @var{t2}.
+The result is @code{nil} if either argument is a NaN.
address@hidden defun
+
address@hidden time-equal-p t1 t2
+This returns @code{t} if @var{t1} and @var{t2} are equal time values.
+The result is @code{nil} if either argument is a NaN.
 @end defun
 
 @defun time-subtract t1 t2
 This returns the time difference @var{t1} @minus{} @var{t2} between
-two time values, as a time value.  If you need the difference in units
+two time values, as a time value.  However, the result is a float
+if either argument is a float infinity or address@hidden
+If you need the difference in units
 of elapsed seconds, use @code{float-time} (@pxref{Time of Day,
 float-time}) to convert the result into seconds.
 @end defun
 
 @defun time-add t1 t2
 This returns the sum of two time values, as a time value.
+However, the result is a float if either argument is a float infinity or 
address@hidden
 One argument should represent a time difference rather than a point in time,
 either as a list or as a single number of elapsed seconds.
 Here is how to add a number of seconds to a time value:
@@ -1990,8 +2000,7 @@ the idleness time, as described below.
 
 @defun current-idle-time
 If Emacs is idle, this function returns the length of time Emacs has
-been idle, as a list of four integers: @code{(@var{sec-high}
address@hidden @var{microsec} @var{picosec})}, using the same format as
+been idle, using the same format as
 @code{current-time} (@pxref{Time of Day}).
 
 When Emacs is not idle, @code{current-idle-time} returns @code{nil}.
@@ -3030,7 +3039,7 @@ Although Emacs normally respects access permissions of 
the underlying
 operating system, in some cases it handles accesses specially.  For
 example, file names can have handlers that treat the files specially,
 with their own access checking.  @xref{Magic File Names}.  Also, a
-buffer can be read-only even if the corresponding file is writeable,
+buffer can be read-only even if the corresponding file is writable,
 and vice versa, which can result in messages such as @samp{File passwd
 is write-protected; try to save anyway? (yes or no)}.  @xref{Read Only
 Buffers}.
diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
index f9ba703..89ad1cf 100644
--- a/doc/lispref/processes.texi
+++ b/doc/lispref/processes.texi
@@ -3126,7 +3126,6 @@ direction is also known as @dfn{serializing} or 
@dfn{packing}.
 @menu
 * Bindat Spec::         Describing data layout.
 * Bindat Functions::    Doing the unpacking and packing.
-* Bindat Examples::     Samples of what bindat.el can do for you!
 @end menu
 
 @node Bindat Spec
@@ -3369,132 +3368,3 @@ dotted notation.
      @result{} "127.0.0.1"
 @end example
 @end defun
-
address@hidden Bindat Examples
address@hidden Examples of Byte Unpacking and Packing
address@hidden FIXME?  This seems a very long example for something that is not 
used
address@hidden very often.  As of 25.2, gdb-mi.el is the only user of bindat.el 
in Emacs.
address@hidden Maybe one or both of these examples should just be moved to the
address@hidden commentary of bindat.el.
-
-  Here are two complete examples that use bindat.el.
-The first shows simple byte packing:
-
address@hidden
-(require 'bindat)
-
-(defun rfc868-payload ()
-  (bindat-pack
-   '((now-hi u16)
-     (now-lo u16))
-   ;; Emacs uses Unix epoch, while RFC868 epoch
-   ;; is 1900-01-01 00:00:00, which is 2208988800
-   ;; (or #x83aa7e80) seconds more.
-   (let ((now (time-add nil '(#x83aa #x7e80))))
-     `((now-hi . ,(car now))
-       (now-lo . ,(cadr now))))))
-
-(let ((s (rfc868-payload)))
-  (list (multibyte-string-p s)
-        (mapconcat (lambda (byte)
-                     (format "%02x" byte))
-                   s " ")
-        (current-time-string)))
-     @result{} (nil "dc 6d 17 01" "Fri Mar 10 13:13:53 2017")
address@hidden lisp
-
-The following is an example of defining and unpacking a complex
-structure.  Consider the following C structures:
-
address@hidden
-struct header @{
-    unsigned long    dest_ip;
-    unsigned long    src_ip;
-    unsigned short   dest_port;
-    unsigned short   src_port;
address@hidden;
-
-struct data @{
-    unsigned char    type;
-    unsigned char    opcode;
-    unsigned short   length;  /* in network byte order  */
-    unsigned char    id[8];   /* null-terminated string  */
-    unsigned char    data[/* (length + 3) & ~3 */];
address@hidden;
-
-struct packet @{
-    struct header    header;
-    unsigned long    counters[2];  /* in little endian order  */
-    unsigned char    items;
-    unsigned char    filler[3];
-    struct data      item[/* items */];
-
address@hidden;
address@hidden example
-
-The corresponding data layout specification is:
-
address@hidden
-(setq header-spec
-      '((dest-ip   ip)
-        (src-ip    ip)
-        (dest-port u16)
-        (src-port  u16)))
-
-(setq data-spec
-      '((type      u8)
-        (opcode    u8)
-        (length    u16)  ; network byte order
-        (id        strz 8)
-        (data      vec (length))
-        (align     4)))
-
-(setq packet-spec
-      '((header    struct header-spec)
-        (counters  vec 2 u32r)   ; little endian order
-        (items     u8)
-        (fill      3)
-        (item      repeat (items)
-                   (struct data-spec))))
address@hidden lisp
-
-A binary data representation is:
-
address@hidden
-(setq binary-data
-      [ 192 168 1 100 192 168 1 101 01 28 21 32
-        160 134 1 0 5 1 0 0 2 0 0 0
-        2 3 0 5 ?A ?B ?C ?D ?E ?F 0 0 1 2 3 4 5 0 0 0
-        1 4 0 7 ?B ?C ?D ?E ?F ?G 0 0 6 7 8 9 10 11 12 0 ])
address@hidden lisp
-
-The corresponding decoded structure is:
-
address@hidden
-(setq decoded (bindat-unpack packet-spec binary-data))
-     @result{}
-((header
-  (dest-ip   . [192 168 1 100])
-  (src-ip    . [192 168 1 101])
-  (dest-port . 284)
-  (src-port  . 5408))
- (counters . [100000 261])
- (items . 2)
- (item ((data . [1 2 3 4 5])
-        (id . "ABCDEF")
-        (length . 5)
-        (opcode . 3)
-        (type . 2))
-       ((data . [6 7 8 9 10 11 12])
-        (id . "BCDEFG")
-        (length . 7)
-        (opcode . 4)
-        (type . 1))))
address@hidden lisp
-
-An example of fetching data from this structure:
-
address@hidden
-(bindat-get-field decoded 'item 1 'id)
-     @result{} "BCDEFG"
address@hidden lisp
diff --git a/doc/man/emacsclient.1 b/doc/man/emacsclient.1
index daaacab..5aaa6d1 100644
--- a/doc/man/emacsclient.1
+++ b/doc/man/emacsclient.1
@@ -1,7 +1,7 @@
 .\" See section COPYING for conditions for redistribution.
 .TH EMACSCLIENT 1
 .\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection
-.\" other parms are allowed: see man(7), man(1)
+.\" other params are allowed: see man(7), man(1)
 .SH NAME
 emacsclient \- tells a running Emacs to visit a file
 .SH SYNOPSIS
diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in
index 11086b3..fd07ea4 100644
--- a/doc/misc/Makefile.in
+++ b/doc/misc/Makefile.in
@@ -224,13 +224,13 @@ ${buildinfodir}/tramp.info tramp.html: 
${srcdir}/trampver.texi
 .PHONY: mostlyclean clean distclean bootstrap-clean maintainer-clean
 
 mostlyclean:
-       rm -f *.aux *.log *.toc *.c[mp] *.c[mp]s *.fn *.fns \
-         *.ky *.kys *.op *.ops *.p[gj] *.p[gj]s *.sc *.scs *.ss \
-         *.t[gp] *.t[gp]s *.vr *.vrs
+       rm -f ./*.aux ./*.log ./*.toc ./*.c[mp] ./*.c[mp]s ./*.fn ./*.fns \
+         ./*.ky ./*.kys ./*.op ./*.ops ./*.p[gj] ./*.p[gj]s ./*.sc ./*.scs 
./*.ss \
+         ./*.t[gp] ./*.t[gp]s ./*.vr ./*.vrs
        rm -f gnustmp*
 
 clean: mostlyclean
-       rm -f *.dvi *.html *.pdf *.ps
+       rm -f ./*.dvi ./*.html ./*.pdf ./*.ps
 
 distclean: clean
        rm -f Makefile
diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi
index 9cf16d8..fcbc83e 100644
--- a/doc/misc/auth.texi
+++ b/doc/misc/auth.texi
@@ -348,25 +348,36 @@ Returns all the item labels of @var{collection} as a list.
 
 @defun secrets-create-item collection item password &rest attributes
 This function creates a new item in @var{collection} with label
address@hidden and password @var{password}.  @var{attributes} are
-key-value pairs set for the created item.  The keys are keyword
-symbols, starting with a colon.  Example:
address@hidden and password @var{password}.  The label @var{item} does not
+have to be unique in @var{collection}.  @var{attributes} are key-value
+pairs set for the created item.  The keys are keyword symbols,
+starting with a colon.  Example:
 
 @example
-;;; The session "session", the label is "my item"
-;;; and the secret (password) is "geheim"
+;;; The session is "session", the label is "my item"
+;;; and the secret (password) is "geheim".
 (secrets-create-item "session" "my item" "geheim"
  :method "sudo" :user "joe" :host "remote-host")
 @end example
+
+The key @code{:xdg:schema} determines the scope of the item to be
+generated, i.e.@: for which applications the item is intended for.
+This is just a string like "org.freedesktop.NetworkManager.Mobile" or
+"org.gnome.OnlineAccounts", the other required keys are determined by
+this.  If no @code{:xdg:schema} is given,
+"org.freedesktop.Secret.Generic" is used by default.
 @end defun
 
 @defun secrets-get-secret collection item
-Return the secret of item labeled @var{item} in @var{collection}.
-If there is no such item, return @code{nil}.
+Return the secret of item labeled @var{item} in @var{collection}.  If
+there are several items labeled @var{item}, it is undefined which one
+is returned.  If there is no such item, return @code{nil}.
 @end defun
 
 @defun secrets-delete-item collection item
-This function deletes item @var{item} in @var{collection}.
+This function deletes item @var{item} in @var{collection}.  If there
+are several items labeled @var{item}, it is undefined which one is
+deleted.
 @end defun
 
 The lookup attributes, which are specified during creation of a
@@ -376,18 +387,20 @@ from a given secret item and they can be used for 
searching of items.
 
 @defun secrets-get-attribute collection item attribute
 Returns the value of key @var{attribute} of item labeled @var{item} in
address@hidden  If there is no such item, or the item doesn't own
-this key, the function returns @code{nil}.
address@hidden  If there are several items labeled @var{item}, it
+is undefined which one is returned.  If there is no such item, or the
+item doesn't own this key, the function returns @code{nil}.
 @end defun
 
 @defun secrets-get-attributes collection item
 Return the lookup attributes of item labeled @var{item} in
address@hidden  If there is no such item, or the item has no
-attributes, it returns @code{nil}.  Example:
address@hidden  If there are several items labeled @var{item}, it
+is undefined which one is returned.  If there is no such item, or the
+item has no attributes, it returns @code{nil}.  Example:
 
 @example
 (secrets-get-attributes "session" "my item")
-     @result{} ((:user . "joe") (:host ."remote-host"))
+     @result{} ((:user . "joe") (:host . "remote-host"))
 @end example
 @end defun
 
diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi
index 02deee9..83807c6 100644
--- a/doc/misc/calc.texi
+++ b/doc/misc/calc.texi
@@ -35724,19 +35724,12 @@ The default value of @code{calc-gregorian-switch} is 
@code{nil}.
 @appendix Reporting Bugs
 
 @noindent
-If you find a bug in Calc, send e-mail to Jay Belanger,
-
address@hidden
-jay.p.belanger@@gmail.com
address@hidden example
-
address@hidden
-There is an automatic command @kbd{M-x report-calc-bug} which helps
+If you find a bug in Calc, send e-mail to @email{bug-gnu-emacs@@gnu.org}.
+There is an automatic command @kbd{M-x report-emacs-bug} which helps
 you to report bugs.  This command prompts you for a brief subject
 line, then leaves you in a mail editing buffer.  Type @kbd{C-c C-c} to
 send your mail.  Make sure your subject line indicates that you are
-reporting a Calc bug; this command sends mail to the maintainer's
-regular mailbox.
+reporting a Calc bug.
 
 If you have suggestions for additional features for Calc, please send
 them.  Some have dared to suggest that Calc is already top-heavy with
@@ -35745,7 +35738,7 @@ them right in.
 
 At the front of the source file, @file{calc.el}, is a list of ideas for
 future work.  If any enthusiastic souls wish to take it upon themselves
-to work on these, please send a message (using @kbd{M-x report-calc-bug})
+to work on these, please send a message (using @kbd{M-x report-emacs-bug})
 so any efforts can be coordinated.
 
 The latest version of Calc is available from Savannah, in the Emacs
@@ -36256,7 +36249,7 @@ keystrokes are not listed in this summary.
 @c
 @r{       @:      j +   @:formula      @:    27  @:calc-sel-add-both-sides@:}
 @r{       @:      j -   @:formula      @:    27  @:calc-sel-sub-both-sides@:}
address@hidden       @:      j *   @:formula      @:    27  
@:calc-sel-mul-both-sides@:}
address@hidden       @:      j *   @:formula      @:    27  
@:calc-sel-mult-both-sides@:}
 @r{       @:      j /   @:formula      @:    27  @:calc-sel-div-both-sides@:}
 @r{       @:      j &   @:             @:    27  @:calc-sel-invert@:}
 
diff --git a/doc/misc/dired-x.texi b/doc/misc/dired-x.texi
index 3617920..36a9cb0 100644
--- a/doc/misc/dired-x.texi
+++ b/doc/misc/dired-x.texi
@@ -521,8 +521,9 @@ where each @var{command} can either be a string or a Lisp 
expression
 that evaluates to a string.  If several commands are given, all of
 them will temporarily be pushed onto the history.
 
-If @samp{*} in the shell command, that means to substitute the file
-name.
+A @samp{*} in the shell command stands for the file name that matched
address@hidden  When Emacs invokes the @var{command}, it replaces each
+instance of @samp{*} with the matched file name.
 
 You can set this variable in your @file{~/.emacs}.  For example,
 to add rules for @samp{.foo} and @samp{.bar} file extensions, write
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index 5b432d5..26d9c82 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -3392,8 +3392,9 @@ and binaries, and how to install Emacs on those systems.
 
 Most GNU/Linux distributions provide pre-built Emacs packages.
 If Emacs is not installed already, you can install it by running (as
-root) a command such as @samp{yum install emacs} (Red Hat and
-derivatives) or @samp{apt-get install emacs} (Debian and derivatives).
+root) a command such as @samp{dnf install emacs} (Red Hat and
+derivatives; use @samp{yum} in older distributions) or
address@hidden install emacs} (Debian and derivatives).
 
 If you want to compile Emacs yourself, read the file @file{INSTALL} in
 the source distribution.  In brief:
diff --git a/doc/misc/emacs-mime.texi b/doc/misc/emacs-mime.texi
index b71cc37..9280311 100644
--- a/doc/misc/emacs-mime.texi
+++ b/doc/misc/emacs-mime.texi
@@ -1535,7 +1535,7 @@ Here's a bunch of time/date/second/day examples:
 
 @example
 (parse-time-string "Sat Sep 12 12:21:54 1998 +0200")
address@hidden (54 21 12 12 9 1998 6 nil 7200)
address@hidden (54 21 12 12 9 1998 6 -1 7200)
 
 (date-to-time "Sat Sep 12 12:21:54 1998 +0200")
 @result{} (13818 19266)
@@ -1561,6 +1561,9 @@ Here's a bunch of time/date/second/day examples:
 (time-less-p '(13818 19266) '(13818 19145))
 @result{} nil
 
+(time-equal-p '(13818 19266) '(13818 19145))
address@hidden nil
+
 (time-subtract '(13818 19266) '(13818 19145))
 @result{} (0 121)
 
@@ -1641,6 +1644,10 @@ return a ``zero'' time.
 Take two times and say whether the first time is less (i.e., earlier)
 than the second time.  (This is a built-in function.)
 
address@hidden time-equal-p
+Check, whether two time values are equal.  The time values must not be
+in the same format.  (This is a built-in function.)
+
 @item time-since
 Take a time and return a time saying how long it was since that time.
 
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index 817e50d..c19d5e1 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -346,8 +346,9 @@ Alias to Emacs's @code{locate} function, which simply runs 
the external
 
 @item make
 @cmindex make
-Run @command{make} through @code{compile}.
address@hidden, , , emacs, The GNU Emacs Manual}.
+Run @command{make} through @code{compile} when run asynchronously
+(e.g., @samp{make &}).  @xref{Compilation, , , emacs, The GNU Emacs
+Manual}.  Otherwise call the external @command{make} command.
 
 @item occur
 @cmindex occur
@@ -850,7 +851,7 @@ since.
 
 Make it so that the Lisp command on the right of the pipe is repeatedly
 called with the input strings as arguments.  This will require changing
address@hidden to handle non-process targets.
address@hidden to handle non-process targets.
 
 @item Input redirection is not supported
 
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 6ccb9e5..2f7d840 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -4457,7 +4457,7 @@ generated.  It may be used to modify the buffer in some 
strange,
 unnatural way.
 
 @item gnus-group-prepared-hook
address@hidden gnus-group-prepare-hook
address@hidden gnus-group-prepared-hook
 is called as the very last thing after the group buffer has been
 generated.  It may be used to move point around, for instance.
 
@@ -25889,13 +25889,13 @@ Reset: (setq spam-stat (make-hash-table :test 'equal))
 Learn spam: (spam-stat-process-spam-directory "~/Mail/mail/spam")
 Learn non-spam: (spam-stat-process-non-spam-directory "~/Mail/mail/misc")
 Save table: (spam-stat-save)
-File size: (nth 7 (file-attributes spam-stat-file))
+File size: (file-attribute-size (file-attributes spam-stat-file))
 Number of words: (hash-table-count spam-stat)
 Test spam: (spam-stat-test-directory "~/Mail/mail/spam")
 Test non-spam: (spam-stat-test-directory "~/Mail/mail/misc")
 Reduce table size: (spam-stat-reduce-size)
 Save table: (spam-stat-save)
-File size: (nth 7 (file-attributes spam-stat-file))
+File size: (file-attribute-size (file-attributes spam-stat-file))
 Number of words: (hash-table-count spam-stat)
 Test spam: (spam-stat-test-directory "~/Mail/mail/spam")
 Test non-spam: (spam-stat-test-directory "~/Mail/mail/misc")
diff --git a/doc/misc/org.texi b/doc/misc/org.texi
index 3bce0dd..ccb5f88 100644
--- a/doc/misc/org.texi
+++ b/doc/misc/org.texi
@@ -17991,7 +17991,7 @@ supports Imenu menus.  Enable it with a mode hook as 
follows:
 @end lisp
 @vindex org-imenu-depth
 By default the Imenu index is two levels deep.  Change the index depth using
-thes variable, @code{org-imenu-depth}.
+the variable @code{org-imenu-depth}.
 @item @file{speedbar.el} by Eric M. Ludlam
 @cindex @file{speedbar.el}
 @cindex Ludlam, Eric M.
@@ -18065,7 +18065,7 @@ different replacement keys, look at the variable 
@code{org-disputed-keys}.
 @cindex @file{ecomplete.el}
 
 Ecomplete provides ``electric'' address completion in address header
-lines in message buffers.  Sadly Orgtbl mode cuts ecompletes power
+lines in message buffers.  Sadly Orgtbl mode cuts ecomplete's power
 supply: No completion happens when Orgtbl mode is enabled in message
 buffers while entering text in address header lines.  If one wants to
 use ecomplete one should @emph{not} follow the advice to automagically
diff --git a/doc/misc/reftex.texi b/doc/misc/reftex.texi
index 2ea98cf..4367d77 100644
--- a/doc/misc/reftex.texi
+++ b/doc/misc/reftex.texi
@@ -4618,7 +4618,7 @@ return the string to insert into the buffer.
 
 @defopt reftex-cite-prompt-optional-args
 address@hidden means, prompt for empty optional arguments in cite macros.
-When an entry in @code{reftex-cite-format} ist given with square brackets to
+When an entry in @code{reftex-cite-format} is given with square brackets to
 indicate optional arguments (for example @address@hidden@}}), RefTeX can
 prompt for values.  Possible values are:
 @example
diff --git a/doc/misc/sieve.texi b/doc/misc/sieve.texi
index 2d290b3..cad3cd8 100644
--- a/doc/misc/sieve.texi
+++ b/doc/misc/sieve.texi
@@ -127,7 +127,7 @@ bindings to manage Sieve scripts remotely. @xref{Managing 
Sieve}.
 @kindex C-c RET
 @findex sieve-manage
 @cindex manage remote sieve script
-Open a connection to a remote server using the Managesieve protocol.
+Open a connection to a remote server using the Manage Sieve protocol.
 
 @item C-c C-l
 @kindex C-c C-l
diff --git a/doc/misc/srecode.texi b/doc/misc/srecode.texi
index 2987f62..7d8416e 100644
--- a/doc/misc/srecode.texi
+++ b/doc/misc/srecode.texi
@@ -1474,7 +1474,7 @@ to write your own function in order to provide your 
dictionaries with
 the values needed for custom templates.
 
 In this way, you can build your own code generator for any language
-based on a set of predefined macros whos values you need to derive
+based on a set of predefined macros whose values you need to derive
 from Emacs Lisp code yourself.
 
 For example:
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index 78f55e0..55cb232 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -301,7 +301,7 @@ into a buffer, and then deletes the temporary file.
 
 @item
 Edit, modify, change the buffer contents as normal, and then save the
-buffer wth @kbd{C-x C-s}.
+buffer with @kbd{C-x C-s}.
 
 @item
 @value{tramp} transfers the buffer contents to the remote host in
diff --git a/doc/misc/url.texi b/doc/misc/url.texi
index a8ac117..eaeae60 100644
--- a/doc/misc/url.texi
+++ b/doc/misc/url.texi
@@ -1342,7 +1342,7 @@ The User Agent string used for sending 
@acronym{HTTP}/@acronym{HTTPS}
 requests.  The value should be @code{nil}, which means that no
 @samp{User-Agent} header is generated, @code{default}, which means
 that a string is generated based on the setting of
address@hidden, a string or a function of no arguments that
address@hidden, a string or a function of no arguments that
 returns a string.
 
 The default is @code{default}, which means that the
diff --git a/doc/misc/vhdl-mode.texi b/doc/misc/vhdl-mode.texi
index 8fc7510..c0efdbf 100644
--- a/doc/misc/vhdl-mode.texi
+++ b/doc/misc/vhdl-mode.texi
@@ -734,7 +734,7 @@ operator on the first line of the statement.  Here is the 
lisp code
 Custom indent functions take a single argument, which is a syntactic
 component cons cell (see @ref{Syntactic Analysis}).  The
 function returns an integer offset value that will be added to the
-running total indentation for the lne.  Note that what actually gets
+running total indentation for the line.  Note that what actually gets
 returned is the difference between the column that the signal assignment
 operator is on, and the column of the buffer relative position passed in
 the function's argument.  Remember that VHDL Mode automatically
diff --git a/etc/NEWS b/etc/NEWS
index f06d083..a33296c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -62,6 +62,11 @@ to reduce differences between developer and production 
builds.
 ** Ibuffer
 
 ---
+*** All mode filters can now accept a list of symbols.
+This means you can now easily filter several major modes, as well
+as a single mode.
+
+---
 *** New toggle 'ibuffer-do-toggle-lock', bound to 'L'.
 
 ** Gnus
@@ -196,6 +201,9 @@ regular expression was previously invalid, but is now 
accepted:
 ---
 ** The German prefix and postfix input methods now support Capital sharp S.
 
+---
+** New input methods hawaiian-postfix and hawaiian-prefix.
+
 +++
 ** New function 'exec-path'.
 This function by default returns the value of the corresponding
@@ -232,11 +240,24 @@ typographic quotes, “like this”, in text modes, and in 
comments in
 non-text modes.
 
 ---
+** New user option 'flyspell-case-fold-duplications'.
+This option controls whether Flyspell mode considers consecutive words
+to be duplicates if they are not in the same case.  If non-nil, the
+default, words are considered to be duplicates even if their letters'
+case does not match.
+
+---
 ** 'write-abbrev-file' now includes special properties.
 'write-abbrev-file' now writes special properties like ':case-fixed'
 for abbrevs that have them.
 
 +++
+** 'insert-abbrev-table-description' skips empty tables.
+'insert-abbrev-table-description' skips inserting empty tables when
+inserting non-readable tables.  By extension, this makes
+'write-abbrev-file' skip writing empty tables.
+
++++
 ** The new functions and commands 'text-property-search-forward' and
 'text-property-search-backward' have been added.  These provide an
 interface that's more like functions like @code{search-forward}.
@@ -262,9 +283,26 @@ remote files.  If the value is a regular expression, files 
matching
 this expression are loaded asynchronously.  See the node "(emacs)
 Visiting" in the user manual for the supported commands.
 
+---
+** add-dir-local-variable now uses dotted pair notation syntax
+to write alists of variables to .dir-locals.el.  This is the same
+syntax that you can see in the example of a .dir-locals.el file
+in (info "(emacs) Directory Variables")
+
 
 * Changes in Specialized Modes and Packages in Emacs 27.1
 
+** project.el
+*** New commands project-search and project-query-replace
+
+** Etags
++++
+*** 'next-file' is now an obsolete alias of tags-next-file
+*** tags-loop-revert-buffers is an obsolete alias of multifile-revert-buffers
+*** The tags-loop-continue function along with the tags-loop-operate and
+tags-loop-scan variables are now obsolete; use the new multifile-initialize and
+multifile-continue functions instead.
+
 ---
 ** bibtex
 *** New commands 'bibtex-next-entry' and 'bibtex-previous-entry'.
@@ -773,6 +811,8 @@ subexpression.
 
 * New Modes and Packages in Emacs 27.1
 
+** multifile.el lets one setup multifile operations like search&replace
+
 +++
 ** Emacs can now visit files in archives as if they were directories.
 This feature uses Tramp and works only on systems which support GVFS,
@@ -935,6 +975,14 @@ like file-attributes that compute file sizes and other 
attributes,
 functions like process-id that compute process IDs, and functions like
 user-uid and group-gid that compute user and group IDs.
 
++++
+** 'time-add', 'time-subtract', and 'time-less-p' now accept
+infinities and NaNs too, and propagate them or return nil like
+floating-point operators do.
+
++++
+** New function 'time-equal-p' compares time values for equality.
+
 ** define-minor-mode automatically documents the meaning of ARG.
 
 +++
@@ -958,6 +1006,11 @@ This works like 'dolist', but reports progress similar to
 This works like 'delete-frame-functions', but runs after the frame to
 be deleted has been made dead and removed from the frame list.
 
+---
+** The function 'provided-mode-derived-p' was extended to support aliases.
+The function now returns non-nil when the argument MODE is derived
+from any alias of any of MODES.
+
 +++
 ** New frame focus state inspection interface.
 The hooks 'focus-in-hook' and 'focus-out-hook' are now obsolete.
@@ -982,7 +1035,7 @@ A buffer-local value of this hook is now run only if at 
least one
 window showing the buffer has changed its size.
 
 +++
-** New function assoc-delete-all.
+** The function assoc-delete-all now takes an optional predicate argument.
 
 +++
 ** New function 'string-distance' to calculate the Levenshtein distance
@@ -1063,6 +1116,14 @@ a multibyte string even if its second argument is an 
ASCII character.
 ** (format "%d" X) no longer mishandles a floating-point number X that
 does not fit in a machine integer.
 
++++
+** In the DST slot, encode-time and parse-time-string now return -1
+if it is not known whether daylight saving time is in effect.
+Formerly they were inconsistent: encode-time returned t in this
+situation, whereas parse-time-string returned nil.  Now they
+consistently use use nil to mean that DST is not in effect, and use -1
+to mean that it is not known whether DST is in effect.
+
 ** New JSON parsing and serialization functions 'json-serialize',
 'json-insert', 'json-parse-string', and 'json-parse-buffer'.  These
 are implemented in C using the Jansson library.
diff --git a/etc/NEWS.1-17 b/etc/NEWS.1-17
index 63ef9a3..c74cc3d 100644
--- a/etc/NEWS.1-17
+++ b/etc/NEWS.1-17
@@ -8,21 +8,21 @@ This file is about changes in emacs versions 1 through 17.
 
 
 
-Changes in Emacs 17
+* Changes in Emacs 17
 
-* Frustrated?
+** Frustrated?
 
 Try M-x doctor.
 
-* Bored?
+** Bored?
 
 Try M-x hanoi.
 
-* Brain-damaged?
+** Brain-damaged?
 
 Try M-x yow.
 
-* Sun3, Tahoe, Apollo, HP9000s300, Celerity, NCR Tower 32,
+** Sun3, Tahoe, Apollo, HP9000s300, Celerity, NCR Tower 32,
   Sequent, Stride, Encore, Plexus and AT&T 7300 machines supported.
 
 The Tahoe, Sun3, Sequent and Celerity use 4.2.  In regard to the
@@ -30,24 +30,24 @@ Apollo, see the file APOLLO in this directory.  NCR Tower32,
 HP9000s300, Stride and Nu run forms of System V.  System V rel 2 also
 works on Vaxes now.  See etc/MACHINES.
 
-* System V Unix supported, including subprocesses.
+** System V Unix supported, including subprocesses.
 
 It should be possible now to bring up Emacs on a machine running
 mere unameliorated system V Unix with no major work; just possible bug
 fixes.  But you can expect to find a handful of those on any machine
 that Emacs has not been run on before.
 
-* Berkeley 4.1 Unix supported.
+** Berkeley 4.1 Unix supported.
 
 See etc/MACHINES.
 
-* Portable `alloca' provided.
+** Portable `alloca' provided.
 
 Emacs can now run on machines that do not and cannot support the library
 subroutine `alloca' in the canonical fashion, using an `alloca' emulation
 written in C.
 
-* On-line manual.
+** On-line manual.
 
 Info now contains an Emacs manual, with essentially the same text
 as in the printed manual.
@@ -57,7 +57,7 @@ The manual can now be printed with a standard TeX.
 Nicely typeset and printed copies of the manual are available
 from the Free Software Foundation.
 
-* Backup file version numbers.
+** Backup file version numbers.
 
 Emacs now supports version numbers in backup files.
 
@@ -108,7 +108,7 @@ to keep, overriding `dired-kept-versions'.  A negative 
argument specifies
 the number of oldest versions to keep, using minus the argument to override
 `kept-old-versions'.
 
-* Immediate conflict detection.
+** Immediate conflict detection.
 
 Emacs now locks the files it is modifying, so that if
 you start to modify within Emacs a file that is being
@@ -130,27 +130,27 @@ directory.  If such a directory is not provided and told 
to
 Emacs as part of configuring it for your machine, the lock feature
 is turned off.
 
-* M-x recover-file.
+** M-x recover-file.
 
 This command is used to get a file back from an auto-save
 (after a system crash, for example).  It takes a file name
 as argument and visits that file, but gets the data from the
 file's last auto save rather than from the file itself.
 
-* M-x normal-mode.
+** M-x normal-mode.
 
 This command resets the current buffer's major mode and local
 variables to be as specified by the visit filename, the -*- line
 and/or the Local Variables: block at the end of the buffer.
 It is the same thing normally done when a file is first visited.
 
-* Echo area messages disappear shortly if minibuffer is in use.
+** Echo area messages disappear shortly if minibuffer is in use.
 
 Any message in the echo area disappears after 2 seconds
 if the minibuffer is active.  This allows the minibuffer
 to become visible again.
 
-* C-z on System V runs a subshell.
+** C-z on System V runs a subshell.
 
 On systems which do not allow programs to be suspended, the C-z command
 forks a subshell that talks directly to the terminal, and then waits
@@ -158,18 +158,18 @@ for the subshell to exit.  This gets almost the effect of 
suspending
 in that you can run other programs and then return to Emacs.  However,
 you cannot log out from the subshell.
 
-* C-c is always a prefix character.
+** C-c is always a prefix character.
 
 Also, subcommands of C-c which are letters are always
 reserved for the user.  No standard Emacs major mode
 defines any of them.
 
-* Picture mode C-c commands changed.
+** Picture mode C-c commands changed.
 
 The old C-c k command is now C-c C-w.
 The old C-c y command is now C-c C-x.
 
-* Shell mode commands changed.
+** Shell mode commands changed.
 
 All the special commands of Shell mode are now moved onto
 the C-c prefix.  Most are not changed aside from that.
@@ -182,7 +182,7 @@ is now C-c C-o, and C-x C-v (show output) is now C-c C-r.
 
 The old M-= (copy previous input) command is now C-c C-y.
 
-* Shell mode recognizes aliases for `pushd', `popd' and `cd'.
+** Shell mode recognizes aliases for `pushd', `popd' and `cd'.
 
 Shell mode now uses the variable `shell-pushd-regexp' as a
 regular expression to recognize any command name that is
@@ -194,13 +194,13 @@ There are also `shell-popd-regexp' to recognize commands
 with the effect of a `popd', and `shell-cd-regexp' to recognize
 commands with the effect of a `cd'.
 
-* "Exit" command in certain modes now C-c C-c.
+** "Exit" command in certain modes now C-c C-c.
 
 These include electric buffer menu mode, electric command history
 mode, Info node edit mode, and Rmail edit mode.  In all these
 modes, the command to exit used to be just C-c.
 
-* Outline mode changes.
+** Outline mode changes.
 
 Lines that are not heading lines are now called "body" lines.
 The command `hide-text' is renamed to `hide-body'.
@@ -212,7 +212,7 @@ Changes of line visibility are no longer undoable.  As a 
result,
 they no longer use up undo memory and no longer interfere with
 undoing earlier commands.
 
-* Rmail changes.
+** Rmail changes.
 
 The s and q commands now both expunge deleted messages before saving;
 use C-x C-s to save without expunging.
@@ -229,23 +229,23 @@ o now outputs to an Rmail file, and C-o to a Unix mail 
file.
 The F command (rmail-find) is renamed to M-s (rmail-search).
 Various new commands and features exist; see the Emacs manual.
 
-* Local bindings described first in describe-bindings.
+** Local bindings described first in describe-bindings.
 
-* [...], {...} now balance in Fundamental mode.
+** [...], {...} now balance in Fundamental mode.
 
-* Nroff mode and TeX mode.
+** Nroff mode and TeX mode.
 
 There are two new major modes for editing nroff input and TeX input.
 See the Emacs manual for full information.
 
-* New C indentation style variable `c-brace-imaginary-offset'.
+** New C indentation style variable `c-brace-imaginary-offset'.
 
 The value of `c-brace-imaginary-offset', normally zero, controls the
 indentation of a statement inside a brace-group where the open-brace
 is not the first thing on a line.  The value says where the open-brace
 is imagined to be, relative to the first nonblank character on the line.
 
-* Dired improvements.
+** Dired improvements.
 
 Dired now normally keeps the cursor at the beginning of the file name,
 not at the beginning of the line.  The most used motion commands are
@@ -259,22 +259,22 @@ printed in an error message.
 If the `v' command is invoked on a file which is a directory,
 dired is run on that directory.
 
-* `visit-tag-table' renamed `visit-tags-table'.
+** `visit-tag-table' renamed `visit-tags-table'.
 
 This is so apropos of `tags' finds everything you need to
 know about in connection with Tags.
 
-* `mh-e' library uses C-c as prefix.
+** `mh-e' library uses C-c as prefix.
 
 All the special commands of `mh-rmail' now are placed on a
 C-c prefix rather than on the C-x prefix.  This is for
 consistency with other special modes with their own commands.
 
-* M-$ or `spell-word' checks word before point.
+** M-$ or `spell-word' checks word before point.
 
 It used to check the word after point.
 
-* Quitting during autoloading no longer causes trouble.
+** Quitting during autoloading no longer causes trouble.
 
 Now, when a file is autoloaded, all function redefinitions
 and `provide' calls are recorded and are undone if you quit
@@ -284,14 +284,14 @@ As a result, it no longer happens that some of the entry 
points
 which are normally autoloading have been defined already, but the
 entire file is not really present to support them.
 
-* `else' can now be indented correctly in C mode.
+** `else' can now be indented correctly in C mode.
 
 TAB in C mode now knows which `if' statement an `else' matches
 up with, and can indent the `else' correctly under the `if',
 even if the `if' contained such things as another `if' statement,
 or a `while' or `for' statement, with no braces around it.
 
-* `batch-byte-compile'
+** `batch-byte-compile'
 
 Runs byte-compile-file on the files specified on the command line.
 All the rest of the command line arguments are taken as files to
@@ -300,7 +300,7 @@ Must be used only with -batch, and kills emacs on 
completion.
 Each file will be processed even if an error occurred previously.
 For example, invoke `emacs -batch -f batch-byte-compile *.el'.
 
-* `-batch' changes.
+** `-batch' changes.
 
 `-batch' now implies `-q': no init file is loaded by Emacs when
 `-batch' is used.  Also, no `term/TERMTYPE.el' file is loaded.  Auto
@@ -313,7 +313,7 @@ One echo-area message that is not suppressed is the one 
that says
 that a file is being loaded.  That is because you can prevent this
 message by passing `t' as the third argument to `load'.
 
-* Display of search string in incremental search.
+** Display of search string in incremental search.
 
 Now, when you type C-s or C-r to reuse the previous search
 string, that search string is displayed immediately in the echo area.
@@ -321,23 +321,23 @@ string, that search string is displayed immediately in 
the echo area.
 Three dots are displayed after the search string while search
 is actually going on.
 
-* View commands.
+** View commands.
 
 The commands C-x ], C-x [, C-x /, C-x j and C-x o are now
 available inside `view-buffer' and `view-file', with their
 normal meanings.
 
-* Full-width windows preferred.
+** Full-width windows preferred.
 
 The ``other-window'' commands prefer other full width windows,
 and will split only full width windows.
 
-* M-x rename-file can copy if necessary.
+** M-x rename-file can copy if necessary.
 
 When used between different file systems, since actual renaming does
 not work, the old file will be copied and deleted.
 
-* Within C-x ESC, you can pick the command to repeat.
+** Within C-x ESC, you can pick the command to repeat.
 
 While editing a previous command to be repeated, inside C-x ESC,
 you can now use the commands M-p and M-n to pick an earlier or
@@ -353,24 +353,24 @@ The command you finally execute using C-x ESC is added to 
the
 front of the command history, unless it is identical with the
 first thing in the command history.
 
-* Use C-c C-c to exit from editing within Info.
+** Use C-c C-c to exit from editing within Info.
 
 It used to be C-z for this.  Somehow this use of C-z was
 left out when all the others were moved.  The intention is that
 C-z should always suspend Emacs.
 
-* Default arg to C-x < and C-x > now window width minus 2.
+** Default arg to C-x < and C-x > now window width minus 2.
 
 These commands, which scroll the current window horizontally
 by a specified number of columns, now scroll a considerable
 distance rather than a single column if used with no argument.
 
-* Auto Save Files Deleted.
+** Auto Save Files Deleted.
 
 The default value of `delete-auto-save-files' is now `t', so that
 when you save a file for real, its auto save file is deleted.
 
-* Rnews changes.
+** Rnews changes.
 
 The N, P and J keys in Rnews are renamed to M-n, M-p and M-j.
 These keys move among newsgroups.
@@ -382,7 +382,7 @@ this change, are eliminated.
 The s command for outputting the current article to a file
 is renamed as o, to be compatible with Rmail.
 
-* Sendmail changes.
+** Sendmail changes.
 
 If you have a ~/.mailrc file, Emacs searches it for mailing address
 aliases, and these aliases are expanded when you send mail in Emacs.
@@ -407,15 +407,15 @@ The new variable `mail-header-separator' now specifies 
the string
 to use on the line that goes between the headers and the message text.
 By default it is still "--text follows this line--".
 
-* Command history truncated automatically.
+** Command history truncated automatically.
 
 Just before each garbage collection, all but the last 30 elements
 of the command history are discarded.
 
 
-Incompatible Lisp Programming Changes in Emacs 17
+* Incompatible Lisp Programming Changes in Emacs 17
 
-* `&quote' no longer supported.
+** `&quote' no longer supported.
 
 This feature, which allowed Lisp functions to take arguments
 that were not evaluated, has been eliminated, because it is
@@ -434,7 +434,7 @@ with
 
    (defun foo-1 (x y z) ...
 
-* Functions `region-to-string' and `region-around-match' removed.
+** Functions `region-to-string' and `region-around-match' removed.
 
 These functions were made for compatibility with Gosling Emacs, but it
 turns out to be undesirable to use them in GNU Emacs because they use
@@ -450,24 +450,24 @@ the two functions `match-beginning' and `match-end'.  
These give
 you one bound at a time, as a numeric value, without changing
 point or the mark.
 
-* Function `function-type' removed.
+** Function `function-type' removed.
 
 This just appeared not to be very useful.  It can easily be written in
 Lisp if you happen to want it.  Just use `symbol-function' to get the
 function definition of a symbol, and look at its data type or its car
 if it is a list.
 
-* Variable `buffer-number' removed.
+** Variable `buffer-number' removed.
 
 You can still use the function `buffer-number' to find out
 a buffer's unique number (assigned in order of creation).
 
-* Variable `executing-macro' renamed `executing-kbd-macro'.
+** Variable `executing-macro' renamed `executing-kbd-macro'.
 
 This variable is the currently executing keyboard macro, as
 a string, or `nil' when no keyboard macro is being executed.
 
-* Loading term/$TERM.
+** Loading term/$TERM.
 
 The library term/$TERM (where $TERM get replaced by your terminal
 type), which is done by Emacs automatically when it starts up, now
@@ -478,12 +478,12 @@ term-$TERM; thus, for example, term-vt100.el, but now 
they live
 in a special subdirectory named term, and have names like
 term/vt100.el.
 
-* `command-history' format changed.
+** `command-history' format changed.
 
 The elements of this list are now Lisp expressions which can
 be evaluated directly to repeat a command.
 
-* Unused editing commands removed.
+** Unused editing commands removed.
 
 The functions `forward-to-word', `backward-to-word',
 `upcase-char', `mark-beginning-of-buffer' and `mark-end-of-buffer'
@@ -491,9 +491,9 @@ have been removed.  Their definitions can be found in file
 lisp/unused.el if you need them.
 
 
-Upward Compatible Lisp Programming Changes in Emacs 17
+* Upward Compatible Lisp Programming Changes in Emacs 17
 
-* You can now continue after errors and quits.
+** You can now continue after errors and quits.
 
 When the debugger is entered because of a C-g, due to
 a non-`nil' value of `debug-on-quit', the `c' command in the debugger
@@ -513,7 +513,7 @@ is not valid, another error occurs.
 Errors signaled with the function `error' cannot be continued.
 If you try to continue, the error just happens again.
 
-* `dot' renamed `point'.
+** `dot' renamed `point'.
 
 The word `dot' has been replaced with `point' in all
 function and variable names, including:
@@ -526,7 +526,7 @@ function and variable names, including:
 
 The old names are still supported, for now.
 
-* `string-match' records position of end of match.
+** `string-match' records position of end of match.
 
 After a successful call to `string-match', `(match-end 0)' will
 return the index in the string of the first character after the match.
@@ -534,7 +534,7 @@ Also, `match-begin' and `match-end' with nonzero arguments 
can be
 used to find the indices of beginnings and ends of substrings matched
 by subpatterns surrounded by parentheses.
 
-* New function `insert-before-markers'.
+** New function `insert-before-markers'.
 
 This function is just like `insert' except in the handling of any
 relocatable markers that are located at the point of insertion.
@@ -542,7 +542,7 @@ With `insert', such markers end up pointing before the 
inserted text.
 With `insert-before-markers', they end up pointing after the inserted
 text.
 
-* New function `copy-alist'.
+** New function `copy-alist'.
 
 This function takes one argument, a list, and makes a disjoint copy
 of the alist structure.  The list itself is copied, and each element
@@ -552,30 +552,30 @@ remain shared with the original argument.
 This is what it takes to get two alists disjoint enough that changes
 in one do not change the result of `assq' on the other.
 
-* New function `copy-keymap'.
+** New function `copy-keymap'.
 
 This function takes a keymap as argument and returns a new keymap
 containing initially the same bindings.  Rebindings in either one of
 them will not alter the bindings in the other.
 
-* New function `copy-syntax-table'.
+** New function `copy-syntax-table'.
 
 This function takes a syntax table as argument and returns a new
 syntax table containing initially the same syntax settings.  Changes
 in either one of them will not alter the other.
 
-* Randomizing the random numbers.
+** Randomizing the random numbers.
 
 `(random t)' causes the random number generator's seed to be set
 based on the current time and Emacs's process id.
 
-* Third argument to `modify-syntax-entry'.
+** Third argument to `modify-syntax-entry'.
 
 The optional third argument to `modify-syntax-entry', if specified
 should be a syntax table.  The modification is made in that syntax table
 rather than in the current syntax table.
 
-* New function `run-hooks'.
+** New function `run-hooks'.
 
 This function takes any number of symbols as arguments.
 It processes the symbols in order.  For each symbol which
@@ -584,7 +584,7 @@ called as a function, with no arguments.
 
 This is useful in major mode commands.
 
-* Second arg to `switch-to-buffer'.
+** Second arg to `switch-to-buffer'.
 
 If this function is given a non-`nil' second argument, then the
 selection being done is not recorded on the selection history.
@@ -592,7 +592,7 @@ The buffer's position in the history remains unchanged.  
This
 feature is used by the view commands, so that the selection history
 after exiting from viewing is the same as it was before.
 
-* Second arg to `display-buffer' and `pop-to-buffer'.
+** Second arg to `display-buffer' and `pop-to-buffer'.
 
 These two functions both accept an optional second argument which
 defaults to `nil'.  If the argument is not `nil', it means that
@@ -602,7 +602,7 @@ the selected window.
 
 This feature is used by `switch-to-buffer-other-window'.
 
-* New variable `completion-ignore-case'.
+** New variable `completion-ignore-case'.
 
 If this variable is non-`nil', completion allows strings
 in different cases to be considered matching.  The global value
@@ -614,13 +614,13 @@ to change the value globally, but you might not like the 
consequences
 in the many situations (buffer names, command names, file names)
 where case makes a difference.
 
-* Major modes related to Text mode call text-mode-hook, then their own hooks.
+** Major modes related to Text mode call text-mode-hook, then their own hooks.
 
 For example, turning on Outline mode first calls the value of
 `text-mode-hook' as a function, if it exists and is non-`nil',
 and then does likewise for the variable `outline-mode-hook'.
 
-* Defining new command line switches.
+** Defining new command line switches.
 
 You can define a new command line switch in your .emacs file
 by putting elements on the value of `command-switch-alist'.
@@ -638,26 +638,26 @@ examine this variable, and do
     (setq command-line-args (cdr command-line-args)
 to "use up" an argument.
 
-* New variable `load-in-progress'.
+** New variable `load-in-progress'.
 
 This variable is non-`nil' when a file of Lisp code is being read
 and executed by `load'.
 
-* New variable `print-length'.
+** New variable `print-length'.
 
 The value of this variable is normally `nil'.  It may instead be
 a number; in that case, when a list is printed by `prin1' or
 `princ' only that many initial elements are printed; the rest are
 replaced by `...'.
 
-* New variable `find-file-not-found-hook'.
+** New variable `find-file-not-found-hook'.
 
 If `find-file' or any of its variants is used on a nonexistent file,
 the value of `find-file-not-found-hook' is called (if it is not `nil')
 with no arguments, after creating an empty buffer.  The file's name
 can be found as the value of `buffer-file-name'.
 
-* Processes without buffers.
+** Processes without buffers.
 
 In the function `start-process', you can now specify `nil' as
 the process's buffer.  You can also set a process's buffer to `nil'
@@ -672,7 +672,7 @@ When a process has no buffer, its output is lost unless it 
has a
 filter, and no indication of its being stopped or killed is given
 unless it has a sentinel.
 
-* New function `user-variable-p'.  `v' arg prompting changed.
+** New function `user-variable-p'.  `v' arg prompting changed.
 
 This function takes a symbol as argument and returns `t' if
 the symbol is defined as a user option variable.  This means
@@ -686,7 +686,7 @@ user variables.
 The function `read-variable' also now accepts and completes
 over user variables only.
 
-* CBREAK mode input is the default in Unix 4.3 bsd.
+** CBREAK mode input is the default in Unix 4.3 bsd.
 
 In Berkeley 4.3 Unix, there are sufficient features for Emacs to
 work fully correctly using CBREAK mode and not using SIGIO.
@@ -695,7 +695,7 @@ This mode corresponds to `nil' as the first argument to
 `set-input-mode'.  You can still select either mode by calling
 that function.
 
-* Information on memory usage.
+** Information on memory usage.
 
 The new variable `data-bytes-used' contains the number
 of bytes of impure space allocated in Emacs.
@@ -704,18 +704,18 @@ Emacs could allocate.  Note that space formerly allocated
 and freed again still counts as `used', since it is still
 in Emacs's address space.
 
-* No limit on size of output from `format'.
+** No limit on size of output from `format'.
 
 The string output from `format' used to be truncated to
 100 characters in length.  Now it can have any length.
 
-* New errors `void-variable' and `void-function' replace `void-symbol'.
+** New errors `void-variable' and `void-function' replace `void-symbol'.
 
 This change makes it possible to have error messages that
 clearly distinguish undefined variables from undefined functions.
 It also allows `condition-case' to handle one case without the other.
 
-* `replace-match' handling of `\'.
+** `replace-match' handling of `\'.
 
 In `replace-match', when the replacement is not literal,
 `\' in the replacement string is always treated as an
@@ -728,19 +728,19 @@ This level of escaping is comparable with what goes on in
 a regular expression.  It is over and above the level of `\'
 escaping that goes on when strings are read in Lisp syntax.
 
-* New error `invalid-regexp'.
+** New error `invalid-regexp'.
 
 A regexp search signals this type of error if the argument does
 not meet the rules for regexp syntax.
 
-* `kill-emacs' with argument.
+** `kill-emacs' with argument.
 
 If the argument is a number, it is returned as the exit status code
 of the Emacs process.  If the argument is a string, its contents
 are stuffed as pending terminal input, to be read by another program
 after Emacs is dead.
 
-* New fifth argument to `subst-char-in-region'.
+** New fifth argument to `subst-char-in-region'.
 
 This argument is optional and defaults to `nil'.  If it is not `nil',
 then the substitutions made by this function are not recorded
@@ -749,7 +749,7 @@ in the Undo mechanism.
 This feature should be used with great care.  It is now used
 by Outline mode to make lines visible or invisible.
 
-* ` *Backtrace*' buffer renamed to `*Backtrace*'.
+** ` *Backtrace*' buffer renamed to `*Backtrace*'.
 
 As a result, you can now reselect this buffer easily if you switch to
 another while in the debugger.
@@ -757,7 +757,7 @@ another while in the debugger.
 Exiting from the debugger kills the `*Backtrace*' buffer, so you will
 not try to give commands in it when no longer really in the debugger.
 
-* New function `switch-to-buffer-other-window'.
+** New function `switch-to-buffer-other-window'.
 
 This is the new primitive to select a specified buffer (the
 argument) in another window.  It is not quite the same as
@@ -768,7 +768,7 @@ leave the current window's old buffer displayed as well.
 All functions to select a buffer in another window should
 do so by calling this new function.
 
-* New variable `minibuffer-help-form'.
+** New variable `minibuffer-help-form'.
 
 At entry to the minibuffer, the variable `help-form' is bound
 to the value of `minibuffer-help-form'.
@@ -779,7 +779,7 @@ the definition of C-h as a command).  `minibuffer-help-form'
 can be used to provide a different default way of handling
 C-h while in the minibuffer.
 
-* New \{...} documentation construct.
+** New \{...} documentation construct.
 
 It is now possible to set up the documentation string for
 a major mode in such a way that it always describes the contents
@@ -799,23 +799,23 @@ For example, the documentation string for the function 
`c-mode' contains
     Variables controlling indentation style:
     ...
 
-* New character syntax class "punctuation".
+** New character syntax class "punctuation".
 
 Punctuation characters behave like whitespace in word and
 list parsing, but can be distinguished in regexps and in the
 function `char-syntax'.  Punctuation syntax is represented by
 a period in `modify-syntax-entry'.
 
-* `auto-mode-alist' no longer needs entries for backup-file names,
+** `auto-mode-alist' no longer needs entries for backup-file names,
 
 Backup suffixes of all kinds are now stripped from a file's name
 before searching `auto-mode-alist'.
 
 
 
-Changes in Emacs 16
+* Changes in Emacs 16
 
-* No special code for Ambassadors, VT-100's and Concept-100's.
+** No special code for Ambassadors, VT-100's and Concept-100's.
 
 Emacs now controls these terminals based on the termcap entry, like
 all other terminals.  Formerly it did not refer to the termcap entries
@@ -827,24 +827,24 @@ fixing up the termcap entry.  See ./TERMS for more info.
 See ./TERMS in any case if you find that some terminal does not work
 right with Emacs now.
 
-* Minibuffer default completion character is TAB (and not ESC).
+** Minibuffer default completion character is TAB (and not ESC).
 
 So that ESC can be used in minibuffer for more useful prefix commands.
 
-* C-z suspends Emacs in all modes.
+** C-z suspends Emacs in all modes.
 
 Formerly, C-z was redefined for other purposes by certain modes,
 such as Buffer Menu mode.  Now other keys are used for those purposes,
 to keep the meaning of C-z uniform.
 
-* C-x ESC (repeat-complex-command) allows editing the command it repeats.
+** C-x ESC (repeat-complex-command) allows editing the command it repeats.
 
 Instead of asking for confirmation to re-execute a command from the
 command history, the command is placed, in its Lisp form, into the
 minibuffer for editing.  You can confirm by typing RETURN, change some
 arguments and then confirm, or abort with C-g.
 
-* Incremental search does less redisplay on slow terminals.
+** Incremental search does less redisplay on slow terminals.
 
 If the terminal baud rate is <= the value of `isearch-slow-speed',
 incremental searching outside the text on the screen creates
@@ -857,7 +857,7 @@ The initial value of `isearch-slow-speed' is 1200.
 
 This feature is courtesy of address@hidden
 
-* Recursive minibuffers not allowed.
+** Recursive minibuffers not allowed.
 
 If the minibuffer window is selected, most commands that would
 use the minibuffer gets an error instead.  (Specific commands
@@ -873,7 +873,7 @@ you can probably understand recursive minibuffers.
 This may be overridden by binding the variable
 `enable-recursive-minibuffers' to t.
 
-* New major mode Emacs-Lisp mode, for editing Lisp code to run in Emacs.
+** New major mode Emacs-Lisp mode, for editing Lisp code to run in Emacs.
 
 The mode in which emacs lisp files is edited is now called emacs-lisp-mode
 and is distinct from lisp-mode.  The latter is intended for use with
@@ -884,7 +884,7 @@ called emacs-lisp-mode-hook.  A consequence of this changes 
is that
 .emacs init files which set the value of lisp-mode-hook may need to be
 changed to use the new names.
 
-* Correct matching of parentheses is checked on insertion.
+** Correct matching of parentheses is checked on insertion.
 
 When you insert a close-paren, the matching open-paren
 is checked for validity.  The close paren must be the kind
@@ -894,9 +894,9 @@ preceded by quoting backslash syntax character is not 
matched.
 
 This feature was originally written by address@hidden
 
-* M-x list-command-history
-* M-x command-history-mode
-* M-x electric-command-history
+** M-x list-command-history
+** M-x command-history-mode
+** M-x electric-command-history
 
 `list-command-history' displays forms from the command history subject
 to user controlled filtering and limit on number of forms.  It leaves
@@ -913,7 +913,7 @@ which invoked `electric-command-history'.  The original 
window
 configuration is restored on exit unless the command selected changes
 it.
 
-* M-x edit-picture
+** M-x edit-picture
 
 Enters a temporary major mode (the previous major mode is remembered
 and can is restored on exit) designed for editing pictures and tables.
@@ -926,7 +926,7 @@ the documentation of function  edit-picture  for more 
details.
 
 Calls value of `edit-picture-hook' on entry if non-nil.
 
-* Stupid C-s/C-q `flow control' supported.
+** Stupid C-s/C-q `flow control' supported.
 
 Do (set-input-mode nil t) to tell Emacs to use CBREAK mode and interpret
 C-s and C-q as flow control commands.  (set-input-mode t nil) switches
@@ -955,18 +955,18 @@ The configuration switch CBREAK_INPUT is now eliminated.
 INTERRUPT_INPUT exists only to specify the default mode of operation;
 #define it to make interrupt-driven input the default.
 
-* Completion of directory names provides a slash.
+** Completion of directory names provides a slash.
 
 If file name completion yields the name of a directory,
 a slash is appended to it.
 
-* Undo can clear modified-flag.
+** Undo can clear modified-flag.
 
 If you undo changes in a buffer back to a state in which the
 buffer was not considered "modified", then it is labeled as
 once again "unmodified".
 
-* M-x run-lisp.
+** M-x run-lisp.
 
 This command creates an inferior Lisp process whose input and output
 appear in the Emacs buffer named `*lisp*'.  That buffer uses a major mode
@@ -977,21 +977,21 @@ lisp-mode-hook, in that order, if non-nil.
 Meanwhile, in lisp-mode, the command C-M-x is defined to
 send the current defun as input to the `*lisp*' subprocess.
 
-* Mode line says `Narrow' when buffer is clipped.
+** Mode line says `Narrow' when buffer is clipped.
 
 If a buffer has a clipping restriction (made by `narrow-to-region')
 then its mode line contains the word `Narrow' after the major and
 minor modes.
 
-* Mode line says `Abbrev' when abbrev mode is on.
+** Mode line says `Abbrev' when abbrev mode is on.
 
-* add-change-log-entry takes prefix argument
+** add-change-log-entry takes prefix argument
 
 Giving a prefix argument makes it prompt for login name, full name,
 and site name, with defaults.  Otherwise the defaults are used
 with no confirmation.
 
-* M-x view-buffer and M-x view-file
+** M-x view-buffer and M-x view-file
 
 view-buffer selects the named buffer, view-file finds the named file; the
 resulting buffer is placed into view-mode (a recursive edit).  The normal
@@ -1004,7 +1004,7 @@ Each calls value of `view-hook' if non-nil on entry.
 
 written by address@hidden
 
-* New key commands in dired.
+** New key commands in dired.
 
 `v' views (like more) the file on the current line.
 `#' marks auto-save files for deletion.
@@ -1014,7 +1014,7 @@ file is renamed to same directory.
 `c' copies a file and updates the directory listing if the file is
 copied to the same directory.
 
-* New function `electric-buffer-list'.
+** New function `electric-buffer-list'.
 
 This pops up a buffer describing the set of emacs buffers.
 Immediately typing space makes the buffer list go away and returns
@@ -1032,15 +1032,15 @@ Type C-h after invoking electric-buffer-list for more 
information.
 Calls value of `electric-buffer-menu-mode-hook' if non-nil on entry.
 Calls value of `after-electric-buffer-menu' on exit (select) if non-nil.
 
-Changes in version 16 for mail reading and sending
+** Changes in version 16 for mail reading and sending
 
-* sendmail prefix character is C-c (and not C-z).  New command C-c w.
+*** sendmail prefix character is C-c (and not C-z).  New command C-c w.
 
 For instance C-c C-c (or C-c C-s) sends mail now rather than C-z C-z.
 C-c w inserts your `signature' (contents of ~/.signature) at the end
 of mail.
 
-* New feature in C-c y command in sending mail.
+*** New feature in C-c y command in sending mail.
 
 C-c y is the command to insert the message being replied to.
 Normally it deletes most header fields and indents everything
@@ -1050,7 +1050,7 @@ Now, C-c y does not delete header fields or indent.
 C-c y with any other numeric argument does delete most header
 fields, but indents by the amount specified in the argument.
 
-* C-r command in Rmail edits current message.
+*** C-r command in Rmail edits current message.
 
 It does this by switching to a different major mode
 which is nearly the same as Text mode.  The only difference
@@ -1063,31 +1063,31 @@ C-c and C-] are the only ways "back into Rmail", but you
 can switch to other buffers and edit them as usual.
 C-r in Rmail changes only the handling of the Rmail buffer.
 
-* Rmail command `t' toggles header display.
+*** Rmail command `t' toggles header display.
 
 Normally Rmail reformats messages to hide most header fields.
 `t' switches to display of all the header fields of the
 current message, as long as it remains current.
 Another `t' switches back to the usual display.
 
-* Rmail command '>' goes to the last message.
+*** Rmail command '>' goes to the last message.
 
-* Rmail commands `a' and `k' set message attributes.
+*** Rmail commands `a' and `k' set message attributes.
 `a' adds an attribute and `k' removes one.  You specify
 the attribute by name.  You can specify either a built-in
 flag such as "deleted" or "filed", or a user-defined keyword
 (anything not recognized as built-in).
 
-* Rmail commands `l' and `L' summarize by attributes.
+*** Rmail commands `l' and `L' summarize by attributes.
 
 These commands create a summary with one line per message,
 like `h', but they list only some of the messages.  You
 specify which attribute (for `l') or attributes (for `L')
 the messages should have.
 
-* Rmail can parse mmdf mail files.
+*** Rmail can parse mmdf mail files.
 
-* Interface to MH mail system.
+*** Interface to MH mail system.
 
 mh-e is a front end for GNU emacs and the MH mail system.  It
 provides a friendly and convenient interface to the MH commands.
@@ -1103,9 +1103,9 @@ compiler switch.
 
 From address@hidden
 
-New hooks and parameters in version 16
+** New hooks and parameters in version 16
 
-* New variable `blink-matching-paren-distance'.
+*** New variable `blink-matching-paren-distance'.
 
 This is the maximum number of characters to search for
 an open-paren to match an inserted close-paren.
@@ -1118,13 +1118,13 @@ open-paren is found.
 
 This feature was originally written by address@hidden
 
-* New variable `find-file-run-dired'
+*** New variable `find-file-run-dired'
 
 If nil, find-file will report an error if an attempt to visit a
 directory is detected; otherwise, it runs dired on that directory.
 The default is t.
 
-* Variable `dired-listing-switches' holds switches given to `ls' by dired.
+*** Variable `dired-listing-switches' holds switches given to `ls' by dired.
 
 The value should be a string containing `-' followed by letters.
 The letter `l' had better be included and letter 'F' had better be excluded!
@@ -1132,12 +1132,12 @@ The default is "-al".
 
 This feature was originally written by address@hidden
 
-* New variable `display-time-day-and-date'.
+*** New variable `display-time-day-and-date'.
 
 If this variable is set non-`nil', the function M-x display-time
 displays the day and date, as well as the time.
 
-* New parameter `c-continued-statement-indent'.
+*** New parameter `c-continued-statement-indent'.
 
 This controls the extra indentation given to a line
 that continues a C statement started on the previous line.
@@ -1147,7 +1147,7 @@ By default it is 2, which is why you would see
          bar ();
 
 
-* Changed meaning of `c-indent-level'.
+*** Changed meaning of `c-indent-level'.
 
 The value of `c-brace-offset' used to be
 subtracted from the value of `c-indent-level' whenever
@@ -1157,20 +1157,20 @@ As a result, `c-indent-level' is now the offset of
 statements within a block, relative to the line containing
 the open-brace that starts the block.
 
-* turn-on-auto-fill is useful value for text-mode-hook.
+*** turn-on-auto-fill is useful value for text-mode-hook.
 
 (setq text-mode-hook 'turn-on-auto-fill)
 is all you have to do to make sure Auto Fill mode is turned
 on whenever you enter Text mode.
 
-* Parameter explicit-shell-file-name for M-x shell.
+*** Parameter explicit-shell-file-name for M-x shell.
 
 This variable, if non-nil, specifies the file name to use
 for the shell to run if you do M-x shell.
 
 Changes in version 16 affecting Lisp programming:
 
-* Documentation strings adapt to customization.
+*** Documentation strings adapt to customization.
 
 Often the documentation string for a command wants to mention
 another command.  Simply stating the other command as a
@@ -1201,12 +1201,12 @@ The new function `substitute-command-keys' takes a 
string possibly
 containing \[...] constructs and replaces those constructs with
 the key sequences they currently stand for.
 
-* Primitives `find-line-comment' and `find-line-comment-body' flushed.
+*** Primitives `find-line-comment' and `find-line-comment-body' flushed.
 
 Search for the value of `comment-start-skip' if you want to find
 whether and where a line has a comment.
 
-* New function `auto-save-file-name-p'
+*** New function `auto-save-file-name-p'
 
 Should return non-`nil' if given a string which is the name of an
 auto-save file (sans directory name).  If you redefine
@@ -1214,11 +1214,11 @@ auto-save file (sans directory name).  If you redefine
 default, this function returns `t' for filenames beginning with
 character `#'.
 
-* The value of `exec-directory' now ends in a slash.
+*** The value of `exec-directory' now ends in a slash.
 
 This is to be compatible with most directory names in GNU Emacs.
 
-* Dribble files and termscript files.
+*** Dribble files and termscript files.
 
 (open-dribble-file FILE) opens a dribble file named FILE.  When a
 dribble file is open, every character Emacs reads from the terminal is
@@ -1231,51 +1231,51 @@ are also written in the termscript file.
 The two of these together are very useful for debugging Emacs problems
 in redisplay.
 
-* Upper case command characters by default are same as lower case.
+*** Upper case command characters by default are same as lower case.
 
 If a character in a command is an upper case letter, and is not defined,
 Emacs uses the definition of the corresponding lower case letter.
 For example, if C-x U is not directly undefined, it is treated as
 a synonym for C-x u (undo).
 
-* Undefined function errors versus undefined variable errors.
+*** Undefined function errors versus undefined variable errors.
 
 Void-symbol errors now say "boundp" if the symbol's value was void
 or "fboundp" if the function definition was void.
 
-* New function `bury-buffer'.
+*** New function `bury-buffer'.
 
 The new function `bury-buffer' takes one argument, a buffer object,
 and puts that buffer at the end of the internal list of buffers.
 So it is the least preferred candidate for use as the default value
 of C-x b, or for other-buffer to return.
 
-* Already-displayed buffers have low priority for display.
+*** Already-displayed buffers have low priority for display.
 
 When a buffer is chosen automatically for display, or to be the
 default in C-x b, buffers already displayed in windows have lower
 priority than buffers not currently visible.
 
-* `set-window-start' accepts a third argument NOFORCE.
+*** `set-window-start' accepts a third argument NOFORCE.
 
 This argument, if non-nil, prevents the window's force_start flag
 from being set.  Setting the force_start flag causes the next
 redisplay to insist on starting display at the specified starting
 point, even if dot must be moved to get it onto the screen.
 
-* New function `send-string-to-terminal'.
+*** New function `send-string-to-terminal'.
 
 This function takes one argument, a string, and outputs its contents
 to the terminal exactly as specified: control characters, escape
 sequences, and all.
 
-* Keypad put in command mode.
+*** Keypad put in command mode.
 
 The terminal's keypad is now put into command mode, as opposed to
 numeric mode, while Emacs is running.  This is done by means of the
 termcap `ks' and `ke' strings.
 
-* New function `generate-new-buffer'
+*** New function `generate-new-buffer'
 
 This function takes a string as an argument NAME and looks for a
 creates and returns a buffer called NAME if one did not already exist.
@@ -1283,12 +1283,12 @@ Otherwise, it successively tries appending suffixes of 
the form "<1>",
 "<2>" etc to NAME until it creates a string which does not name an
 existing buffer.  A new buffer with that name is the created and returned.
 
-* New function `prin1-to-string'
+*** New function `prin1-to-string'
 This function takes one argument, a lisp object, and returns a string
 containing that object's printed representation, such as `prin1'
 would output.
 
-* New function `read-from-minibuffer'
+*** New function `read-from-minibuffer'
 Lets you supply a prompt, initial-contents, a keymap, and specify
 whether the result should be interpreted as a string or a lisp object.
 
@@ -1296,23 +1296,23 @@ Old functions `read-minibuffer', `eval-minibuffer', 
`read-string' all
 take second optional string argument which is initial contents of
 minibuffer.
 
-* minibuffer variable names changed (names of keymaps)
+*** minibuffer variable names changed (names of keymaps)
 
 minibuf-local-map -> minibuffer-local-map
 minibuf-local-ns-map -> minibuffer-local-ns-map
 minibuf-local-completion-map -> minibuffer-local-completion-map
 minibuf-local-must-match-map -> minibuffer-local-must-match-map
 
-Changes in version 16 affecting configuring and building Emacs
+** Changes in version 16 affecting configuring and building Emacs
 
-* Configuration switch VT100_INVERSE eliminated.
+*** Configuration switch VT100_INVERSE eliminated.
 
 You can control the use of inverse video on any terminal by setting
 the variable `inverse-video', or by changing the termcap entry.  If
 you like, set `inverse-video' in your `.emacs' file based on
 examination of (getenv "TERM").
 
-* New switch `-batch' makes Emacs run noninteractively.
+*** New switch `-batch' makes Emacs run noninteractively.
 
 If the switch `-batch' is used, Emacs treats its standard output
 and input like ordinary files (even if they are a terminal).
@@ -1330,22 +1330,22 @@ way to accomplish this.
 The Lisp variable `noninteractive' is now defined, to be `nil'
 except when `-batch' has been specified.
 
-* Emacs can be built with output redirected to a file.
+*** Emacs can be built with output redirected to a file.
 
 This is because -batch (see above) is now used in building Emacs.
 
 
 
-Changes in Emacs 15
+* Changes in Emacs 15
 
-* Emacs now runs on Sun and Megatest 68000 systems;
+** Emacs now runs on Sun and Megatest 68000 systems;
  also on at least one 16000 system running 4.2.
 
-* Emacs now alters the output-start and output-stop characters
+** Emacs now alters the output-start and output-stop characters
  to prevent C-s and C-q from being considered as flow control
  by cretinous rlogin software in 4.2.
 
-* It is now possible convert Mocklisp code (for Gosling Emacs) to Lisp code
+** It is now possible convert Mocklisp code (for Gosling Emacs) to Lisp code
  that can run in GNU Emacs.  M-x convert-mocklisp-buffer
  converts the contents of the current buffer from Mocklisp to
  GNU Emacs Lisp.  You should then save the converted buffer with C-x C-w
@@ -1365,7 +1365,7 @@ Changes in Emacs 15
  to GNU lisp code, with M-x convert-mocklisp-buffer being the first
  step in this process.
 
-* Control-x n (narrow-to-region) is now by default a disabled command.
+** Control-x n (narrow-to-region) is now by default a disabled command.
 
  This means that, if you issue this command, it will ask whether
  you really mean it.  You have the opportunity to enable the
@@ -1373,7 +1373,7 @@ Changes in Emacs 15
  This will place the form "(put 'narrow-to-region 'disabled nil)" in your
  .emacs file.
 
-* Tags now prompts for the tag table file name to use.
+** Tags now prompts for the tag table file name to use.
 
  All the tags commands ask for the tag table file name
  if you have not yet specified one.
@@ -1382,12 +1382,12 @@ Changes in Emacs 15
  specify the tag table file name initially, or to switch
  to a new tag table.
 
-* If truncate-partial-width-windows is non-nil (as it initially is),
+** If truncate-partial-width-windows is non-nil (as it initially is),
  all windows less than the full screen width (that is,
  made by side-by-side splitting) truncate lines rather than continuing
  them.
 
-* Emacs now checks for Lisp stack overflow to avoid fatal errors.
+** Emacs now checks for Lisp stack overflow to avoid fatal errors.
  The depth in eval, apply and funcall may not exceed max-lisp-eval-depth.
  The depth in variable bindings and unwind-protects may not exceed
  max-specpdl-size.  If either limit is exceeded, an error occurs.
@@ -1395,7 +1395,7 @@ Changes in Emacs 15
  too large, you are vulnerable to a fatal error if you invoke
  Lisp code that does infinite recursion.
 
-* New hooks  find-file-hook  and  write-file-hook.
+** New hooks  find-file-hook  and  write-file-hook.
  Both of these variables if non-nil should be functions of no arguments.
  At the time they are called (current-buffer) will be the buffer being
  read or written respectively.
@@ -1409,13 +1409,13 @@ Changes in Emacs 15
 
  write-file-hook  is called just before writing out a file from a buffer.
 
-* The initial value of shell-prompt-pattern is now  "^[^#$%>]*[#$%>] *"
+** The initial value of shell-prompt-pattern is now  "^[^#$%>]*[#$%>] *"
 
-* If the .emacs file sets inhibit-startup-message to non-nil,
+** If the .emacs file sets inhibit-startup-message to non-nil,
  the messages normally printed by Emacs at startup time
  are inhibited.
 
-* Facility for run-time conditionalization on the basis of emacs features.
+** Facility for run-time conditionalization on the basis of emacs features.
 
  The new variable  features  is a list of symbols which represent "features"
  of the executing emacs, for use in run-time conditionalization.
@@ -1438,14 +1438,14 @@ Changes in Emacs 15
                                   (if (not featurep FEATURE) (error ...))))
  FILE-NAME is optional and defaults to FEATURE.
 
-* New function load-average.
+** New function load-average.
 
  This returns a list of three integers, which are
  the current 1 minute, 5 minute and 15 minute load averages,
  each multiplied by a hundred (since normally they are floating
  point numbers).
 
-* Per-terminal libraries loaded automatically.
+** Per-terminal libraries loaded automatically.
 
  Emacs when starting up on terminal type T automatically loads
  a library named term-T.  T is the value of the TERM environment variable.
@@ -1457,7 +1457,7 @@ Changes in Emacs 15
  redefinitions and let the user's init file, which is loaded later,
  call that command or not, as the user prefers.
 
-* Programmer's note: detecting killed buffers.
+** Programmer's note: detecting killed buffers.
 
  Buffers are eliminated by explicitly killing them, using
  the function kill-buffer.  This does not eliminate or affect
@@ -1466,7 +1466,7 @@ Changes in Emacs 15
  the buffer has been killed, use the function buffer-name.
  It returns nil on a killed buffer, and a string on a live buffer.
 
-* New ways to access the last command input character.
+** New ways to access the last command input character.
 
  The function last-key-struck, which used to return the last
  input character that was read by command input, is eliminated.
@@ -1479,13 +1479,13 @@ Changes in Emacs 15
  read for.  last-input-char and last-command-char are different
  only inside a command that has called read-char to read input.
 
-* The new switch -kill causes Emacs to exit after processing the
+** The new switch -kill causes Emacs to exit after processing the
  preceding command line arguments.  Thus,
     emacs -l lib data -e do-it -kill
  means to load lib, find file data, call do-it on no arguments,
  and then exit.
 
-* The config.h file has been modularized.
+** The config.h file has been modularized.
 
  Options that depend on the machine you are running on are defined
  in a file whose name starts with "m-", such as m-vax.h.
@@ -1499,25 +1499,25 @@ Changes in Emacs 15
  select the correct m- and s- files but will never have to change their
  contents.
 
-* Termcap AL and DL strings are understood.
+** Termcap AL and DL strings are understood.
 
  If the termcap entry defines AL and DL strings, for insertion
  and deletion of multiple lines in one blow, Emacs now uses them.
  This matters most on certain bit map display terminals for which
  scrolling is comparatively slow.
 
-* Bias against scrolling screen far on fast terminals.
+** Bias against scrolling screen far on fast terminals.
 
  Emacs now prefers to redraw a few lines rather than
  shift them a long distance on the screen, when the terminal is fast.
 
-* New major mode, mim-mode.
+** New major mode, mim-mode.
 
  This major mode is for editing MDL code.  Perhaps a MDL
  user can explain why it is not called mdl-mode.
  You must load the library mim-mode explicitly to use this.
 
-* GNU documentation formatter `texinfo'.
+** GNU documentation formatter `texinfo'.
 
  The `texinfo' library defines a format for documentation
  files which can be passed through Tex to make a printed manual
@@ -1532,7 +1532,7 @@ Changes in Emacs 15
  This is not ready for distribution yet, but will appear at
  a later time.
 
-* New function read-from-string (emacs 15.29)
+** New function read-from-string (emacs 15.29)
 
  read-from-string takes three arguments: a string to read from,
  and optionally start and end indices which delimit a substring
@@ -1551,14 +1551,14 @@ Changes in Emacs 15
 
 
 
-Changes in Emacs 14
+* Changes in Emacs 14
 
-* Completion now prints various messages such as [Sole Completion]
+** Completion now prints various messages such as [Sole Completion]
  or [Next Character Not Unique] to describe the results obtained.
  These messages appear after the text in the minibuffer, and remain
  on the screen until a few seconds go by or you type a key.
 
-* The buffer-read-only flag is implemented.
+** The buffer-read-only flag is implemented.
  Setting or binding this per-buffer variable to a non-nil value
  makes illegal any operation which would modify the textual content of
  the buffer.  (Such operations signal a  buffer-read-only  error)
@@ -1568,12 +1568,12 @@ Changes in Emacs 14
  by default to prevent accidental damage to the information in those
  buffers.
 
-* Functions car-safe and cdr-safe.
+** Functions car-safe and cdr-safe.
  These functions are like car and cdr when the argument is a cons.
  Given an argument not a cons, car-safe always returns nil, with
  no error; the same for cdr-safe.
 
-* The new function user-real-login-name returns the name corresponding
+** The new function user-real-login-name returns the name corresponding
  to the real uid of the Emacs process.  This is usually the same
  as what user-login-name returns; however, when Emacs is invoked
  from su, user-real-login-name returns "root" but user-login-name
@@ -1581,9 +1581,9 @@ Changes in Emacs 14
 
 
 
-Changes in Emacs 13
+* Changes in Emacs 13
 
-* There is a new version numbering scheme.
+** There is a new version numbering scheme.
 
  What used to be the first version number, which was 1,
  has been discarded since it does not seem that I need three
@@ -1594,7 +1594,7 @@ Changes in Emacs 13
  Emacs when I distribute it; it will be incremented each time
  Emacs is built at another site.
 
-* There is now a reader syntax for Meta characters:
+** There is now a reader syntax for Meta characters:
  \M-CHAR means CHAR or'ed with the Meta bit.  For example:
 
     ?\M-x   is   (+ ?x 128)
@@ -1608,7 +1608,7 @@ Changes in Emacs 13
 
  ?\C- can be used likewise for control characters.  (13.9)
 
-* Installation change
+** Installation change
  The string "../lisp" now adds to the front of the load-path
  used for searching for Lisp files during Emacs initialization.
  It used to replace the path specified in paths.h entirely.
@@ -1617,13 +1617,13 @@ Changes in Emacs 13
 
 
 
-Changes in Emacs 1.12
+* Changes in Emacs 1.12
 
-* There is a new installation procedure.
+** There is a new installation procedure.
  See the file INSTALL that comes in the top level
  directory in the tar file or tape.
 
-* The Meta key is now supported on terminals that have it.
+** The Meta key is now supported on terminals that have it.
  This is a shift key which causes the high bit to be turned on
  in all input characters typed while it is held down.
 
@@ -1643,10 +1643,10 @@ Changes in Emacs 1.12
  explicitly, but not effective if the character comes from
  the use of the Meta key.
 
-* `-' is no longer a completion command in the minibuffer.
+** `-' is no longer a completion command in the minibuffer.
  It is an ordinary self-inserting character.
 
-* The list load-path of directories load to search for Lisp files
+** The list load-path of directories load to search for Lisp files
  is now controlled by the EMACSLOADPATH environment variable
 [[ Note this was originally EMACS-LOAD-PATH and has been changed
  again; sh does not deal properly with hyphens in env variable names]]
@@ -1658,7 +1658,7 @@ Changes in Emacs 1.12
  ignore EMACSLOADPATH, however; you should avoid having
  this variable set while building Emacs.
 
-* You can now specify a translation table for keyboard
+** You can now specify a translation table for keyboard
  input characters, as a way of exchanging or substituting
  keys on the keyboard.
 
@@ -1709,20 +1709,20 @@ Changes in Emacs 1.12
   (aset keyboard-translate-table (+ 128 ?\_) (+ 128 ?\^?))
   (aset keyboard-translate-table (+ 128 ?\^?) (+ 128 ?\_))
 
-* (process-kill-without-query PROCESS)
+** (process-kill-without-query PROCESS)
 
 This marks the process so that, when you kill Emacs,
 you will not on its account be queried about active subprocesses.
 
 
 
-Changes in Emacs 1.11
+* Changes in Emacs 1.11
 
-* The commands C-c and C-z have been interchanged,
+** The commands C-c and C-z have been interchanged,
  for greater compatibility with normal Unix usage.
  C-z now runs suspend-emacs and C-c runs exit-recursive-edit.
 
-* The value returned by file-name-directory now ends
+** The value returned by file-name-directory now ends
  with a slash.  (file-name-directory "foo/bar") => "foo/".
  This avoids confusing results when dealing with files
  in the root directory.
@@ -1730,13 +1730,13 @@ Changes in Emacs 1.11
  The value of the per-buffer variable default-directory
  is also supposed to have a final slash now.
 
-* There are now variables to control the switches passed to
+** There are now variables to control the switches passed to
  `ls' by the C-x C-d command (list-directory).
  list-directory-brief-switches is a string, initially "-CF",
  used for brief listings, and list-directory-verbose-switches
  is a string, initially "-l", used for verbose ones.
 
-* For Ann Arbor Ambassador terminals, the termcap "ti" string
+** For Ann Arbor Ambassador terminals, the termcap "ti" string
  is now used to initialize the screen geometry on entry to Emacs,
  and the "te" string is used to set it back on exit.
  If the termcap entry does not define the "ti" or "te" string,
@@ -1744,36 +1744,36 @@ Changes in Emacs 1.11
 
 
 
-Changes in Emacs 1.10
+* Changes in Emacs 1.10
 
-* GNU Emacs has been made almost 1/3 smaller.
+** GNU Emacs has been made almost 1/3 smaller.
  It now dumps out as only 530kbytes on Vax 4.2bsd.
 
-* The term "checkpoint" has been replaced by "auto save"
+** The term "checkpoint" has been replaced by "auto save"
  throughout the function names, variable names and documentation
  of GNU Emacs.
 
-* The function load now tries appending ".elc" and ".el"
+** The function load now tries appending ".elc" and ".el"
  to the specified filename BEFORE it tries the filename
  without change.
 
-* rmail now makes the mode line display the total number
+** rmail now makes the mode line display the total number
  of messages and the current message number.
  The "f" command now means forward a message to another user.
  The command to search through all messages for a string is now "F".
  The "u" command now means to move back to the previous
  message and undelete it.  To undelete the selected message, use Meta-u.
 
-* The hyphen character is now equivalent to a Space while
+** The hyphen character is now equivalent to a Space while
  in completing minibuffers.  Both mean to complete an additional word.
 
-* The Lisp function error now takes args like format
+** The Lisp function error now takes args like format
  which are used to construct the error message.
 
-* Redisplay will refuse to start its display at the end of the buffer.
+** Redisplay will refuse to start its display at the end of the buffer.
  It will pick a new place to display from, rather than use that.
 
-* The value returned by garbage-collect has been changed.
+** The value returned by garbage-collect has been changed.
  Its first element is no longer a number but a cons,
  whose car is the number of cons cells now in use,
  and whose cdr is the number of cons cells that have been
@@ -1781,42 +1781,42 @@ Changes in Emacs 1.10
  The second element is similar but describes symbols rather than cons cells.
  The third element is similar but describes markers.
 
-* The variable buffer-name has been eliminated.
+** The variable buffer-name has been eliminated.
  The function buffer-name still exists.  This is to prevent
  user programs from changing buffer names without going
  through the rename-buffer function.
 
 
 
-Changes in Emacs 1.9
+* Changes in Emacs 1.9
 
-* When a fill prefix is in effect, paragraphs are started
+** When a fill prefix is in effect, paragraphs are started
  or separated by lines that do not start with the fill prefix.
  Also, a line which consists of the fill prefix followed by
  white space separates paragraphs.
 
-* C-x C-v runs the new function find-alternate-file.
+** C-x C-v runs the new function find-alternate-file.
  It finds the specified file, switches to that buffer,
  and kills the previous current buffer.  (It requires
  confirmation if that buffer had changes.)  This is
  most useful after you find the wrong file due to a typo.
 
-* Exiting the minibuffer moves the cursor to column 0,
+** Exiting the minibuffer moves the cursor to column 0,
  to show you that it has really been exited.
 
-* Meta-g (fill-region) now fills each paragraph in the
+** Meta-g (fill-region) now fills each paragraph in the
  region individually.  To fill the region as if it were
  a single paragraph (for when the paragraph-delimiting mechanism
  does the wrong thing), use fill-region-as-paragraph.
 
-* Tab in text mode now runs the function tab-to-tab-stop.
+** Tab in text mode now runs the function tab-to-tab-stop.
  A new mode called indented-text-mode is like text-mode
  except that in it Tab runs the function indent-relative,
  which indents the line under the previous line.
  If auto fill is enabled while in indented-text-mode,
  the new lines that it makes are indented.
 
-* Functions kill-rectangle and yank-rectangle.
+** Functions kill-rectangle and yank-rectangle.
  kill-rectangle deletes the rectangle specified by dot and mark
  (or by two arguments) and saves it in the variable killed-rectangle.
  yank-rectangle inserts the rectangle in that variable.
@@ -1826,7 +1826,7 @@ Changes in Emacs 1.9
  not be changed if the rectangle is later reinserted
  at a different column position.
 
-* `+' in a regular expression now means
+** `+' in a regular expression now means
  to repeat the previous expression one or more times.
  `?' means to repeat it zero or one time.
  They are in all regards like `*' except for the
@@ -1836,19 +1836,19 @@ Changes in Emacs 1.9
  when it is at the beginning of a word; \> matches
  the null string at the end of a word.
 
-* C-x p narrows the buffer so that only the current page
+** C-x p narrows the buffer so that only the current page
  is visible.
 
-* C-x ) with argument repeats the kbd macro just
+** C-x ) with argument repeats the kbd macro just
  defined that many times, counting the definition
  as one repetition.
 
-* C-x ( with argument begins defining a kbd macro
+** C-x ( with argument begins defining a kbd macro
  starting with the last one defined.  It executes that
  previous kbd macro initially, just as if you began
  by typing it over again.
 
-* C-x q command queries the user during kbd macro execution.
+** C-x q command queries the user during kbd macro execution.
  With prefix argument, enters recursive edit,
   reading keyboard commands even within a kbd macro.
   You can give different commands each time the macro executes.
@@ -1859,7 +1859,7 @@ Changes in Emacs 1.9
   C-r -- enter a recursive edit, then on exit ask again for a character
   C-l -- redisplay screen and ask again."
 
-* write-kbd-macro and append-kbd-macro are used to save
+** write-kbd-macro and append-kbd-macro are used to save
  a kbd macro definition in a file (as Lisp code to
  redefine the macro when the file is loaded).
  These commands differ in that write-kbd-macro
@@ -1868,26 +1868,26 @@ Changes in Emacs 1.9
  record the keys which invoke the macro as well as the
  macro's definition.
 
-* The variable global-minor-modes is used to display
+** The variable global-minor-modes is used to display
  strings in the mode line of all buffers.  It should be
  a list of elements that are conses whose cdrs are strings
  to be displayed.  This complements the variable
  minor-modes, which has the same effect but has a separate
  value in each buffer.
 
-* C-x = describes horizontal scrolling in effect, if any.
+** C-x = describes horizontal scrolling in effect, if any.
 
-* Return now auto-fills the line it is ending, in auto fill mode.
+** Return now auto-fills the line it is ending, in auto fill mode.
  Space with zero as argument auto-fills the line before it
  just like Space without an argument.
 
 
 
-Changes in Emacs 1.8
+* Changes in Emacs 1.8
 
 This release mostly fixes bugs.  There are a few new features:
 
-* apropos now sorts the symbols before displaying them.
+** apropos now sorts the symbols before displaying them.
  Also, it returns a list of the symbols found.
 
  apropos now accepts a second arg PRED which should be a function
@@ -1901,26 +1901,26 @@ This release mostly fixes bugs.  There are a few new 
features:
  C-h a now runs the new function command-apropos rather than
  apropos, and shows only symbols with definitions as commands.
 
-* M-x shell sends the command
+** M-x shell sends the command
     if (-f ~/.emacs_NAME)source ~/.emacs_NAME
  invisibly to the shell when it starts.  Here NAME
  is replaced by the name of shell used,
  as it came from your ESHELL or SHELL environment variable
  but with directory name, if any, removed.
 
-* M-, now runs the command tags-loop-continue, which is used
+** M-, now runs the command tags-loop-continue, which is used
  to resume a terminated tags-search or tags-query-replace.
 
 
 
-Changes in Emacs 1.7
+* Changes in Emacs 1.7
 
 It's Beat CCA Week.
 
-* The initial buffer is now called "*scratch*" instead of "scratch",
+** The initial buffer is now called "*scratch*" instead of "scratch",
  so that all buffer names used automatically by Emacs now have *'s.
 
-* Undo information is now stored separately for each buffer.
+** Undo information is now stored separately for each buffer.
  The Undo command (C-x u) always applies to the current
  buffer only.
 
@@ -1932,7 +1932,7 @@ It's Beat CCA Week.
  kept for buffers whose names start with spaces.  (These
  buffers also do not appear in the C-x C-b display.)
 
-* Rectangle operations are now implemented.
+** Rectangle operations are now implemented.
  C-x r stores the rectangle described by dot and mark
  into a register; it reads the register name from the keyboard.
  C-x g, the command to insert the contents of a register,
@@ -1950,7 +1950,7 @@ It's Beat CCA Week.
     delete the text of the specified rectangle,
     moving the text beyond it on each line leftward.
 
-* Side-by-side windows are allowed.  Use C-x 5 to split the
+** Side-by-side windows are allowed.  Use C-x 5 to split the
  current window into two windows side by side.
  C-x } makes the selected window ARG columns wider at the
  expense of the windows at its sides.  C-x { makes the selected
@@ -1960,7 +1960,7 @@ It's Beat CCA Week.
  C-x 2 now accepts a numeric argument to specify the number of
  lines to give to the uppermost of the two windows it makes.
 
-* Horizontal scrolling of the lines in a window is now implemented.
+** Horizontal scrolling of the lines in a window is now implemented.
  C-x < (scroll-left) scrolls all displayed lines left,
  with the numeric argument (default 1) saying how far to scroll.
  When the window is scrolled left, some amount of the beginning
@@ -1972,17 +1972,17 @@ It's Beat CCA Week.
  regardless of the value of the variable truncate-lines in the
  buffer being displayed.
 
-* C-x C-d now uses the default output format of `ls',
+** C-x C-d now uses the default output format of `ls',
  which gives just file names in multiple columns.
  C-u C-x C-d passes the -l switch to `ls'.
 
-* C-t at the end of a line now exchanges the two preceding characters.
+** C-t at the end of a line now exchanges the two preceding characters.
 
  All the transpose commands now interpret zero as an argument
  to mean to transpose the textual unit after or around dot
  with the one after or around the mark.
 
-* M-! executes a shell command in an inferior shell
+** M-! executes a shell command in an inferior shell
  and displays the output from it.  With a prefix argument,
  it inserts the output in the current buffer after dot
  and sets the mark after the output.  The shell command
@@ -1992,10 +1992,10 @@ It's Beat CCA Week.
  as input to the shell command.  A prefix argument makes
  the output from the command replace the contents of the region.
 
-* The mode line will now say "Def" after the major mode
+** The mode line will now say "Def" after the major mode
  while a keyboard macro is being defined.
 
-* The variable fill-prefix is now used by Meta-q.
+** The variable fill-prefix is now used by Meta-q.
  Meta-q removes the fill prefix from lines that start with it
  before filling, and inserts the fill prefix on each line
  after filling.
@@ -2003,35 +2003,35 @@ It's Beat CCA Week.
  The command C-x . sets the fill prefix equal to the text
  on the current line before dot.
 
-* The new command Meta-j (indent-new-comment-line),
+** The new command Meta-j (indent-new-comment-line),
  is like Linefeed (indent-new-line) except when dot is inside a comment;
  in that case, Meta-j inserts a comment starter on the new line,
  indented under the comment starter above.  It also inserts
  a comment terminator at the end of the line above,
  if the language being edited calls for one.
 
-* Rmail should work correctly now, and has some C-h m documentation.
+** Rmail should work correctly now, and has some C-h m documentation.
 
 
 
-Changes in Emacs 1.6
+* Changes in Emacs 1.6
 
-* save-buffers-kill-emacs is now on C-x C-c
+** save-buffers-kill-emacs is now on C-x C-c
  while C-x C-z does suspend-emacs.  This is to make
  C-x C-c like the normal Unix meaning of C-c
  and C-x C-z like the normal Unix meaning of C-z.
 
-* M-ESC (eval-expression) is now a disabled command by default.
+** M-ESC (eval-expression) is now a disabled command by default.
  This prevents users who type ESC ESC accidentally from
  getting confusing results.  Put
     (put 'eval-expression 'disabled nil)
  in your ~/.emacs file to enable the command.
 
-* Self-inserting text is grouped into bunches for undoing.
+** Self-inserting text is grouped into bunches for undoing.
  Each C-x u command undoes up to 20 consecutive self-inserting
  characters.
 
-* Help f now uses as a default the function being called
+** Help f now uses as a default the function being called
  in the innermost Lisp expression that dot is in.
  This makes it more convenient to use while writing
  Lisp code to run in Emacs.
@@ -2041,7 +2041,7 @@ Changes in Emacs 1.6
  Likewise, Help v uses the symbol around or before dot
  as a default, if that is a variable name.
 
-* Commands that read filenames now insert the default
+** Commands that read filenames now insert the default
  directory in the minibuffer, to become part of your input.
  This allows you to see what the default is.
  You may type a filename which goes at the end of the
@@ -2060,13 +2060,13 @@ Changes in Emacs 1.6
  Set the variable insert-default-directory to nil
  to turn off this feature.
 
-* M-x shell now uses the environment variable ESHELL,
+** M-x shell now uses the environment variable ESHELL,
  if it exists, as the file name of the shell to run.
  If there is no ESHELL variable, the SHELL variable is used.
  This is because some shells do not work properly as inferiors
  of Emacs (or anything like Emacs).
 
-* A new variable minor-modes now exists, with a separate value
+** A new variable minor-modes now exists, with a separate value
  in each buffer.  Its value should be an alist of elements
  (MODE-FUNCTION-SYMBOL . PRETTY-NAME-STRING), one for each
  minor mode that is turned on in the buffer.  The pretty
@@ -2076,7 +2076,7 @@ Changes in Emacs 1.6
  turn on the minor mode if given 1 as an argument; they are present
  so that Help m can find their documentation strings.
 
-* The format of tag table files has been changed.
+** The format of tag table files has been changed.
  The new format enables Emacs to find tags much faster.
 
  A new program, etags, exists to make the kind of
@@ -2092,13 +2092,13 @@ Changes in Emacs 1.6
  The tags library can no longer use standard ctags-style
  tag tables files.
 
-* The file of Lisp code Emacs reads on startup is now
+** The file of Lisp code Emacs reads on startup is now
  called ~/.emacs rather than ~/.emacs_pro.
 
-* copy-file now gives the copied file the same mode bits
+** copy-file now gives the copied file the same mode bits
  as the original file.
 
-* Output from a process inserted into the process's buffer
+** Output from a process inserted into the process's buffer
  no longer sets the buffer's mark.  Instead it sets a
  marker associated with the process to point to the end
  of the inserted text.  You can access this marker with
@@ -2106,27 +2106,27 @@ Changes in Emacs 1.6
  and then either examine its position with marker-position
  or set its position with set-marker.
 
-* completing-read takes a new optional fifth argument which,
+** completing-read takes a new optional fifth argument which,
  if non-nil, should be a string of text to insert into
  the minibuffer before reading user commands.
 
-* The Lisp function elt now exists:
+** The Lisp function elt now exists:
  (elt ARRAY N) is like (aref ARRAY N),
  (elt LIST N) is like (nth N LIST).
 
-* rplaca is now a synonym for setcar, and rplacd for setcdr.
+** rplaca is now a synonym for setcar, and rplacd for setcdr.
  eql is now a synonym for eq; it turns out that the Common Lisp
  distinction between eq and eql is insignificant in Emacs.
  numberp is a new synonym for integerp.
 
-* auto-save has been renamed to auto-save-mode.
+** auto-save has been renamed to auto-save-mode.
 
-* Auto save file names for buffers are now created by the
+** Auto save file names for buffers are now created by the
  function make-auto-save-file-name.  This is so you can
  redefine that function to change the way auto save file names
  are chosen.
 
-* expand-file-name no longer discards a final slash.
+** expand-file-name no longer discards a final slash.
     (expand-file-name "foo" "/lose") => "/lose/foo"
     (expand-file-name "foo/" "/lose") => "/lose/foo/"
 
@@ -2140,7 +2140,7 @@ Changes in Emacs 1.6
  delete-file call expand-file-name on the file name supplied.
  This change makes them considerably faster in the usual case.
 
-* Interactive calling spec strings allow the new code letter 'D'
+** Interactive calling spec strings allow the new code letter 'D'
  which means to read a directory name.  It is like 'f' except
  that the default if the user makes no change in the minibuffer
  is to return the current default directory rather than the
@@ -2148,9 +2148,9 @@ Changes in Emacs 1.6
 
 
 
-Changes in Emacs 1.5
+* Changes in Emacs 1.5
 
-* suspend-emacs now accepts an optional argument
+** suspend-emacs now accepts an optional argument
  which is a string to be stuffed as terminal input
  to be read by Emacs's superior shell after Emacs exits.
 
@@ -2158,28 +2158,28 @@ Changes in Emacs 1.5
  to transmit text to a Lisp job running as a sibling of
  Emacs.
 
-* If find-file is given the name of a directory,
+** If find-file is given the name of a directory,
  it automatically invokes dired on that directory
  rather than reading in the binary data that make up
  the actual contents of the directory according to Unix.
 
-* Saving an Emacs buffer now preserves the file modes
+** Saving an Emacs buffer now preserves the file modes
  of any previously existing file with the same name.
  This works using new Lisp functions file-modes and
  set-file-modes, which can be used to read or set the mode
  bits of any file.
 
-* The Lisp function  cond  now exists, with its traditional meaning.
+** The Lisp function  cond  now exists, with its traditional meaning.
 
-* defvar and defconst now permit the documentation string
+** defvar and defconst now permit the documentation string
  to be omitted.  defvar also permits the initial value
  to be omitted; then it acts only as a comment.
 
 
 
-Changes in Emacs 1.4
+* Changes in Emacs 1.4
 
-* Auto-filling now normally indents the new line it creates
+** Auto-filling now normally indents the new line it creates
  by calling indent-according-to-mode.  This function, meanwhile,
  has in Fundamental and Text modes the effect of making the line
  have an indentation of the value of left-margin, a per-buffer variable.
@@ -2188,7 +2188,7 @@ Changes in Emacs 1.4
  it does that in all modes that supply their own indentation routine,
  but in Fundamental, Text and allied modes it inserts a tab character.
 
-* The command M-x grep now invokes grep (on arguments
+** The command M-x grep now invokes grep (on arguments
  supplied by the user) and reads the output from grep
  asynchronously into a buffer.  The command C-x ` can
  be used to move to the lines that grep has found.
@@ -2199,35 +2199,35 @@ Changes in Emacs 1.4
  is proceeding; as more matches or error messages arrive,
  C-x ` will parse them and be able to find them.
 
-* M-x mail now provides a command to send the message
+** M-x mail now provides a command to send the message
  and "exit"--that is, return to the previously selected
  buffer.  It is C-z C-z.
 
-* Tab in C mode now tries harder to adapt to all indentation styles.
+** Tab in C mode now tries harder to adapt to all indentation styles.
  If the line being indented is a statement that is not the first
  one in the containing compound-statement, it is aligned under
  the beginning of the first statement.
 
-* The functions screen-width and screen-height return the
+** The functions screen-width and screen-height return the
  total width and height of the screen as it is now being used.
  set-screen-width and set-screen-height tell Emacs how big
  to assume the screen is; they each take one argument,
  an integer.
 
-* The Lisp function 'function' now exists.  function is the
+** The Lisp function 'function' now exists.  function is the
  same as quote, except that it serves as a signal to the
  Lisp compiler that the argument should be compiled as
  a function.  Example:
    (mapcar (function (lambda (x) (+ x 5))) list)
 
-* The function set-key has been renamed to global-set-key.
+** The function set-key has been renamed to global-set-key.
  undefine-key and local-undefine-key has been renamed to
  global-unset-key and local-unset-key.
 
-* Emacs now collects input from asynchronous subprocesses
+** Emacs now collects input from asynchronous subprocesses
  while waiting in the functions sleep-for and sit-for.
 
-* Shell mode's Newline command attempts to distinguish subshell
+** Shell mode's Newline command attempts to distinguish subshell
  prompts from user input when issued in the middle of the buffer.
  It no longer reexecutes from dot to the end of the line;
  it reeexecutes the entire line minus any prompt.
@@ -2237,9 +2237,9 @@ Changes in Emacs 1.4
 
 
 
-Changes in Emacs 1.3
+* Changes in Emacs 1.3
 
-* An undo facility exists now.  Type C-x u to undo a batch of
+** An undo facility exists now.  Type C-x u to undo a batch of
  changes (usually one command's changes, but some commands
  such as query-replace divide their changes into multiple
  batches.  You can repeat C-x u to undo further.  As long
@@ -2256,45 +2256,45 @@ Changes in Emacs 1.3
  for each buffer, so it is mainly good if you do something
  totally spastic.  [This has since been fixed.]
 
-* A learn-by-doing tutorial introduction to Emacs now exists.
+** A learn-by-doing tutorial introduction to Emacs now exists.
  Type C-h t to enter it.
 
-* An Info documentation browser exists.  Do M-x info to enter it.
+** An Info documentation browser exists.  Do M-x info to enter it.
  It contains a tutorial introduction so that no more documentation
  is needed here.  As of now, the only documentation in it
  is that of Info itself.
 
-* Help k and Help c are now different.  Help c prints just the
+** Help k and Help c are now different.  Help c prints just the
  name of the function which the specified key invokes.  Help k
  prints the documentation of the function as well.
 
-* A document of the differences between GNU Emacs and Twenex Emacs
+** A document of the differences between GNU Emacs and Twenex Emacs
  now exists.  It is called DIFF, in the same directory as this file.
 
-* C mode can now indent comments better, including multi-line ones.
+** C mode can now indent comments better, including multi-line ones.
  Meta-Control-q now reindents comment lines within the expression
  being aligned.
 
-* Insertion of a close-parenthesis now shows the matching open-parenthesis
+** Insertion of a close-parenthesis now shows the matching open-parenthesis
  even if it is off screen, by printing the text following it on its line
  in the minibuffer.
 
-* A file can now contain a list of local variable values
+** A file can now contain a list of local variable values
  to be in effect when the file is edited.  See the file DIFF
  in the same directory as this file for full details.
 
-* A function nth is defined.  It means the same thing as in Common Lisp.
+** A function nth is defined.  It means the same thing as in Common Lisp.
 
-* The function install-command has been renamed to set-key.
+** The function install-command has been renamed to set-key.
  It now takes the key sequence as the first argument
  and the definition for it as the second argument.
  Likewise, local-install-command has been renamed to local-set-key.
 
 
 
-Changes in Emacs 1.2
+* Changes in Emacs 1.2
 
-* A Lisp single-stepping and debugging facility exists.
+** A Lisp single-stepping and debugging facility exists.
  To cause the debugger to be entered when an error
  occurs, set the variable debug-on-error non-nil.
 
@@ -2337,7 +2337,7 @@ Changes in Emacs 1.2
  You can mark a frame to enter the debugger on exit
  with the `b' command, or clear such a mark with `u'.
 
-* Lisp macros now exist.
+** Lisp macros now exist.
  For example, you can write
     (defmacro cadr (arg) (list 'car (list 'cdr arg)))
  and then the expression
@@ -2347,9 +2347,9 @@ Changes in Emacs 1.2
 
 
 
-Changes in Emacs 1.1
+* Changes in Emacs 1.1
 
-* The initial buffer is now called "scratch" and is in a
+** The initial buffer is now called "scratch" and is in a
  new major mode, Lisp Interaction mode.  This mode is
  intended for typing Lisp expressions, evaluating them,
  and having the values printed into the buffer.
@@ -2360,31 +2360,31 @@ Changes in Emacs 1.1
 
  The other commands of Lisp mode are available.
 
-* The C-x C-e command for evaluating the Lisp expression
+** The C-x C-e command for evaluating the Lisp expression
  before dot has been changed to print the value in the
  minibuffer line rather than insert it in the buffer.
  A numeric argument causes the printed value to appear
  in the buffer instead.
 
-* In Lisp mode, the command M-C-x evaluates the defun
+** In Lisp mode, the command M-C-x evaluates the defun
  containing or following dot.  The value is printed in
  the minibuffer.
 
-* The value of a Lisp expression evaluated using M-ESC
+** The value of a Lisp expression evaluated using M-ESC
  is now printed in the minibuffer.
 
-* M-q now runs fill-paragraph, independent of major mode.
+** M-q now runs fill-paragraph, independent of major mode.
 
-* C-h m now prints documentation on the current buffer's
+** C-h m now prints documentation on the current buffer's
  major mode.  What it prints is the documentation of the
  major mode name as a function.  All major modes have been
  equipped with documentation that describes all commands
  peculiar to the major mode, for this purpose.
 
-* You can display a Unix manual entry with
+** You can display a Unix manual entry with
  the M-x manual-entry command.
 
-* You can run a shell, displaying its output in a buffer,
+** You can run a shell, displaying its output in a buffer,
  with the M-x shell command.  The Return key sends input
  to the subshell.  Output is printed inserted automatically
  in the buffer.  Commands C-c, C-d, C-u, C-w and C-z are redefined
@@ -2393,7 +2393,7 @@ Changes in Emacs 1.1
  enter them, so that the default directory of the Emacs buffer
  always remains the same as that of the subshell.
 
-* C-x $ (that's a real dollar sign) controls line-hiding based
+** C-x $ (that's a real dollar sign) controls line-hiding based
  on indentation.  With a numeric arg N > 0, it causes all lines
  indented by N or more columns to become invisible.
  They are, effectively, tacked onto the preceding line, where
@@ -2408,7 +2408,7 @@ Changes in Emacs 1.1
  C-x $ with no argument turns off this mode, which in any case
  is remembered separately for each buffer.
 
-* Outline mode is another form of selective display.
+** Outline mode is another form of selective display.
  It is a major mode invoked with M-x outline-mode.
  It is intended for editing files that are structured as
  outlines, with heading lines (lines that begin with one
@@ -2429,12 +2429,12 @@ Changes in Emacs 1.1
   All editing commands treat hidden outline-mode lines
  as part of the preceding visible line.
 
-* C-x C-z runs save-buffers-kill-emacs
+** C-x C-z runs save-buffers-kill-emacs
  offers to save each file buffer, then exits.
 
-* C-c's function is now called suspend-emacs.
+** C-c's function is now called suspend-emacs.
 
-* The command C-x m runs mail, which switches to a buffer *mail*
+** The command C-x m runs mail, which switches to a buffer *mail*
  and lets you compose a message to send.  C-x 4 m runs mail in
  another window.  Type C-z C-s in the mail buffer to send the
  message according to what you have entered in the buffer.
@@ -2442,7 +2442,7 @@ Changes in Emacs 1.1
   You must separate the headers from the message text with
  an empty line.
 
-* You can now dired partial directories (specified with names
+** You can now dired partial directories (specified with names
  containing *'s, etc, all processed by the shell).  Also, you
  can dired more than one directory; dired names the buffer
  according to the filespec or directory name.  Reinvoking
@@ -2455,9 +2455,9 @@ Changes in Emacs 1.1
   C-x C-d (list-directory) also allows partial directories now.
 
 
-Lisp programming changes
+** Lisp programming changes
 
-* t as an output stream now means "print to the minibuffer".
+*** t as an output stream now means "print to the minibuffer".
  If there is already text in the minibuffer printed via t
  as an output stream, the new text is appended to the old
  (or is truncated and lost at the margin).  If the minibuffer
@@ -2472,17 +2472,17 @@ Lisp programming changes
  is ignored; each `read' from t reads fresh input.
  t is now the top-level value of standard-input.
 
-* A marker may be used as an input stream or an output stream.
+*** A marker may be used as an input stream or an output stream.
  The effect is to grab input from where the marker points,
  advancing it over the characters read, or to insert output
  at the marker and advance it.
 
-* Output from an asynchronous subprocess is now inserted at
+*** Output from an asynchronous subprocess is now inserted at
  the end of the associated buffer, not at the buffer's dot,
  and the buffer's mark is set to the end of the inserted output
  each time output is inserted.
 
-* (pos-visible-in-window-p POS WINDOW)
+*** (pos-visible-in-window-p POS WINDOW)
  returns t if position POS in WINDOW's buffer is in the range
  that is being displayed in WINDOW; nil if it is scrolled
  vertically out of visibility.
@@ -2493,18 +2493,18 @@ Lisp programming changes
 
   POS defaults to (dot), and WINDOW to (selected-window).
 
-* Variable buffer-alist replaced by function (buffer-list).
+*** Variable buffer-alist replaced by function (buffer-list).
  The actual alist of buffers used internally by Emacs is now
  no longer accessible, to prevent the user from crashing Emacs
  by modifying it.  The function buffer-list returns a list
  of all existing buffers.  Modifying this list cannot hurt anything
  as a new list is constructed by each call to buffer-list.
 
-* load now takes an optional third argument NOMSG which, if non-nil,
+*** load now takes an optional third argument NOMSG which, if non-nil,
  prevents load from printing a message when it starts and when
  it is done.
 
-* byte-recompile-directory is a new function which finds all
+*** byte-recompile-directory is a new function which finds all
  the .elc files in a directory, and regenerates each one which
  is older than the corresponding .el (Lisp source) file.
 
@@ -2528,5 +2528,5 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.
 
 
 Local variables:
-mode: text
+mode: outline
 end:
diff --git a/etc/NEWS.18 b/etc/NEWS.18
index e2645b9..ab76c3c 100644
--- a/etc/NEWS.18
+++ b/etc/NEWS.18
@@ -8,23 +8,23 @@ This file is about changes in emacs version 18.
 
 
 
-Changes in version 18.52.
+* Changes in Emacs 18.52.
 
-* X windows version 10 is supported under system V.
+** X windows version 10 is supported under system V.
 
-* Pop-up menus are now supported with the same Lisp interface in
+** Pop-up menus are now supported with the same Lisp interface in
 both version 10 and 11 of X windows.
 
-* C-x 4 a is a new command to edit a change-log entry in another window.
+** C-x 4 a is a new command to edit a change-log entry in another window.
 
-* The emacs client program now allows an option +NNN to specify the
+** The emacs client program now allows an option +NNN to specify the
 line number to go to in the file whose name follows.  Thus,
     emacsclient foo.c +45 bar.c
 will find the files `foo.c' and `bar.c', going to line 45 in `bar.c'.
 
-* Dired allows empty directories to be deleted like files.
+** Dired allows empty directories to be deleted like files.
 
-* When the terminal type is used to find a terminal-specific file to
+** When the terminal type is used to find a terminal-specific file to
 run, Emacs now tries the entire terminal type first.  If that doesn't
 yield a file that exists, the last hyphen and what follows it is
 stripped.  If that doesn't yield a file that exists, the previous
@@ -34,97 +34,97 @@ example, if the terminal type is `aaa-48-foo', Emacs will 
try first
 
 Underscores now receive the same treatment as hyphens.
 
-* Texinfo features: @defun, etc.  texinfo-show-structure.
+** Texinfo features: @defun, etc.  texinfo-show-structure.
 New template commands.  texinfo-format-region.
 
-* The special "local variable" `eval' is now ignored if you are running
+** The special "local variable" `eval' is now ignored if you are running
 as root.
 
-* New command `c-macro-expand' shows the result of C macro expansion
+** New command `c-macro-expand' shows the result of C macro expansion
 in the region.  It works using the C preprocessor, so its results
 are completely accurate.
 
-* Errors in trying to auto save now flash error messages for a few seconds.
+** Errors in trying to auto save now flash error messages for a few seconds.
 
-* Killing a buffer now sends SIGHUP to the buffer's process.
+** Killing a buffer now sends SIGHUP to the buffer's process.
 
-* New hooks.
+** New hooks.
 
-** `spell-region' now allows you to filter the text before spelling-checking.
+*** `spell-region' now allows you to filter the text before spelling-checking.
 If the value of `spell-filter' is non-nil, it is called, with no arguments,
 looking at a temporary buffer containing a copy of the text to be checked.
 It can alter the text freely before the spell program sees it.
 
-** The variable `lpr-command' now specifies the command to be used when
+*** The variable `lpr-command' now specifies the command to be used when
 you use the commands to print text (such as M-x print-buffer).
 
-** Posting netnews now calls the value of `news-inews-hook' (if not nil)
+*** Posting netnews now calls the value of `news-inews-hook' (if not nil)
 as a function of no arguments before the actual posting.
 
-** Rmail now calls the value of `rmail-show-message-hook' (if not nil)
+*** Rmail now calls the value of `rmail-show-message-hook' (if not nil)
 as a function of no arguments, each time a new message is selected.
 
-** `kill-emacs' calls the value of `kill-emacs-hook' as a function of no args.
+*** `kill-emacs' calls the value of `kill-emacs-hook' as a function of no args.
 
-* New libraries.
+** New libraries.
 See the source code of each library for more information.
 
-** icon.el: a major mode for editing programs written in Icon.
+*** icon.el: a major mode for editing programs written in Icon.
 
-** life.el: a simulator for the cellular automaton "life".  Load the
+*** life.el: a simulator for the cellular automaton "life".  Load the
 library and run M-x life.
 
-** doctex.el: a library for converting the Emacs `etc/DOC' file of
+*** doctex.el: a library for converting the Emacs `etc/DOC' file of
 documentation strings into TeX input.
 
-** saveconf.el: a library which records the arrangement of windows and
+*** saveconf.el: a library which records the arrangement of windows and
 buffers when you exit Emacs, and automatically recreates the same
 setup the next time you start Emacs.
 
-** uncompress.el: a library that automatically uncompresses files
+*** uncompress.el: a library that automatically uncompresses files
 when you visit them.
 
-** c-fill.el: a mode for editing filled comments in C.
+*** c-fill.el: a mode for editing filled comments in C.
 
-** kermit.el: an extended version of shell-mode designed for running kermit.
+*** kermit.el: an extended version of shell-mode designed for running kermit.
 
-** spook.el: a library for adding some "distract the NSA" keywords to every
+*** spook.el: a library for adding some "distract the NSA" keywords to every
 message you send.
 
-** hideif.el: a library for hiding parts of a C program based on preprocessor
+*** hideif.el: a library for hiding parts of a C program based on preprocessor
 conditionals.
 
-** autoinsert.el: a library to put in some initial text when you visit
+*** autoinsert.el: a library to put in some initial text when you visit
 a nonexistent file.  The text used depends on the major mode, and
 comes from a directory of files created by you.
 
-* New programming features.
+** New programming features.
 
-** The variable `window-system-version' now contains the version number
+*** The variable `window-system-version' now contains the version number
 of the window system you are using (if appropriate).  When using X windows,
 its value is either 10 or 11.
 
-** (interactive "N") uses the prefix argument if any; otherwise, it reads
+*** (interactive "N") uses the prefix argument if any; otherwise, it reads
 a number using the minibuffer.
 
-** VMS: there are two new functions `vms-system-info' and `shrink-to-icon'.
+*** VMS: there are two new functions `vms-system-info' and `shrink-to-icon'.
 The former allows you to get many kinds of system status information.
 See its self-documentation for full details.
 The second is used with the window system: it iconifies the Emacs window.
 
-** VMS: the new function `define-logical-name' allows you to create
+*** VMS: the new function `define-logical-name' allows you to create
 job-wide logical names.  The old function `define-dcl-symbol' has been
 removed.
 
 
 
-Changes in version 18.50.
+* Changes in Emacs 18.50.
 
-* X windows version 11 is supported.
+** X windows version 11 is supported.
 
 Define X11 in config.h if you want X version 11 instead of version 10.
 
-* The command M-x gdb runs the GDB debugger as an inferior.
+** The command M-x gdb runs the GDB debugger as an inferior.
 It asks for the filename of the executable you want to debug.
 
 GDB runs as an inferior with I/O through an Emacs buffer.  All the
@@ -140,21 +140,21 @@ and `finish'.
 In any source file, the commands C-x SPC tells GDB to set a breakpoint
 on the current line.
 
-* M-x calendar displays a three-month calendar.
+** M-x calendar displays a three-month calendar.
 
-* C-u 0 C-x C-s never makes a backup file.
+** C-u 0 C-x C-s never makes a backup file.
 
 This is a way you can explicitly request not to make a backup.
 
-* `term-setup-hook' is for users only.
+** `term-setup-hook' is for users only.
 
 Emacs never uses this variable for internal purposes, so you can freely
 set it in your `.emacs' file to make Emacs do something special after
 loading any terminal-specific setup file from `lisp/term'.
 
-* `copy-keymap' now copies recursive submaps.
+** `copy-keymap' now copies recursive submaps.
 
-* New overlay-arrow feature.
+** New overlay-arrow feature.
 
 If you set the variable `overlay-arrow-string' to a string
 and `overlay-arrow-position' to a marker, that string is displayed on
@@ -162,12 +162,12 @@ the screen at the position of that marker, hiding 
whatever text would
 have appeared there.  If that position isn't on the screen, or if
 the buffer the marker points into isn't displayed, there is no effect.
 
-* -batch mode can read from the terminal.
+** -batch mode can read from the terminal.
 
 It now works to use `read-char' to do terminal input in a noninteractive
 Emacs run.  End of file causes Emacs to exit.
 
-* Variables `data-bytes-used' and `data-bytes-free' removed.
+** Variables `data-bytes-used' and `data-bytes-free' removed.
 
 These variables cannot really work because the 24-bit range of an
 integer in (most ports of) GNU Emacs is not large enough to hold their
@@ -175,9 +175,9 @@ values on many systems.
 
 
 
-Changes in version 18.45, since version 18.41.
+* Changes in Emacs 18.45, since version 18.41.
 
-* C indentation parameter `c-continued-brace-offset'.
+** C indentation parameter `c-continued-brace-offset'.
 
 This parameter's value is added to the indentation of any
 line that is in a continuation context and starts with an open-brace.
@@ -188,26 +188,26 @@ For example, it applies to the open brace shown here:
 
 The default value is zero.
 
-* Dabbrev expansion (Meta-/) preserves case.
+** Dabbrev expansion (Meta-/) preserves case.
 
 When you use Meta-/ to search the buffer for an expansion of an
 abbreviation, if the expansion found is all lower case except perhaps
 for its first letter, then the case pattern of the abbreviation
 is carried over to the expansion that replaces it.
 
-* TeX-mode syntax.
+** TeX-mode syntax.
 
 \ is no longer given "escape character" syntax in TeX mode.  It now
 has the syntax of an ordinary punctuation character.  As a result,
 \[...\] and such like are considered to balance each other.
 
-* Mail-mode automatic Reply-To field.
+** Mail-mode automatic Reply-To field.
 
 If the variable `mail-default-reply-to' is non-`nil', then each time
 you start to compose a message, a Reply-To field is inserted with
 its contents taken from the value of `mail-default-reply-to'.
 
-* Where is your .emacs file?
+** Where is your .emacs file?
 
 If you run Emacs under `su', so your real and effective uids are
 different, Emacs uses the home directory associated with the real uid
@@ -218,23 +218,23 @@ file.
 
 The .emacs file is not loaded at all if -batch is specified.
 
-* Prolog mode is the default for ".pl" files.
+** Prolog mode is the default for ".pl" files.
 
-* File names are not case-sensitive on VMS.
+** File names are not case-sensitive on VMS.
 
 On VMS systems, all file names that you specify are converted to upper
 case.  You can use either upper or lower case indiscriminately.
 
-* VMS-only function 'define-dcl-symbol'.
+** VMS-only function 'define-dcl-symbol'.
 
 This is a new name for the function formerly called
 `define-logical-name'.
 
 
 
-Editing Changes in Emacs 18
+* Editing Changes in Emacs 18
 
-* Additional systems and machines are supported.
+** Additional systems and machines are supported.
 
 GNU Emacs now runs on Vax VMS.  However, many facilities that are normally
 implemented by running subprocesses do not work yet.  This includes listing
@@ -256,13 +256,13 @@ to working.  The port for the Elxsi is partly merged.  
See the file
 MACHINES for full status information and machine-specific installation
 advice.
 
-* Searching is faster.
+** Searching is faster.
 
 Forward search for a text string, or for a regexp that is equivalent
 to a text string, is now several times faster.  Motion by lines and
 counting lines is also faster.
 
-* Memory usage improvements.
+** Memory usage improvements.
 
 It is no longer possible to run out of memory during garbage
 collection.  As a result, running out of memory is never fatal.  This
@@ -271,27 +271,27 @@ strings in place rather than copying them.  Another 
consequence of the
 change is a reduction in total memory usage and a slight increase in
 garbage collection speed.
 
-* Display changes.
+** Display changes.
 
-** Editing above top of screen.
+*** Editing above top of screen.
 
 When you delete or kill or alter text that reaches to the top of the
 screen or above it, so that display would start in the middle of a
 line, Emacs will usually attempt to scroll the text so that display
 starts at the beginning of a line again.
 
-** Yanking in the minibuffer.
+*** Yanking in the minibuffer.
 
 The message "Mark Set" is no longer printed when the minibuffer is
 active.  This is convenient with many commands, including C-y, that
 normally print such a message.
 
-** Cursor appears in last line during y-or-n questions.
+*** Cursor appears in last line during y-or-n questions.
 
 Questions that want a `y' or `n' answer now move the cursor
 to the last line, following the question.
 
-* Library loading changes.
+** Library loading changes.
 
 `load' now considers all possible suffixes (`.elc', `.el' and none)
 for each directory in `load-path' before going on to the next directory.
@@ -313,13 +313,13 @@ is no longer allowed.  Instead, there are two commands 
for loading files.
 `M-x load-file' reads a file name with completion and defaulting
 and then loads exactly that file, with no searching and no suffixes.
 
-* Emulation of other editors.
+** Emulation of other editors.
 
-** `edt-emulation-on' starts emulating DEC's EDT editor.
+*** `edt-emulation-on' starts emulating DEC's EDT editor.
 
 Do `edt-emulation-off' to return Emacs to normal.
 
-** `vi-mode' and `vip-mode' starts emulating vi.
+*** `vi-mode' and `vip-mode' starts emulating vi.
 
 These are two different vi emulations provided by GNU Emacs users.
 We are interested in feedback as to which emulation is preferable.
@@ -327,20 +327,20 @@ We are interested in feedback as to which emulation is 
preferable.
 See the documentation and source code for these functions
 for more information.
 
-** `set-gosmacs-bindings' emulates Gosling Emacs.
+*** `set-gosmacs-bindings' emulates Gosling Emacs.
 
 This command changes many global bindings to resemble those of
 Gosling Emacs.  The previous bindings are saved and can be restored using
 `set-gnu-bindings'.
 
-* Emulation of a display terminal.
+** Emulation of a display terminal.
 
 Within Emacs it is now possible to run programs (such as emacs or
 supdup) which expect to do output to a visual display terminal.
 
 See the function `terminal-emulator' for more information.
 
-* New support for keypads and function keys.
+** New support for keypads and function keys.
 
 There is now a first attempt at terminal-independent support for
 keypad and function keys.
@@ -369,7 +369,7 @@ used in forming the name of the terminal-specific file.  
Thus, for
 terminal type `aaa-48', the file loaded is now `term/aaa.el' rather
 than `term/aaa-48.el'.
 
-* New startup command line options.
+** New startup command line options.
 
 `-i FILE' or `-insert FILE' in the command line to Emacs tells Emacs to
 insert the contents of FILE into the current buffer at that point in
@@ -383,7 +383,7 @@ emulator on the X window system and you want to run Emacs 
to work through
 the terminal emulator instead of working directly with the window system,
 use this switch.
 
-* Buffer-sorting commands.
+** Buffer-sorting commands.
 
 Various M-x commands whose names start with `sort-' sort parts of
 the region:
@@ -404,13 +404,13 @@ sort-columns      divides into lines and sorts them 
according to the contents
 
 Refer to the self-documentation of these commands for full usage information.
 
-* Changes in various commands.
+** Changes in various commands.
 
-** `tags-query-replace' and `tags-search' change.
+*** `tags-query-replace' and `tags-search' change.
 
 These functions now display the name of the file being searched at the moment.
 
-** `occur' output now serves as a menu.  `occur-menu' command deleted.
+*** `occur' output now serves as a menu.  `occur-menu' command deleted.
 
 `M-x occur' now allows you to move quickly to any of the occurrences
 listed.  Select the `*Occur*' buffer that contains the output of `occur',
@@ -423,7 +423,7 @@ The command `occur-menu' is thus obsolete, and has been 
deleted.
 One way to get a list of matching lines without line numbers is to
 copy the text to another buffer and use the command `keep-lines'.
 
-** Incremental search changes.
+*** Incremental search changes.
 
 Ordinary and regexp incremental searches now have distinct default
 search strings.  Thus, regexp searches recall only previous regexp
@@ -458,12 +458,12 @@ If `search-slow-window-lines' is negative, the slow 
search window
 is put at the top of the screen, and the absolute value or the
 negative number specifies the height of it.
 
-** Undo changes
+*** Undo changes
 
 The undo command now will mark the buffer as unmodified only when it is
 identical to the contents of the visited file.
 
-** C-M-v in minibuffer.
+*** C-M-v in minibuffer.
 
 If while in the minibuffer you request help in a way that uses a
 window to display something, then until you exit the minibuffer C-M-v
@@ -472,7 +472,7 @@ in the minibuffer window scrolls the window of help.
 For example, if you request a list of possible completions, C-M-v can
 be used reliably to scroll the completion list.
 
-** M-TAB command.
+*** M-TAB command.
 
 Meta-TAB performs completion on the Emacs Lisp symbol names.  The sexp
 in the buffer before point is compared against all existing nontrivial
@@ -483,12 +483,12 @@ or properties.
 If there are multiple possibilities for the very next character, a
 list of possible completions is displayed.
 
-** Dynamic abbreviation package.
+*** Dynamic abbreviation package.
 
 The new command Meta-/ expands an abbreviation in the buffer before point
 by searching the buffer for words that start with the abbreviation.
 
-** Changes in saving kbd macros.
+*** Changes in saving kbd macros.
 
 The commands `write-kbd-macro' and `append-kbd-macro' have been
 deleted.  The way to save a keyboard macro is to use the new command
@@ -498,12 +498,12 @@ file such as your Emacs init file `~/.emacs', insert the 
macro
 definition (perhaps deleting an old definition for the same macro)
 and then save the file.
 
-** C-x ' command.
+*** C-x ' command.
 
 The new command C-x ' (expand-abbrev) expands the word before point as
 an abbrev, even if abbrev-mode is not turned on.
 
-** Sending to inferior Lisp.
+*** Sending to inferior Lisp.
 
 The command C-M-x in Lisp mode, which sends the current defun to
 an inferior Lisp process, now works by writing the text into a temporary
@@ -517,20 +517,20 @@ appear on the screen and scrolls it so that the bottom is 
showing.
 Two variables `inferior-lisp-load-command' and `inferior-lisp-prompt',
 exist to customize these feature for different Lisp implementations.
 
-** C-x p now disabled.
+*** C-x p now disabled.
 
 The command C-x p, a nonrecommended command which narrows to the current
 page, is now initially disabled like C-x n.
 
-* Dealing with files.
+** Dealing with files.
 
-** C-x C-v generalized
+*** C-x C-v generalized
 
 This command is now allowed even if the current buffer is not visiting
 a file.  As usual, it kills the current buffer and replaces it with a
 newly found file.
 
-** M-x recover-file improved; auto save file names changed.
+*** M-x recover-file improved; auto save file names changed.
 
 M-x recover-file now checks whether the last auto-save file is more
 recent than the real visited file before offering to read in the
@@ -555,21 +555,21 @@ You can customize the way auto save file names are made 
by redefining
 the two functions `make-auto-save-file-name' and `auto-save-file-name-p',
 both of which are defined in `files.el'.
 
-** Modifying a buffer whose file is changed on disk is detected instantly.
+*** Modifying a buffer whose file is changed on disk is detected instantly.
 
 On systems where clash detection (locking of files being edited) is
 implemented, Emacs also checks the first time you modify a buffer
 whether the file has changed on disk since it was last visited or saved.
 If it has, you are asked to confirm that you want to change the buffer.
 
-** Exiting Emacs offers to save `*mail*'.
+*** Exiting Emacs offers to save `*mail*'.
 
 Emacs can now know about buffers that it should offer to save on exit
 even though they are not visiting files.  This is done for any buffer
 which has a non-nil local value of `buffer-offer-save'.  By default,
 Mail mode provides such a local value.
 
-** Backup file changes.
+*** Backup file changes.
 
 If a backup file cannot be written in the directory of the visited file
 due to fascist file protection, a backup file is now written in your home
@@ -579,7 +579,7 @@ the most recently made such backup is available.
 When backup files are made by copying, the last-modification time of the
 original file is now preserved in the backup copy.
 
-** Visiting remote files.
+*** Visiting remote files.
 
 On an internet host, you can now visit and save files on any other
 internet host directly from Emacs with the commands M-x ftp-find-file
@@ -592,14 +592,14 @@ give the user name and password for use on that host.  
FTP is reinvoked
 each time you ask to use it, but previously specified user names and
 passwords are remembered automatically.
 
-** Dired `g' command.
+*** Dired `g' command.
 
 `g' in Dired mode is equivalent to M-x revert-buffer; it causes the
 current contents of the same directory to be read in.
 
-* Changes in major modes.
+** Changes in major modes.
 
-** C mode indentation change.
+*** C mode indentation change.
 
 The binding of Linefeed is no longer changed by C mode.  It once again
 has its normal meaning, which is to insert a newline and then indent
@@ -618,28 +618,28 @@ is non-whitespace preceding point on the current line.  
Giving it a
 prefix argument will force reindentation of the line (as well as
 of the compound statement that begins after point, if any).
 
-** Fortran mode now exists.
+*** Fortran mode now exists.
 
 This mode provides commands for motion and indentation of Fortran code,
 plus built-in abbrevs for Fortran keywords.  For details, see the manual
 or the on-line documentation of the command `fortran-mode'.
 
-** Scribe mode now exists.
+*** Scribe mode now exists.
 
 This mode does something useful for editing files of Scribe input.
 It is used automatically for files with names ending in ".mss".
 
-** Modula2 and Prolog modes now exist.
+*** Modula2 and Prolog modes now exist.
 
 These modes are for editing programs in the languages of the same names.
 They can be selected with M-x modula-2-mode and M-x prolog-mode.
 
-** Telnet mode changes.
+*** Telnet mode changes.
 
 The telnet mode special commands have now been assigned to C-c keys.
 Most of them are the same as in Shell mode.
 
-** Picture mode changes.
+*** Picture mode changes.
 
 The special picture-mode commands to specify the direction of cursor
 motion after insertion have been moved to C-c keys.  The commands to
@@ -647,13 +647,13 @@ specify diagonal motion were already C-c keys; they are 
unchanged.
 The keys to specify horizontal or vertical motion are now
 C-c < (left), C-c > (right), C-c ^ (up) and C-c . (down).
 
-** Nroff mode comments.
+*** Nroff mode comments.
 
 Comments are now supported in Nroff mode.  The standard comment commands
 such as M-; and C-x ; know how to insert, align and delete comments
 that start with backslash-doublequote.
 
-** LaTeX mode.
+*** LaTeX mode.
 
 LaTeX mode now exists.  Use M-x latex-mode to select this mode, and
 M-x plain-tex-mode to select the previously existing mode for Plain
@@ -677,7 +677,7 @@ C-c C-f             close a block (appropriate for LaTeX 
only).
                 this inserts an \end{...} on the following line
                 and puts point on a blank line between them.
 
-** Outline mode changes.
+*** Outline mode changes.
 
 Invisible lines in outline mode are now indicated by `...' at the
 end of the previous visible line.
@@ -701,9 +701,9 @@ the string that matches.
 A line starting with a ^L (formfeed) is now by default considered
 a header line.
 
-* Mail reading and sending.
+** Mail reading and sending.
 
-** MH-E changes.
+*** MH-E changes.
 
 MH-E has been extensively modified and improved since the v17 release.
 It contains many new features, including commands to: extracted failed
@@ -715,7 +715,7 @@ single messages.  MH-E also has had numerous bugs fixed and 
commands
 made to run faster.  Furthermore, its keybindings have been changed to
 be compatible with Rmail and the rest of GNU Emacs.
 
-** Mail mode changes.
+*** Mail mode changes.
 
 The C-c commands of mail mode have been rearranged:
 
@@ -727,28 +727,28 @@ C-c y, C-c w and C-c q have been changed to C-c C-y, C-c 
C-w and C-c C-q.
 
 Thus, C-c LETTER is always unassigned.
 
-** Rmail C-r command changed to w.
+*** Rmail C-r command changed to w.
 
 The Rmail command to edit the current message is now `w'.  This change
 has been made because people frequently type C-r while in Rmail hoping
 to do a reverse incremental search.  That now works.
 
-* Rnews changes.
+** Rnews changes.
 
-** Caesar rotation added.
+*** Caesar rotation added.
 
 The function news-caesar-buffer-body performs encryption and
 decryption of the body of a news message.  It defaults to the USENET
 standard of 13, and accepts any numeric arg between 1 to 25 and -25 to -1.
 The function is bound to C-c C-r in both news-mode and news-reply-mode.
 
-** rmail-output command added.
+*** rmail-output command added.
 
 The C-o command has been bound to rmail-output in news-mode.
 This allows one to append an article to a file which is in either Unix
 mail or RMAIL format.
 
-** news-reply-mode changes.
+*** news-reply-mode changes.
 
 The C-c commands of news reply mode have been rearranged and changed,
 so that C-c LETTER is always unassigned:
@@ -773,7 +773,7 @@ C-c C-y  news-reply-yank-original (insert current message, 
in NEWS).
 C-c C-q  mail-fill-yanked-message (fill what was yanked).
 C-c C-r  caesar rotate all letters by 13 places in the article's body (rot13).
 
-* Existing Emacs usable as a server.
+** Existing Emacs usable as a server.
 
 Programs such as mailers that invoke "the editor" as an inferior
 to edit some text can now be told to use an existing Emacs process
@@ -810,11 +810,11 @@ The client/server work only on Berkeley Unix, since they 
use the Berkeley
 sockets mechanism for their communication.
 
 
-Changes in Lisp programming in Emacs version 18.
+* Changes in Lisp programming in Emacs 18.
 
-* Init file changes.
+** Init file changes.
 
-** Suffixes no longer accepted on `.emacs'.
+*** Suffixes no longer accepted on `.emacs'.
 
 Emacs will no longer load a file named `.emacs.el' or `emacs.elc'
 in place of `.emacs'.  This is so that it will take less time to
@@ -822,7 +822,7 @@ find `.emacs'.  If you want to compile your init file, give 
it another
 name and make `.emacs' a link to the `.elc' file, or make it contain
 a call to `load' to load the `.elc' file.
 
-** `default-profile' renamed to `default', and loaded after `.emacs'.
+*** `default-profile' renamed to `default', and loaded after `.emacs'.
 
 It used to be the case that the file `default-profile' was loaded if
 and only if `.emacs' was not found.
@@ -839,13 +839,13 @@ Note that for most purposes you are better off using a 
`site-init' library
 since that will be loaded before the runnable Emacs is dumped.  By using
 a `site-init' library, you avoid taking up time each time Emacs is started.
 
-** inhibit-command-line has been eliminated.
+*** inhibit-command-line has been eliminated.
 
 This variable used to exist for .emacs files to set.  It has been
 eliminated because you can get the same effect by setting
 command-line-args to nil and setting inhibit-startup-message to t.
 
-* `apply' is more general.
+** `apply' is more general.
 
 `apply' now accepts any number of arguments.  The first one is a function;
 the rest are individual arguments to pass to that function, except for the
@@ -854,7 +854,7 @@ last, which is a list of arguments to pass.
 Previously, `apply' required exactly two arguments.  Its old behavior
 follows as a special case of the new definition.
 
-* New code-letter for `interactive'.
+** New code-letter for `interactive'.
 
 (interactive "NFoo: ") is like (interactive "nFoo: ") in reading
 a number using the minibuffer to serve as the argument; however,
@@ -863,9 +863,9 @@ value as the argument, and does not use the minibuffer at 
all.
 
 This is used by the `goto-line' and `goto-char' commands.
 
-* Semantics of variables.
+** Semantics of variables.
 
-** Built-in per-buffer variables improved.
+*** Built-in per-buffer variables improved.
 
 Several built-in variables which in the past had a different value in
 each buffer now behave exactly as if `make-variable-buffer-local' had
@@ -887,12 +887,12 @@ They now refer to the default value of the variable, 
which is not
 quite the same behavior as before, but it should enable old init files
 to continue to work.
 
-** New per-buffer variables.
+*** New per-buffer variables.
 
 The variables `fill-prefix', `comment-column' and `indent-tabs-mode'
 are now per-buffer.  They work just like `fill-column', etc.
 
-** New function `setq-default'.
+*** New function `setq-default'.
 
 `setq-default' sets the default value of a variable, and uses the
 same syntax that `setq' accepts: the variable name is not evaluated
@@ -901,12 +901,12 @@ and need not be quoted.
 `(setq-default case-fold-search nil)' would make searches case-sensitive
 in all buffers that do not have local values for `case-fold-search'.
 
-** Functions `global-set' and `global-value' deleted.
+*** Functions `global-set' and `global-value' deleted.
 
 These functions were never used except by mistake by users expecting
 the functionality of `set-default' and `default-value'.
 
-* Changes in defaulting of major modes.
+** Changes in defaulting of major modes.
 
 When `default-major-mode' is `nil', new buffers are supposed to
 get their major mode from the buffer that is current.  However,
@@ -917,7 +917,7 @@ Now such modes' names have been given non-`nil' 
`mode-class' properties.
 If the current buffer's mode has such a property, Fundamental mode is
 used as the default for newly created buffers.
 
-* `where-is-internal' requires additional arguments.
+** `where-is-internal' requires additional arguments.
 
 This function now accepts three arguments, two of them required:
 DEFINITION, the definition to search for; LOCAL-KEYMAP, the keymap
@@ -938,38 +938,38 @@ The incompatibility is sad, but `nil' is a legitimate 
value for the
 second argument (it means there is no local keymap), so it cannot also
 serve as a default meaning to use the current local keymap.
 
-* Abbrevs with hooks.
+** Abbrevs with hooks.
 
 When an abbrev defined with a hook is expanded, it now performs the
 usual replacement of the abbrev with the expansion before running the
 hook.  Previously the abbrev itself was deleted but the expansion was
 not inserted.
 
-* Function `scan-buffer' deleted.
+** Function `scan-buffer' deleted.
 
 Use `search-forward' or `search-backward' in place of `scan-buffer'.
 You will have to rearrange the arguments.
 
-* X window interface improvements.
+** X window interface improvements.
 
-** Detect release of mouse buttons.
+*** Detect release of mouse buttons.
 
 Button-up events can now be detected.  See the file `lisp/x-mouse.el'
 for details.
 
-** New pop-up menu facility.
+*** New pop-up menu facility.
 
 The new function `x-popup-menu' pops up a menu (in a X window)
 and returns an indication of which selection the user made.
 For more information, see its self-documentation.
 
-* M-x disassemble.
+** M-x disassemble.
 
 This command prints the disassembly of a byte-compiled Emacs Lisp function.
 
 Would anyone like to interface this to the debugger?
 
-* `insert-buffer-substring' can insert part of the current buffer.
+** `insert-buffer-substring' can insert part of the current buffer.
 
 The old restriction that the text being inserted had to come from
 a different buffer is now lifted.
@@ -977,7 +977,7 @@ a different buffer is now lifted.
 When inserting text from the current buffer, the text to be inserted
 is determined from the specified bounds before any copying takes place.
 
-* New function `substitute-key-definition'.
+** New function `substitute-key-definition'.
 
 This is a new way to replace one command with another command as the
 binding of whatever keys may happen to refer to it.
@@ -986,29 +986,29 @@ binding of whatever keys may happen to refer to it.
 for keys defined to run OLDDEF, and rebinds those keys to run NEWDEF
 instead.
 
-* New function `insert-char'.
+** New function `insert-char'.
 
 Insert a specified character, a specified number of times.
 
-* `mark-marker' changed.
+** `mark-marker' changed.
 
 When there is no mark, this now returns a marker that points
 nowhere, rather than `nil'.
 
-* `ding' accepts argument.
+** `ding' accepts argument.
 
 When given an argument, the function `ding' does not terminate
 execution of a keyboard macro.  Normally, `ding' does terminate
 all macros that are currently executing.
 
-* New function `minibuffer-depth'.
+** New function `minibuffer-depth'.
 
 This function returns the current depth in minibuffer activations.
 The value is zero when the minibuffer is not in use.
 Values greater than one are possible if the user has entered the
 minibuffer recursively.
 
-* New function `documentation-property'.
+** New function `documentation-property'.
 
 (documentation-property SYMBOL PROPNAME) is like (get SYMBOL PROPNAME),
 except that if the property value is a number `documentation-property'
@@ -1018,7 +1018,7 @@ in the DOC file and return the string found there.
 (documentation-property VAR 'variable-documentation) is the proper
 way for a Lisp program to get the documentation of variable VAR.
 
-* New documentation-string expansion feature.
+** New documentation-string expansion feature.
 
 If a documentation string (for a variable or function) contains text
 of the form `\<FOO>', it means that all command names specified in
@@ -1045,7 +1045,7 @@ in the current buffer's local map.
 The current global keymap is always searched second, whether `\<...>'
 has been used or not.
 
-* Multiple hooks allowed in certain contexts.
+** Multiple hooks allowed in certain contexts.
 
 The old hook variables `find-file-hook', `find-file-not-found-hook' and
 `write-file-hook' have been replaced.
@@ -1072,7 +1072,7 @@ together to implement editing of files that are not 
stored as Unix
 files: stored in archives, or inside version control systems, or on
 other machines running other operating systems and accessible via ftp.
 
-* New hooks for suspending Emacs.
+** New hooks for suspending Emacs.
 
 Suspending Emacs runs the hook `suspend-hook' before suspending
 and the hook `suspend-resume-hook' if the suspended Emacs is resumed.
@@ -1082,22 +1082,22 @@ non-`nil', then suspending is inhibited and so is 
running the
 `suspend-resume-hook'.  The non-`nil' value means that the `suspend-hook'
 has done whatever suspending is required.
 
-* Disabling commands can print a special message.
+** Disabling commands can print a special message.
 
 A command is disabled by giving it a non-`nil' `disabled' property.
 Now, if this property is a string, it is included in the message
 printed when the user tries to run the command.
 
-* Emacs can open TCP connections.
+** Emacs can open TCP connections.
 
 The function `open-network-stream' opens a TCP connection to
 a specified host and service.  Its value is a Lisp object that represents
 the connection.  The object is a kind of "subprocess", and I/O are
 done like I/O to subprocesses.
 
-* Display-related changes.
+** Display-related changes.
 
-** New mode-line control features.
+*** New mode-line control features.
 
 The display of the mode line used to be controlled by a format-string
 that was the value of the variable `mode-line-format'.
@@ -1188,12 +1188,12 @@ global-mode-string
 The idea of these variables is to eliminate the need for major modes
 to alter mode-line-format itself.
 
-** `window-point' valid for selected window.
+*** `window-point' valid for selected window.
 
 The value returned by `window-point' used to be incorrect when its
 argument was the selected window.  Now the value is correct.
 
-** Window configurations may be saved as Lisp objects.
+*** Window configurations may be saved as Lisp objects.
 
 The function `current-window-configuration' returns a special type of
 Lisp object that represents the current layout of windows: the
@@ -1203,7 +1203,7 @@ which parts of the buffers appear on the screen.
 The function `set-window-configuration' takes one argument, which must
 be a window configuration object, and restores that configuration.
 
-** New hook `temp-output-buffer-show-hook'.
+*** New hook `temp-output-buffer-show-hook'.
 
 This hook allows you to control how help buffers are displayed.
 Whenever `with-output-to-temp-buffer' has executed its body and wants
@@ -1213,30 +1213,30 @@ The hook function is solely responsible for displaying 
the buffer.
 The standard manner of display--making the buffer appear in a window--is
 used only if there is no hook function.
 
-** New function `minibuffer-window'.
+*** New function `minibuffer-window'.
 
 This function returns the window used (sometimes) for displaying
 the minibuffer.  It can be used even when the minibuffer is not active.
 
-** New feature to `next-window'.
+*** New feature to `next-window'.
 
 If the optional second argument is neither `nil' nor `t', the minibuffer
 window is omitted from consideration even when active; if the starting
 window was the last non-minibuffer window, the value will be the first
 non-minibuffer window.
 
-** New variable `minibuffer-scroll-window'.
+*** New variable `minibuffer-scroll-window'.
 
 When this variable is non-`nil', the command `scroll-other-window'
 uses it as the window to be scrolled.  Displays of completion-lists
 set this variable to the window containing the display.
 
-** New argument to `sit-for'.
+*** New argument to `sit-for'.
 
 A non-nil second argument to `sit-for' means do not redisplay;
 just wait for the specified time or until input is available.
 
-** Deleted function `set-minor-mode'; minor modes must be changed.
+*** Deleted function `set-minor-mode'; minor modes must be changed.
 
 The function `set-minor-mode' has been eliminated.  The display
 of minor mode names in the mode line is now controlled by the
@@ -1245,7 +1245,7 @@ mode, it is sufficient to add an element to this list.  
Once that
 is done, you can turn the mode on and off just by setting a variable,
 and the display will show its status automatically.
 
-** New variable `cursor-in-echo-area'.
+*** New variable `cursor-in-echo-area'.
 
 If this variable is non-nil, the screen cursor appears on the
 last line of the screen, at the end of the text displayed there.
@@ -1253,7 +1253,7 @@ last line of the screen, at the end of the text displayed 
there.
 Binding this variable to t is useful at times when reading single
 characters of input with `read-char'.
 
-** New per-buffer variable `selective-display-ellipses'.
+*** New per-buffer variable `selective-display-ellipses'.
 
 If this variable is non-nil, an ellipsis (`...') appears on the screen
 at the end of each text line that is followed by invisible text.
@@ -1264,14 +1264,14 @@ on the screen that invisible text is present.
 Text is made invisible under the control of the variable
 `selective-display'; this is how Outline mode and C-x $ work.
 
-** New variable `no-redraw-on-reenter'.
+*** New variable `no-redraw-on-reenter'.
 
 If you set this variable non-nil, Emacs will not clear the screen when
 you resume it after suspending it.  This is for the sake of terminals
 with multiple screens of memory, where the termcap entry has been set
 up to switch between screens when Emacs is suspended and resumed.
 
-** New argument to `set-screen-height' or `set-screen-width'.
+*** New argument to `set-screen-height' or `set-screen-width'.
 
 These functions now take an optional second argument which says
 what significance the newly specified height or width has.
@@ -1293,9 +1293,9 @@ to move the cursor to the last line will do.
 2. The ``real'' height of the terminal determines how much padding is
 needed.
 
-* File-related changes.
+** File-related changes.
 
-** New parameter `backup-by-copying-when-mismatch'.
+*** New parameter `backup-by-copying-when-mismatch'.
 
 If this variable is non-`nil', then when Emacs is about to save a
 file, it will create the backup file by copying if that would avoid
@@ -1307,7 +1307,7 @@ last.  I recommend that this variable be left normally 
`nil' and
 changed with a local variables list in those particular files where
 the uid needs to be preserved.
 
-** New parameter `file-precious-flag'.
+*** New parameter `file-precious-flag'.
 
 If this variable is non-`nil', saving the buffer tries to avoid
 leaving an incomplete file due to disk full or other I/O errors.
@@ -1317,14 +1317,14 @@ file is renamed back to the name you visited.
 
 Backups are always made by copying for such files.
 
-** New variable `buffer-offer-save'.
+*** New variable `buffer-offer-save'.
 
 If the value of this variable is non-`nil' in a buffer then exiting
 Emacs will offer to save the buffer (if it is modified and nonempty)
 even if the buffer is not visiting a file.  This variable is
 automatically made local to the current buffer whenever it is set.
 
-** `rename-file', `copy-file', `add-name-to-file' and `make-symbolic-link'.
+*** `rename-file', `copy-file', `add-name-to-file' and `make-symbolic-link'.
 
 The third argument to these functions used to be `t' or `nil'; `t'
 meaning go ahead even if the specified new file name already has a file,
@@ -1333,13 +1333,13 @@ and `nil' meaning to get an error.
 Now if the third argument is a number it means to ask the user for
 confirmation in this case.
 
-** New optional argument to `copy-file'.
+*** New optional argument to `copy-file'.
 
 If `copy-file' receives a non-nil fourth argument, it attempts
 to give the new copy the same time-of-last-modification that the
 original file has.
 
-** New function `file-newer-than-file-p'.
+*** New function `file-newer-than-file-p'.
 
 (file-newer-than-file-p FILE1 FILE2) returns non-nil if FILE1 has been
 modified more recently than FILE2.  If FILE1 does not exist, the value
@@ -1347,24 +1347,24 @@ is always nil; otherwise, if FILE2 does not exist, the 
value is t.
 This is meant for use when FILE2 depends on FILE1, to see if changes
 in FILE1 make it necessary to recompute FILE2 from it.
 
-** Changed function `file-exists-p'.
+*** Changed function `file-exists-p'.
 
 This function is no longer the same as `file-readable-p'.
 `file-exists-p' can now return t for a file that exists but which
 the fascists won't allow you to read.
 
-** New function `file-locked-p'.
+*** New function `file-locked-p'.
 
 This function receives a file name as argument and returns `nil'
 if the file is not locked, `t' if locked by this Emacs, or a
 string giving the name of the user who has locked it.
 
-** New function `file-name-sans-versions'.
+*** New function `file-name-sans-versions'.
 
 (file-name-sans-versions NAME) returns a substring of NAME, with any
 version numbers or other backup suffixes deleted from the end.
 
-** New functions for directory names.
+*** New functions for directory names.
 
 Although a directory is really a kind of file, specifying a directory
 uses a somewhat different syntax from specifying a file.
@@ -1390,7 +1390,7 @@ and (directory-file-name "/usr/rms/") returns "/usr/rms".
 On VMS, (file-name-as-directory "du:[rms]foo.dir") returns "du:[rms.foo]"
 and (directory-file-name "du:[rms.foo]") returns "du:[rms]foo.dir".
 
-** Value of `file-attributes' changed.
+*** Value of `file-attributes' changed.
 
 The function file-attributes returns a list containing many kinds of
 information about a file.  Now the list has eleven elements.
@@ -1403,14 +1403,14 @@ the same directory by you.
 
 The eleventh element is the inode number of the file.
 
-** VMS-only function `file-name-all-versions'.
+*** VMS-only function `file-name-all-versions'.
 
 This function returns a list of all the completions, including version
 number, of a specified version-number-less file name.  This is like
 `file-name-all-completions', except that the latter returns values
 that do not include version numbers.
 
-** VMS-only variable `vms-stmlf-recfm'.
+*** VMS-only variable `vms-stmlf-recfm'.
 
 On a VMS system, if this variable is non-nil, Emacs will give newly
 created files the record format `stmlf'.  This is necessary for files
@@ -1423,46 +1423,46 @@ no effect.
 
 This variable has no effect on Unix systems.
 
-** `insert-file-contents' on an empty file.
+*** `insert-file-contents' on an empty file.
 
 This no longer sets the buffer's "modified" flag.
 
-** New function (VMS only) `define-logical-name':
+*** New function (VMS only) `define-logical-name':
 
 (define-logical-name LOGICAL TRANSLATION) defines a VMS logical name
 LOGICAL whose translation is TRANSLATION.  The new name applies to
 the current process only.
 
-** Deleted variable `ask-about-buffer-names'.
+*** Deleted variable `ask-about-buffer-names'.
 
 If you want buffer names for files to be generated in a special way,
 you must redefine `create-file-buffer'.
 
-* Subprocess-related changes.
+** Subprocess-related changes.
 
-** New function `process-list'.
+*** New function `process-list'.
 
 This function takes no arguments and returns a list of all
 of Emacs's asynchronous subprocesses.
 
-** New function `process-exit-status'.
+*** New function `process-exit-status'.
 
 This function, given a process, process name or buffer as argument,
 returns the exit status code or signal number of the process.
 If the process has not yet exited or died, this function returns 0.
 
-** Process output ignores `buffer-read-only'.
+*** Process output ignores `buffer-read-only'.
 
 Output from a process will go into the process's buffer even if the
 buffer is read only.
 
-** Switching buffers in filter functions and sentinels.
+*** Switching buffers in filter functions and sentinels.
 
 Emacs no longer saves and restore the current buffer around calling
 the filter and sentinel functions, so these functions can now
 permanently alter the selected buffer in a straightforward manner.
 
-** Specifying environment variables for subprocesses.
+*** Specifying environment variables for subprocesses.
 
 When a subprocess is started with `start-process' or `call-process',
 the value of the variable `process-environment' is taken to
@@ -1472,38 +1472,38 @@ value should be a list of strings, each of the form 
"VAR=VALUE".
 `process-environment' is initialized when Emacs starts up
 based on Emacs's environment.
 
-** New variable `process-connection-type'.
+*** New variable `process-connection-type'.
 
 If this variable is `nil', when a subprocess is created, Emacs uses
 a pipe rather than a pty to communicate with it.  Normally this
 variable is `t', telling Emacs to use a pty if ptys are supported
 and one is available.
 
-** New function `waiting-for-user-input-p'.
+*** New function `waiting-for-user-input-p'.
 
 This function, given a subprocess as argument, returns `t' if that
 subprocess appears to be waiting for input sent from Emacs,
 or `nil' otherwise.
 
-** New hook `shell-set-directory-error-hook'.
+*** New hook `shell-set-directory-error-hook'.
 
 The value of this variable is called, with no arguments, whenever
 Shell mode gets an error trying to keep track of directory-setting
 commands (such as `cd' and `pushd') used in the shell buffer.
 
-* New functions `user-uid' and `user-real-uid'.
+** New functions `user-uid' and `user-real-uid'.
 
 These functions take no arguments and return, respectively,
 the effective uid and the real uid of the Emacs process.
 The value in each case is an integer.
 
-* New variable `print-escape-newlines' controls string printing.
+** New variable `print-escape-newlines' controls string printing.
 
 If this variable is non-`nil', then when a Lisp string is printed
 by the Lisp printing function `prin1' or `print', newline characters
 are printed as `\n' rather than as a literal newline.
 
-* New function `sysnetunam' on HPUX.
+** New function `sysnetunam' on HPUX.
 
 This function takes two arguments, a network address PATH and a
 login string LOGIN, and executes the system call `netunam'.
@@ -1511,7 +1511,7 @@ It returns `t' if the call succeeds, otherwise `nil'.
 
 News regarding installation:
 
-* Many `s-...' file names changed.
+** Many `s-...' file names changed.
 
 Many `s-...' files have been renamed.  All periods in such names,
 except the ones just before the final `h', have been changed to
@@ -1519,7 +1519,7 @@ hyphens.  Thus, `s-bsd4.2.h' has been renamed to 
`s-bsd4-2.h'.
 
 This is so a Unix distribution can be moved mechanically to VMS.
 
-* `DOCSTR...' file now called `DOC-...'.
+** `DOCSTR...' file now called `DOC-...'.
 
 The file of on-line documentation strings, that used to be
 `DOCSTR.mm.nn.oo' in this directory, is now called `DOC-mm.nn.oo'.
@@ -1529,11 +1529,11 @@ for translating filenames for VMS.
 This file also now contains the doc strings for variables as
 well as functions.
 
-* Emacs no longer uses floating point arithmetic.
+** Emacs no longer uses floating point arithmetic.
 
 This may make it easier to port to some machines.
 
-* Macros `XPNTR' and `XSETPNTR'; flag `DATA_SEG_BITS'.
+** Macros `XPNTR' and `XSETPNTR'; flag `DATA_SEG_BITS'.
 
 These macros exclusively are used to unpack a pointer from a Lisp_Object
 and to insert a pointer into a Lisp_Object.  Redefining them may help
@@ -1543,7 +1543,7 @@ certain high bits set.
 If `DATA_SEG_BITS' is defined, it should be a number which contains
 the high bits to be inclusive or'ed with pointers that are unpacked.
 
-* New flag `HAVE_X_MENU'.
+** New flag `HAVE_X_MENU'.
 
 Define this flag in `config.h' in addition to `HAVE_X_WINDOWS'
 to enable use of the Emacs interface to X Menus.  On some operating
@@ -1551,11 +1551,11 @@ systems, the rest of the X interface works properly but 
X Menus
 do not work; hence this separate flag.  See the file `src/xmenu.c'
 for more information.
 
-* Macros `ARRAY_MARK_FLAG' and `DONT_COPY_FLAG'.
+** Macros `ARRAY_MARK_FLAG' and `DONT_COPY_FLAG'.
 
-* `HAVE_ALLOCA' prevents assembly of `alloca.s'.
+** `HAVE_ALLOCA' prevents assembly of `alloca.s'.
 
-* `SYSTEM_MALLOC' prevents use of GNU `malloc.c'.
+** `SYSTEM_MALLOC' prevents use of GNU `malloc.c'.
 
 SYSTEM_MALLOC, if defined, means use the system's own `malloc' routines
 rather than those that come with Emacs.
@@ -1563,21 +1563,21 @@ rather than those that come with Emacs.
 Use this only if absolutely necessary, because if it is used you do
 not get warnings when space is getting low.
 
-* New flags to control unexec.
+** New flags to control unexec.
 
 See the file `unexec.c' for a long comment on the compilation
 switches that suffice to make it work on many machines.
 
-* `PNTR_COMPARISON_TYPE'
+** `PNTR_COMPARISON_TYPE'
 
 Pointers that need to be compared for ordering are converted to this type
 first.  Normally this is `unsigned int'.
 
-* `HAVE_VFORK', `HAVE_DUP2' and `HAVE_GETTIMEOFDAY'.
+** `HAVE_VFORK', `HAVE_DUP2' and `HAVE_GETTIMEOFDAY'.
 
 These flags just say whether certain system calls are available.
 
-* New macros control compiler switches, linker switches and libraries.
+** New macros control compiler switches, linker switches and libraries.
 
 The m- and s- files can now control in a modular fashion the precise
 arguments passed to `cc' and `ld'.
@@ -1618,5 +1618,5 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.
 
 
 Local variables:
-mode: text
+mode: outline
 end:
diff --git a/etc/NEWS.26 b/etc/NEWS.26
index 9722270..19dd433 100644
--- a/etc/NEWS.26
+++ b/etc/NEWS.26
@@ -37,6 +37,11 @@ in its NEWS.)
 
 * Changes in Specialized Modes and Packages in Emacs 26.2
 
+** Imenu
+
+---
+*** The value for 'imenu-auto-rescan-maxout' has been increased to 600000.
+
 ** Gnus
 
 ---
@@ -60,6 +65,7 @@ in its NEWS.)
 
 ** VC
 
+---
 *** VC support for Mercurial was improved.
 Emacs now avoids invoking 'hg' as much as possible, for faster operation.
 (This and the following changes were actually made in Emacs 26.1, but
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index b863572..eba3420 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -2957,6 +2957,15 @@ as a macro.  If the definition (in both unex*.c and 
malloc.c) is wrong,
 it can cause problems like this.  You might be able to find the correct
 value in the man page for a.out(5).
 
+* 'make check' failures
+
+** emacs-module-tests fail on Ubuntu 16.04
+
+This is due to a bug in GCC that was fixed in 2015; see
+<https://lists.gnu.org/r/emacs-devel/2018-09/msg00548.html>.
+You can work around the problem by using a later version of GCC or of
+Ubuntu, or by configuring without modules.
+
 * Problems on legacy systems
 
 This section covers bugs reported on very old hardware or software.
diff --git a/etc/refcards/Makefile b/etc/refcards/Makefile
index b61ff5f..a3c8e55 100644
--- a/etc/refcards/Makefile
+++ b/etc/refcards/Makefile
@@ -311,7 +311,7 @@ viperCard.dvi: $(vipercard_deps)
 .PHONY: clean
 
 clean:
-       -rm -f *.dvi *.log *.aux
+       -rm -f ./*.dvi ./*.log ./*.aux
 
 distclean: clean
 
diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in
index b2b9017..ecb9208 100644
--- a/lib-src/Makefile.in
+++ b/lib-src/Makefile.in
@@ -334,7 +334,7 @@ uninstall:
        fi
 
 mostlyclean:
-       rm -f core *.o *.res
+       rm -f core ./*.o ./*.res
 
 clean: mostlyclean
        rm -f ${EXE_FILES}
@@ -345,7 +345,7 @@ distclean: clean
 bootstrap-clean maintainer-clean: distclean
 
 extraclean: maintainer-clean
-       rm -f *~ \#*
+       rm -f ./*~ \#*
 
 ## Test the contents of the directory.
 check:
diff --git a/lib-src/profile.c b/lib-src/profile.c
index 3818d33..649eb04 100644
--- a/lib-src/profile.c
+++ b/lib-src/profile.c
@@ -30,20 +30,19 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
  **  operations: reset_watch, get_time
  */
 
-#define INLINE EXTERN_INLINE
 #include <config.h>
 
 #include <inttypes.h>
 #include <stdlib.h>
 
 #include <intprops.h>
-#include <systime.h>
+#include <timespec.h>
 #include <unlocked-io.h>
 
 static struct timespec TV1;
 static int watch_not_started = 1; /* flag */
 static char time_string[INT_STRLEN_BOUND (uintmax_t) + sizeof "."
-                       + LOG10_TIMESPEC_RESOLUTION];
+                       + LOG10_TIMESPEC_HZ];
 
 /* Reset the stopwatch to zero.  */
 
@@ -66,7 +65,7 @@ get_time (void)
   int ns = TV2.tv_nsec;
   if (watch_not_started)
     exit (EXIT_FAILURE);  /* call reset_watch first ! */
-  sprintf (time_string, "%"PRIuMAX".%0*d", s, LOG10_TIMESPEC_RESOLUTION, ns);
+  sprintf (time_string, "%"PRIuMAX".%0*d", s, LOG10_TIMESPEC_HZ, ns);
   return time_string;
 }
 
diff --git a/lib/Makefile.in b/lib/Makefile.in
index b26db27..7dba31b 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -118,7 +118,7 @@ TAGS: $(ETAGS) $(tagsfiles)
 .PHONY: $(ETAGS) tags
 
 clean:
-       rm -f *.[ao] *-t \#* $(DEPDIR)/*
+       rm -f ./*.[ao] ./*-t \#* $(DEPDIR)/*
 mostlyclean: clean
        rm -f $(filter-out %-t,$(MOSTLYCLEANFILES))
 distclean bootstrap-clean: mostlyclean
diff --git a/lib/dtotimespec.c b/lib/dtotimespec.c
index 599f742..dcbd280 100644
--- a/lib/dtotimespec.c
+++ b/lib/dtotimespec.c
@@ -32,20 +32,20 @@ dtotimespec (double sec)
   if (! (TYPE_MINIMUM (time_t) < sec))
     return make_timespec (TYPE_MINIMUM (time_t), 0);
   else if (! (sec < 1.0 + TYPE_MAXIMUM (time_t)))
-    return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_RESOLUTION - 1);
+    return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_HZ - 1);
   else
     {
       time_t s = sec;
-      double frac = TIMESPEC_RESOLUTION * (sec - s);
+      double frac = TIMESPEC_HZ * (sec - s);
       long ns = frac;
       ns += ns < frac;
-      s += ns / TIMESPEC_RESOLUTION;
-      ns %= TIMESPEC_RESOLUTION;
+      s += ns / TIMESPEC_HZ;
+      ns %= TIMESPEC_HZ;
 
       if (ns < 0)
         {
           s--;
-          ns += TIMESPEC_RESOLUTION;
+          ns += TIMESPEC_HZ;
         }
 
       return make_timespec (s, ns);
diff --git a/lib/fcntl.c b/lib/fcntl.c
index be65835..8e97617 100644
--- a/lib/fcntl.c
+++ b/lib/fcntl.c
@@ -329,6 +329,12 @@ rpl_fcntl (int fd, int action, /* arg */...)
         result = dupfd (fd, target, O_CLOEXEC);
         break;
 #else /* HAVE_FCNTL */
+# if defined __HAIKU__
+        /* On Haiku, the system fcntl (fd, F_DUPFD_CLOEXEC, target) sets
+           the FD_CLOEXEC flag on fd, not on target.  Therefore avoid the
+           system fcntl in this case.  */
+#  define have_dupfd_cloexec -1
+# else
         /* Try the system call first, if the headers claim it exists
            (that is, if GNULIB_defined_F_DUPFD_CLOEXEC is 0), since we
            may be running with a glibc that has the macro but with an
@@ -343,10 +349,10 @@ rpl_fcntl (int fd, int action, /* arg */...)
             if (0 <= result || errno != EINVAL)
               {
                 have_dupfd_cloexec = 1;
-# if REPLACE_FCHDIR
+#  if REPLACE_FCHDIR
                 if (0 <= result)
                   result = _gl_register_dup (fd, result);
-# endif
+#  endif
               }
             else
               {
@@ -357,6 +363,7 @@ rpl_fcntl (int fd, int action, /* arg */...)
               }
           }
         else
+# endif
           result = rpl_fcntl (fd, F_DUPFD, target);
         if (0 <= result && have_dupfd_cloexec == -1)
           {
@@ -405,8 +412,183 @@ rpl_fcntl (int fd, int action, /* arg */...)
     default:
       {
 #if HAVE_FCNTL
-        void *p = va_arg (arg, void *);
-        result = fcntl (fd, action, p);
+        switch (action)
+          {
+          #ifdef F_BARRIERFSYNC                  /* macOS */
+          case F_BARRIERFSYNC:
+          #endif
+          #ifdef F_CHKCLEAN                      /* macOS */
+          case F_CHKCLEAN:
+          #endif
+          #ifdef F_CLOSEM                        /* NetBSD, HP-UX */
+          case F_CLOSEM:
+          #endif
+          #ifdef F_FLUSH_DATA                    /* macOS */
+          case F_FLUSH_DATA:
+          #endif
+          #ifdef F_FREEZE_FS                     /* macOS */
+          case F_FREEZE_FS:
+          #endif
+          #ifdef F_FULLFSYNC                     /* macOS */
+          case F_FULLFSYNC:
+          #endif
+          #ifdef F_GETCONFINED                   /* macOS */
+          case F_GETCONFINED:
+          #endif
+          #ifdef F_GETDEFAULTPROTLEVEL           /* macOS */
+          case F_GETDEFAULTPROTLEVEL:
+          #endif
+          #ifdef F_GETFD                         /* POSIX */
+          case F_GETFD:
+          #endif
+          #ifdef F_GETFL                         /* POSIX */
+          case F_GETFL:
+          #endif
+          #ifdef F_GETLEASE                      /* Linux */
+          case F_GETLEASE:
+          #endif
+          #ifdef F_GETNOSIGPIPE                  /* macOS */
+          case F_GETNOSIGPIPE:
+          #endif
+          #ifdef F_GETOWN                        /* POSIX */
+          case F_GETOWN:
+          #endif
+          #ifdef F_GETPIPE_SZ                    /* Linux */
+          case F_GETPIPE_SZ:
+          #endif
+          #ifdef F_GETPROTECTIONCLASS            /* macOS */
+          case F_GETPROTECTIONCLASS:
+          #endif
+          #ifdef F_GETPROTECTIONLEVEL            /* macOS */
+          case F_GETPROTECTIONLEVEL:
+          #endif
+          #ifdef F_GET_SEALS                     /* Linux */
+          case F_GET_SEALS:
+          #endif
+          #ifdef F_GETSIG                        /* Linux */
+          case F_GETSIG:
+          #endif
+          #ifdef F_MAXFD                         /* NetBSD */
+          case F_MAXFD:
+          #endif
+          #ifdef F_RECYCLE                       /* macOS */
+          case F_RECYCLE:
+          #endif
+          #ifdef F_SETFIFOENH                    /* HP-UX */
+          case F_SETFIFOENH:
+          #endif
+          #ifdef F_THAW_FS                       /* macOS */
+          case F_THAW_FS:
+          #endif
+            /* These actions take no argument.  */
+            result = fcntl (fd, action);
+            break;
+
+          #ifdef F_ADD_SEALS                     /* Linux */
+          case F_ADD_SEALS:
+          #endif
+          #ifdef F_BADFD                         /* Solaris */
+          case F_BADFD:
+          #endif
+          #ifdef F_CHECK_OPENEVT                 /* macOS */
+          case F_CHECK_OPENEVT:
+          #endif
+          #ifdef F_DUP2FD                        /* FreeBSD, AIX, Solaris */
+          case F_DUP2FD:
+          #endif
+          #ifdef F_DUP2FD_CLOEXEC                /* FreeBSD, Solaris */
+          case F_DUP2FD_CLOEXEC:
+          #endif
+          #ifdef F_DUP2FD_CLOFORK                /* Solaris */
+          case F_DUP2FD_CLOFORK:
+          #endif
+          #ifdef F_DUPFD                         /* POSIX */
+          case F_DUPFD:
+          #endif
+          #ifdef F_DUPFD_CLOEXEC                 /* POSIX */
+          case F_DUPFD_CLOEXEC:
+          #endif
+          #ifdef F_DUPFD_CLOFORK                 /* Solaris */
+          case F_DUPFD_CLOFORK:
+          #endif
+          #ifdef F_GETXFL                        /* Solaris */
+          case F_GETXFL:
+          #endif
+          #ifdef F_GLOBAL_NOCACHE                /* macOS */
+          case F_GLOBAL_NOCACHE:
+          #endif
+          #ifdef F_MAKECOMPRESSED                /* macOS */
+          case F_MAKECOMPRESSED:
+          #endif
+          #ifdef F_MOVEDATAEXTENTS               /* macOS */
+          case F_MOVEDATAEXTENTS:
+          #endif
+          #ifdef F_NOCACHE                       /* macOS */
+          case F_NOCACHE:
+          #endif
+          #ifdef F_NODIRECT                      /* macOS */
+          case F_NODIRECT:
+          #endif
+          #ifdef F_NOTIFY                        /* Linux */
+          case F_NOTIFY:
+          #endif
+          #ifdef F_OPLKACK                       /* IRIX */
+          case F_OPLKACK:
+          #endif
+          #ifdef F_OPLKREG                       /* IRIX */
+          case F_OPLKREG:
+          #endif
+          #ifdef F_RDAHEAD                       /* macOS */
+          case F_RDAHEAD:
+          #endif
+          #ifdef F_SETBACKINGSTORE               /* macOS */
+          case F_SETBACKINGSTORE:
+          #endif
+          #ifdef F_SETCONFINED                   /* macOS */
+          case F_SETCONFINED:
+          #endif
+          #ifdef F_SETFD                         /* POSIX */
+          case F_SETFD:
+          #endif
+          #ifdef F_SETFL                         /* POSIX */
+          case F_SETFL:
+          #endif
+          #ifdef F_SETLEASE                      /* Linux */
+          case F_SETLEASE:
+          #endif
+          #ifdef F_SETNOSIGPIPE                  /* macOS */
+          case F_SETNOSIGPIPE:
+          #endif
+          #ifdef F_SETOWN                        /* POSIX */
+          case F_SETOWN:
+          #endif
+          #ifdef F_SETPIPE_SZ                    /* Linux */
+          case F_SETPIPE_SZ:
+          #endif
+          #ifdef F_SETPROTECTIONCLASS            /* macOS */
+          case F_SETPROTECTIONCLASS:
+          #endif
+          #ifdef F_SETSIG                        /* Linux */
+          case F_SETSIG:
+          #endif
+          #ifdef F_SINGLE_WRITER                 /* macOS */
+          case F_SINGLE_WRITER:
+          #endif
+            /* These actions take an 'int' argument.  */
+            {
+              int x = va_arg (arg, int);
+              result = fcntl (fd, action, x);
+            }
+            break;
+
+          default:
+            /* Other actions take a pointer argument.  */
+            {
+              void *p = va_arg (arg, void *);
+              result = fcntl (fd, action, p);
+            }
+            break;
+          }
 #else
         errno = EINVAL;
 #endif
diff --git a/lib/gettime.c b/lib/gettime.c
index 9a4e342..171f224 100644
--- a/lib/gettime.c
+++ b/lib/gettime.c
@@ -28,21 +28,24 @@
 void
 gettime (struct timespec *ts)
 {
-#if HAVE_NANOTIME
+#if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME
+  clock_gettime (CLOCK_REALTIME, ts);
+#elif HAVE_NANOTIME
   nanotime (ts);
 #else
+  struct timeval tv;
+  gettimeofday (&tv, NULL);
+  ts->tv_sec = tv.tv_sec;
+  ts->tv_nsec = tv.tv_usec * 1000;
+#endif
+}
 
-# if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME
-  if (clock_gettime (CLOCK_REALTIME, ts) == 0)
-    return;
-# endif
-
-  {
-    struct timeval tv;
-    gettimeofday (&tv, NULL);
-    ts->tv_sec = tv.tv_sec;
-    ts->tv_nsec = tv.tv_usec * 1000;
-  }
+/* Return the current system time as a struct timespec.  */
 
-#endif
+struct timespec
+current_timespec (void)
+{
+  struct timespec ts;
+  gettime (&ts);
+  return ts;
 }
diff --git a/lib/intprops.h b/lib/intprops.h
index 3d6b3cf4..cdaf658 100644
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -342,8 +342,8 @@
    Arguments should be free of side effects.  */
 #define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow)        \
   op_result_overflow (a, b,                                     \
-                      _GL_INT_MINIMUM ((1 ? 0 : (b)) + (a)),    \
-                      _GL_INT_MAXIMUM ((1 ? 0 : (b)) + (a)))
+                      _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \
+                      _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b)))
 
 /* Store the low-order bits of A + B, A - B, A * B, respectively, into *R.
    Return 1 if the result overflows.  See above for restrictions.  */
diff --git a/lib/limits.in.h b/lib/limits.in.h
index 2c809d9..89d7195 100644
--- a/lib/limits.in.h
+++ b/lib/limits.in.h
@@ -28,15 +28,32 @@
 #ifndef address@hidden@_LIMITS_H
 #define address@hidden@_LIMITS_H
 
-/* For HP-UX 11.31.  */
-#if defined LONG_LONG_MIN && !defined LLONG_MIN
-# define LLONG_MIN LONG_LONG_MIN
+#ifndef LLONG_MIN
+# if defined LONG_LONG_MIN /* HP-UX 11.31 */
+#  define LLONG_MIN LONG_LONG_MIN
+# elif defined LONGLONG_MIN /* IRIX 6.5 */
+#  define LLONG_MIN LONGLONG_MIN
+# elif defined __GNUC__
+#  define LLONG_MIN (- __LONG_LONG_MAX__ - 1LL)
+# endif
 #endif
-#if defined LONG_LONG_MAX && !defined LLONG_MAX
-# define LLONG_MAX LONG_LONG_MAX
+#ifndef LLONG_MAX
+# if defined LONG_LONG_MAX /* HP-UX 11.31 */
+#  define LLONG_MAX LONG_LONG_MAX
+# elif defined LONGLONG_MAX /* IRIX 6.5 */
+#  define LLONG_MAX LONGLONG_MAX
+# elif defined __GNUC__
+#  define LLONG_MAX __LONG_LONG_MAX__
+# endif
 #endif
-#if defined ULONG_LONG_MAX && !defined ULLONG_MAX
-# define ULLONG_MAX ULONG_LONG_MAX
+#ifndef ULLONG_MAX
+# if defined ULONG_LONG_MAX /* HP-UX 11.31 */
+#  define ULLONG_MAX ULONG_LONG_MAX
+# elif defined ULONGLONG_MAX /* IRIX 6.5 */
+#  define ULLONG_MAX ULONGLONG_MAX
+# elif defined __GNUC__
+#  define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL)
+# endif
 #endif
 
 /* The number of usable bits in an unsigned or signed integer type
@@ -53,6 +70,19 @@
 #define _GL_COB8(n) (_GL_COB4 ((n) >> 4) + _GL_COB4 (n))
 #define _GL_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + !!((n) & 1))
 
+#ifndef WORD_BIT
+/* Assume 'int' is 32 bits wide.  */
+# define WORD_BIT 32
+#endif
+#ifndef LONG_BIT
+/* Assume 'long' is 32 or 64 bits wide.  */
+# if LONG_MAX == INT_MAX
+#  define LONG_BIT 32
+# else
+#  define LONG_BIT 64
+# endif
+#endif
+
 /* Macros specified by ISO/IEC TS 18661-1:2014.  */
 
 #if (! defined ULLONG_WIDTH                                             \
diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h
index 92bdda6..31cf3a4 100644
--- a/lib/mktime-internal.h
+++ b/lib/mktime-internal.h
@@ -35,3 +35,19 @@ typedef int mktime_offset_t;
 time_t mktime_internal (struct tm *,
                         struct tm * (*) (time_t const *, struct tm *),
                         mktime_offset_t *);
+
+/* Although glibc source code uses leading underscores, Gnulib wants
+   ordinary names.
+
+   Portable standalone applications should supply a <time.h> that
+   declares a POSIX-compliant localtime_r, for the benefit of older
+   implementations that lack localtime_r or have a nonstandard one.
+   Similarly for gmtime_r.  See the gnulib time_r module for one way
+   to implement this.  */
+
+#undef __gmtime_r
+#undef __localtime_r
+#define __gmtime_r gmtime_r
+#define __localtime_r localtime_r
+
+#define __mktime_internal mktime_internal
diff --git a/lib/mktime.c b/lib/mktime.c
index 007adf1..6953e98 100644
--- a/lib/mktime.c
+++ b/lib/mktime.c
@@ -28,6 +28,8 @@
    Macro/expression            Which gnulib module    This compilation unit
                                                       should define
 
+   _LIBC                       (glibc proper)         mktime
+
    NEED_MKTIME_WORKING         mktime                 rpl_mktime
    || NEED_MKTIME_WINDOWS
 
@@ -51,25 +53,70 @@
 
 #include <limits.h>
 #include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include <intprops.h>
 #include <verify.h>
 
 #if DEBUG_MKTIME
 # include <stdio.h>
-# include <stdlib.h>
-# include <string.h>
 /* Make it work even if the system's libc has its own mktime routine.  */
 # undef mktime
 # define mktime my_mktime
+#endif /* DEBUG_MKTIME */
+
+#ifndef NEED_MKTIME_INTERNAL
+# define NEED_MKTIME_INTERNAL 0
+#endif
+#ifndef NEED_MKTIME_WINDOWS
+# define NEED_MKTIME_WINDOWS 0
+#endif
+#ifndef NEED_MKTIME_WORKING
+# define NEED_MKTIME_WORKING DEBUG_MKTIME
 #endif
 
-#if NEED_MKTIME_WINDOWS /* on native Windows */
-# include <stdlib.h>
-# include <string.h>
+#include "mktime-internal.h"
+
+#ifndef _LIBC
+static void
+my_tzset (void)
+{
+# if NEED_MKTIME_WINDOWS
+  /* Rectify the value of the environment variable TZ.
+     There are four possible kinds of such values:
+       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
+         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
+       - Time zone names based on geography, that contain one or more
+         slashes, e.g. "Europe/Moscow".
+       - Time zone names based on geography, without slashes, e.g.
+         "Singapore".
+       - Time zone names that contain explicit DST rules.  Syntax: see
+         
<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
+     The Microsoft CRT understands only the first kind.  It produces incorrect
+     results if the value of TZ is of the other kinds.
+     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
+     of the second kind for most geographies, or of the first kind in a few
+     other geographies.  If it is of the second kind, neutralize it.  For the
+     Microsoft CRT, an absent or empty TZ means the time zone that the user
+     has set in the Windows Control Panel.
+     If the value of TZ is of the third or fourth kind -- Cygwin programs
+     understand these syntaxes as well --, it does not matter whether we
+     neutralize it or not, since these values occur only when a Cygwin user
+     has set TZ explicitly; this case is 1. rare and 2. under the user's
+     responsibility.  */
+  const char *tz = getenv ("TZ");
+  if (tz != NULL && strchr (tz, '/') != NULL)
+    _putenv ("TZ=");
+# elif HAVE_TZSET
+  tzset ();
+# endif
+}
+# undef __tzset
+# define __tzset() my_tzset ()
 #endif
 
-#if NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL || DEBUG_MKTIME
+#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL
 
 /* A signed type that can represent an integer number of years
    multiplied by three times the number of seconds in a year.  It is
@@ -150,19 +197,6 @@ const unsigned short int __mon_yday[2][13] =
   };
 
 
-#ifdef _LIBC
-typedef time_t mktime_offset_t;
-#else
-/* Portable standalone applications should supply a <time.h> that
-   declares a POSIX-compliant localtime_r, for the benefit of older
-   implementations that lack localtime_r or have a nonstandard one.
-   See the gnulib time_r module for one way to implement this.  */
-# undef __localtime_r
-# define __localtime_r localtime_r
-# define __mktime_internal mktime_internal
-# include "mktime-internal.h"
-#endif
-
 /* Do the values A and B differ according to the rules for tm_isdst?
    A and B differ if one is zero and the other positive.  */
 static bool
@@ -304,6 +338,7 @@ ranged_convert (struct tm *(*convert) (const time_t *, 
struct tm *),
   return r;
 }
 
+
 /* Convert *TP to a time_t value, inverting
    the monotonic and mostly-unit-linear conversion function CONVERT.
    Use *OFFSET to keep track of a guess at the offset of the result,
@@ -355,6 +390,7 @@ __mktime_internal (struct tm *tp,
   long_int lmday = mday;
   long_int yday = mon_yday + lmday;
 
+  mktime_offset_t off = *offset;
   int negative_offset_guess;
 
   int sec_requested = sec;
@@ -372,7 +408,7 @@ __mktime_internal (struct tm *tp,
   /* Invert CONVERT by probing.  First assume the same offset as last
      time.  */
 
-  INT_SUBTRACT_WRAPV (0, *offset, &negative_offset_guess);
+  INT_SUBTRACT_WRAPV (0, off, &negative_offset_guess);
   t0 = ydhms_diff (year, yday, hour, min, sec,
                   EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, negative_offset_guess);
 
@@ -478,64 +514,28 @@ __mktime_internal (struct tm *tp,
   return t;
 }
 
-#endif /* NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL || DEBUG_MKTIME */
+#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL */
 
-#if NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS || DEBUG_MKTIME
-
-# if NEED_MKTIME_WORKING || DEBUG_MKTIME
-static mktime_offset_t localtime_offset;
-# endif
+#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS
 
 /* Convert *TP to a time_t value.  */
 time_t
 mktime (struct tm *tp)
 {
-# if NEED_MKTIME_WINDOWS
-  /* Rectify the value of the environment variable TZ.
-     There are four possible kinds of such values:
-       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
-         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
-       - Time zone names based on geography, that contain one or more
-         slashes, e.g. "Europe/Moscow".
-       - Time zone names based on geography, without slashes, e.g.
-         "Singapore".
-       - Time zone names that contain explicit DST rules.  Syntax: see
-         
<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
-     The Microsoft CRT understands only the first kind.  It produces incorrect
-     results if the value of TZ is of the other kinds.
-     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
-     of the second kind for most geographies, or of the first kind in a few
-     other geographies.  If it is of the second kind, neutralize it.  For the
-     Microsoft CRT, an absent or empty TZ means the time zone that the user
-     has set in the Windows Control Panel.
-     If the value of TZ is of the third or fourth kind -- Cygwin programs
-     understand these syntaxes as well --, it does not matter whether we
-     neutralize it or not, since these values occur only when a Cygwin user
-     has set TZ explicitly; this case is 1. rare and 2. under the user's
-     responsibility.  */
-  const char *tz = getenv ("TZ");
-  if (tz != NULL && strchr (tz, '/') != NULL)
-    _putenv ("TZ=");
-# endif
-
-# if NEED_MKTIME_WORKING || DEBUG_MKTIME
-#  ifdef _LIBC
   /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
      time zone names contained in the external variable 'tzname' shall
      be set as if the tzset() function had been called.  */
   __tzset ();
-#  elif HAVE_TZSET
-  tzset ();
-#  endif
 
+# if defined __LIBC || NEED_MKTIME_WORKING
+  static mktime_offset_t localtime_offset;
   return __mktime_internal (tp, __localtime_r, &localtime_offset);
 # else
 #  undef mktime
   return mktime (tp);
 # endif
 }
-
-#endif /* NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS || DEBUG_MKTIME */
+#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */
 
 #ifdef weak_alias
 weak_alias (mktime, timelocal)
diff --git a/lib/stat-time.h b/lib/stat-time.h
index 8e787bd..69ebe85 100644
--- a/lib/stat-time.h
+++ b/lib/stat-time.h
@@ -213,7 +213,7 @@ stat_time_normalize (int result, struct stat *st _GL_UNUSED)
 #if defined __sun && defined STAT_TIMESPEC
   if (result == 0)
     {
-      long int timespec_resolution = 1000000000;
+      long int timespec_hz = 1000000000;
       short int const ts_off[] = { offsetof (struct stat, st_atim),
                                    offsetof (struct stat, st_mtim),
                                    offsetof (struct stat, st_ctim) };
@@ -221,11 +221,11 @@ stat_time_normalize (int result, struct stat *st 
_GL_UNUSED)
       for (i = 0; i < sizeof ts_off / sizeof *ts_off; i++)
         {
           struct timespec *ts = (struct timespec *) ((char *) st + ts_off[i]);
-          long int q = ts->tv_nsec / timespec_resolution;
-          long int r = ts->tv_nsec % timespec_resolution;
+          long int q = ts->tv_nsec / timespec_hz;
+          long int r = ts->tv_nsec % timespec_hz;
           if (r < 0)
             {
-              r += timespec_resolution;
+              r += timespec_hz;
               q--;
             }
           ts->tv_nsec = r;
diff --git a/lib/strtol.c b/lib/strtol.c
index 55871b4..f6f5c32 100644
--- a/lib/strtol.c
+++ b/lib/strtol.c
@@ -117,35 +117,6 @@
 # define STRTOL_LONG_MIN LLONG_MIN
 # define STRTOL_LONG_MAX LLONG_MAX
 # define STRTOL_ULONG_MAX ULLONG_MAX
-
-/* The extra casts in the following macros work around compiler bugs,
-   e.g., in Cray C 5.0.3.0.  */
-
-/* True if the arithmetic type T is signed.  */
-# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-
-/* Minimum and maximum values for integer types.
-   These macros have undefined behavior for signed types that either
-   have padding bits or do not use two's complement.  If this is a
-   problem for you, please let us know how to fix it for your host.  */
-
-/* The maximum and minimum values for the integer type T.  */
-# define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t))
-# define TYPE_MAXIMUM(t)                                                 \
-   ((t) (! TYPE_SIGNED (t)                                               \
-         ? (t) -1                                                        \
-         : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
-
-# ifndef ULLONG_MAX
-#  define ULLONG_MAX TYPE_MAXIMUM (unsigned long long)
-# endif
-# ifndef LLONG_MAX
-#  define LLONG_MAX TYPE_MAXIMUM (long long int)
-# endif
-# ifndef LLONG_MIN
-#  define LLONG_MIN TYPE_MINIMUM (long long int)
-# endif
-
 # if __GNUC__ == 2 && __GNUC_MINOR__ < 7
    /* Work around gcc bug with using this constant.  */
    static const unsigned long long int maxquad = ULLONG_MAX;
diff --git a/lib/timegm.c b/lib/timegm.c
index 7eb5ecb..9d9ab11 100644
--- a/lib/timegm.c
+++ b/lib/timegm.c
@@ -1,20 +1,21 @@
 /* Convert UTC calendar time to simple time.  Like mktime but assumes UTC.
 
-   Copyright (C) 1994, 1997, 2003-2004, 2006-2007, 2009-2018 Free Software
-   Foundation, Inc.  This file is part of the GNU C Library.
+   Copyright (C) 1994-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3, or (at your option)
-   any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+   You should have received a copy of the GNU General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #ifndef _LIBC
 # include <config.h>
@@ -22,14 +23,7 @@
 
 #include <time.h>
 
-#ifdef _LIBC
-typedef time_t mktime_offset_t;
-#else
-# undef __gmtime_r
-# define __gmtime_r gmtime_r
-# define __mktime_internal mktime_internal
-# include "mktime-internal.h"
-#endif
+#include "mktime-internal.h"
 
 time_t
 timegm (struct tm *tmp)
diff --git a/lib/timespec-add.c b/lib/timespec-add.c
index f6a8c38..1913b97 100644
--- a/lib/timespec-add.c
+++ b/lib/timespec-add.c
@@ -18,7 +18,7 @@
 /* Written by Paul Eggert.  */
 
 /* Return the sum of two timespec values A and B.  On overflow, return
-   an extremal value.  This assumes 0 <= tv_nsec < TIMESPEC_RESOLUTION.  */
+   an extremal value.  This assumes 0 <= tv_nsec < TIMESPEC_HZ.  */
 
 #include <config.h>
 #include "timespec.h"
@@ -31,7 +31,7 @@ timespec_add (struct timespec a, struct timespec b)
   time_t rs = a.tv_sec;
   time_t bs = b.tv_sec;
   int ns = a.tv_nsec + b.tv_nsec;
-  int nsd = ns - TIMESPEC_RESOLUTION;
+  int nsd = ns - TIMESPEC_HZ;
   int rns = ns;
   time_t tmin = TYPE_MINIMUM (time_t);
   time_t tmax = TYPE_MAXIMUM (time_t);
@@ -63,7 +63,7 @@ timespec_add (struct timespec a, struct timespec b)
         {
         high_overflow:
           rs = tmax;
-          rns = TIMESPEC_RESOLUTION - 1;
+          rns = TIMESPEC_HZ - 1;
         }
     }
 
diff --git a/lib/timespec-sub.c b/lib/timespec-sub.c
index 398a6a5..9eac36e 100644
--- a/lib/timespec-sub.c
+++ b/lib/timespec-sub.c
@@ -19,7 +19,7 @@
 
 /* Return the difference between two timespec values A and B.  On
    overflow, return an extremal value.  This assumes 0 <= tv_nsec <
-   TIMESPEC_RESOLUTION.  */
+   TIMESPEC_HZ.  */
 
 #include <config.h>
 #include "timespec.h"
@@ -38,7 +38,7 @@ timespec_sub (struct timespec a, struct timespec b)
 
   if (ns < 0)
     {
-      rns = ns + TIMESPEC_RESOLUTION;
+      rns = ns + TIMESPEC_HZ;
       if (bs < tmax)
         bs++;
       else if (- TYPE_SIGNED (time_t) < rs)
@@ -63,7 +63,7 @@ timespec_sub (struct timespec a, struct timespec b)
       else
         {
           rs = tmax;
-          rns = TIMESPEC_RESOLUTION - 1;
+          rns = TIMESPEC_HZ - 1;
         }
     }
 
diff --git a/lib/timespec.h b/lib/timespec.h
index 94ba8d0..cc49668 100644
--- a/lib/timespec.h
+++ b/lib/timespec.h
@@ -17,9 +17,9 @@
    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
 
 #if ! defined TIMESPEC_H
-# define TIMESPEC_H
+#define TIMESPEC_H
 
-# include <time.h>
+#include <time.h>
 
 #ifndef _GL_INLINE_HEADER_BEGIN
  #error "Please include config.h first."
@@ -33,13 +33,20 @@ _GL_INLINE_HEADER_BEGIN
 extern "C" {
 #endif
 
+#include "arg-nonnull.h"
 #include "verify.h"
 
-/* Resolution of timespec timestamps (in units per second), and log
-   base 10 of the resolution.  */
+/* Inverse resolution of timespec timestamps (in units per second),
+   and log base 10 of the inverse resolution.  */
 
-enum { TIMESPEC_RESOLUTION = 1000000000 };
-enum { LOG10_TIMESPEC_RESOLUTION = 9 };
+enum { TIMESPEC_HZ = 1000000000 };
+enum { LOG10_TIMESPEC_HZ = 9 };
+
+/* Obsolescent names for backward compatibility.
+   They are misnomers, because TIMESPEC_RESOLUTION is not a resolution.  */
+
+enum { TIMESPEC_RESOLUTION = TIMESPEC_HZ };
+enum { LOG10_TIMESPEC_RESOLUTION = LOG10_TIMESPEC_HZ };
 
 /* Return a timespec with seconds S and nanoseconds NS.  */
 
@@ -88,8 +95,8 @@ timespec_cmp (struct timespec a, struct timespec b)
 
   /* Pacify gcc -Wstrict-overflow (bleeding-edge circa 2017-10-02).  See:
      https://lists.gnu.org/r/bug-gnulib/2017-10/msg00006.html  */
-  assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_RESOLUTION);
-  assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_RESOLUTION);
+  assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_HZ);
+  assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_HZ);
 
   return a.tv_nsec - b.tv_nsec;
 }
@@ -116,8 +123,9 @@ timespectod (struct timespec a)
   return a.tv_sec + a.tv_nsec / 1e9;
 }
 
-void gettime (struct timespec *);
-int settime (struct timespec const *);
+struct timespec current_timespec (void);
+void gettime (struct timespec *) _GL_ARG_NONNULL ((1));
+int settime (struct timespec const *) _GL_ARG_NONNULL ((1));
 
 #ifdef __cplusplus
 }
diff --git a/lib/utimens.c b/lib/utimens.c
index e65f55d..f6c4fe3 100644
--- a/lib/utimens.c
+++ b/lib/utimens.c
@@ -91,11 +91,11 @@ validate_timespec (struct timespec timespec[2])
   if ((timespec[0].tv_nsec != UTIME_NOW
        && timespec[0].tv_nsec != UTIME_OMIT
        && ! (0 <= timespec[0].tv_nsec
-             && timespec[0].tv_nsec < TIMESPEC_RESOLUTION))
+             && timespec[0].tv_nsec < TIMESPEC_HZ))
       || (timespec[1].tv_nsec != UTIME_NOW
           && timespec[1].tv_nsec != UTIME_OMIT
           && ! (0 <= timespec[1].tv_nsec
-                && timespec[1].tv_nsec < TIMESPEC_RESOLUTION)))
+                && timespec[1].tv_nsec < TIMESPEC_HZ)))
     {
       errno = EINVAL;
       return -1;
diff --git a/lisp/abbrev.el b/lisp/abbrev.el
index cddce8f..e1fd366 100644
--- a/lisp/abbrev.el
+++ b/lisp/abbrev.el
@@ -896,24 +896,22 @@ is not undone."
 
 (defun abbrev--write (sym)
   "Write the abbrev in a `read'able form.
-Only writes the non-system abbrevs.
 Presumes that `standard-output' points to `current-buffer'."
-  (unless (or (null (symbol-value sym)) (abbrev-get sym :system))
-    (insert "    (")
-    (prin1 (symbol-name sym))
-    (insert " ")
-    (prin1 (symbol-value sym))
-    (insert " ")
-    (prin1 (symbol-function sym))
-    (insert " :count ")
-    (prin1 (abbrev-get sym :count))
-    (when (abbrev-get sym :case-fixed)
-      (insert " :case-fixed ")
-      (prin1 (abbrev-get sym :case-fixed)))
-    (when (abbrev-get sym :enable-function)
-      (insert " :enable-function ")
-      (prin1 (abbrev-get sym :enable-function)))
-    (insert ")\n")))
+  (insert "    (")
+  (prin1 (symbol-name sym))
+  (insert " ")
+  (prin1 (symbol-value sym))
+  (insert " ")
+  (prin1 (symbol-function sym))
+  (insert " :count ")
+  (prin1 (abbrev-get sym :count))
+  (when (abbrev-get sym :case-fixed)
+    (insert " :case-fixed ")
+    (prin1 (abbrev-get sym :case-fixed)))
+  (when (abbrev-get sym :enable-function)
+    (insert " :enable-function ")
+    (prin1 (abbrev-get sym :enable-function)))
+  (insert ")\n"))
 
 (defun abbrev--describe (sym)
   (when (symbol-value sym)
@@ -934,31 +932,38 @@ Presumes that `standard-output' points to 
`current-buffer'."
   "Insert before point a full description of abbrev table named NAME.
 NAME is a symbol whose value is an abbrev table.
 If optional 2nd arg READABLE is non-nil, a human-readable description
-is inserted.  Otherwise the description is an expression,
-a call to `define-abbrev-table', which would
-define the abbrev table NAME exactly as it is currently defined.
-
-Abbrevs marked as \"system abbrevs\" are omitted."
+is inserted.
+
+If READABLE is nil, an expression is inserted.  The expression is
+a call to `define-abbrev-table' that when evaluated will define
+the abbrev table NAME exactly as it is currently defined.
+Abbrevs marked as \"system abbrevs\" are ignored.  If the
+resulting expression would not define any abbrevs, nothing is
+inserted."
   (let ((table (symbol-value name))
         (symbols ()))
-    (mapatoms (lambda (sym) (if (symbol-value sym) (push sym symbols))) table)
-    (setq symbols (sort symbols 'string-lessp))
-    (let ((standard-output (current-buffer)))
-      (if readable
-         (progn
-           (insert "(")
-           (prin1 name)
-           (insert ")\n\n")
-           (mapc 'abbrev--describe symbols)
-           (insert "\n\n"))
-       (insert "(define-abbrev-table '")
-       (prin1 name)
-       (if (null symbols)
-           (insert " '())\n\n")
-         (insert "\n  '(\n")
-         (mapc 'abbrev--write symbols)
-         (insert "   ))\n\n")))
-      nil)))
+    (mapatoms (lambda (sym)
+                (if (and (symbol-value sym) (or readable (not (abbrev-get sym 
:system))))
+                    (push sym symbols)))
+              table)
+    (when symbols
+      (setq symbols (sort symbols 'string-lessp))
+      (let ((standard-output (current-buffer)))
+        (if readable
+            (progn
+              (insert "(")
+              (prin1 name)
+              (insert ")\n\n")
+              (mapc 'abbrev--describe symbols)
+              (insert "\n\n"))
+          (insert "(define-abbrev-table '")
+          (prin1 name)
+          (if (null symbols)
+              (insert " '())\n\n")
+            (insert "\n  '(\n")
+            (mapc 'abbrev--write symbols)
+            (insert "   ))\n\n")))
+        nil))))
 
 (defun define-abbrev-table (tablename definitions
                                       &optional docstring &rest props)
diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index 261e972..eb262a1 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -956,7 +956,8 @@ Note that the MAX parameter is used so we can exit the 
parse early."
 
           (if (and (functionp cached-secrets)
                    (equal cached-mtime
-                          (nth 5 (file-attributes file))))
+                          (file-attribute-modification-time
+                           (file-attributes file))))
               (progn
                 (auth-source-do-trivia
                  "auth-source-netrc-parse: using CACHED file data for %s"
@@ -968,7 +969,8 @@ Note that the MAX parameter is used so we can exit the 
parse early."
             ;; (note for the irony-impaired: they are just obfuscated)
             (auth-source--aput
              auth-source-netrc-cache file
-             (list :mtime (nth 5 (file-attributes file))
+             (list :mtime (file-attribute-modification-time
+                           (file-attributes file))
                    :secret (let ((v (mapcar #'1+ (buffer-string))))
                              (lambda () (apply #'string (mapcar #'1- v)))))))
           (goto-char (point-min))
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index c60fe01..fc3469e 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -321,7 +321,7 @@ the list of old buffers.")
 
 (defun auto-revert-find-file-function ()
   (setq-local auto-revert-tail-pos
-              (nth 7 (file-attributes buffer-file-name))))
+              (file-attribute-size (file-attributes buffer-file-name))))
 
 (add-hook 'find-file-hook
          #'auto-revert-find-file-function)
@@ -434,7 +434,8 @@ Perform a full revert? ")
       (add-hook 'before-save-hook (lambda () (auto-revert-tail-mode 0)) nil t)
       (or (local-variable-p 'auto-revert-tail-pos) ; don't lose prior position
          (setq-local auto-revert-tail-pos
-                      (nth 7 (file-attributes buffer-file-name))))
+                      (file-attribute-size
+                       (file-attributes buffer-file-name))))
       ;; let auto-revert-mode set up the mechanism for us if it isn't already
       (or auto-revert-mode
          (let ((auto-revert-tail-mode t))
@@ -656,8 +657,8 @@ This is an internal function used by Auto-Revert Mode."
                        (and (file-readable-p buffer-file-name)
                             (/= auto-revert-tail-pos
                                 (setq size
-                                      (nth 7 (file-attributes
-                                              buffer-file-name)))))
+                                      (file-attribute-size
+                                       (file-attributes buffer-file-name)))))
                      (funcall (or buffer-stale-function
                                   #'buffer-stale--default-function)
                               t)))
diff --git a/lisp/bs.el b/lisp/bs.el
index 0d65da1..32431ba 100644
--- a/lisp/bs.el
+++ b/lisp/bs.el
@@ -1159,7 +1159,7 @@ and move point to current buffer."
   (bs-mode)
   (let* ((inhibit-read-only t)
         (map-fun (lambda (entry)
-                   (length (buffer-name entry))))
+                   (string-width (buffer-name entry))))
         (max-length-of-names (apply 'max
                                     (cons 0 (mapcar map-fun list))))
         (name-entry-length (min bs-maximal-buffer-name-column
@@ -1371,7 +1371,7 @@ normally *buffer-selection*."
                                                          apply-args)
                                           (nth 3 column)                ; align
                                           (- min to-much)))
-              (len (length new-string)))
+              (len (string-width new-string)))
          (setq string (concat string new-string))
          (when (> len min)
            (setq to-much (- len min))))))
diff --git a/lisp/calc/calc-misc.el b/lisp/calc/calc-misc.el
index 29e8510..6543920 100644
--- a/lisp/calc/calc-misc.el
+++ b/lisp/calc/calc-misc.el
@@ -943,19 +943,9 @@ loaded and the keystroke automatically re-typed."
 ;;; Bug reporting
 
 ;;;###autoload
-(defun report-calc-bug ()
-  "Report a bug in Calc, the GNU Emacs calculator.
-Prompts for bug subject.  Leaves you in a mail buffer."
-  (interactive)
-  (let ((reporter-prompt-for-summary-p t))
-    (reporter-submit-bug-report calc-bug-address "Calc"
-                               nil nil nil
-                               "Please describe exactly what actions triggered 
the bug and the
-precise symptoms of the bug.  If possible, include a backtrace by
-doing `\\[toggle-debug-on-error]', then reproducing the bug.
-" )))
-;;;###autoload
-(defalias 'calc-report-bug 'report-calc-bug)
+(define-obsolete-function-alias 'report-calc-bug 'report-emacs-bug "26.2")
+;;;###autoload
+(define-obsolete-function-alias 'calc-report-bug 'report-emacs-bug "26.2")
 
 (provide 'calc-misc)
 
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index 364b44b..c79db82 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -486,8 +486,8 @@ to be identified as that note."
   "Face used to show the selected portion of a formula."
   :group 'calc)
 
-(defvar calc-bug-address "address@hidden"
-  "Address of the maintainer of Calc, for use by `report-calc-bug'.")
+(define-obsolete-variable-alias 'calc-bug-address 'report-emacs-bug-address
+  "26.2")
 
 (defvar calc-scan-for-dels t
   "If t, scan keymaps to find all DEL-like keys.
diff --git a/lisp/calculator.el b/lisp/calculator.el
index b6959af..f559fb4 100644
--- a/lisp/calculator.el
+++ b/lisp/calculator.el
@@ -627,7 +627,7 @@ Here are the editing keys:
 
 These operators are pre-defined:
 * `+' `-' `*' `/' the common binary operators
-* `\\' `%'         integer division and reminder
+* `\\' `%'         integer division and remainder
 * `_' `;'         postfix unary negation and reciprocal
 * `^' `L'         binary operators for x^y and log(x) in base y
 * `Q' `!'         unary square root and factorial
diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index c1a3e0a..e3e458a 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -1016,9 +1016,7 @@ current iCalendar object, as a string.  Increase
       (setq icalendar--uid-count (1+ icalendar--uid-count))
       (setq uid (replace-regexp-in-string
                  "%t"
-                 (format "%d%d%d" (car (current-time))
-                         (cadr (current-time))
-                         (car (cddr (current-time))))
+                 (format-time-string "%s%N")
                  uid t t))
       (setq uid (replace-regexp-in-string
                  "%h"
diff --git a/lisp/calendar/parse-time.el b/lisp/calendar/parse-time.el
index 2f9e557..d6c1e9e 100644
--- a/lisp/calendar/parse-time.el
+++ b/lisp/calendar/parse-time.el
@@ -29,8 +29,9 @@
 
 ;; `parse-time-string' parses a time in a string and returns a list of 9
 ;; values, just like `decode-time', where unspecified elements in the
-;; string are returned as nil.  `encode-time' may be applied on these
-;; values to obtain an internal time value.
+;; string are returned as nil (except unspecfied DST is returned as -1).
+;; `encode-time' may be applied on these values to obtain an internal
+;; time value.
 
 ;;; Code:
 
@@ -151,8 +152,9 @@ STRING should be on something resembling an RFC2822 string, 
a la
 somewhat liberal in what format it accepts, and will attempt to
 return a \"likely\" value even for somewhat malformed strings.
 The values returned are identical to those of `decode-time', but
-any values that are unknown are returned as nil."
-  (let ((time (list nil nil nil nil nil nil nil nil nil))
+any unknown values other than DST are returned as nil, and an
+unknown DST value is returned as -1."
+  (let ((time (list nil nil nil nil nil nil nil -1 nil))
        (temp (parse-time-tokenize (downcase string))))
     (while temp
       (let ((parse-time-elt (pop temp))
diff --git a/lisp/cedet/ede/files.el b/lisp/cedet/ede/files.el
index c95402e..2c47481 100644
--- a/lisp/cedet/ede/files.el
+++ b/lisp/cedet/ede/files.el
@@ -113,7 +113,7 @@ of the anchor file for the project."
        (if ede--disable-inode
            (ede--put-inode-dir-hash dir 0)
          (let ((fattr (file-attributes dir)))
-           (ede--put-inode-dir-hash dir (nth 10 fattr))
+           (ede--put-inode-dir-hash dir (file-attribute-inode-number fattr))
            )))))
 
 (cl-defmethod ede--project-inode ((proj ede-project-placeholder))
diff --git a/lisp/cedet/ede/pconf.el b/lisp/cedet/ede/pconf.el
index 9368420..cba7aaa 100644
--- a/lisp/cedet/ede/pconf.el
+++ b/lisp/cedet/ede/pconf.el
@@ -135,7 +135,9 @@ don't do it.  A value of nil means to just do it.")
          (with-current-buffer "*compilation*"
            (goto-char (point-max))
 
-           (when (not (string= mode-line-process ":exit [0]"))
+           ;; FIXME: Use `compilation-finish-functions' or similar to
+           ;; avoid relying on exact format of `mode-line-process'.
+            (when (not (string= (car mode-line-process) ":exit [0]"))
              (error "Configure failed!"))
 
            ;; The Makefile is now recreated by configure?
diff --git a/lisp/cedet/semantic/db-file.el b/lisp/cedet/semantic/db-file.el
index 7035939..2d55c27 100644
--- a/lisp/cedet/semantic/db-file.el
+++ b/lisp/cedet/semantic/db-file.el
@@ -307,8 +307,8 @@ Argument OBJ is the object to write."
     ;; Make sure that the file size and other attributes are
     ;; up to date.
     (let ((fattr (file-attributes (semanticdb-full-filename obj))))
-      (oset obj fsize (nth 7 fattr))
-      (oset obj lastmodtime (nth 5 fattr))
+      (oset obj fsize (file-attribute-size fattr))
+      (oset obj lastmodtime (file-attribute-modification-time fattr))
       )
 
     ;; Do it!
diff --git a/lisp/cedet/semantic/db-mode.el b/lisp/cedet/semantic/db-mode.el
index 638f291..e61eb71 100644
--- a/lisp/cedet/semantic/db-mode.el
+++ b/lisp/cedet/semantic/db-mode.el
@@ -178,8 +178,9 @@ handle it later if need be."
            (let ((fattr (file-attributes
                          (semanticdb-full-filename
                           semanticdb-current-table))))
-             (oset semanticdb-current-table fsize (nth 7 fattr))
-             (oset semanticdb-current-table lastmodtime (nth 5 fattr))
+             (oset semanticdb-current-table fsize (file-attribute-size fattr))
+             (oset semanticdb-current-table lastmodtime
+                   (file-attribute-modification-time fattr))
              (oset semanticdb-current-table buffer nil)
              ))
        ;; If this messes up, just clear the system
diff --git a/lisp/cedet/semantic/db.el b/lisp/cedet/semantic/db.el
index 491752e..05484fc 100644
--- a/lisp/cedet/semantic/db.el
+++ b/lisp/cedet/semantic/db.el
@@ -611,8 +611,8 @@ The file associated with OBJ does not need to be in a 
buffer."
       ;; Buffer isn't loaded.  The only clue we have is if the file
       ;; is somehow different from our mark in the semanticdb table.
       (let* ((stats (file-attributes ff))
-            (actualsize (nth 7 stats))
-            (actualmod (nth 5 stats))
+            (actualsize (file-attribute-size stats))
+            (actualmod (file-attribute-modification-time stats))
             )
 
        (or (not (slot-boundp obj 'tags))
@@ -631,8 +631,8 @@ The file associated with OBJ does not need to be in a 
buffer."
   (oset table tags new-tags)
   (oset table pointmax (point-max))
   (let ((fattr (file-attributes (semanticdb-full-filename table))))
-    (oset table fsize (nth 7 fattr))
-    (oset table lastmodtime (nth 5 fattr))
+    (oset table fsize (file-attribute-size fattr))
+    (oset table lastmodtime (file-attribute-modification-time fattr))
     )
   ;; Assume it is now up to date.
   (oset table unmatched-syntax semantic-unmatched-syntax-cache)
diff --git a/lisp/cedet/srecode/table.el b/lisp/cedet/srecode/table.el
index ac968a6..af2e8b1 100644
--- a/lisp/cedet/srecode/table.el
+++ b/lisp/cedet/srecode/table.el
@@ -187,8 +187,8 @@ INIT are the initialization parameters for the new template 
table."
         (new (apply 'srecode-template-table
                     (file-name-nondirectory file)
                     :file file
-                    :filesize (nth 7 attr)
-                    :filedate (nth 5 attr)
+                    :filesize (file-attribute-size attr)
+                    :filedate (file-attribute-modification-time attr)
                     :major-mode mode
                     init
                     )))
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 1a5b3ca..88a6175 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -711,6 +711,8 @@ since it could result in memory overflow and make Emacs 
crash."
          (put symbol 'risky-local-variable (cadr prop)))
       (if (setq prop (memq :set rest))
          (put symbol 'custom-set (cadr prop)))
+      ;; This is used by describe-variable.
+      (if version (put symbol 'custom-version version))
       ;; Don't re-add to custom-delayed-init-variables post-startup.
       (unless after-init-time
        ;; Note this is the _only_ initialize property we handle.
@@ -731,7 +733,6 @@ since it could result in memory overflow and make Emacs 
crash."
          (custom-add-to-group group symbol 'custom-variable))
        ;; Set the type.
        (put symbol 'custom-type type)
-       (if version (put symbol 'custom-version version))
        (while rest
          (setq prop (car rest)
                propval (cadr rest)
diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el
index 57ee9a5..913b23d 100644
--- a/lisp/dabbrev.el
+++ b/lisp/dabbrev.el
@@ -219,7 +219,7 @@ designated by `dabbrev-select-buffers-function'.
 
 Then, if `dabbrev-check-all-buffers' is non-nil, dabbrev searches
 all the other buffers, except those named in `dabbrev-ignored-buffer-names',
-or matched by `dabbrev-ignored-regexps'."
+or matched by `dabbrev-ignored-buffer-regexps'."
   :type 'boolean
   :group 'dabbrev)
 
@@ -434,7 +434,7 @@ buffers accepted by the function pointed out by variable
 `dabbrev-friend-buffer-function', if `dabbrev-check-other-buffers'
 says so.  Then, if `dabbrev-check-all-buffers' is non-nil, look in
 all the other buffers, subject to constraints specified
-by `dabbrev-ignored-buffer-names' and `dabbrev-ignored-regexps'.
+by `dabbrev-ignored-buffer-names' and `dabbrev-ignored-buffer-regexps'.
 
 A positive prefix argument, N, says to take the Nth backward *distinct*
 possibility.  A negative argument says search forward.
diff --git a/lisp/delsel.el b/lisp/delsel.el
index a3c2934..9582272 100644
--- a/lisp/delsel.el
+++ b/lisp/delsel.el
@@ -294,18 +294,10 @@ then it takes a second \\[keyboard-quit] to abort the 
minibuffer."
     (abort-recursive-edit)))
 
 (define-key minibuffer-local-map "\C-g" 'minibuffer-keyboard-quit)
-(define-key minibuffer-local-ns-map "\C-g" 'minibuffer-keyboard-quit)
-(define-key minibuffer-local-completion-map "\C-g" 'minibuffer-keyboard-quit)
-(define-key minibuffer-local-must-match-map "\C-g" 'minibuffer-keyboard-quit)
-(define-key minibuffer-local-isearch-map "\C-g" 'minibuffer-keyboard-quit)
 
 (defun delsel-unload-function ()
   "Unload the Delete Selection library."
   (define-key minibuffer-local-map "\C-g" 'abort-recursive-edit)
-  (define-key minibuffer-local-ns-map "\C-g" 'abort-recursive-edit)
-  (define-key minibuffer-local-completion-map "\C-g" 'abort-recursive-edit)
-  (define-key minibuffer-local-must-match-map "\C-g" 'abort-recursive-edit)
-  (define-key minibuffer-local-isearch-map "\C-g" 'abort-recursive-edit)
   (dolist (sym '(self-insert-command insert-char quoted-insert yank
                  clipboard-yank insert-register newline-and-indent
                  reindent-then-newline-and-indent newline open-line))
diff --git a/lisp/desktop.el b/lisp/desktop.el
index a9fa287..1346fa3 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -1031,7 +1031,8 @@ without further confirmation."
   (setq desktop-dirname (file-name-as-directory (expand-file-name dirname)))
   (save-excursion
     (let ((eager desktop-restore-eager)
-         (new-modtime (nth 5 (file-attributes (desktop-full-file-name)))))
+         (new-modtime (file-attribute-modification-time
+                       (file-attributes (desktop-full-file-name)))))
       (when
          (or (not new-modtime)         ; nothing to overwrite
              (equal desktop-file-modtime new-modtime)
@@ -1134,7 +1135,9 @@ without further confirmation."
                (write-region (point-min) (point-max) (desktop-full-file-name) 
nil 'nomessage))
              (setq desktop-file-checksum checksum)
              ;; We remember when it was modified (which is presumably just 
now).
-             (setq desktop-file-modtime (nth 5 (file-attributes 
(desktop-full-file-name)))))))))))
+             (setq desktop-file-modtime (file-attribute-modification-time
+                                         (file-attributes
+                                          (desktop-full-file-name)))))))))))
 
 ;; ----------------------------------------------------------------------------
 ;;;###autoload
@@ -1238,7 +1241,9 @@ Using it may cause conflicts.  Use it anyway? " owner)))))
                           'window-configuration-change-hook)))
            (desktop-auto-save-disable)
            ;; Evaluate desktop buffer and remember when it was modified.
-           (setq desktop-file-modtime (nth 5 (file-attributes 
(desktop-full-file-name))))
+           (setq desktop-file-modtime (file-attribute-modification-time
+                                       (file-attributes
+                                        (desktop-full-file-name))))
            (load (desktop-full-file-name) t t t)
            ;; If it wasn't already, mark it as in-use, to bother other
            ;; desktop instances.
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 21ee50c..1f13204 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -200,9 +200,12 @@ Examples of PREDICATE:
 
     (> mtime1 mtime2) - mark newer files
     (not (= size1 size2)) - mark files with different sizes
-    (not (string= (nth 8 fa1) (nth 8 fa2))) - mark files with different modes
-    (not (and (= (nth 2 fa1) (nth 2 fa2))   - mark files with different UID
-              (= (nth 3 fa1) (nth 3 fa2))))   and GID."
+    (not (string= (file-attribute-modes fa1)  - mark files with different modes
+                  (file-attribute-modes fa2)))
+    (not (and (= (file-attribute-user-id fa1) - mark files with different UID
+                 (file-attribute-user-id fa2))
+              (= (file-attribute-group-id fa1) - and GID.
+                 (file-attribute-group-id fa2))))"
   (interactive
    (list
     (let* ((target-dir (dired-dwim-target-directory))
@@ -269,12 +272,12 @@ condition.  Two file items are considered to match if 
they are equal
                                  (eval predicate
                                        `((fa1 . ,fa1)
                                          (fa2 . ,fa2)
-                                         (size1 . ,(nth 7 fa1))
-                                         (size2 . ,(nth 7 fa2))
+                                         (size1 . ,(file-attribute-size fa1))
+                                         (size2 . ,(file-attribute-size fa2))
                                          (mtime1
-                                          . ,(float-time (nth 5 fa1)))
+                                          . ,(float-time 
(file-attribute-modification-time fa1)))
                                          (mtime2
-                                          . ,(float-time (nth 5 fa2)))
+                                          . ,(float-time 
(file-attribute-modification-time fa2)))
                                          )))))
                    (setq list (cdr list)))
                  list)
@@ -308,11 +311,14 @@ List has a form of (file-name full-file-name 
(attribute-list))."
                    (cond ((eq op-symbol 'touch)
                           (format-time-string
                            "%Y%m%d%H%M.%S"
-                           (nth 5 (file-attributes default-file))))
+                           (file-attribute-modification-time
+                            (file-attributes default-file))))
                          ((eq op-symbol 'chown)
-                          (nth 2 (file-attributes default-file 'string)))
+                          (file-attribute-user-id
+                           (file-attributes default-file 'string)))
                          ((eq op-symbol 'chgrp)
-                          (nth 3 (file-attributes default-file 'string))))))
+                          (file-attribute-group-id
+                           (file-attributes default-file 'string))))))
         (prompt (concat "Change " attribute-name " of %s to"
                         (if (eq op-symbol 'touch)
                             " (default now): "
@@ -365,7 +371,7 @@ into the minibuffer."
         ;; The source of default file attributes is the file at point.
         (default-file (dired-get-filename t t))
         (modestr (when default-file
-                   (nth 8 (file-attributes default-file))))
+                   (file-attribute-modes (file-attributes default-file))))
         (default
           (and (stringp modestr)
                (string-match "^.\\(...\\)\\(...\\)\\(...\\)$" modestr)
@@ -1571,20 +1577,20 @@ If `ask', ask for user confirmation."
 
 (defun dired-copy-file-recursive (from to ok-flag &optional
                                       preserve-time top recursive)
-  (when (and (eq t (car (file-attributes from)))
+  (when (and (eq t (file-attribute-type (file-attributes from)))
             (file-in-directory-p to from))
     (error "Cannot copy `%s' into its subdirectory `%s'" from to))
   (let ((attrs (file-attributes from)))
     (if (and recursive
-            (eq t (car attrs))
+            (eq t (file-attribute-type attrs))
             (or (eq recursive 'always)
                 (yes-or-no-p (format "Recursive copies of %s? " from))))
        (copy-directory from to preserve-time)
       (or top (dired-handle-overwrite to))
       (condition-case err
-         (if (stringp (car attrs))
+         (if (stringp (file-attribute-type attrs))
              ;; It is a symlink
-             (make-symbolic-link (car attrs) to ok-flag)
+             (make-symbolic-link (file-attribute-type attrs) to ok-flag)
             (dired-maybe-create-dirs (file-name-directory to))
            (copy-file from to ok-flag preserve-time))
        (file-date-error
@@ -1765,7 +1771,7 @@ ESC or `q' to not overwrite any of the remaining files,
                 (setq to destname))
              ;; If DESTNAME is a subdirectory of FROM, not a symlink,
              ;; and the method in use is copying, signal an error.
-             (and (eq t (car (file-attributes destname)))
+             (and (eq t (file-attribute-type (file-attributes destname)))
                   (eq file-creator 'dired-copy-file)
                   (file-in-directory-p destname from)
                   (error "Cannot copy `%s' into its subdirectory `%s'"
@@ -2832,7 +2838,7 @@ is part of a file name (i.e., has the text property 
`dired-filename')."
   "Search for a string through all marked files using Isearch."
   (interactive)
   (multi-isearch-files
-   (dired-get-marked-files nil nil 'dired-nondirectory-p nil t)))
+   (dired-get-marked-files nil nil #'dired-nondirectory-p nil t)))
 
 ;;;###autoload
 (defun dired-do-isearch-regexp ()
@@ -2847,7 +2853,11 @@ is part of a file name (i.e., has the text property 
`dired-filename')."
 Stops when a match is found.
 To continue searching for next match, use command \\[tags-loop-continue]."
   (interactive "sSearch marked files (regexp): ")
-  (tags-search regexp '(dired-get-marked-files nil nil 'dired-nondirectory-p)))
+  (multifile-initialize-search
+   regexp
+   (dired-get-marked-files nil nil #'dired-nondirectory-p)
+   'default)
+  (multifile-continue))
 
 ;;;###autoload
 (defun dired-do-query-replace-regexp (from to &optional delimited)
@@ -2860,13 +2870,16 @@ with the command \\[tags-loop-continue]."
          (query-replace-read-args
           "Query replace regexp in marked files" t t)))
      (list (nth 0 common) (nth 1 common) (nth 2 common))))
-  (dolist (file (dired-get-marked-files nil nil 'dired-nondirectory-p nil t))
+  (dolist (file (dired-get-marked-files nil nil #'dired-nondirectory-p nil t))
     (let ((buffer (get-file-buffer file)))
       (if (and buffer (with-current-buffer buffer
                        buffer-read-only))
          (error "File `%s' is visited read-only" file))))
-  (tags-query-replace from to delimited
-                     '(dired-get-marked-files nil nil 'dired-nondirectory-p)))
+  (multifile-initialize-replace
+   from to (dired-get-marked-files nil nil #'dired-nondirectory-p)
+   (if (equal from (downcase from)) nil 'default)
+   delimited)
+  (multifile-continue))
 
 (declare-function xref--show-xrefs "xref")
 (declare-function xref-query-replace-in-results "xref")
diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index f07a5de..6c19863 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -445,6 +445,7 @@ See variables `dired-texinfo-unclean-extensions',
                                 dired-tex-unclean-extensions
                                 (list ".dvi"))))
 
+(defvar archive-superior-buffer)
 (defvar tar-superior-buffer)
 ;;; JUMP.
 
@@ -461,8 +462,12 @@ Interactively with prefix argument, read FILE-NAME."
   (interactive
    (list nil (and current-prefix-arg
                   (read-file-name "Jump to Dired file: "))))
-  (if (bound-and-true-p tar-subfile-mode)
-      (switch-to-buffer tar-superior-buffer)
+  (cond
+   ((bound-and-true-p archive-subfile-mode)
+    (switch-to-buffer archive-superior-buffer))
+   ((bound-and-true-p tar-subfile-mode)
+    (switch-to-buffer tar-superior-buffer))
+   (t
     ;; Expand file-name before `dired-goto-file' call:
     ;; `dired-goto-file' requires its argument to be an absolute
     ;; file name; the result of `read-file-name' could be
@@ -490,7 +495,7 @@ Interactively with prefix argument, read FILE-NAME."
                 ;; Toggle omitting, if it is on, and try again.
                 (when dired-omit-mode
                   (dired-omit-mode)
-                  (dired-goto-file file))))))))
+                  (dired-goto-file file)))))))))
 
 ;;;###autoload
 (defun dired-jump-other-window (&optional file-name)
diff --git a/lisp/dired.el b/lisp/dired.el
index 26a7449..5c7bb95 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -88,9 +88,11 @@ If nil, `dired-listing-switches' is used."
 
 (defcustom dired-use-ls-dired 'unspecified
   "Non-nil means Dired should pass the \"--dired\" option to \"ls\".
-The special value of `unspecified' means to check explicitly, and
-save the result in this variable.  This is performed the first
-time `dired-insert-directory' is called.
+If nil, don't pass \"--dired\" to \"ls\".
+The special value of `unspecified' means to check whether \"ls\"
+supports the \"--dired\" option, and save the result in this
+variable.  This is performed the first time `dired-insert-directory'
+is invoked.
 
 Note that if you set this option to nil, either through choice or
 because your \"ls\" program does not support \"--dired\", Dired
@@ -104,9 +106,10 @@ This is used by default on MS Windows, which does not have 
an \"ls\" program.
 Note that `ls-lisp' does not support as many options as GNU ls, though.
 For more details, see Info node `(emacs)ls in Lisp'."
   :group 'dired
-  :type '(choice (const :tag "Check for --dired support" unspecified)
+  :type '(choice (const :tag
+                        "Use --dired only if 'ls' supports it" unspecified)
                  (const :tag "Do not use --dired" nil)
-                 (other :tag "Use --dired" t)))
+                 (other :tag "Always use --dired" t)))
 
 (defcustom dired-chmod-program "chmod"
   "Name of chmod command (usually `chmod')."
@@ -847,8 +850,8 @@ If DIRNAME is already in a Dired buffer, that buffer is 
used without refresh."
   (not (let ((attributes (file-attributes dirname))
             (modtime (visited-file-modtime)))
         (or (eq modtime 0)
-            (not (eq (car attributes) t))
-            (equal (nth 5 attributes) modtime)))))
+            (not (eq (file-attribute-type attributes) t))
+            (equal (file-attribute-modification-time attributes) modtime)))))
 
 (defvar auto-revert-remote-files)
 
@@ -1089,7 +1092,8 @@ wildcards, erases the buffer, and builds the subdir-alist 
anew
       (dired-build-subdir-alist)
       (let ((attributes (file-attributes dirname)))
        (if (eq (car attributes) t)
-           (set-visited-file-modtime (nth 5 attributes))))
+           (set-visited-file-modtime (file-attribute-modification-time
+                                       attributes))))
       (set-buffer-modified-p nil)
       ;; No need to narrow since the whole buffer contains just
       ;; dired-readin's output, nothing else.  The hook can
diff --git a/lisp/dos-w32.el b/lisp/dos-w32.el
index a45a9d1..c19aa44 100644
--- a/lisp/dos-w32.el
+++ b/lisp/dos-w32.el
@@ -342,7 +342,7 @@ filesystem mounted on drive Z:, FILESYSTEM could be \"Z:\"."
               w32-direct-print-region-use-command-dot-com
               ;; file-attributes fails on LPT ports on Windows 9x but
               ;; not on NT, so handle both cases for safety.
-              (eq (or (nth 7 (file-attributes printer)) 0) 0))
+              (eq (or (file-attribute-size (file-attributes printer)) 0) 0))
          (write-region start end tempfile nil 0)
          (let ((w32-quote-process-args nil))
            (call-process "command.com" nil errbuf nil "/c"
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index 49c2d5f..04d2fbf 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -1575,7 +1575,6 @@
 ;; ==============================
 
 (require 'macroexp)
-;; At run-time also, since ad-do-advised-functions returns code that uses it.
 (eval-when-compile (require 'cl-lib))
 
 ;; @@ Variable definitions:
@@ -1662,18 +1661,14 @@ generates a copy of TREE."
 ;; (this list is maintained as a completion table):
 (defvar ad-advised-functions nil)
 
-(defmacro ad-pushnew-advised-function (function)
+(defun ad-pushnew-advised-function (function)
   "Add FUNCTION to `ad-advised-functions' unless its already there."
-  `(if (not (assoc (symbol-name ,function) ad-advised-functions))
-    (setq ad-advised-functions
-     (cons (list (symbol-name ,function))
-      ad-advised-functions))))
+  (add-to-list 'ad-advised-functions (symbol-name function)))
 
-(defmacro ad-pop-advised-function (function)
+(defun ad-pop-advised-function (function)
   "Remove FUNCTION from `ad-advised-functions'."
-  `(setq ad-advised-functions
-    (delq (assoc (symbol-name ,function) ad-advised-functions)
-     ad-advised-functions)))
+  (setq ad-advised-functions
+        (delete (symbol-name function) ad-advised-functions)))
 
 (defmacro ad-do-advised-functions (varform &rest body)
   "`dolist'-style iterator that maps over advised functions.
@@ -1683,14 +1678,14 @@ On each iteration VAR will be bound to the name of an 
advised function
 \(a symbol)."
   (declare (indent 1))
   `(dolist (,(car varform) ad-advised-functions)
-     (setq ,(car varform) (intern (car ,(car varform))))
+     (setq ,(car varform) (intern ,(car varform)))
      ,@body))
 
-(defun ad-get-advice-info (function)
+(defsubst ad-get-advice-info (function)
   (get function 'ad-advice-info))
 
-(defmacro ad-get-advice-info-macro (function)
-  `(get ,function 'ad-advice-info))
+(define-obsolete-function-alias 'ad-get-advice-info-macro
+  #'ad-get-advice-info "27.1")
 
 (defsubst ad-set-advice-info (function advice-info)
   (cond
@@ -1702,13 +1697,12 @@ On each iteration VAR will be bound to the name of an 
advised function
                      #'ad--defalias-fset)))
   (put function 'ad-advice-info advice-info))
 
-(defmacro ad-copy-advice-info (function)
-  `(copy-tree (get ,function 'ad-advice-info)))
+(defsubst ad-copy-advice-info (function)
+  (copy-tree (get function 'ad-advice-info)))
 
-(defmacro ad-is-advised (function)
+(defalias 'ad-is-advised #'ad-get-advice-info
   "Return non-nil if FUNCTION has any advice info associated with it.
-This does not mean that the advice is also active."
-  `(ad-get-advice-info-macro ,function))
+This does not mean that the advice is also active.")
 
 (defun ad-initialize-advice-info (function)
   "Initialize the advice info for FUNCTION.
@@ -1716,19 +1710,19 @@ Assumes that FUNCTION has not yet been advised."
   (ad-pushnew-advised-function function)
   (ad-set-advice-info function (list (cons 'active nil))))
 
-(defmacro ad-get-advice-info-field (function field)
+(defsubst ad-get-advice-info-field (function field)
   "Retrieve the value of the advice info FIELD of FUNCTION."
-  `(cdr (assq ,field (ad-get-advice-info-macro ,function))))
+  (cdr (assq field (ad-get-advice-info function))))
 
 (defun ad-set-advice-info-field (function field value)
   "Destructively modify VALUE of the advice info FIELD of FUNCTION."
-  (and (ad-is-advised function)
-       (cond ((assq field (ad-get-advice-info-macro function))
-             ;; A field with that name is already present:
-              (rplacd (assq field (ad-get-advice-info-macro function)) value))
-            (t;; otherwise, create a new field with that name:
-             (nconc (ad-get-advice-info-macro function)
-                    (list (cons field value)))))))
+  (let ((info (ad-get-advice-info function)))
+    (and info
+         (cond ((assq field info)
+               ;; A field with that name is already present:
+                (rplacd (assq field info) value))
+              (t;; otherwise, create a new field with that name:
+               (nconc info (list (cons field value))))))))
 
 ;; Don't make this a macro so we can use it as a predicate:
 (defun ad-is-active (function)
@@ -1849,7 +1843,7 @@ function at point for which PREDICATE returns non-nil)."
                              (require 'help)
                              (function-called-at-point))))
              (and function
-                  (assoc (symbol-name function) ad-advised-functions)
+                  (member (symbol-name function) ad-advised-functions)
                   (or (null predicate)
                       (funcall predicate function))
                   function))
@@ -1939,9 +1933,9 @@ be used to prompt for the function."
 ;; @@ Finding, enabling, adding and removing pieces of advice:
 ;; ===========================================================
 
-(defmacro ad-find-advice (function class name)
+(defsubst ad-find-advice (function class name)
   "Find the first advice of FUNCTION in CLASS with NAME."
-  `(assq ,name (ad-get-advice-info-field ,function ,class)))
+  (assq name (ad-get-advice-info-field function class)))
 
 (defun ad-advice-position (function class name)
   "Return position of first advice of FUNCTION in CLASS with NAME."
@@ -2109,34 +2103,33 @@ the cache-id will clear the cache."
 ;; @@ Accessing and manipulating function definitions:
 ;; ===================================================
 
-(defmacro ad-macrofy (definition)
+(defsubst ad-macrofy (definition)
   "Take a lambda function DEFINITION and make a macro out of it."
-  `(cons 'macro ,definition))
+  (cons 'macro definition))
 
-(defmacro ad-lambdafy (definition)
-  "Take a macro function DEFINITION and make a lambda out of it."
-  `(cdr ,definition))
+(defalias 'ad-lambdafy #'cdr
+  "Take a macro function DEFINITION and make a lambda out of it.")
 
-(defmacro ad-lambda-p (definition)
+(defsubst ad-lambda-p (definition)
   ;;"non-nil if DEFINITION is a lambda expression."
-  `(eq (car-safe ,definition) 'lambda))
+  (eq (car-safe definition) 'lambda))
 
 ;; see ad-make-advice for the format of advice definitions:
-(defmacro ad-advice-p (definition)
+(defsubst ad-advice-p (definition)
   ;;"non-nil if DEFINITION is a piece of advice."
-  `(eq (car-safe ,definition) 'advice))
+  (eq (car-safe definition) 'advice))
 
-(defmacro ad-compiled-p (definition)
+(defsubst ad-compiled-p (definition)
   "Return non-nil if DEFINITION is a compiled byte-code object."
-  `(or (byte-code-function-p ,definition)
-       (and (macrop ,definition)
-            (byte-code-function-p (ad-lambdafy ,definition)))))
+  (or (byte-code-function-p definition)
+       (and (macrop definition)
+            (byte-code-function-p (ad-lambdafy definition)))))
 
-(defmacro ad-compiled-code (compiled-definition)
+(defsubst ad-compiled-code (compiled-definition)
   "Return the byte-code object of a COMPILED-DEFINITION."
-  `(if (macrop ,compiled-definition)
-    (ad-lambdafy ,compiled-definition)
-    ,compiled-definition))
+  (if (macrop compiled-definition)
+    (ad-lambdafy compiled-definition)
+    compiled-definition))
 
 (defun ad-lambda-expression (definition)
   "Return the lambda expression of a function/macro/advice DEFINITION."
@@ -2697,15 +2690,15 @@ should be modified.  The assembled function will be 
returned."
 ;; the added efficiency.  The validation itself is also pretty cheap, certainly
 ;; a lot cheaper than reconstructing an advised definition.
 
-(defmacro ad-get-cache-definition (function)
-  `(car (ad-get-advice-info-field ,function 'cache)))
+(defsubst ad-get-cache-definition (function)
+  (car (ad-get-advice-info-field function 'cache)))
 
-(defmacro ad-get-cache-id (function)
-  `(cdr (ad-get-advice-info-field ,function 'cache)))
+(defsubst ad-get-cache-id (function)
+  (cdr (ad-get-advice-info-field function 'cache)))
 
-(defmacro ad-set-cache (function definition id)
-  `(ad-set-advice-info-field
-    ,function 'cache (cons ,definition ,id)))
+(defsubst ad-set-cache (function definition id)
+  (ad-set-advice-info-field
+    function 'cache (cons definition id)))
 
 (defun ad-clear-cache (function)
   "Clears a previously cached advised definition of FUNCTION.
@@ -2813,7 +2806,7 @@ advised definition from scratch."
 ;; advised definition will be generated.
 
 (defun ad-preactivate-advice (function advice class position)
-  "Preactivate FUNCTION and returns the constructed cache."
+  "Preactivate FUNCTION and return the constructed cache."
   (let* ((advicefunname (ad-get-advice-info-field function 'advicefunname))
          (old-advice (symbol-function advicefunname))
         (old-advice-info (ad-copy-advice-info function))
@@ -3098,9 +3091,8 @@ deactivation, which might run hooks and get into other 
trouble."
 
 
 ;; Completion alist of valid `defadvice' flags
-(defvar ad-defadvice-flags
-  '(("protect") ("disable") ("activate")
-    ("compile") ("preactivate")))
+(defconst ad-defadvice-flags
+  '("protect" "disable" "activate" "compile" "preactivate"))
 
 ;;;###autoload
 (defmacro defadvice (function args &rest body)
@@ -3180,7 +3172,7 @@ usage: (defadvice FUNCTION (CLASS NAME [POSITION] 
[ARGLIST] FLAG...)
              (let ((completion
                     (try-completion (symbol-name flag) ad-defadvice-flags)))
                (cond ((eq completion t) flag)
-                     ((assoc completion ad-defadvice-flags)
+                     ((member completion ad-defadvice-flags)
                       (intern completion))
                      (t (error "defadvice: Invalid or ambiguous flag: %s"
                                flag))))))
@@ -3221,7 +3213,7 @@ usage: (defadvice FUNCTION (CLASS NAME [POSITION] 
[ARGLIST] FLAG...)
 For any members of FUNCTIONS that are not currently advised the rebinding will
 be a noop.  Any modifications done to the definitions of FUNCTIONS will be
 undone on exit of this macro."
-  (declare (indent 1))
+  (declare (indent 1) (obsolete nil "27.1"))
   (let* ((index -1)
         ;; Make let-variables to store current definitions:
         (current-bindings
diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el
index efeb056..3d73351 100644
--- a/lisp/emacs-lisp/autoload.el
+++ b/lisp/emacs-lisp/autoload.el
@@ -813,7 +813,8 @@ FILE's modification time."
                          (marker-buffer other-output-start)
                          "actual autoloads are elsewhere" load-name relfile
                         (if autoload-timestamps
-                            (nth 5 (file-attributes absfile))
+                            (file-attribute-modification-time
+                             (file-attributes absfile))
                           autoload--non-timestamp))
                         (insert ";;; Generated autoloads from " relfile "\n")))
                     (insert generate-autoload-section-trailer)))))))
@@ -849,7 +850,8 @@ FILE's modification time."
                                       ;; `emacs-internal' instead.
                                       nil nil 'emacs-mule-unix)
                                (if autoload-timestamps
-                                   (nth 5 (file-attributes relfile))
+                                   (file-attribute-modification-time
+                                   (file-attributes relfile))
                                  autoload--non-timestamp)))
                             (insert ";;; Generated autoloads from " relfile 
"\n")))
                         (insert generate-autoload-section-trailer))))
@@ -862,7 +864,7 @@ FILE's modification time."
                   ;; If the entries were added to some other buffer, then the 
file
                   ;; doesn't add entries to OUTFILE.
                   otherbuf))
-          (nth 5 (file-attributes absfile))))
+          (file-attribute-modification-time (file-attributes absfile))))
     (error
      ;; Probably unbalanced parens in forward-sexp. In that case, the
      ;; condition is scan-error, and the signal data includes point
@@ -943,7 +945,8 @@ removes any prior now out-of-date autoload entries."
            (existing-buffer (if buffer-file-name buf))
            (output-file (autoload-generated-file))
            (output-time (if (file-exists-p output-file)
-                            (nth 5 (file-attributes output-file))))
+                            (file-attribute-modification-time
+                            (file-attributes output-file))))
            (found nil))
       (with-current-buffer (autoload-find-generated-file)
         ;; This is to make generated-autoload-file have Unix EOLs, so
@@ -965,7 +968,8 @@ removes any prior now out-of-date autoload entries."
                    ;; Check if it is up to date.
                    (let ((begin (match-beginning 0))
                          (last-time (nth 4 form))
-                         (file-time (nth 5 (file-attributes file))))
+                         (file-time (file-attribute-modification-time
+                                    (file-attributes file))))
                      (if (and (or (null existing-buffer)
                                   (not (buffer-modified-p existing-buffer)))
                               (cond
@@ -1058,7 +1062,8 @@ write its autoloads into the specified file instead."
            generated-autoload-file))
         (output-time
          (if (file-exists-p generated-autoload-file)
-             (nth 5 (file-attributes generated-autoload-file)))))
+             (file-attribute-modification-time
+              (file-attributes generated-autoload-file)))))
 
     (with-current-buffer (autoload-find-generated-file)
       (save-excursion
@@ -1079,7 +1084,8 @@ write its autoloads into the specified file instead."
                   (if (member last-time (list t autoload--non-timestamp))
                       (setq last-time output-time))
                   (dolist (file file)
-                    (let ((file-time (nth 5 (file-attributes file))))
+                    (let ((file-time (file-attribute-modification-time
+                                      (file-attributes file))))
                       (when (and file-time
                                  (not (time-less-p last-time file-time)))
                         ;; file unchanged
@@ -1098,7 +1104,8 @@ write its autoloads into the specified file instead."
                                                    t autoload--non-timestamp))
                                           output-time
                                         oldtime))
-                                     (nth 5 (file-attributes file))))
+                                     (file-attribute-modification-time
+                                     (file-attributes file))))
                   ;; File hasn't changed.
                   nil)
                  (t
diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el
index 506df59..e38c7d9 100644
--- a/lisp/emacs-lisp/generator.el
+++ b/lisp/emacs-lisp/generator.el
@@ -567,8 +567,11 @@ modified copy."
            (unless ,normal-exit-symbol
              ,@unwind-forms))))))
 
-(put 'iter-end-of-sequence 'error-conditions '(iter-end-of-sequence))
-(put 'iter-end-of-sequence 'error-message "iteration terminated")
+(define-error 'iter-end-of-sequence "Iteration terminated"
+  ;; FIXME: This was not defined originally as an `error' condition, so
+  ;; we reproduce this by passing itself as the parent, which avoids the
+  ;; default `error' parent.  Maybe it *should* be in the `error' category?
+  'iter-end-of-sequence)
 
 (defun cps--make-close-iterator-form (terminal-state)
   (if cps--cleanup-table-symbol
@@ -700,6 +703,14 @@ of values.  Callers can retrieve each value using 
`iter-next'."
   `(lambda ,arglist
      ,(cps-generate-evaluator body)))
 
+(defmacro iter-make (&rest body)
+  "Return a new iterator."
+  (declare (debug t))
+  (cps-generate-evaluator body))
+
+(defconst iter-empty (lambda (_op _val) (signal 'iter-end-of-sequence nil))
+  "Trivial iterator that always signals the end of sequence.")
+
 (defun iter-next (iterator &optional yield-result)
   "Extract a value from an iterator.
 YIELD-RESULT becomes the return value of `iter-yield' in the
diff --git a/lisp/emacs-lisp/shadow.el b/lisp/emacs-lisp/shadow.el
index 2e53382..260ac36 100644
--- a/lisp/emacs-lisp/shadow.el
+++ b/lisp/emacs-lisp/shadow.el
@@ -161,8 +161,8 @@ See the documentation for `list-load-path-shadows' for 
further information."
             (or (equal (file-truename f1) (file-truename f2))
                 ;; As a quick test, avoiding spawning a process, compare file
                 ;; sizes.
-                (and (= (nth 7 (file-attributes f1))
-                        (nth 7 (file-attributes f2)))
+                (and (= (file-attribute-size (file-attributes f1))
+                        (file-attribute-size (file-attributes f2)))
                      (eq 0 (call-process "cmp" nil nil nil "-s" f1 f2))))))))
 
 (defvar load-path-shadows-font-lock-keywords
diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el
index 3c66abe..3b617a4 100644
--- a/lisp/emulation/viper-cmd.el
+++ b/lisp/emulation/viper-cmd.el
@@ -748,7 +748,7 @@ Vi's prefix argument will be used.  Otherwise, the prefix 
argument passed to
          (unwind-protect
              (progn
                (setq com
-                     (key-binding (setq key (viper-read-key-sequence nil))))
+                     (key-binding (setq key (read-key-sequence nil))))
                ;; In case of binding indirection--chase definitions.
                ;; Have to do it here because we execute this command under
                ;; different keymaps, so command-execute may not do the
@@ -2449,7 +2449,7 @@ These keys are ESC, RET, and LineFeed."
     (if (eq this-command 'viper-intercept-ESC-key)
        (setq com 'viper-exit-insert-state)
       (viper-set-unread-command-events last-input-event)
-      (setq com (key-binding (viper-read-key-sequence nil))))
+      (setq com (key-binding (read-key-sequence nil))))
 
     (condition-case conds
        (command-execute com)
diff --git a/lisp/emulation/viper-keym.el b/lisp/emulation/viper-keym.el
index 5196ca6..cc0b7eb 100644
--- a/lisp/emulation/viper-keym.el
+++ b/lisp/emulation/viper-keym.el
@@ -1,4 +1,4 @@
-;;; viper-keym.el --- Viper keymaps
+;;; viper-keym.el --- Viper keymaps  -*- lexical-binding:t -*-
 
 ;; Copyright (C) 1994-1997, 2000-2018 Free Software Foundation, Inc.
 
@@ -82,10 +82,6 @@ major mode in effect."
 (defvar viper-insert-intercept-map (make-sparse-keymap))
 (defvar viper-emacs-intercept-map (make-sparse-keymap))
 
-;; keymap used to zap all keymaps other than function-key-map,
-;; device-function-key-map, etc.
-(defvar viper-overriding-map (make-sparse-keymap))
-
 (viper-deflocalvar viper-vi-local-user-map (make-sparse-keymap)
   "Keymap for user-defined local bindings.
 Useful for changing bindings such as ZZ in certain major modes.
diff --git a/lisp/emulation/viper-macs.el b/lisp/emulation/viper-macs.el
index 247180c..cfb46cc 100644
--- a/lisp/emulation/viper-macs.el
+++ b/lisp/emulation/viper-macs.el
@@ -1,4 +1,4 @@
-;;; viper-macs.el --- functions implementing keyboard macros for Viper
+;;; viper-macs.el --- functions implementing keyboard macros for Viper  -*- 
lexical-binding:t -*-
 
 ;; Copyright (C) 1994-1997, 2000-2018 Free Software Foundation, Inc.
 
@@ -174,7 +174,7 @@ a key is a symbol, e.g., `a', `\\1', `f2', etc., or a list, 
e.g.,
                           (prin1-to-string (viper-display-macro key-seq))
                         "")))
        (message "%s" message)
-       (setq event (viper-read-key))
+       (setq event (read-key))
        ;;(setq event (viper-read-event))
        (setq key
              (if (viper-mouse-event-p event)
@@ -251,7 +251,7 @@ a key is a symbol, e.g., `a', `\\1', `f2', etc., or a list, 
e.g.,
                            (viper-display-macro key-seq))
                         "")))
        (message "%s" message)
-       (setq event (viper-read-key))
+       (setq event (read-key))
        ;;(setq event (viper-read-event))
        (setq key
              (if (viper-mouse-event-p event)
@@ -867,15 +867,18 @@ mistakes in macro names to be passed to this function is 
to use
 ;; A fast keysequence is one that is terminated by a pause longer than
 ;; viper-fast-keyseq-timeout.
 (defun viper-read-fast-keysequence (event macro-alist)
+  ;; FIXME: Do we still need this?  Now that the discrimination between the ESC
+  ;; key and the ESC byte sent as part of terminal escape sequences is 
performed
+  ;; in the input-decode-map, I suspect that we don't need this hack any more.
   (let ((lis (vector event))
        next-event)
     (while (and (viper-fast-keysequence-p)
            (viper-keyseq-is-a-possible-macro lis macro-alist))
       ;; Seems that viper-read-event is more robust here. We need to be able to
       ;; place these events on unread-command-events list. If we use
-      ;; viper-read-key then events will be converted to keys, and sometimes
+      ;; read-key then events will be converted to keys, and sometimes
       ;; (e.g., (control \[)) those keys differ from the corresponding events.
-      ;; So, do not use (setq next-event (viper-read-key))
+      ;; So, do not use (setq next-event (read-key))
       (setq next-event (viper-read-event))
       (or (viper-mouse-event-p next-event)
          (setq lis (vconcat lis (vector next-event)))))
diff --git a/lisp/emulation/viper-util.el b/lisp/emulation/viper-util.el
index 2e759bc..aa45655 100644
--- a/lisp/emulation/viper-util.el
+++ b/lisp/emulation/viper-util.el
@@ -1,4 +1,4 @@
-;;; viper-util.el --- Utilities used by viper.el
+;;; viper-util.el --- Utilities used by viper.el  -*- lexical-binding:t -*-
 
 ;; Copyright (C) 1994-1997, 1999-2018 Free Software Foundation, Inc.
 
@@ -28,7 +28,6 @@
 
 
 ;; Compiler pacifier
-(defvar viper-overriding-map)
 (defvar viper-minibuffer-current-face)
 (defvar viper-minibuffer-insert-face)
 (defvar viper-minibuffer-vi-face)
@@ -631,15 +630,15 @@ Otherwise return the normal value."
 
 ;;; Saving settings in custom file
 
-;; Save the current setting of VAR in CUSTOM-FILE.
+;; Save the current setting of VAR in FILE.
 ;; If given, MESSAGE is a message to be displayed after that.
 ;; This message is erased after 2 secs, if erase-msg is non-nil.
-;; Arguments: var message custom-file &optional erase-message
-(defun viper-save-setting (var message custom-file &optional erase-msg)
+;; Arguments: var message file &optional erase-message
+(defun viper-save-setting (var message file &optional erase-msg)
   (let* ((var-name (symbol-name var))
         (var-val (if (boundp var) (eval var)))
         (regexp (format "^[^;]*%s[ \t\n]*[a-zA-Z---_']*[ \t\n)]" var-name))
-        (buf (find-file-noselect (substitute-in-file-name custom-file)))
+        (buf (find-file-noselect (substitute-in-file-name file)))
        )
     (message "%s" (or message ""))
     (with-current-buffer buf
@@ -661,12 +660,12 @@ Otherwise return the normal value."
            (message "")))
       ))
 
-;; Save STRING in CUSTOM-FILE.  If PATTERN is non-nil, remove strings that
+;; Save STRING in FILE.  If PATTERN is non-nil, remove strings that
 ;; match this pattern.
-(defun viper-save-string-in-file (string custom-file &optional pattern)
-  (let ((buf (find-file-noselect (substitute-in-file-name custom-file))))
+(defun viper-save-string-in-file (string file &optional pattern)
+  (let ((buf (find-file-noselect (substitute-in-file-name file))))
     (with-current-buffer buf
-      (let (buffer-read-only)
+      (let ((inhibit-read-only t))
        (goto-char (point-min))
        (if pattern (delete-matching-lines pattern))
        (goto-char (point-max))
@@ -944,48 +943,6 @@ Otherwise return the normal value."
               event))
       (read-event))))
 
-;; Viperized read-key-sequence
-(defun viper-read-key-sequence (prompt &optional continue-echo)
-  (let (inhibit-quit event keyseq)
-    (setq keyseq (read-key-sequence prompt continue-echo))
-    (setq event (if (featurep 'xemacs)
-                   (elt keyseq 0) ; XEmacs returns vector of events
-                 (elt (listify-key-sequence keyseq) 0)))
-    (if (viper-ESC-event-p event)
-       (let (unread-command-events)
-         (if (viper-fast-keysequence-p)
-             (let ((viper-vi-global-user-minor-mode  nil)
-                   (viper-vi-local-user-minor-mode  nil)
-                   (viper-vi-intercept-minor-mode nil)
-                   (viper-insert-intercept-minor-mode nil)
-                   (viper-replace-minor-mode nil) ; actually unnecessary
-                   (viper-insert-global-user-minor-mode  nil)
-                   (viper-insert-local-user-minor-mode  nil))
-               ;; Note: set unread-command-events only after testing for fast
-               ;; keysequence. Otherwise, viper-fast-keysequence-p will be
-               ;; always t -- whether there is anything after ESC or not
-               (viper-set-unread-command-events keyseq)
-               (setq keyseq (read-key-sequence nil)))
-           (viper-set-unread-command-events keyseq)
-           (setq keyseq (read-key-sequence nil)))))
-    keyseq))
-
-
-;; This function lets function-key-map convert key sequences into logical
-;; keys.  This does a better job than viper-read-event when it comes to kbd
-;; macros, since it enables certain macros to be shared between X and TTY modes
-;; by correctly mapping key sequences for Left/Right/... (on an ascii
-;; terminal) into logical keys left, right, etc.
-(defun viper-read-key () ;; FIXME: Use `read-key'?
-  (let ((overriding-local-map viper-overriding-map)
-       (inhibit-quit t)
-       help-char key)
-    (use-global-map viper-overriding-map)
-    (unwind-protect
-       (setq key (elt (viper-read-key-sequence nil) 0))
-      (use-global-map global-map))
-    key))
-
 
 ;; Emacs has a bug in eventp, which causes (eventp nil) to return (nil)
 ;; instead of nil, if '(nil) was previously inadvertently assigned to
diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el
index 8604020..8dd150b 100644
--- a/lisp/emulation/viper.el
+++ b/lisp/emulation/viper.el
@@ -1057,108 +1057,6 @@ Two differences:
       (setq global-mode-string
            (append '("" viper-mode-string) (cdr global-mode-string))))
 
-  (if (featurep 'xemacs)
-      ;; XEmacs
-      (defadvice describe-key (before viper-describe-key-ad protect activate)
-       "Force to read key via `viper-read-key-sequence'."
-       (interactive (list (viper-read-key-sequence "Describe key: "))))
-    ;; Emacs
-    (viper--advice-add 'describe-key :before
-     (lambda (&rest _)
-      "Force to read key via `viper-read-key-sequence'."
-      (interactive (let ((key (viper-read-key-sequence
-                              "Describe key (or click or menu item): ")))
-                    (list key
-                          (prefix-numeric-value current-prefix-arg)
-                          ;; If KEY is a down-event, read also the
-                          ;; corresponding up-event.
-                          (and (vectorp key)
-                               (let ((last-idx (1- (length key))))
-                                 (and (eventp (aref key last-idx))
-                                      (memq 'down (event-modifiers
-                                                   (aref key last-idx)))))
-                               (or (and (eventp (aref key 0))
-                                        (memq 'down (event-modifiers
-                                                     (aref key 0)))
-                                        ;; For the C-down-mouse-2 popup menu,
-                                        ;; there is no subsequent up-event
-                                        (= (length key) 1))
-                                   (and (> (length key) 1)
-                                        (eventp (aref key 1))
-                                        (memq 'down (event-modifiers (aref key 
1)))))
-                               (read-event)))))
-      nil))
-
-    ) ; (if (featurep 'xemacs)
-
-  (if (featurep 'xemacs)
-      ;; XEmacs
-      (defadvice describe-key-briefly
-       (before viper-describe-key-briefly-ad protect activate)
-       "Force to read key via `viper-read-key-sequence'."
-       (interactive (list (viper-read-key-sequence "Describe key briefly: "))))
-    ;; Emacs
-    (viper--advice-add 'describe-key-briefly :before
-     (lambda (&rest _)
-      "Force to read key via `viper-read-key-sequence'."
-      (interactive (let ((key (viper-read-key-sequence
-                              "Describe key (or click or menu item): ")))
-                    ;; If KEY is a down-event, read and discard the
-                    ;; corresponding up-event.
-                    (and (vectorp key)
-                         (let ((last-idx (1- (length key))))
-                           (and (eventp (aref key last-idx))
-                                (memq 'down (event-modifiers (aref key 
last-idx)))))
-                         (read-event))
-                    (list key
-                          (if current-prefix-arg
-                              (prefix-numeric-value current-prefix-arg))
-                          1)))
-      nil))
-    ) ; (if (featurep 'xemacs)
-
-  ;; FIXME: The default already uses read-file-name, so it looks like this
-  ;; advice is not needed any more.
-  ;; (defadvice find-file (before viper-add-suffix-advice activate)
-  ;;   "Use `read-file-name' for reading arguments."
-  ;;   (interactive (cons (read-file-name "Find file: " nil default-directory)
-  ;;                  ;; XEmacs: if Mule & prefix arg, ask for coding system
-  ;;                  (cond ((and (featurep 'xemacs) (featurep 'mule))
-  ;;                         (list
-  ;;                          (and current-prefix-arg
-  ;;                               (read-coding-system "Coding-system: "))))
-  ;;                        ;; Emacs: do wildcards
-  ;;                        ((and (featurep 'emacs) (boundp 
'find-file-wildcards))
-  ;;                              (list find-file-wildcards))))
-  ;;            ))
-  ;; (defadvice find-file-other-window (before viper-add-suffix-advice 
activate)
-  ;;   "Use `read-file-name' for reading arguments."
-  ;;   (interactive (cons (read-file-name "Find file in other window: "
-  ;;                                  nil default-directory)
-  ;;                  ;; XEmacs: if Mule & prefix arg, ask for coding system
-  ;;                  (cond ((and (featurep 'xemacs) (featurep 'mule))
-  ;;                         (list
-  ;;                          (and current-prefix-arg
-  ;;                               (read-coding-system "Coding-system: "))))
-  ;;                        ;; Emacs: do wildcards
-  ;;                        ((and (featurep 'emacs) (boundp 
'find-file-wildcards))
-  ;;                         (list find-file-wildcards))))
-  ;;            ))
-  ;; (defadvice find-file-other-frame (before viper-add-suffix-advice activate)
-  ;;   "Use `read-file-name' for reading arguments."
-  ;;   (interactive (cons (read-file-name "Find file in other frame: "
-  ;;                                  nil default-directory)
-  ;;                  ;; XEmacs: if Mule & prefix arg, ask for coding system
-  ;;                  (cond ((and (featurep 'xemacs) (featurep 'mule))
-  ;;                         (list
-  ;;                          (and current-prefix-arg
-  ;;                               (read-coding-system "Coding-system: "))))
-  ;;                        ;; Emacs: do wildcards
-  ;;                        ((and (featurep 'emacs) (boundp 
'find-file-wildcards))
-  ;;                         (list find-file-wildcards))))
-  ;;            ))
-
-
   (viper--advice-add 'read-file-name :around
    (lambda (orig-fun &rest args)
     "Tell `exit-minibuffer' to run `viper-file-add-suffix' as a hook."
diff --git a/lisp/epg.el b/lisp/epg.el
index f79f204..8f26cd3 100644
--- a/lisp/epg.el
+++ b/lisp/epg.el
@@ -608,7 +608,9 @@ callback data (if any)."
     ;; for more details.
     (when (and agent-info (string-match "\\(.*\\):[0-9]+:[0-9]+" agent-info))
       (setq agent-file (match-string 1 agent-info)
-           agent-mtime (or (nth 5 (file-attributes agent-file)) '(0 0 0 0))))
+           agent-mtime (or (file-attribute-modification-time
+                            (file-attributes agent-file))
+                           '(0 0 0 0))))
     (if epg-debug
        (save-excursion
          (unless epg-debug-buffer
@@ -735,7 +737,9 @@ callback data (if any)."
   (if (with-current-buffer (process-buffer (epg-context-process context))
        (and epg-agent-file
             (time-less-p epg-agent-mtime
-                         (or (nth 5 (file-attributes epg-agent-file)) 0))))
+                         (or (file-attribute-modification-time
+                              (file-attributes epg-agent-file))
+                             0))))
       (redraw-frame))
   (epg-context-set-result-for
    context 'error
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 8c4da32..a7e2742 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -75,7 +75,7 @@
 (require 'thingatpt)
 (require 'auth-source)
 (require 'erc-compat)
-(require 'subr-x)
+(eval-when-compile (require 'subr-x))
 
 (defvar erc-official-location
   "https://www.emacswiki.org/emacs/ERC (mailing list: address@hidden)"
@@ -6040,8 +6040,7 @@ non-nil value is found.
 ;; time routines
 
 (defun erc-string-to-emacs-time (string)
-  "Convert the long number represented by STRING into an Emacs format.
-Returns a list of the form (HIGH LOW), compatible with Emacs time format."
+  "Convert the long number represented by STRING into an Emacs timestamp."
   (let* ((n (string-to-number (concat string ".0"))))
     (list (truncate (/ n 65536))
           (truncate (mod n 65536)))))
diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el
index 5180a07..b7d13ee 100644
--- a/lisp/eshell/em-dirs.el
+++ b/lisp/eshell/em-dirs.el
@@ -314,16 +314,18 @@ Thus, this does not include the current directory.")
       path)))
 
 (defun eshell-expand-multiple-dots (path)
+  ;; FIXME: This advice recommendation is rather odd: it's somewhat
+  ;; dangerous and it claims not to work with minibuffer-completion, which
+  ;; makes it much less interesting.
   "Convert `...' to `../..', `....' to `../../..', etc..
 
 With the following piece of advice, you can make this functionality
 available in most of Emacs, with the exception of filename completion
 in the minibuffer:
 
-  (defadvice expand-file-name
-    (before translate-multiple-dots
-           (filename &optional directory) activate)
-    (setq filename (eshell-expand-multiple-dots filename)))"
+    (advice-add 'expand-file-name :around #'my-expand-multiple-dots)
+    (defun my-expand-multiple-dots (orig-fun filename &rest args)
+      (apply orig-fun (eshell-expand-multiple-dots filename) args))"
   (while (string-match "\\(?:^\\|/\\)\\.\\.\\(\\.+\\)\\(?:$\\|/\\)" path)
     (let* ((extra-dots (match-string 1 path))
           (len (length extra-dots))
diff --git a/lisp/eshell/em-ls.el b/lisp/eshell/em-ls.el
index 2b568a9..53de7f7 100644
--- a/lisp/eshell/em-ls.el
+++ b/lisp/eshell/em-ls.el
@@ -183,9 +183,9 @@ really need to stick around for very long."
   "The face used for highlighting junk file names.")
 
 (defsubst eshell-ls-filetype-p (attrs type)
-  "Test whether ATTRS specifies a directory."
-  (if (nth 8 attrs)
-      (eq (aref (nth 8 attrs) 0) type)))
+  "Test whether ATTRS specifies a file of type TYPE."
+  (if (file-attribute-modes attrs)
+      (eq (aref (file-attribute-modes attrs) 0) type)))
 
 (defmacro eshell-ls-applicable (attrs index func file)
   "Test whether, for ATTRS, the user can do what corresponds to INDEX.
@@ -193,8 +193,8 @@ ATTRS is a string of file modes.  See `file-attributes'.
 If we cannot determine the answer using ATTRS (e.g., if we need
 to know what group the user is in), compute the return value by
 calling FUNC with FILE as an argument."
-  `(let ((owner (nth 2 ,attrs))
-        (modes (nth 8 ,attrs)))
+  `(let ((owner (file-attribute-user-id ,attrs))
+        (modes (file-attribute-modes ,attrs)))
      (cond ((cond ((numberp owner)
                   (= owner (user-uid)))
                  ((stringp owner)
@@ -437,7 +437,7 @@ Sort entries alphabetically across.")
 
 (defsubst eshell-ls-size-string (attrs size-width)
   "Return the size string for ATTRS length, using SIZE-WIDTH."
-  (let* ((str (eshell-ls-printable-size (nth 7 attrs) t))
+  (let* ((str (eshell-ls-printable-size (file-attribute-size attrs) t))
         (len (length str)))
     (if (< len size-width)
        (concat (make-string (- size-width len) ? ) str)
@@ -503,19 +503,19 @@ whose cdr is the list of file attributes."
                 (if numeric-uid-gid
                     "%s%4d %-8s %-8s "
                   "%s%4d %-14s %-8s ")
-                (or (nth 8 attrs) "??????????")
-                (or (nth 1 attrs) 0)
-                (or (let ((user (nth 2 attrs)))
+                (or (file-attribute-modes attrs) "??????????")
+                (or (file-attribute-link-number attrs) 0)
+                (or (let ((user (file-attribute-user-id attrs)))
                       (and (stringp user)
                            (eshell-substring user 14)))
-                    (nth 2 attrs)
+                    (file-attribute-user-id attrs)
                     "")
-                (or (let ((group (nth 3 attrs)))
+                (or (let ((group (file-attribute-group-id attrs)))
                       (and (stringp group)
                            (eshell-substring group 8)))
-                    (nth 3 attrs)
+                    (file-attribute-group-id attrs)
                     ""))
-               (let* ((str (eshell-ls-printable-size (nth 7 attrs)))
+               (let* ((str (eshell-ls-printable-size (file-attribute-size 
attrs)))
                       (len (length str)))
                  ;; Let file sizes shorter than 9 align neatly.
                  (if (< len (or size-width 8))
@@ -585,12 +585,12 @@ relative to that directory."
            (let ((total 0.0))
              (setq size-width 0)
              (dolist (e entries)
-               (if (nth 7 (cdr e))
-                   (setq total (+ total (nth 7 (cdr e)))
+               (if (file-attribute-size (cdr e))
+                   (setq total (+ total (file-attribute-size (cdr e)))
                          size-width
                          (max size-width
                               (length (eshell-ls-printable-size
-                                       (nth 7 (cdr e))
+                                       (file-attribute-size (cdr e))
                                        (not
                                         ;; If we are under -l, count length
                                         ;; of sizes in bytes, not in blocks.
@@ -700,7 +700,7 @@ Each member of FILES is either a string or a cons cell of 
the form
       (if (not show-size)
          (setq display-files (mapcar 'eshell-ls-annotate files))
        (dolist (file files)
-         (let* ((str (eshell-ls-printable-size (nth 7 (cdr file)) t))
+         (let* ((str (eshell-ls-printable-size (file-attribute-size (cdr 
file)) t))
                 (len (length str)))
            (if (< len size-width)
                (setq str (concat (make-string (- size-width len) ? ) str)))
@@ -766,14 +766,14 @@ need to be printed."
                    (if show-size
                        (max size-width
                             (length (eshell-ls-printable-size
-                                     (nth 7 (cdr entry)) t))))))
+                                     (file-attribute-size (cdr entry)) t))))))
            (setq dirs (cons entry dirs)))
        (setq files (cons entry files)
              size-width
              (if show-size
                  (max size-width
                       (length (eshell-ls-printable-size
-                               (nth 7 (cdr entry)) t)))))))
+                               (file-attribute-size (cdr entry)) t)))))))
     (when files
       (eshell-ls-files (eshell-ls-sort-entries files)
                       size-width show-recursive)
diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el
index b3b16d9..c3b942d 100644
--- a/lisp/eshell/em-pred.el
+++ b/lisp/eshell/em-pred.el
@@ -89,10 +89,12 @@ ordinary strings."
     (?t . (eshell-pred-file-mode 1000)) ; sticky bit
     (?U . #'(lambda (file)                   ; owned by effective uid
               (if (file-exists-p file)
-                  (= (nth 2 (file-attributes file)) (user-uid)))))
+                  (= (file-attribute-user-id (file-attributes file))
+                    (user-uid)))))
     ;; (?G . #'(lambda (file)               ; owned by effective gid
     ;;          (if (file-exists-p file)
-    ;;              (= (nth 2 (file-attributes file)) (user-uid)))))
+    ;;              (= (file-attribute-user-id (file-attributes file))
+    ;;                 (user-uid)))))
     (?* . #'(lambda (file)
               (and (file-regular-p file)
                    (not (file-symlink-p file))
@@ -460,7 +462,7 @@ that `ls -l' will show in the first column of its display. "
   `(lambda (file)
      (let ((attrs (eshell-file-attributes (directory-file-name file))))
        (if attrs
-          (memq (aref (nth 8 attrs) 0)
+          (memq (aref (file-attribute-modes attrs) 0)
                 ,(if (eq type ?%)
                      '(?b ?c)
                    (list 'quote (list type))))))))
@@ -489,7 +491,8 @@ that `ls -l' will show in the first column of its display. "
                   '<
                 (if (eq qual ?+)
                     '>
-                  '=)) (nth 1 attrs) ,amount))))))
+                  '=))
+             (file-attribute-link-number attrs) ,amount))))))
 
 (defun eshell-pred-file-size ()
   "Return a predicate to test whether a file is of a given size."
@@ -518,7 +521,8 @@ that `ls -l' will show in the first column of its display. "
                   '<
                 (if (eq qual ?+)
                     '>
-                  '=)) (nth 7 attrs) ,amount))))))
+                  '=))
+             (file-attribute-size attrs) ,amount))))))
 
 (defun eshell-pred-substitute (&optional repeat)
   "Return a modifier function that will substitute matches."
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el
index c912c15..3aecebc 100644
--- a/lisp/eshell/em-unix.el
+++ b/lisp/eshell/em-unix.el
@@ -370,12 +370,14 @@ Remove the DIRECTORY(ies), if they are empty.")
             (or (not (eshell-under-windows-p))
                 (eq system-type 'ms-dos))
             (setq attr (eshell-file-attributes (car files)))
-            (nth 10 attr-target) (nth 10 attr)
-            ;; Use equal, not -, since the inode and the device could
-            ;; cons cells.
-            (equal (nth 10 attr-target) (nth 10 attr))
-            (nth 11 attr-target) (nth 11 attr)
-            (equal (nth 11 attr-target) (nth 11 attr)))
+            (file-attribute-inode-number attr-target)
+            (file-attribute-inode-number attr)
+            (equal (file-attribute-inode-number attr-target)
+                   (file-attribute-inode-number attr))
+            (file-attribute-device-number attr-target)
+            (file-attribute-device-number attr)
+            (equal (file-attribute-device-number attr-target)
+                   (file-attribute-device-number attr)))
        (eshell-error (format-message "%s: `%s' and `%s' are the same file\n"
                                      command (car files) target)))
        (t
@@ -397,16 +399,16 @@ Remove the DIRECTORY(ies), if they are empty.")
                (let (eshell-warn-dot-directories)
                  (if (and (not deep)
                           (eq func 'rename-file)
-                          ;; Use equal, since the device might be a
-                          ;; cons cell.
-                          (equal (nth 11 (eshell-file-attributes
-                                          (file-name-directory
-                                           (directory-file-name
-                                            (expand-file-name source)))))
-                                 (nth 11 (eshell-file-attributes
-                                          (file-name-directory
-                                           (directory-file-name
-                                            (expand-file-name target)))))))
+                          (equal (file-attribute-device-number
+                                  (eshell-file-attributes
+                                   (file-name-directory
+                                    (directory-file-name
+                                     (expand-file-name source)))))
+                                 (file-attribute-device-number
+                                  (eshell-file-attributes
+                                   (file-name-directory
+                                    (directory-file-name
+                                     (expand-file-name target)))))))
                      (apply 'eshell-funcalln func source target args)
                  (unless (file-directory-p target)
                    (if em-verbose
@@ -612,7 +614,8 @@ symlink, then revert to the system's definition of cat."
                               (> (length arg) 0)
                               (eq (aref arg 0) ?-))
                          (let ((attrs (eshell-file-attributes arg)))
-                           (and attrs (memq (aref (nth 8 attrs) 0)
+                           (and attrs
+                                (memq (aref (file-attribute-modes attrs) 0)
                                             '(?d ?l ?-)))))
                (throw 'special t)))))
       (let ((ext-cat (eshell-search-path "cat")))
@@ -656,7 +659,8 @@ Concatenate FILE(s), or standard input, to standard 
output.")
 ;; special front-end functions for compilation-mode buffers
 
 (defun eshell/make (&rest args)
-  "Use `compile' to do background makes."
+  "Use `compile' to do background makes.
+Fallback to standard make when called synchronously."
   (if (and eshell-current-subjob-p
           (eshell-interactive-output-p))
       (let ((compilation-process-setup-function
@@ -842,19 +846,19 @@ external command."
       (unless (string-match "\\`\\.\\.?\\'" (caar entries))
        (let* ((entry (concat path "/"
                              (caar entries)))
-              (symlink (and (stringp (cadr (car entries)))
-                            (cadr (car entries)))))
+              (symlink (and (stringp (file-attribute-type (cdar entries)))
+                            (file-attribute-type (cdar entries)))))
          (unless (or (and symlink (not dereference-links))
                      (and only-one-filesystem
                           (/= only-one-filesystem
-                              (nth 12 (car entries)))))
+                              (file-attribute-device-number (cdar entries)))))
            (if symlink
                (setq entry symlink))
            (setq size
                  (+ size
-                    (if (eq t (cadr (car entries)))
+                    (if (eq t (car (cdar entries)))
                         (eshell-du-sum-directory entry (1+ depth))
-                      (let ((file-size (nth 8 (car entries))))
+                      (let ((file-size (file-attribute-size (cdar entries))))
                         (prog1
                             file-size
                           (if show-all
@@ -925,7 +929,7 @@ Summarize disk usage of each FILE, recursively for 
directories.")
         (while args
           (if only-one-filesystem
               (setq only-one-filesystem
-                    (nth 11 (eshell-file-attributes
+                    (file-attribute-device-number (eshell-file-attributes
                              (file-name-as-directory (car args))))))
           (setq size (+ size (eshell-du-sum-directory
                               (directory-file-name (car args)) 0)))
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index 5ef1ae4..8fe8c46 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -447,7 +447,7 @@ list."
          (not (symbol-value timestamp-var))
          (time-less-p
           (symbol-value timestamp-var)
-          (nth 5 (file-attributes file))))
+          (file-attribute-modification-time (file-attributes file))))
       (progn
        (set result-var (eshell-read-passwd-file file))
        (set timestamp-var (current-time))))
@@ -501,7 +501,7 @@ list."
          (not (symbol-value timestamp-var))
          (time-less-p
           (symbol-value timestamp-var)
-          (nth 5 (file-attributes file))))
+          (file-attribute-modification-time (file-attributes file))))
       (progn
        (set result-var (eshell-read-hosts-file file))
        (set timestamp-var (current-time))))
diff --git a/lisp/files-x.el b/lisp/files-x.el
index 92532e8..9af399c 100644
--- a/lisp/files-x.el
+++ b/lisp/files-x.el
@@ -492,15 +492,32 @@ from the MODE alist ignoring the input argument VALUE."
       ;; Insert modified alist of directory-local variables.
       (insert ";;; Directory Local Variables\n")
       (insert ";;; For more information see (info \"(emacs) Directory 
Variables\")\n\n")
-      (pp (sort variables
-               (lambda (a b)
-                 (cond
-                  ((null (car a)) t)
-                  ((null (car b)) nil)
-                  ((and (symbolp (car a)) (stringp (car b))) t)
-                  ((and (symbolp (car b)) (stringp (car a))) nil)
-                  (t (string< (car a) (car b))))))
-         (current-buffer)))))
+      (princ (dir-locals-to-string
+              (sort variables
+                   (lambda (a b)
+                     (cond
+                      ((null (car a)) t)
+                      ((null (car b)) nil)
+                      ((and (symbolp (car a)) (stringp (car b))) t)
+                      ((and (symbolp (car b)) (stringp (car a))) nil)
+                      (t (string< (car a) (car b)))))))
+             (current-buffer))
+      (goto-char (point-min))
+      (indent-sexp))))
+
+(defun dir-locals-to-string (variables)
+  "Output alists of VARIABLES to string in dotted pair notation syntax."
+  (format "(%s)" (mapconcat
+                  (lambda (mode-variables)
+                    (format "(%S . %s)"
+                            (car mode-variables)
+                            (format "(%s)" (mapconcat
+                                            (lambda (variable-value)
+                                              (format "(%S . %S)"
+                                                      (car variable-value)
+                                                      (cdr variable-value)))
+                                            (cdr mode-variables) "\n"))))
+                  variables "\n")))
 
 ;;;###autoload
 (defun add-dir-local-variable (mode variable value)
diff --git a/lisp/files.el b/lisp/files.el
index 8ed683d..2a770df 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -490,7 +490,8 @@ The functions are called in the order given until one of 
them returns non-nil.")
 (defcustom find-file-hook nil
   "List of functions to be called after a buffer is loaded from a file.
 The buffer's local variables (if any) will have been processed before the
-functions are called."
+functions are called.  This includes directory-local variables, if any,
+for the file's directory."
   :group 'find-file
   :type 'hook
   :options '(auto-insert)
@@ -1152,7 +1153,8 @@ consecutive checks.  For example:
   (defun display-time-file-nonempty-p (file)
     (let ((remote-file-name-inhibit-cache (- display-time-interval 5)))
       (and (file-exists-p file)
-           (< 0 (nth 7 (file-attributes (file-chase-links file)))))))"
+           (< 0 (file-attribute-size
+                 (file-attributes (file-chase-links file)))))))"
   :group 'files
   :version "24.1"
   :type `(choice
@@ -2254,10 +2256,10 @@ every file will be loaded in an own thread."
        ;; Check to see if the file looks uncommonly large.
        (when (not (or buf nowarn))
           (when (eq (abort-if-file-too-large
-                     (nth 7 attributes) "open" filename t)
+                     (file-attribute-size attributes) "open" filename t)
                     'raw)
             (setf rawfile t))
-         (warn-maybe-out-of-memory (nth 7 attributes)))
+         (warn-maybe-out-of-memory (file-attribute-size attributes)))
        (if buf
            ;; We are using an existing buffer.
            (let (nonexistent)
@@ -2471,7 +2473,8 @@ This function ensures that none of these modifications 
will take place."
       (signal 'file-error (list "Opening input file" "Is a directory"
                                 filename)))
   ;; Check whether the file is uncommonly large
-  (abort-if-file-too-large (nth 7 (file-attributes filename)) "insert" 
filename)
+  (abort-if-file-too-large (file-attribute-size (file-attributes filename))
+                          "insert" filename)
   (let* ((buffer (find-buffer-visiting (abbreviate-file-name (file-truename 
filename))
                                        #'buffer-modified-p))
          (tem (funcall insert-func filename)))
@@ -2534,7 +2537,7 @@ the file contents into it using 
`insert-file-contents-literally'."
                                  _after-find-file-from-revert-buffer
                                  nomodes)
   "Called after finding a file and by the default revert function.
-Sets buffer mode, parses local variables.
+Sets buffer mode, parses file-local and directory-local variables.
 Optional args ERROR, WARN, and NOAUTO: ERROR non-nil means there was an
 error in reading the file.  WARN non-nil means warn if there
 exists an auto-save file more recent than the visited file.
@@ -2619,7 +2622,7 @@ unless NOMODES is non-nil."
 
 (defun normal-mode (&optional find-file)
   "Choose the major mode for this buffer automatically.
-Also sets up any specified local variables of the file.
+Also sets up any specified local variables of the file or its directory.
 Uses the visited file name, the -*- line, and the local variables spec.
 
 This function is called automatically from `find-file'.  In that case,
@@ -3650,6 +3653,8 @@ DIR-NAME is the name of the associated directory.  
Otherwise it is nil."
 
 (defun hack-local-variables (&optional handle-mode)
   "Parse and put into effect this buffer's local variables spec.
+For buffers visiting files, also puts into effect directory-local
+variables.
 Uses `hack-local-variables-apply' to apply the variables.
 
 If HANDLE-MODE is nil, we apply all the specified local
@@ -3961,8 +3966,8 @@ Each element in this list has the form (DIR CLASS MTIME).
 DIR is the name of the directory.
 CLASS is the name of a variable class (a symbol).
 MTIME is the recorded modification time of the directory-local
-variables file associated with this entry.  This time is a list
-of integers (the same format as `file-attributes'), and is
+variables file associated with this entry.  This time is a Lisp
+timestamp (the same format as `current-time'), and is
 used to test whether the cache entry is still valid.
 Alternatively, MTIME can be nil, which means the entry is always
 considered valid.")
@@ -4166,7 +4171,9 @@ This function returns either:
                       (equal (nth 2 dir-elt)
                              (let ((latest 0))
                                (dolist (f cached-files latest)
-                                 (let ((f-time (nth 5 (file-attributes f))))
+                                 (let ((f-time
+                                        (file-attribute-modification-time
+                                         (file-attributes f))))
                                    (if (time-less-p latest f-time)
                                        (setq latest f-time)))))))))
             ;; This cache entry is OK.
@@ -4198,7 +4205,8 @@ Return the new class name, which is a symbol named DIR."
          (variables))
     (with-demoted-errors "Error reading dir-locals: %S"
       (dolist (file files)
-       (let ((file-time (nth 5 (file-attributes file))))
+       (let ((file-time (file-attribute-modification-time
+                         (file-attributes file))))
          (if (time-less-p latest file-time)
            (setq latest file-time)))
         (with-temp-buffer
@@ -4550,7 +4558,7 @@ BACKUPNAME is the backup file name, which is the old file 
renamed."
                                      (let ((attr (file-attributes
                                                   real-file-name
                                                   'integer)))
-                                       (<= (nth 2 attr)
+                                       (<= (file-attribute-user-id attr)
                                            copy-when-priv-mismatch))))
                             (not (file-ownership-preserved-p real-file-name
                                                              t)))))
@@ -4642,32 +4650,36 @@ the group would be preserved too."
        ;; Return t if the file doesn't exist, since it's true that no
        ;; information would be lost by an (attempted) delete and create.
        (or (null attributes)
-           (and (or (= (nth 2 attributes) (user-uid))
+           (and (or (= (file-attribute-user-id attributes) (user-uid))
                     ;; Files created on Windows by Administrator (RID=500)
                     ;; have the Administrators group (RID=544) recorded as
                     ;; their owner.  Rewriting them will still preserve the
                     ;; owner.
                     (and (eq system-type 'windows-nt)
-                         (= (user-uid) 500) (= (nth 2 attributes) 544)))
+                         (= (user-uid) 500)
+                         (= (file-attribute-user-id attributes) 544)))
                 (or (not group)
                     ;; On BSD-derived systems files always inherit the parent
                     ;; directory's group, so skip the group-gid test.
                     (memq system-type '(berkeley-unix darwin gnu/kfreebsd))
-                    (= (nth 3 attributes) (group-gid)))
+                    (= (file-attribute-group-id attributes) (group-gid)))
                 (let* ((parent (or (file-name-directory file) "."))
                        (parent-attributes (file-attributes parent 'integer)))
                   (and parent-attributes
                        ;; On some systems, a file created in a setuid directory
                        ;; inherits that directory's owner.
                        (or
-                        (= (nth 2 parent-attributes) (user-uid))
-                        (string-match "^...[^sS]" (nth 8 parent-attributes)))
+                        (= (file-attribute-user-id parent-attributes)
+                           (user-uid))
+                        (string-match
+                         "^...[^sS]"
+                         (file-attribute-modes parent-attributes)))
                        ;; On many systems, a file created in a setgid directory
                        ;; inherits that directory's group.  On some systems
                        ;; this happens even if the setgid bit is not set.
                        (or (not group)
-                           (= (nth 3 parent-attributes)
-                              (nth 3 attributes)))))))))))
+                           (= (file-attribute-group-id parent-attributes)
+                              (file-attribute-group-id attributes)))))))))))
 
 (defun file-name-sans-extension (filename)
   "Return FILENAME sans final \"extension\".
@@ -5827,7 +5839,8 @@ into NEWNAME instead."
 
       ;; Set directory attributes.
       (let ((modes (file-modes directory))
-           (times (and keep-time (nth 5 (file-attributes directory)))))
+           (times (and keep-time (file-attribute-modification-time
+                                  (file-attributes directory)))))
        (if modes (set-file-modes newname modes))
        (if times (set-file-times newname times))))))
 
@@ -7433,7 +7446,7 @@ based on existing mode bits, as in \"og+rX-w\"."
   (let* ((modes (or (if orig-file (file-modes orig-file) 0)
                    (error "File not found")))
         (modestr (and (stringp orig-file)
-                      (nth 8 (file-attributes orig-file))))
+                      (file-attribute-modes (file-attributes orig-file))))
         (default
           (and (stringp modestr)
                (string-match "^.\\(...\\)\\(...\\)\\(...\\)$" modestr)
@@ -7613,27 +7626,24 @@ returned."
 
 (defsubst file-attribute-access-time (attributes)
   "The last access time in ATTRIBUTES returned by `file-attributes'.
-This a list of integers (HIGH LOW USEC PSEC) in the same style
-as (current-time)."
+This a Lisp timestamp in the style of `current-time'."
   (nth 4 attributes))
 
 (defsubst file-attribute-modification-time (attributes)
   "The modification time in ATTRIBUTES returned by `file-attributes'.
 This is the time of the last change to the file's contents, and
-is a list of integers (HIGH LOW USEC PSEC) in the same style
-as (current-time)."
+is a Lisp timestamp in the style of `current-time'."
   (nth 5 attributes))
 
 (defsubst file-attribute-status-change-time (attributes)
   "The status modification time in ATTRIBUTES returned by `file-attributes'.
 This is the time of last change to the file's attributes: owner
-and group, access mode bits, etc, and is a list of integers (HIGH
-LOW USEC PSEC) in the same style as (current-time)."
+and group, access mode bits, etc., and is a Lisp timestamp in the
+style of `current-time'."
   (nth 6 attributes))
 
 (defsubst file-attribute-size (attributes)
-  "The size (in bytes) in ATTRIBUTES returned by `file-attributes'.
-This is a floating point number if the size is too large for an integer."
+  "The integer size (in bytes) in ATTRIBUTES returned by `file-attributes'."
   (nth 7 attributes))
 
 (defsubst file-attribute-modes (attributes)
@@ -7643,20 +7653,12 @@ This is a string of ten letters or dashes as in ls -l."
 
 (defsubst file-attribute-inode-number (attributes)
   "The inode number in ATTRIBUTES returned by `file-attributes'.
-If it is larger than what an Emacs integer can hold, this is of
-the form (HIGH . LOW): first the high bits, then the low 16 bits.
-If even HIGH is too large for an Emacs integer, this is instead
-of the form (HIGH MIDDLE . LOW): first the high bits, then the
-middle 24 bits, and finally the low 16 bits."
+It is a nonnegative integer."
   (nth 10 attributes))
 
 (defsubst file-attribute-device-number (attributes)
   "The file system device number in ATTRIBUTES returned by `file-attributes'.
-If it is larger than what an Emacs integer can hold, this is of
-the form (HIGH . LOW): first the high bits, then the low 16 bits.
-If even HIGH is too large for an Emacs integer, this is instead
-of the form (HIGH MIDDLE . LOW): first the high bits, then the
-middle 24 bits, and finally the low 16 bits."
+It is an integer."
   (nth 11 attributes))
 
 (defun file-attribute-collect (attributes &rest attr-names)
diff --git a/lisp/filesets.el b/lisp/filesets.el
index 63f7c75..c1e6ef1 100644
--- a/lisp/filesets.el
+++ b/lisp/filesets.el
@@ -242,8 +242,7 @@ key is supported."
 (defun filesets-set-config (fileset var val)
   "Set-default wrapper function."
   (filesets-reset-fileset fileset)
-  (set-default var val))
-;  (customize-set-variable var val))
+  (customize-set-variable var val))
 ;  (filesets-build-menu))
 
 ;; It seems this is a workaround for the XEmacs issue described in the
diff --git a/lisp/find-dired.el b/lisp/find-dired.el
index ebd14b0..9a798b0 100644
--- a/lisp/find-dired.el
+++ b/lisp/find-dired.el
@@ -144,7 +144,7 @@ use in place of \"-ls\" as the final argument."
     ;; Check that it's really a directory.
     (or (file-directory-p dir)
        (error "find-dired needs a directory: %s" dir))
-    (switch-to-buffer (get-buffer-create "*Find*"))
+    (pop-to-buffer-same-window (get-buffer-create "*Find*"))
 
     ;; See if there's still a `find' running, and offer to kill
     ;; it first, if it is.
diff --git a/lisp/find-lisp.el b/lisp/find-lisp.el
index 0070e59..a3e4511 100644
--- a/lisp/find-lisp.el
+++ b/lisp/find-lisp.el
@@ -300,24 +300,24 @@ It is a function which takes two arguments, the directory 
and its parent."
   "Format one line of long ls output for file FILE-NAME.
 FILE-ATTR and FILE-SIZE give the file's attributes and size.
 SWITCHES and TIME-INDEX give the full switch list and time data."
-  (let ((file-type (nth 0 file-attr)))
+  (let ((file-type (file-attribute-type file-attr)))
     (concat (if (memq ?i switches)     ; inode number
-               (format "%6d " (nth 10 file-attr)))
+               (format "%6d " (file-attribute-inode-number file-attr)))
            ;; nil is treated like "" in concat
            (if (memq ?s switches)      ; size in K
-               (format "%4d " (1+ (/ (nth 7 file-attr) 1024))))
-           (nth 8 file-attr)           ; permission bits
+               (format "%4d " (1+ (/ (file-attribute-size file-attr) 1024))))
+           (file-attribute-modes file-attr)
            (format " %3d %-8s %-8s %8d "
-                   (nth 1 file-attr)   ; no. of links
-                   (if (numberp (nth 2 file-attr))
-                       (int-to-string (nth 2 file-attr))
-                     (nth 2 file-attr)) ; uid
+                   (file-attribute-link-number file-attr)
+                   (if (numberp (file-attribute-user-id file-attr))
+                       (int-to-string (file-attribute-user-id file-attr))
+                     (file-attribute-user-id file-attr))
                    (if (eq system-type 'ms-dos)
                        "root"          ; everything is root on MSDOS.
-                     (if (numberp (nth 3 file-attr))
-                         (int-to-string (nth 3 file-attr))
-                       (nth 3 file-attr))) ; gid
-                   (nth 7 file-attr)   ; size in bytes
+                     (if (numberp (file-attribute-group-id file-attr))
+                         (int-to-string (file-attribute-group-id file-attr))
+                       (file-attribute-group-id file-attr)))
+                   (file-attribute-size file-attr)
                    )
            (find-lisp-format-time file-attr switches now)
            " "
diff --git a/lisp/gnus/deuglify.el b/lisp/gnus/deuglify.el
index d2bc87c..6286c53 100644
--- a/lisp/gnus/deuglify.el
+++ b/lisp/gnus/deuglify.el
@@ -299,8 +299,12 @@ It is run after `gnus-article-prepare-hook'."
     ;; it. Calling `gnus-article-prepare-display' on an already
     ;; prepared article removes all MIME parts.  I'm unsure whether
     ;; this is a bug or not.
-    (gnus-article-highlight t)
-    (gnus-treat-article nil)
+    (save-excursion
+      (save-restriction
+       (widen)
+       (article-goto-body)
+       (narrow-to-region (point) (point-max))
+       (gnus-treat-article nil)))
     (gnus-run-hooks 'gnus-article-prepare-hook
                    'gnus-outlook-display-hook)))
 
diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el
index 532fd7e..18e6174 100644
--- a/lisp/gnus/gnus-agent.el
+++ b/lisp/gnus/gnus-agent.el
@@ -1603,7 +1603,8 @@ downloaded into the agent."
                                           (number-to-string have-this)))
                        (size-file
                         (float (or (and gnus-agent-total-fetched-hashtb
-                                        (nth 7 (file-attributes file-name)))
+                                        (file-attribute-size
+                                         (file-attributes file-name)))
                                    0)))
                        (file-name-coding-system
                         nnmail-pathname-coding-system))
@@ -2096,12 +2097,16 @@ doesn't exist, to valid the overview buffer."
           (let* (alist
                  (file-name-coding-system nnmail-pathname-coding-system)
                  (file-attributes (directory-files-and-attributes
-                                   (gnus-agent-article-name ""
-                                                            
gnus-agent-read-agentview) nil "^[0-9]+$" t)))
+                                   (gnus-agent-article-name
+                                    "" gnus-agent-read-agentview)
+                                   nil "^[0-9]+$" t)))
             (while file-attributes
               (let ((fa (pop file-attributes)))
-                (unless (nth 1 fa)
-                  (push (cons (string-to-number (nth 0 fa)) (time-to-days (nth 
5 fa))) alist))))
+                (unless (file-attribute-type (cdr fa))
+                  (push (cons (string-to-number (car fa))
+                              (time-to-days
+                               (file-attribute-access-time (cdr fa))))
+                        alist))))
             alist)
         (file-error nil))))))
 
@@ -3347,7 +3352,8 @@ missing NOV entry.  Run gnus-agent-regenerate-group to 
restore it.")))
                     (ignore-errors     ; Just being paranoid.
                       (let* ((file-name (nnheader-concat dir (number-to-string
                                                               article-number)))
-                             (size (float (nth 7 (file-attributes 
file-name)))))
+                             (size (float (file-attribute-size
+                                           (file-attributes file-name)))))
                         (cl-incf bytes-freed size)
                         (cl-incf size-files-deleted size)
                         (cl-incf files-deleted)
@@ -3800,7 +3806,7 @@ has been fetched."
            (buffer-read-only nil)
           (file-name-coding-system nnmail-pathname-coding-system))
       (when (and (file-exists-p file)
-                 (> (nth 7 (file-attributes file)) 0))
+                 (> (file-attribute-size (file-attributes file)) 0))
         (erase-buffer)
         (gnus-kill-all-overlays)
         (let ((coding-system-for-read gnus-cache-coding-system))
@@ -3945,9 +3951,11 @@ If REREAD is not nil, downloaded articles are marked as 
unread."
                 ;; This entry in the overview has been downloaded
                 (push (cons (car downloaded)
                             (time-to-days
-                             (nth 5 (file-attributes
-                                     (concat dir (number-to-string
-                                                  (car downloaded))))))) alist)
+                             (file-attribute-modification-time
+                              (file-attributes
+                               (concat dir (number-to-string
+                                            (car downloaded)))))))
+                      alist)
                 (setq downloaded (cdr downloaded))
                 (setq nov-arts (cdr nov-arts)))
                (t
@@ -4105,19 +4113,21 @@ agent has fetched."
               (let ((sum 0.0)
                     file)
                 (while (setq file (pop delta))
-                  (cl-incf sum (float (or (nth 7 (file-attributes
-                                               (nnheader-concat
-                                                path
-                                                (if (numberp file)
-                                                    (number-to-string file)
-                                                  file)))) 0))))
+                  (cl-incf sum (float (or (file-attribute-size
+                                           (file-attributes
+                                            (nnheader-concat
+                                             path
+                                             (if (numberp file)
+                                                 (number-to-string file)
+                                               file))))
+                                          0))))
                 (setq delta sum))
             (let ((sum (- (nth 2 entry)))
                   (info (directory-files-and-attributes
                          path nil "^-?[0-9]+$" t))
                   file)
               (while (setq file (pop info))
-                (cl-incf sum (float (or (nth 8 file) 0))))
+                (cl-incf sum (float (or (file-attribute-size (cdr file)) 0))))
               (setq delta sum))))
 
         (setq gnus-agent-need-update-total-fetched-for t)
@@ -4138,11 +4148,11 @@ modified."
                       (gnus-sethash path (make-list 3 0)
                                     gnus-agent-total-fetched-hashtb)))
            (file-name-coding-system nnmail-pathname-coding-system)
-           (size (or (nth 7 (file-attributes
-                             (nnheader-concat
-                              path (if agent-over
-                                       ".overview"
-                                     ".agentview"))))
+           (size (or (file-attribute-size (file-attributes
+                                           (nnheader-concat
+                                            path (if agent-over
+                                                     ".overview"
+                                                   ".agentview"))))
                      0)))
        (setq gnus-agent-need-update-total-fetched-for t)
        (setf (nth (if agent-over 1 0) entry) size)))))
diff --git a/lisp/gnus/gnus-cache.el b/lisp/gnus/gnus-cache.el
index 6afc52c..a16b61a 100644
--- a/lisp/gnus/gnus-cache.el
+++ b/lisp/gnus/gnus-cache.el
@@ -642,7 +642,8 @@ $ emacs -batch -l ~/.emacs -l gnus -f gnus-jog-cache"
   "Read the cache active file."
   (gnus-make-directory gnus-cache-directory)
   (if (or (not (file-exists-p gnus-cache-active-file))
-         (zerop (nth 7 (file-attributes gnus-cache-active-file)))
+         (zerop (file-attribute-size
+                 (file-attributes gnus-cache-active-file)))
          force)
       ;; There is no active file, so we generate one.
       (gnus-cache-generate-active)
@@ -854,7 +855,7 @@ supported."
            size)
 
        (if file
-          (setq size (or (nth 7 (file-attributes file)) 0))
+          (setq size (or (file-attribute-size (file-attributes file)) 0))
         (let* ((file-name-coding-system nnmail-pathname-coding-system)
                (files (directory-files (gnus-cache-file-name group "")
                                        t nil t))
@@ -862,8 +863,8 @@ supported."
           (setq size 0.0)
           (while (setq file (pop files))
             (setq attrs (file-attributes file))
-            (unless (nth 0 attrs)
-              (cl-incf size (float (nth 7 attrs)))))))
+            (unless (file-attribute-type attrs)
+              (cl-incf size (float (file-attribute-size attrs)))))))
 
        (setq gnus-cache-need-update-total-fetched-for t)
 
@@ -877,7 +878,7 @@ supported."
                       (gnus-sethash group (make-list 2 0)
                                     gnus-cache-total-fetched-hashtb)))
            (file-name-coding-system nnmail-pathname-coding-system)
-           (size (or (nth 7 (file-attributes
+           (size (or (file-attribute-size (file-attributes
                              (or file
                                  (gnus-cache-file-name group ".overview"))))
                      0)))
diff --git a/lisp/gnus/gnus-cloud.el b/lisp/gnus/gnus-cloud.el
index 16bd80d..1aa8e71 100644
--- a/lisp/gnus/gnus-cloud.el
+++ b/lisp/gnus/gnus-cloud.el
@@ -339,7 +339,8 @@ Use old data if FORCE-OLDER is not nil."
   (format-time-string "%FT%T%z" time))
 
 (defun gnus-cloud-file-new-p (file full)
-  (let ((timestamp (gnus-cloud-timestamp (nth 5 (file-attributes file))))
+  (let ((timestamp (gnus-cloud-timestamp (file-attribute-modification-time
+                                         (file-attributes file))))
         (old (cadr (assoc file gnus-cloud-file-timestamps))))
     (when (or full
               (null old)
diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el
index 6878aa6..327cc69 100644
--- a/lisp/gnus/gnus-score.el
+++ b/lisp/gnus/gnus-score.el
@@ -2675,7 +2675,8 @@ the score file and its full name, including the 
directory.")
                (gnus-file-newer-than gnus-kill-files-directory
                                      (car gnus-score-file-list)))
        (setq gnus-score-file-list
-             (cons (nth 5 (file-attributes gnus-kill-files-directory))
+             (cons (file-attribute-modification-time
+                    (file-attributes gnus-kill-files-directory))
                    (nreverse
                     (directory-files
                      gnus-kill-files-directory t
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 623055e..f15d645 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -2822,7 +2822,8 @@ If FORCE is non-nil, the .newsrc file is read."
           ;; Check timestamp of `gnus-current-startup-file'.eld against
           ;; `gnus-save-newsrc-file-last-timestamp'.
          (if (let* ((checkfile (concat gnus-current-startup-file ".eld"))
-                     (mtime (nth 5 (file-attributes checkfile))))
+                    (mtime (file-attribute-modification-time
+                            (file-attributes checkfile))))
                (and gnus-save-newsrc-file-last-timestamp
                      (time-less-p gnus-save-newsrc-file-last-timestamp
                                   mtime)
@@ -2843,7 +2844,8 @@ If FORCE is non-nil, the .newsrc file is read."
                   (gnus-run-hooks 'gnus-save-quick-newsrc-hook)
                   (save-buffer)
                   (setq gnus-save-newsrc-file-last-timestamp
-                        (nth 5 (file-attributes buffer-file-name))))
+                       (file-attribute-modification-time
+                        (file-attributes buffer-file-name))))
               (let ((coding-system-for-write gnus-ding-file-coding-system)
                     (version-control gnus-backup-startup-file)
                     (startup-file (concat gnus-current-startup-file ".eld"))
@@ -2880,7 +2882,8 @@ If FORCE is non-nil, the .newsrc file is read."
                        (rename-file working-file startup-file t)
                        (gnus-set-file-modes startup-file setmodes)
                        (setq gnus-save-newsrc-file-last-timestamp
-                              (nth 5 (file-attributes startup-file)))))
+                             (file-attribute-modification-time
+                              (file-attributes startup-file)))))
                   (condition-case nil
                       (delete-file working-file)
                     (file-error nil)))))
@@ -3053,11 +3056,12 @@ If FORCE is non-nil, the .newsrc file is read."
       (with-current-buffer (gnus-get-buffer-create " *gnus slave*")
        (setq slave-files
              (sort (mapcar (lambda (file)
-                             (list (nth 5 (file-attributes file)) file))
+                             (list (file-attribute-modification-time
+                                    (file-attributes file))
+                                   file))
                            slave-files)
                    (lambda (f1 f2)
-                     (or (< (caar f1) (caar f2))
-                         (< (nth 1 (car f1)) (nth 1 (car f2)))))))
+                     (time-less-p (car f1) (car f2)))))
        (while slave-files
          (erase-buffer)
          (setq file (nth 1 (car slave-files)))
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index ceb9842..f56b822 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -10340,16 +10340,19 @@ latter case, they will be copied into the relevant 
groups."
            (unless (re-search-forward "^date:" nil t)
              (goto-char (point-max))
              (setq atts (file-attributes file))
-             (insert "Date: " (message-make-date (nth 5 atts)) "\n")))
+             (insert "Date: " (message-make-date
+                               (file-attribute-modification-time atts))
+                     "\n")))
        ;; This doesn't look like an article, so we fudge some headers.
        (setq atts (file-attributes file)
              lines (count-lines (point-min) (point-max)))
        (insert "From: " (read-string "From: ") "\n"
                "Subject: " (read-string "Subject: ") "\n"
-               "Date: " (message-make-date (nth 5 atts)) "\n"
+               "Date: " (message-make-date
+                         (file-attribute-modification-time atts)) "\n"
                "Message-ID: " (message-make-message-id) "\n"
                "Lines: " (int-to-string lines) "\n"
-               "Chars: " (int-to-string (nth 7 atts)) "\n\n"))
+               "Chars: " (int-to-string (file-attribute-size atts)) "\n\n"))
       (setq group-art (gnus-request-accept-article group nil t))
       (kill-buffer (current-buffer)))
     (setq gnus-newsgroup-active (gnus-activate-group group))
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index b30e4d1..2e4b054 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -277,10 +277,7 @@ Symbols are also allowed; their print names are used 
instead."
 ;;; Time functions.
 
 (defun gnus-file-newer-than (file date)
-  (let ((fdate (nth 5 (file-attributes file))))
-    (or (> (car fdate) (car date))
-       (and (= (car fdate) (car date))
-            (> (nth 1 fdate) (nth 1 date))))))
+  (time-less-p date (file-attribute-modification-time (file-attributes file))))
 
 ;;; Keymap macros.
 
@@ -1434,7 +1431,7 @@ SPEC is a predicate specifier that contains stuff like 
`or', `and',
 
 (defun gnus-cache-file-contents (file variable function)
   "Cache the contents of FILE in VARIABLE.  The contents come from FUNCTION."
-  (let ((time (nth 5 (file-attributes file)))
+  (let ((time (file-attribute-modification-time (file-attributes file)))
        contents value)
     (if (or (null (setq value (symbol-value variable)))
            (not (equal (car value) file))
diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el
index 0e1c073..5af2920 100644
--- a/lisp/gnus/mail-source.el
+++ b/lisp/gnus/mail-source.el
@@ -602,7 +602,8 @@ If CONFIRM is non-nil, ask for confirmation before removing 
a file."
       (let* ((ffile (car files))
             (bfile (replace-regexp-in-string "\\`.*/\\([^/]+\\)\\'" "\\1"
                                              ffile))
-            (filetime (nth 5 (file-attributes ffile))))
+            (filetime (file-attribute-modification-time
+                       (file-attributes ffile))))
        (setq files (cdr files))
        (when (and (> (time-to-number-of-days (time-subtract now filetime))
                      diff)
@@ -618,7 +619,8 @@ Deleting old (> %s day(s)) incoming mail file `%s'." diff 
bfile)
 (defun mail-source-callback (callback info)
   "Call CALLBACK on the mail file.  Pass INFO on to CALLBACK."
   (if (or (not (file-exists-p mail-source-crash-box))
-         (zerop (nth 7 (file-attributes mail-source-crash-box))))
+         (zerop (file-attribute-size
+                 (file-attributes mail-source-crash-box))))
       (progn
        (when (file-exists-p mail-source-crash-box)
          (delete-file mail-source-crash-box))
@@ -670,7 +672,7 @@ Deleting old (> %s day(s)) incoming mail file `%s'." diff 
bfile)
        ((not (file-exists-p from))
        ;; There is no inbox.
        (setq to nil))
-       ((zerop (nth 7 (file-attributes from)))
+       ((zerop (file-attribute-size (file-attributes from)))
        ;; Empty file.
        (setq to nil))
        (t
diff --git a/lisp/gnus/nneething.el b/lisp/gnus/nneething.el
index abd17c5..10ac702 100644
--- a/lisp/gnus/nneething.el
+++ b/lisp/gnus/nneething.el
@@ -215,8 +215,9 @@ included.")
        (setq nneething-map
              (mapcar (lambda (n)
                        (list (cdr n) (car n)
-                             (nth 5 (file-attributes
-                                     (nneething-file-name (car n))))))
+                             (file-attribute-modification-time
+                              (file-attributes
+                               (nneething-file-name (car n))))))
                      nneething-map)))
       ;; Remove files matching the exclusion regexp.
       (when nneething-exclude-files
@@ -244,7 +245,7 @@ included.")
        (while map
          (if (and (member (cadr (car map)) files)
                  ;; We also remove files that have changed mod times.
-                  (equal (nth 5 (file-attributes
+                  (equal (file-attribute-modification-time (file-attributes
                                  (nneething-file-name (cadr (car map)))))
                          (cadr (cdar map))))
              (progn
@@ -262,7 +263,7 @@ included.")
          (setq touched t)
          (setcdr nneething-active (1+ (cdr nneething-active)))
          (push (list (cdr nneething-active) (car files)
-                     (nth 5 (file-attributes
+                     (file-attribute-modification-time (file-attributes
                              (nneething-file-name (car files)))))
                nneething-map))
        (setq files (cdr files)))
@@ -318,15 +319,17 @@ included.")
      "Subject: " (file-name-nondirectory file) (or extra-msg "") "\n"
      "Message-ID: <nneething-" (nneething-encode-file-name file)
      "@" (system-name) ">\n"
-     (if (equal '(0 0) (nth 5 atts)) ""
-       (concat "Date: " (current-time-string (nth 5 atts)) "\n"))
+     (if (zerop (float-time (file-attribute-modification-time atts))) ""
+       (concat "Date: "
+              (current-time-string (file-attribute-modification-time atts))
+              "\n"))
      (or (when buffer
           (with-current-buffer buffer
             (when (re-search-forward "<address@hidden>" 1000 t)
               (concat "From: " (match-string 0) "\n"))))
-        (nneething-from-line (nth 2 atts) file))
-     (if (> (string-to-number (int-to-string (nth 7 atts))) 0)
-        (concat "Chars: " (int-to-string (nth 7 atts)) "\n")
+        (nneething-from-line (file-attribute-user-id atts) file))
+     (if (> (file-attribute-size atts) 0)
+        (concat "Chars: " (int-to-string (file-attribute-size atts)) "\n")
        "")
      (if buffer
         (with-current-buffer buffer
diff --git a/lisp/gnus/nnfolder.el b/lisp/gnus/nnfolder.el
index 11a3986..8ef6f2a 100644
--- a/lisp/gnus/nnfolder.el
+++ b/lisp/gnus/nnfolder.el
@@ -862,7 +862,7 @@ deleted.  Point is left where the deleted region was."
     (mm-enable-multibyte) ;; Use multibyte buffer for future copying.
     (buffer-disable-undo)
     (if (equal (cadr (assoc group nnfolder-scantime-alist))
-              (nth 5 (file-attributes file)))
+              (file-attribute-modification-time (file-attributes file)))
        ;; This looks up-to-date, so we don't do any scanning.
        (if (file-exists-p file)
            buffer
diff --git a/lisp/gnus/nnheader.el b/lisp/gnus/nnheader.el
index b9ce204..83a9c3f 100644
--- a/lisp/gnus/nnheader.el
+++ b/lisp/gnus/nnheader.el
@@ -896,7 +896,7 @@ without formatting."
 
 (defun nnheader-file-size (file)
   "Return the file size of FILE or 0."
-  (or (nth 7 (file-attributes file)) 0))
+  (or (file-attribute-size (file-attributes file)) 0))
 
 (defun nnheader-find-etc-directory (package &optional file first)
   "Go through `load-path' and find the \"../etc/PACKAGE\" directory.
@@ -951,7 +951,7 @@ find-file-hook, etc.
     (mm-insert-file-contents filename visit beg end replace)))
 
 (defun nnheader-insert-nov-file (file first)
-  (let ((size (nth 7 (file-attributes file)))
+  (let ((size (file-attribute-size (file-attributes file)))
        (cutoff (* 32 1024)))
     (when size
       (if (< size cutoff)
diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el
index 08db5ab..13c4303 100644
--- a/lisp/gnus/nnmail.el
+++ b/lisp/gnus/nnmail.el
@@ -1534,7 +1534,8 @@ See the documentation for the variable 
`nnmail-split-fancy' for details."
            (and (setq file (ignore-errors
                              (symbol-value (intern (format "%s-active-file"
                                                            backend)))))
-                (setq file-time (nth 5 (file-attributes file)))
+                (setq file-time (file-attribute-modification-time
+                                 (file-attributes file)))
                 (or (not
                      (setq timestamp
                            (condition-case ()
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el
index c8480dd..afaf3dc 100644
--- a/lisp/gnus/nnmaildir.el
+++ b/lisp/gnus/nnmaildir.el
@@ -318,15 +318,15 @@ This variable is set by `nnmaildir-request-article'.")
        (setq attr (file-attributes
                    (concat dir (number-to-string number-opened))))
        (or attr (throw 'return (1- number-opened)))
-       (setq ino-opened (nth 10 attr)
-             nlink (nth 1 attr)
+       (setq ino-opened (file-attribute-inode-number attr)
+             nlink (file-attribute-link-number attr)
              number-linked (+ number-opened nlink))
        (if (or (< nlink 1) (< number-linked nlink))
            (signal 'error '("Arithmetic overflow")))
        (setq attr (file-attributes
                    (concat dir (number-to-string number-linked))))
        (or attr (throw 'return (1- number-linked)))
-       (unless (equal ino-opened (nth 10 attr))
+       (unless (equal ino-opened (file-attribute-inode-number attr))
          (setq number-opened number-linked))))))
 
 ;; Make the given server, if non-nil, be the current server.  Then make the
@@ -392,8 +392,8 @@ This variable is set by `nnmaildir-request-article'.")
          (setq make-new-file nil
                previous-number-link 0))
        (let* ((attr (file-attributes path-open))
-              (nlink (nth 1 attr)))
-         (setq ino-open (nth 10 attr)
+              (nlink (file-attribute-link-number attr)))
+         (setq ino-open (file-attribute-inode-number attr)
                number-link (+ number-open nlink))
          (if (or (< nlink 1) (< number-link nlink))
              (signal 'error '("Arithmetic overflow"))))
@@ -412,7 +412,7 @@ This variable is set by `nnmaildir-request-article'.")
                  number-open number-link))
           ((nnmaildir--eexist-p err)
            (let ((attr (file-attributes path-link)))
-             (unless (equal (nth 10 attr) ino-open)
+             (unless (equal (file-attribute-inode-number attr) ino-open)
                (setq number-open number-link
                      number-link 0))))
           (t (signal (car err) (cdr err)))))))))
@@ -437,8 +437,8 @@ This variable is set by `nnmaildir-request-article'.")
       (unless attr
        (nnmaildir--expired-article group article)
        (throw 'return nil))
-      (setq mtime (nth 5 attr)
-           attr (nth 7 attr)
+      (setq mtime (file-attribute-modification-time attr)
+           attr (file-attribute-size attr)
            nov (nnmaildir--art-nov article)
            dir (nnmaildir--nndir dir)
            novdir (nnmaildir--nov-dir dir)
@@ -764,7 +764,7 @@ This variable is set by `nnmaildir-request-article'.")
 
 (defun nnmaildir--scan (gname scan-msgs groups _method srv-dir srv-ls)
   (catch 'return
-    (let ((36h-ago (- (car (current-time)) 2))
+    (let ((36h-ago (- (float-time) 129600))
          absdir nndir tdir ndir cdir nattr cattr isnew pgname read-only ls
          files num dir flist group x)
       (setq absdir (nnmaildir--srvgrp-dir srv-dir gname)
@@ -794,29 +794,33 @@ This variable is set by `nnmaildir-request-article'.")
       (setq read-only (nnmaildir--param pgname 'read-only)
            ls (or (nnmaildir--param pgname 'directory-files) srv-ls))
       (unless read-only
-       (setq x (nth 11 (file-attributes tdir)))
-       (unless (and (equal x (nth 11 nattr)) (equal x (nth 11 cattr)))
+       (setq x (file-attribute-device-number (file-attributes tdir)))
+       (unless (and (equal x (file-attribute-device-number nattr))
+                    (equal x (file-attribute-device-number cattr)))
          (setf (nnmaildir--srv-error nnmaildir--cur-server)
                (concat "Maildir spans filesystems: " absdir))
          (throw 'return nil))
        (dolist (file (funcall ls tdir 'full "\\`[^.]" 'nosort))
          (setq x (file-attributes file))
-         (if (or (> (cadr x) 1) (< (car (nth 4 x)) 36h-ago))
+         (if (or (> (file-attribute-link-number x) 1)
+                 (time-less-p (file-attribute-access-time x) 36h-ago))
              (delete-file file))))
       (or scan-msgs
          isnew
          (throw 'return t))
-      (setq nattr (nth 5 nattr))
+      (setq nattr (file-attribute-modification-time nattr))
       (if (equal nattr (nnmaildir--grp-new group))
          (setq nattr nil))
       (if read-only (setq dir (and (or isnew nattr) ndir))
        (when (or isnew nattr)
          (dolist (file  (funcall ls ndir nil "\\`[^.]" 'nosort))
            (setq x (concat ndir file))
-           (and (time-less-p (nth 5 (file-attributes x)) nil)
+           (and (time-less-p (file-attribute-modification-time
+                              (file-attributes x))
+                             nil)
                 (rename-file x (concat cdir (nnmaildir--ensure-suffix file)))))
          (setf (nnmaildir--grp-new group) nattr))
-       (setq cattr (nth 5 (file-attributes cdir)))
+       (setq cattr (file-attribute-modification-time (file-attributes cdir)))
        (if (equal cattr (nnmaildir--grp-cur group))
            (setq cattr nil))
        (setq dir (and (or isnew cattr) cdir)))
@@ -903,7 +907,7 @@ This variable is set by `nnmaildir-request-article'.")
                (if (nnmaildir--srv-gnm nnmaildir--cur-server)
                    (nnmail-get-new-mail 'nnmaildir nil nil scan-group))
              (unintern scan-group groups))
-         (setq x (nth 5 (file-attributes srv-dir))
+         (setq x (file-attribute-modification-time (file-attributes srv-dir))
                scan-group (null scan-group))
          (if (equal x (nnmaildir--srv-mtime nnmaildir--cur-server))
              (if scan-group
@@ -936,7 +940,7 @@ This variable is set by `nnmaildir-request-article'.")
            (dolist (grp x)
              (unintern grp groups))
            (setf (nnmaildir--srv-mtime nnmaildir--cur-server)
-                 (nth 5 (file-attributes srv-dir))))
+                 (file-attribute-modification-time (file-attributes srv-dir))))
          (and scan-group
               (nnmaildir--srv-gnm nnmaildir--cur-server)
               (nnmail-get-new-mail 'nnmaildir nil nil))))))
@@ -993,7 +997,7 @@ This variable is set by `nnmaildir-request-article'.")
         (curdir (nnmaildir--cur
                  (nnmaildir--srvgrp-dir
                   (nnmaildir--srv-dir nnmaildir--cur-server) gname)))
-        (curdir-mtime (nth 5 (file-attributes curdir)))
+        (curdir-mtime (file-attribute-modification-time (file-attributes 
curdir)))
         pgname flist always-marks never-marks old-marks dir
         all-marks marks ranges markdir read ls
         old-mmth new-mmth mtime existing missing deactivate-mark)
@@ -1046,7 +1050,7 @@ This variable is set by `nnmaildir-request-article'.")
          ;; a filename flag, get the later of the mtimes for markdir and
          ;; curdir, otherwise only the markdir counts.
          (setq mtime
-               (let ((markdir-mtime (nth 5 (file-attributes markdir))))
+               (let ((markdir-mtime (file-attribute-modification-time 
(file-attributes markdir))))
                  (cond
                   ((null (nnmaildir--mark-to-flag mark))
                    markdir-mtime)
@@ -1463,9 +1467,7 @@ This variable is set by `nnmaildir-request-article'.")
       (unless (string-equal nnmaildir--delivery-time file)
        (setq nnmaildir--delivery-time file
              nnmaildir--delivery-count 0))
-      (when (and (consp (cdr time))
-                (consp (cddr time)))
-       (setq file (concat file "M" (number-to-string (caddr time)))))
+      (setq file (concat file "M" (number-to-string (caddr time))))
       (setq file (concat file nnmaildir--delivery-pid)
            file (concat file "Q" (number-to-string nnmaildir--delivery-count))
            file (concat file "." (nnmaildir--system-name))
@@ -1601,7 +1603,7 @@ This variable is set by `nnmaildir-request-article'.")
             (nnmaildir--expired-article group article))
            ((and no-force
                  (progn
-                   (setq time (nth 5 time)
+                   (setq time (file-attribute-modification-time time)
                          bound-iter boundary)
                    (while (and bound-iter time
                                (= (car bound-iter) (car time)))
diff --git a/lisp/gnus/nnmh.el b/lisp/gnus/nnmh.el
index 33be64f..d0f8ec2 100644
--- a/lisp/gnus/nnmh.el
+++ b/lisp/gnus/nnmh.el
@@ -210,8 +210,10 @@ as unread by Gnus.")
        min rdir num subdirectoriesp file)
     ;; Recurse down directories.
     (setq subdirectoriesp
-         ;; nth 1 of file-attributes always 1 on MS Windows :(
-         (/= (nth 1 (file-attributes (file-truename dir))) 2))
+         ;; link number always 1 on MS Windows :(
+         (/= (file-attribute-link-number
+              (file-attributes (file-truename dir)))
+             2))
     (dolist (rdir files)
       (if (or (not subdirectoriesp)
              (file-regular-p rdir))
@@ -263,7 +265,8 @@ as unread by Gnus.")
 
     (while (and articles is-old)
       (setq article (concat dir (int-to-string (car articles))))
-      (when (setq mod-time (nth 5 (file-attributes article)))
+      (when (setq mod-time (file-attribute-modification-time
+                           (file-attributes article)))
        (if (and (nnmh-deletable-article-p newsgroup (car articles))
                 (setq is-old
                       (nnmail-expired-article-p newsgroup mod-time force)))
@@ -534,8 +537,8 @@ as unread by Gnus.")
          art)
       (while (setq art (pop arts))
        (when (not (equal
-                   (nth 5 (file-attributes
-                           (concat dir (int-to-string (car art)))))
+                   (file-attribute-modification-time
+                    (file-attributes (concat dir (int-to-string (car art)))))
                    (cdr art)))
          (setq articles (delq art articles))
          (push (car art) new))))
@@ -546,8 +549,9 @@ as unread by Gnus.")
                 (mapcar
                  (lambda (art)
                    (cons art
-                         (nth 5 (file-attributes
-                                 (concat dir (int-to-string art))))))
+                         (file-attribute-modification-time
+                          (file-attributes
+                           (concat dir (int-to-string art))))))
                  new)))
     ;; Make Gnus mark all new articles as unread.
     (when new
diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el
index 6307e13..e7a5b99 100644
--- a/lisp/gnus/nnml.el
+++ b/lisp/gnus/nnml.el
@@ -344,7 +344,8 @@ non-nil.")
     (while (and articles is-old)
       (if (and (setq article (nnml-article-to-file
                              (setq number (pop articles))))
-              (setq mod-time (nth 5 (file-attributes article)))
+              (setq mod-time (file-attribute-modification-time
+                              (file-attributes article)))
               (nnml-deletable-article-p group number)
               (setq is-old (nnmail-expired-article-p group mod-time force
                                                      nnml-inhibit-expiry)))
diff --git a/lisp/gnus/spam-stat.el b/lisp/gnus/spam-stat.el
index 9205295..3625132 100644
--- a/lisp/gnus/spam-stat.el
+++ b/lisp/gnus/spam-stat.el
@@ -77,13 +77,13 @@
 ;; Learn spam: (spam-stat-process-spam-directory "~/Mail/mail/spam")
 ;; Learn non-spam: (spam-stat-process-non-spam-directory "~/Mail/mail/misc")
 ;; Save table: (spam-stat-save)
-;; File size: (nth 7 (file-attributes spam-stat-file))
+;; File size: (file-attribute-size (file-attributes spam-stat-file))
 ;; Number of words: (hash-table-count spam-stat)
 ;; Test spam: (spam-stat-test-directory "~/Mail/mail/spam")
 ;; Test non-spam: (spam-stat-test-directory "~/Mail/mail/misc")
 ;; Reduce table size: (spam-stat-reduce-size)
 ;; Save table: (spam-stat-save)
-;; File size: (nth 7 (file-attributes spam-stat-file))
+;; File size: (file-attribute-size (file-attributes spam-stat-file))
 ;; Number of words: (hash-table-count spam-stat)
 ;; Test spam: (spam-stat-test-directory "~/Mail/mail/spam")
 ;; Test non-spam: (spam-stat-test-directory "~/Mail/mail/misc")
@@ -424,7 +424,8 @@ spam-stat (spam-stat-to-hash-table '(" spam-stat-ngood 
spam-stat-nbad))
          (insert ")))"))))
     (message "Saved %s."  spam-stat-file)
     (setq spam-stat-dirty nil
-          spam-stat-last-saved-at (nth 5 (file-attributes spam-stat-file)))))
+          spam-stat-last-saved-at (file-attribute-modification-time
+                                  (file-attributes spam-stat-file)))))
 
 (defun spam-stat-load ()
   "Read the `spam-stat' hash table from disk."
@@ -434,12 +435,14 @@ spam-stat (spam-stat-to-hash-table '(" spam-stat-ngood 
spam-stat-nbad))
           ((or (not (boundp 'spam-stat-last-saved-at))
                (null spam-stat-last-saved-at)
                (not (equal spam-stat-last-saved-at
-                           (nth 5 (file-attributes spam-stat-file)))))
+                           (file-attribute-modification-time
+                           (file-attributes spam-stat-file)))))
            (progn
              (load-file spam-stat-file)
              (setq spam-stat-dirty nil
                    spam-stat-last-saved-at
-                   (nth 5 (file-attributes spam-stat-file)))))
+                   (file-attribute-modification-time
+                   (file-attributes spam-stat-file)))))
           (t (message "Spam stat file not loaded: no change in disk.")))))
 
 (defun spam-stat-to-hash-table (entries)
@@ -561,8 +564,10 @@ check the variable `spam-stat-score-data'."
       (dolist (f files)
        (when (and (file-readable-p f)
                   (file-regular-p f)
-                   (> (nth 7 (file-attributes f)) 0)
-                  (< (time-to-number-of-days (time-since (nth 5 
(file-attributes f))))
+                   (> (file-attribute-size (file-attributes f)) 0)
+                  (< (time-to-number-of-days
+                      (time-since (file-attribute-modification-time
+                                   (file-attributes f))))
                      spam-stat-process-directory-age))
          (setq count (1+ count))
          (message "Reading %s: %.2f%%" dir (/ count max))
@@ -607,7 +612,7 @@ display non-spam files; otherwise display spam files."
       (dolist (f files)
        (when (and (file-readable-p f)
                   (file-regular-p f)
-                   (> (nth 7 (file-attributes f)) 0))
+                   (> (file-attribute-size (file-attributes f)) 0))
          (setq count (1+ count))
          (message "Reading %.2f%%, score %.2f"
                   (/ count max) (/ score count))
diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el
index d9949d2..32ec91d 100644
--- a/lisp/ibuf-ext.el
+++ b/lisp/ibuf-ext.el
@@ -1228,28 +1228,33 @@ If INCLUDE-PARENTS is non-nil then include parent 
modes."
 
 ;;;###autoload (autoload 'ibuffer-filter-by-mode "ibuf-ext")
 (define-ibuffer-filter mode
-  "Limit current view to buffers with major mode QUALIFIER."
+    "Limit current view to buffers with major mode(s) specified by QUALIFIER.
+QUALIFIER is the mode name as a symbol or a list of symbols.
+Called interactively, accept a comma separated list of mode names."
   (:description "major mode"
    :reader
    (let* ((buf (ibuffer-current-buffer))
           (default (if (and buf (buffer-live-p buf))
                        (symbol-name (buffer-local-value
                                      'major-mode buf)))))
-     (intern
-      (completing-read
+     (mapcar #'intern
+      (completing-read-multiple
        (if default
            (format "Filter by major mode (default %s): " default)
          "Filter by major mode: ")
        obarray
-       #'(lambda (e)
-           (string-match "-mode\\'" (symbol-name e)))
-       t nil nil default))))
+       (lambda (e)
+           (string-match "-mode\\'" (if (symbolp e) (symbol-name e) e)))
+       t nil nil default)))
+   :accept-list t)
   (eq qualifier (buffer-local-value 'major-mode buf)))
 
 ;;;###autoload (autoload 'ibuffer-filter-by-used-mode "ibuf-ext")
 (define-ibuffer-filter used-mode
-  "Limit current view to buffers with major mode QUALIFIER.
-Called interactively, this function allows selection of modes
+    "Limit current view to buffers with major mode(s) specified by QUALIFIER.
+QUALIFIER is the mode name as a symbol or a list of symbols.
+
+Called interactively, accept a comma separated list of mode names
 currently used by buffers."
   (:description "major mode in use"
    :reader
@@ -1257,23 +1262,29 @@ currently used by buffers."
           (default (if (and buf (buffer-live-p buf))
                        (symbol-name (buffer-local-value
                                      'major-mode buf)))))
-     (intern
-      (completing-read
+     (mapcar #'intern
+      (completing-read-multiple
        (if default
            (format "Filter by major mode (default %s): " default)
          "Filter by major mode: ")
-       (ibuffer-list-buffer-modes) nil t nil nil default))))
+       (ibuffer-list-buffer-modes) nil t nil nil default)))
+   :accept-list t)
   (eq qualifier (buffer-local-value 'major-mode buf)))
 
 ;;;###autoload (autoload 'ibuffer-filter-by-derived-mode "ibuf-ext")
 (define-ibuffer-filter derived-mode
-    "Limit current view to buffers whose major mode inherits from QUALIFIER."
+    "Limit current view to buffers with major mode(s) specified by QUALIFIER.
+QUALIFIER is the mode name as a symbol or a list of symbols.
+ Restrict the view to buffers whose major mode derivates
+ from modes specified by QUALIFIER.
+Called interactively, accept a comma separated list of mode names."
   (:description "derived mode"
-               :reader
-               (intern
-                (completing-read "Filter by derived mode: "
-                                 (ibuffer-list-buffer-modes t)
-                                  nil t)))
+        :reader
+        (mapcar #'intern
+         (completing-read-multiple "Filter by derived mode: "
+                       (ibuffer-list-buffer-modes t)
+                       nil t))
+        :accept-list t)
   (with-current-buffer buf (derived-mode-p qualifier)))
 
 ;;;###autoload (autoload 'ibuffer-filter-by-name "ibuf-ext")
diff --git a/lisp/ibuf-macs.el b/lisp/ibuf-macs.el
index 6a70a83..72a35a5 100644
--- a/lisp/ibuf-macs.el
+++ b/lisp/ibuf-macs.el
@@ -280,14 +280,18 @@ buffer object.
 
 ;;;###autoload
 (cl-defmacro define-ibuffer-filter (name documentation
-                                      (&key
-                                       reader
-                                       description)
-                                      &rest body)
+                                         (&key
+                                          reader
+                                          description
+                                          accept-list)
+                                         &rest body)
   "Define a filter named NAME.
 DOCUMENTATION is the documentation of the function.
 READER is a form which should read a qualifier from the user.
 DESCRIPTION is a short string describing the filter.
+ACCEPT-LIST is a boolean; if non-nil, the filter accepts either
+a single condition or a list of them; in the latter
+case the filter is the `or' composition of the conditions.
 
 BODY should contain forms which will be evaluated to test whether or
 not a particular buffer should be displayed or not.  The forms in BODY
@@ -296,30 +300,41 @@ bound to the current value of the filter.
 
 \(fn NAME DOCUMENTATION (&key READER DESCRIPTION) &rest BODY)"
   (declare (indent 2) (doc-string 2))
-  (let ((fn-name (intern (concat "ibuffer-filter-by-" (symbol-name name)))))
+  (let ((fn-name (intern (concat "ibuffer-filter-by-" (symbol-name name))))
+        (filter (make-symbol "ibuffer-filter"))
+        (qualifier-str (make-symbol "ibuffer-qualifier-str")))
     `(progn
        (defun ,fn-name (qualifier)
-        ,(or documentation "This filter is not documented.")
-        (interactive (list ,reader))
-        (if (null (ibuffer-push-filter (cons ',name qualifier)))
-            (message "%s"
-                     (format ,(concat (format "Filter by %s already applied: " 
description)
-                                      " %s")
-                             qualifier))
-           (message "%s"
-                   (format ,(concat (format "Filter by %s added: " description)
-                                    " %s")
-                           qualifier))
-          (ibuffer-update nil t)))
+     ,(or documentation "This filter is not documented.")
+     (interactive (list ,reader))
+     (let ((,filter (cons ',name qualifier))
+           (,qualifier-str qualifier))
+       ,(when accept-list
+          `(progn
+         (unless (listp qualifier) (setq qualifier (list qualifier)))
+         ;; Reject equivalent filters: (or f1 f2) is same as (or f2 f1).
+         (setq qualifier (sort (delete-dups qualifier) #'string-lessp))
+         (setq ,filter (cons ',name (car qualifier)))
+         (setq ,qualifier-str
+               (mapconcat (lambda (m) (if (symbolp m) (symbol-name m) m))
+                  qualifier ","))
+         (when (cdr qualifier) ; Compose individual filters with `or'.
+           (setq ,filter `(or ,@(mapcar (lambda (m) (cons ',name m)) 
qualifier))))))
+       (if (null (ibuffer-push-filter ,filter))
+           (message ,(format "Filter by %s already applied:  %%s" description)
+                ,qualifier-str)
+         (message ,(format "Filter by %s added:  %%s" description)
+              ,qualifier-str)
+         (ibuffer-update nil t))))
        (push (list ',name ,description
-                  (lambda (buf qualifier)
-                     (condition-case nil
-                         (progn ,@body)
-                       (error (ibuffer-pop-filter)
-                              (when (eq ',name 'predicate)
-                                (error "Wrong filter predicate: %S"
-                                       qualifier))))))
-            ibuffer-filtering-alist)
+           (lambda (buf qualifier)
+                  (condition-case nil
+                      (progn ,@body)
+                    (error (ibuffer-pop-filter)
+                           (when (eq ',name 'predicate)
+                             (error "Wrong filter predicate: %S"
+                                    qualifier))))))
+         ibuffer-filtering-alist)
        :autoload-end)))
 
 (provide 'ibuf-macs)
diff --git a/lisp/ido.el b/lisp/ido.el
index f9a9607..7bf4a92 100644
--- a/lisp/ido.el
+++ b/lisp/ido.el
@@ -1518,9 +1518,7 @@ Removes badly formatted data and ignored directories."
                             (consp time)
                             (cond
                              ((integerp (car time))
-                              (and (/= (car time) 0)
-                                   (integerp (car (cdr time)))
-                                   (/= (car (cdr time)) 0)
+                              (and (not (zerop (float-time time)))
                                    (ido-may-cache-directory dir)))
                              ((eq (car time) 'ftp)
                               (and (numberp (cdr time))
@@ -1750,7 +1748,8 @@ is enabled then some keybindings are changed in the 
keymap."
         (ido-final-slash dir)
         (not (ido-is-unc-host dir))
         (file-directory-p dir)
-        (> (nth 7 (file-attributes (file-truename dir))) 
ido-max-directory-size))))
+        (> (file-attribute-size (file-attributes (file-truename dir)))
+           ido-max-directory-size))))
 
 (defun ido-set-current-directory (dir &optional subdir no-merge)
   ;; Set ido's current directory to DIR or DIR/SUBDIR
@@ -3610,7 +3609,7 @@ Uses and updates `ido-dir-file-cache'."
             (ftp (ido-is-ftp-directory dir))
             (unc (ido-is-unc-host dir))
             (attr (if (or ftp unc) nil (file-attributes dir)))
-            (mtime (nth 5 attr))
+            (mtime (file-attribute-modification-time attr))
             valid)
        (when cached        ; should we use the cached entry ?
          (cond
diff --git a/lisp/image-dired.el b/lisp/image-dired.el
index 1acb319..17e566d 100644
--- a/lisp/image-dired.el
+++ b/lisp/image-dired.el
@@ -587,8 +587,9 @@ Create the thumbnails directory if it does not exist."
   (let* ((thumb-file (image-dired-thumb-name file))
         (thumb-attr (file-attributes thumb-file)))
     (when (or (not thumb-attr)
-             (time-less-p (nth 5 thumb-attr)
-                          (nth 5 (file-attributes file))))
+             (time-less-p (file-attribute-modification-time thumb-attr)
+                          (file-attribute-modification-time
+                           (file-attributes file))))
       (image-dired-create-thumb file thumb-file))
     (create-image thumb-file)
 ;;     (list 'image :type 'jpeg
@@ -752,7 +753,8 @@ Increase at own risk.")
   (let* ((width (int-to-string (image-dired-thumb-size 'width)))
          (height (int-to-string (image-dired-thumb-size 'height)))
         (modif-time (format-time-string
-                     "%s" (nth 5 (file-attributes original-file))))
+                     "%s" (file-attribute-modification-time
+                           (file-attributes original-file))))
          (thumbnail-nq8-file (replace-regexp-in-string ".png\\'" "-nq8.png"
                                                        thumbnail-file))
          (spec
@@ -2652,8 +2654,8 @@ tags to their respective image file.  Internal function 
used by
 ;;            (mapcar
 ;;             (lambda (f)
 ;;               (let ((fattribs (file-attributes f)))
-;;                 ;; Get last access time and file size
-;;                 `(,(nth 4 fattribs) ,(nth 7 fattribs) ,f)))
+;;                 `(,(file-attribute-access-time fattribs)
+;;                   ,(file-attribute-size fattribs) ,f)))
 ;;             (directory-files (image-dired-dir) t ".+\\.thumb\\..+$"))
 ;;            ;; Sort function. Compare time between two files.
 ;;            (lambda (l1 l2)
diff --git a/lisp/imenu.el b/lisp/imenu.el
index 7285b10..09d50da 100644
--- a/lisp/imenu.el
+++ b/lisp/imenu.el
@@ -96,11 +96,11 @@ This might not yet be honored by all index-building 
functions."
   :type 'boolean
   :group 'imenu)
 
-(defcustom imenu-auto-rescan-maxout 60000
-  "Imenu auto-rescan is disabled in buffers larger than this size (in bytes).
-This variable is buffer-local."
+(defcustom imenu-auto-rescan-maxout 600000
+  "Imenu auto-rescan is disabled in buffers larger than this size (in bytes)."
   :type 'integer
-  :group 'imenu)
+  :group 'imenu
+  :version "26.2")
 
 (defcustom imenu-use-popup-menu 'on-mouse
   "Use a popup menu rather than a minibuffer prompt.
diff --git a/lisp/info.el b/lisp/info.el
index ab2c51d..f2e2957 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -654,9 +654,11 @@ Do the right thing if the file has been compressed or 
zipped."
 
     ;; Clear the caches of modified Info files.
     (let* ((attribs-old (cdr (assoc fullname Info-file-attributes)))
-          (modtime-old (and attribs-old (nth 5 attribs-old)))
+          (modtime-old (and attribs-old
+                            (file-attribute-modification-time attribs-old)))
           (attribs-new (and (stringp fullname) (file-attributes fullname)))
-          (modtime-new (and attribs-new (nth 5 attribs-new))))
+          (modtime-new (and attribs-new
+                            (file-attribute-modification-time attribs-new))))
       (when (and modtime-old modtime-new
                 (time-less-p modtime-old modtime-new))
        (setq Info-index-nodes (remove (assoc (or Info-current-file filename)
diff --git a/lisp/leim/quail/latin-post.el b/lisp/leim/quail/latin-post.el
index 791152b..8b0253f 100644
--- a/lisp/leim/quail/latin-post.el
+++ b/lisp/leim/quail/latin-post.el
@@ -739,6 +739,54 @@ Doubling the postfix separates the letter and postfix: 
e.g. a\\='\\=' -> a\\='
  ("z~~" ["z~"])
  )
 
+;;; Hawaiian postfix input method.  It's a small subset of Latin-4
+;;; with the addition of an ʻokina mapping.  Hopefully the ʻokina shows
+;;; correctly on most displays.
+
+;;; This reference is an authoritative guide to Hawaiian orthography:
+;;; http://www2.hawaii.edu/~strauch/tips/HawaiianOrthography.html
+
+;;; Initial coding 2018-09-08 Bob Newell, Honolulu, Hawaiʻi
+;;; Comments to address@hidden
+
+(quail-define-package
+ "hawaiian-postfix" "Hawaiian Postfix" "H<" t
+ "Hawaiian characters input method with postfix modifiers
+
+             | postfix | examples
+ ------------+---------+----------
+  ʻokina     |    \\=`    | \\=` -> ʻ
+  kahakō     |    -    | a- -> ā
+
+Doubling the postfix separates the letter and postfix. a-- -> a-
+" nil t nil nil nil nil nil nil nil nil t)
+
+(quail-define-rules
+ ("A-" ?Ā)
+ ("E-" ?Ē)
+ ("I~" ?Ĩ)
+ ("O-" ?Ō)
+ ("U-" ?Ū)
+ ("a-" ?ā)
+ ("e-" ?ē)
+ ("i-" ?ī)
+ ("o-" ?ō)
+ ("u-" ?ū)
+ ("`" ?ʻ)
+
+ ("A--" ["A-"])
+ ("E--" ["E-"])
+ ("I--" ["I-"])
+ ("O--" ["O-"])
+ ("U--" ["U-"])
+ ("a--" ["a-"])
+ ("e--" ["e-"])
+ ("i--" ["i-"])
+ ("o--" ["o-"])
+ ("u--" ["u-"])
+ ("``"  ["`"])
+ )
+
 (quail-define-package
  "latin-5-postfix" "Latin-5" "5<" t
  "Latin-5 characters input method with postfix modifiers
diff --git a/lisp/leim/quail/latin-pre.el b/lisp/leim/quail/latin-pre.el
index ca5af94..9d343e7 100644
--- a/lisp/leim/quail/latin-pre.el
+++ b/lisp/leim/quail/latin-pre.el
@@ -1285,4 +1285,52 @@ of characters from a single Latin-N charset.
  ("~~" ?¸)
 )
 
+;;; Hawaiian prefix input method. It's a small subset of Latin-4
+;;; with the addition of an ʻokina mapping.  Hopefully the ʻokina shows
+;;; correctly on most displays.
+
+;;; This reference is an authoritative guide to Hawaiian orthography:
+;;; http://www2.hawaii.edu/~strauch/tips/HawaiianOrthography.html
+
+;;; Initial coding 2018-09-08 Bob Newell, Honolulu, Hawaiʻi
+;;; Comments to address@hidden
+
+(quail-define-package
+ "hawaiian-prefix" "Hawaiian Prefix" "H>" t
+ "Hawaiian characters input method with postfix modifiers
+
+             | prefix | examples
+ ------------+---------+----------
+  ʻokina     |    \\=`    | \\=` -> ʻ
+  kahakō     |    -    | -a -> ā
+
+Doubling the prefix separates the letter and prefix. --a -> -a
+" nil t nil nil nil nil nil nil nil nil t)
+
+(quail-define-rules
+ ("-A" ?Ā)
+ ("-E" ?Ē)
+ ("~I" ?Ĩ)
+ ("-O" ?Ō)
+ ("-U" ?Ū)
+ ("-a" ?ā)
+ ("-e" ?ē)
+ ("-i" ?ī)
+ ("-o" ?ō)
+ ("-u" ?ū)
+ ("`" ?ʻ)
+
+ ("--A" ["-A"])
+ ("--E" ["-E"])
+ ("--I" ["-I"])
+ ("--O" ["-O"])
+ ("--U" ["-U"])
+ ("--a" ["-a"])
+ ("--e" ["-e"])
+ ("--i" ["-i"])
+ ("--o" ["-o"])
+ ("--u" ["-u"])
+ ("``"  ["`"])
+ )
+
 ;;; latin-pre.el ends here
diff --git a/lisp/ls-lisp.el b/lisp/ls-lisp.el
index adb86dd..95f3163 100644
--- a/lisp/ls-lisp.el
+++ b/lisp/ls-lisp.el
@@ -385,13 +385,13 @@ not contain `d', so that a full listing is expected."
          ;; files we are about to display.
          (dolist (elt file-alist)
            (setq attr (cdr elt)
-                 fuid (nth 2 attr)
+                 fuid (file-attribute-user-id attr)
                  uid-len (if (stringp fuid) (string-width fuid)
                            (length (format "%d" fuid)))
-                 fgid (nth 3 attr)
+                 fgid (file-attribute-group-id attr)
                  gid-len (if (stringp fgid) (string-width fgid)
                            (length (format "%d" fgid)))
-                 file-size (nth 7 attr))
+                 file-size (file-attribute-size attr))
            (if (> uid-len max-uid-len)
                (setq max-uid-len uid-len))
            (if (> gid-len max-gid-len)
@@ -418,7 +418,7 @@ not contain `d', so that a full listing is expected."
                  files (cdr files)
                  short (car elt)
                  attr (cdr elt)
-                 file-size (nth 7 attr))
+                 file-size (file-attribute-size attr))
            (and attr
                 (setq sum (+ file-size
                              ;; Even if neither SUM nor file's size
@@ -474,7 +474,7 @@ not contain `d', so that a full listing is expected."
                   (if (memq ?F switches)
                       (ls-lisp-classify-file file fattr)
                     file)
-                  fattr (nth 7 fattr)
+                  fattr (file-attribute-size fattr)
                                  switches time-index))
        (message "%s: doesn't exist or is inaccessible" file)
        (ding) (sit-for 2)))))          ; to show user the message!
@@ -659,10 +659,9 @@ SWITCHES is a list of characters.  Default sorting is 
alphabetic."
                  (sort (copy-sequence file-alist) ; modifies its argument!
                        (cond ((memq ?S switches)
                               (lambda (x y) ; sorted on size
-                                ;; 7th file attribute is file size
                                 ;; Make largest file come first
-                                (< (nth 7 (cdr y))
-                                   (nth 7 (cdr x)))))
+                                (< (file-attribute-size (cdr y))
+                                   (file-attribute-size (cdr x)))))
                              ((setq index (ls-lisp-time-index switches))
                               (lambda (x y) ; sorted on time
                                 (time-less-p (nth index (cdr y))
@@ -719,8 +718,8 @@ FATTR is the file attributes returned by `file-attributes' 
for the file.
 The file type indicators are `/' for directories, `@' for symbolic
 links, `|' for FIFOs, `=' for sockets, `*' for regular files that
 are executable, and nothing for other types of files."
-  (let* ((type (car fattr))
-        (modestr (nth 8 fattr))
+  (let* ((type (file-attribute-type fattr))
+        (modestr (file-attribute-modes fattr))
         (typestr (substring modestr 0 1))
          (file-name (propertize filename 'dired-filename t)))
     (cond
@@ -773,35 +772,13 @@ FOLLOWED by null and full filename, SOLELY for full alpha 
sort."
   "Format one line of long ls output for file FILE-NAME.
 FILE-ATTR and FILE-SIZE give the file's attributes and size.
 SWITCHES and TIME-INDEX give the full switch list and time data."
-  (let ((file-type (nth 0 file-attr))
+  (let ((file-type (file-attribute-type file-attr))
        ;; t for directory, string (name linked to)
        ;; for symbolic link, or nil.
-       (drwxrwxrwx (nth 8 file-attr))) ; attribute string ("drwxrwxrwx")
+       (drwxrwxrwx (file-attribute-modes file-attr)))
     (concat (if (memq ?i switches)     ; inode number
-               (let ((inode (nth 10 file-attr)))
-                 (if (consp inode)
-                     (if (consp (cdr inode))
-                         ;; 2^(24+16) = 1099511627776.0, but
-                         ;; multiplying by it and then adding the
-                         ;; other members of the cons cell in one go
-                         ;; loses precision, since a double does not
-                         ;; have enough significant digits to hold a
-                         ;; full 64-bit value.  So below we split
-                         ;; 1099511627776 into high 13 and low 5
-                         ;; digits and compute in two parts.
-                         (let ((p1 (* (car inode) 10995116.0))
-                               (p2 (+ (* (car inode) 27776.0)
-                                      (* (cadr inode) 65536.0)
-                                      (cddr inode))))
-                           (format " %13.0f%05.0f "
-                                   ;; Use floor to emulate integer
-                                   ;; division.
-                                   (+ p1 (floor p2 100000.0))
-                                   (mod p2 100000.0)))
-                       (format " %18.0f "
-                               (+ (* (car inode) 65536.0)
-                                  (cdr inode))))
-                   (format " %18d " inode))))
+               (let ((inode (file-attribute-inode-number file-attr)))
+                 (format " %18d " inode)))
            ;; nil is treated like "" in concat
            (if (memq ?s switches)      ; size in K, rounded up
                ;; In GNU ls, -h affects the size in blocks, displayed
@@ -819,14 +796,14 @@ SWITCHES and TIME-INDEX give the full switch list and 
time data."
                          (fceiling (/ file-size 1024.0)))))
            drwxrwxrwx                  ; attribute string
            (if (memq 'links ls-lisp-verbosity)
-               (format "%3d" (nth 1 file-attr))) ; link count
+               (format "%3d" (file-attribute-link-number file-attr)))
            ;; Numeric uid/gid are more confusing than helpful;
            ;; Emacs should be able to make strings of them.
            ;; They tend to be bogus on non-UNIX platforms anyway so
            ;; optionally hide them.
            (if (memq 'uid ls-lisp-verbosity)
                ;; uid can be a string or an integer
-               (let ((uid (nth 2 file-attr)))
+               (let ((uid (file-attribute-user-id file-attr)))
                   (format (if (stringp uid)
                              ls-lisp-uid-s-fmt
                            ls-lisp-uid-d-fmt)
@@ -834,7 +811,7 @@ SWITCHES and TIME-INDEX give the full switch list and time 
data."
            (if (not (memq ?G switches)) ; GNU ls -- shows group by default
                (if (or (memq ?g switches) ; UNIX ls -- no group by default
                        (memq 'gid ls-lisp-verbosity))
-                    (let ((gid (nth 3 file-attr)))
+                    (let ((gid (file-attribute-group-id file-attr)))
                       (format (if (stringp gid)
                                  ls-lisp-gid-s-fmt
                                ls-lisp-gid-d-fmt)
diff --git a/lisp/mail/blessmail.el b/lisp/mail/blessmail.el
index 8261f17..62e9873 100644
--- a/lisp/mail/blessmail.el
+++ b/lisp/mail/blessmail.el
@@ -49,15 +49,15 @@
   (setq attr (file-attributes dirname))
   (if (not (eq t (car attr)))
       (insert (format "echo %s is not a directory\n" rmail-spool-directory))
-    (setq modes (nth 8 attr))
+    (setq modes (file-attribute-modes attr))
     (cond ((= ?w (aref modes 8))
           ;; Nothing needs to be done.
           )
          ((= ?w (aref modes 5))
-          (insert "chgrp " (number-to-string (nth 3 attr))
+          (insert "chgrp " (number-to-string (file-attribute-group-id attr))
                   " $* && chmod g+s $*\n"))
          ((= ?w (aref modes 2))
-          (insert "chown " (number-to-string (nth 2 attr))
+          (insert "chown " (number-to-string (file-attribute-user-id attr))
                   " $* && chmod u+s $*\n"))
          (t
           (insert "chown root $* && chmod u+s $*\n"))))
diff --git a/lisp/mail/feedmail.el b/lisp/mail/feedmail.el
index 6093aec..2b63343 100644
--- a/lisp/mail/feedmail.el
+++ b/lisp/mail/feedmail.el
@@ -1,5 +1,6 @@
-;;; feedmail.el --- assist other email packages to massage outgoing messages
-;;; This file is in the public domain.
+;;; feedmail.el --- assist other email packages to massage outgoing messages  
-*- lexical-binding:t -*-
+
+;; This file is in the public domain.
 
 ;; This file is part of GNU Emacs.
 
@@ -1312,25 +1313,21 @@ There's no trivial way to avoid it.  It's unwise to 
just set the value
 of `buffer-file-name' to nil because that will defeat feedmail's file
 management features.  Instead, arrange for this variable to be set to
 the value of `buffer-file-name' before setting that to nil.  An easy way
-to do that would be with defadvice on `mail-send' \(undoing the
-assignments in a later advice).
+to do that would be with an advice on `mail-send'.
 
 feedmail will pretend that `buffer-file-name', if nil, has the value
 assigned of `feedmail-queue-buffer-file-name' and carry out its normal
 activities.  feedmail does not restore the non-nil value of
-`buffer-file-name'.  For safe bookkeeping, the user should insure that
+`buffer-file-name'.  For safe bookkeeping, the user should ensure that
 feedmail-queue-buffer-file-name is restored to nil.
 
-Example `defadvice' for mail-send:
-
-   (defadvice mail-send (before feedmail-mail-send-before-advice activate)
-     (setq feedmail-queue-buffer-file-name buffer-file-name)
-     (setq buffer-file-name nil))
+Example advice for mail-send:
 
-   (defadvice mail-send (after feedmail-mail-send-after-advice activate)
-     (if feedmail-queue-buffer-file-name (setq buffer-file-name 
feedmail-queue-buffer-file-name))
-     (setq feedmail-queue-buffer-file-name nil))
-")
+    (advice-add 'mail-send :around #'my-feedmail-mail-send-advice)
+    (defun my-feedmail-mail-send-advice (orig-fun &rest args)
+      (let ((feedmail-queue-buffer-file-name buffer-file-name)
+             (buffer-file-name nil))
+        (apply orig-fun args)))")
 
 ;; defvars to make byte-compiler happy(er)
 (defvar feedmail-error-buffer        nil)
@@ -1438,7 +1435,7 @@ internal buffers will be reused and things will get 
confused."
   )
 
 (defcustom feedmail-queue-runner-mode-setter
-  (lambda (&optional arg) (mail-mode))
+  (lambda (&optional _) (mail-mode))
   "A function to set the proper mode of a message file.
 Called when the message is read back out of the queue directory with a single
 argument, the optional argument used in the call to
@@ -1474,7 +1471,10 @@ set `mail-header-separator' to the value of
 
 
 (defcustom feedmail-queue-runner-message-sender
-  (lambda (&optional arg) (mail-send))
+  (lambda (&optional _)
+    ;; `mail-send' is not autoloaded, which is why we need the `require'.
+    (require 'sendmail) (declare-function mail-send "sendmail")
+    (mail-send))
   "Function to initiate sending a message file.
 Called for each message read back out of the queue directory with a
 single argument, the optional argument used in the call to
@@ -1737,7 +1737,7 @@ insertion.")
 
 (declare-function vm-mail "ext:vm" (&optional to subject))
 
-(defun feedmail-vm-mail-mode (&optional arg)
+(defun feedmail-vm-mail-mode (&optional _)
   "Make something like a buffer that has been created via `vm-mail'.
 The optional argument is ignored and is just for argument compatibility with
 `feedmail-queue-runner-mode-setter'.  This function is suitable for being
@@ -1745,9 +1745,7 @@ applied to a file after you've just read it from disk: 
for example, a
 feedmail FQM message file from a queue.  You could use something like
 this:
 
-\(setq auto-mode-alist
-      (cons \\='(\"\\\\.fqm$\" . feedmail-vm-mail-mode) auto-mode-alist))
-"
+    (add-to-list 'auto-mode-alist \\='(\"\\\\.fqm\\\\\\='\" . 
feedmail-vm-mail-mode))"
   (feedmail-say-debug ">in-> feedmail-vm-mail-mode")
   (let ((the-buf (current-buffer)))
     (vm-mail)
@@ -2150,19 +2148,8 @@ you can set `feedmail-queue-reminder-alist' to nil."
    feedmail-prompt-before-queue-user-alist
    ))
 
-(defun feedmail-queue-runner-prompt ()
-  "Ask whether to queue, send immediately, or return to editing a message, 
etc."
-  (feedmail-say-debug ">in-> feedmail-queue-runner-prompt")
-  (feedmail-queue-send-edit-prompt-inner
-   feedmail-ask-before-queue-default
-   feedmail-ask-before-queue-prompt
-   feedmail-ask-before-queue-reprompt
-   'feedmail-message-action-help
-   feedmail-prompt-before-queue-standard-alist
-   feedmail-prompt-before-queue-user-alist
-   ))
 (defun feedmail-queue-send-edit-prompt-inner (default prompt reprompt helper
-                                              standard-alist user-alist)
+                                             standard-alist user-alist)
   (feedmail-say-debug ">in-> feedmail-queue-send-edit-prompt-inner")
   ;; Some implementation ideas here came from the userlock.el code
   (or defining-kbd-macro (discard-input))
@@ -2181,6 +2168,8 @@ you can set `feedmail-queue-reminder-alist' to nil."
               (let ((inhibit-quit t) (cursor-in-echo-area t) (echo-keystrokes 
0))
                 (read-char-exclusive))))
          (if (= user-sez help-char)
+              ;; FIXME: This seems to want to refer to the `helper' argument,
+              ;; but it's quoted so the `helper' arg ends up unused!
              (setq answer '(^ . helper))
            (if (or (eq user-sez ?\C-m) (eq user-sez ?\C-j) (eq user-sez ?y))
                (setq user-sez d-char))
@@ -2209,7 +2198,7 @@ you can set `feedmail-queue-reminder-alist' to nil."
   ;; emacs convention is that scroll-up moves text up, window down
   (feedmail-say-debug ">in-> feedmail-scroll-buffer %s" direction)
   (save-selected-window
-    (let ((signal-error-on-buffer-boundary nil)
+    (let ((signal-error-on-buffer-boundary nil) ;FIXME: Unknown var!?
          (fqm-window (display-buffer (if buffy buffy (current-buffer)))))
       (select-window fqm-window)
       (if (eq direction 'up)
@@ -2697,8 +2686,10 @@ fiddle-plex, as described in the documentation for the 
variable
   (save-excursion
     (if feedmail-enable-spray
        (mapcar
-        (lambda (feedmail-spray-this-address)
-           (let ((spray-buffer (get-buffer-create " *FQM Outgoing Email 
Spray*")))
+        (lambda (address)
+          (let ((feedmail-spray-this-address address)
+                 (spray-buffer
+                  (get-buffer-create " *FQM Outgoing Email Spray*")))
              (with-current-buffer spray-buffer
                (erase-buffer)
                ;; not life's most efficient methodology, but spraying isn't
@@ -2712,7 +2703,8 @@ fiddle-plex, as described in the documentation for the 
variable
                ;; Message-Id:s, but I doubt that anyone cares,
                ;; practically.  If someone complains about it, I'll
                ;; add it.
-               (feedmail-fiddle-list-of-spray-fiddle-plexes 
feedmail-spray-address-fiddle-plex-list)
+               (feedmail-fiddle-list-of-spray-fiddle-plexes
+                 feedmail-spray-address-fiddle-plex-list)
                ;; this (let ) is just in case some buffer eater
                ;; is cheating and using the global variable name instead
                ;; of its argument to find the buffer
@@ -2823,16 +2815,13 @@ return that value."
 (defun feedmail-default-date-generator (maybe-file)
   "Default function for generating Date: header contents."
   (feedmail-say-debug ">in-> feedmail-default-date-generator")
-  (when maybe-file
-    (feedmail-say-debug (concat "4 cre " (feedmail-rfc822-date (nth 4 
(file-attributes maybe-file)))))
-    (feedmail-say-debug (concat "5 mod " (feedmail-rfc822-date (nth 5 
(file-attributes maybe-file)))))
-    (feedmail-say-debug (concat "6 sta " (feedmail-rfc822-date (nth 6 
(file-attributes maybe-file))))))
-  (let ((date-time))
-    (if (and (not feedmail-queue-use-send-time-for-date) maybe-file)
-       (setq date-time (nth 5 (file-attributes maybe-file))))
-    (feedmail-rfc822-date date-time))
-  )
-
+  (let ((attr (and maybe-file (file-attributes maybe-file))))
+    (when attr
+      (feedmail-say-debug (concat "4 cre " (feedmail-rfc822-date 
(file-attribute-access-time attr))))
+      (feedmail-say-debug (concat "5 mod " (feedmail-rfc822-date 
(file-attribute-modification-time attr))))
+      (feedmail-say-debug (concat "6 sta " (feedmail-rfc822-date 
(file-attribute-status-change-time attr)))))
+    (feedmail-rfc822-date (and attr (not feedmail-queue-use-send-time-for-date)
+                              (file-attribute-modification-time attr)))))
 
 (defun feedmail-fiddle-date (maybe-file)
   "Fiddle Date:.  See documentation of `feedmail-date-generator'."
@@ -2882,7 +2871,8 @@ probably not appropriate for you."
              (concat (if (equal (match-beginning 1) (match-end 1)) "" "-") 
end-stuff))
       (setq end-stuff (concat "@" end-stuff)))
     (if (and (not feedmail-queue-use-send-time-for-message-id) maybe-file)
-       (setq date-time (nth 5 (file-attributes maybe-file))))
+       (setq date-time (file-attribute-modification-time
+                        (file-attributes maybe-file))))
     (format "<%d-%s%s%s>"
            (mod (random) 10000)
            (format-time-string "%a%d%b%Y%H%M%S" date-time)
@@ -3147,13 +3137,17 @@ been weeded out."
     (identity address-list)))
 
 
-(defun feedmail-one-last-look (feedmail-prepped-text-buffer)
+(defun feedmail-one-last-look (buffer)
   "Offer the user one last chance to give it up."
   (feedmail-say-debug ">in-> feedmail-one-last-look")
   (save-excursion
+    ;; FIXME: switch-to-buffer may fail or pop up a new frame
+    ;; (in minibuffer-only frames, for example) and save-window-excursion
+    ;; won't delete the newly created frame upon exit!
     (save-window-excursion
-      (switch-to-buffer feedmail-prepped-text-buffer)
-      (if (and (fboundp 'y-or-n-p-with-timeout) (numberp 
feedmail-confirm-outgoing-timeout))
+      (switch-to-buffer buffer)
+      (if (and (fboundp 'y-or-n-p-with-timeout)
+               (numberp feedmail-confirm-outgoing-timeout))
          (y-or-n-p-with-timeout
           "FQM: Send this email? "
           (abs feedmail-confirm-outgoing-timeout)
diff --git a/lisp/mail/mailabbrev.el b/lisp/mail/mailabbrev.el
index 0ce1a3b..e5456d9 100644
--- a/lisp/mail/mailabbrev.el
+++ b/lisp/mail/mailabbrev.el
@@ -163,7 +163,8 @@ no aliases, which is represented by this being a table with 
no entries.)")
 (defun mail-abbrevs-sync-aliases ()
   (when mail-personal-alias-file
     (if (file-exists-p mail-personal-alias-file)
-       (let ((modtime (nth 5 (file-attributes mail-personal-alias-file))))
+       (let ((modtime (file-attribute-modification-time
+                       (file-attributes mail-personal-alias-file))))
          (if (not (equal mail-abbrev-modtime modtime))
              (progn
                (setq mail-abbrev-modtime modtime)
@@ -176,7 +177,8 @@ no aliases, which is represented by this being a table with 
no entries.)")
           (file-exists-p mail-personal-alias-file))
       (progn
        (setq mail-abbrev-modtime
-             (nth 5 (file-attributes mail-personal-alias-file)))
+             (file-attribute-modification-time
+              (file-attributes mail-personal-alias-file)))
        (build-mail-abbrevs)))
   (mail-abbrevs-sync-aliases)
   (add-function :around (local 'abbrev-expand-function)
diff --git a/lisp/mail/mspools.el b/lisp/mail/mspools.el
index aa91f36..2e8765e 100644
--- a/lisp/mail/mspools.el
+++ b/lisp/mail/mspools.el
@@ -387,7 +387,7 @@ nil."
   (let ((file (concat mspools-folder-directory spool))
        size)
     (setq file (or (file-symlink-p file) file))
-    (setq size (nth 7 (file-attributes file)))
+    (setq size (file-attribute-size (file-attributes file)))
     ;; size could be nil if the sym-link points to a non-existent file
     ;; so check this first.
     (if (and size  (> size 0))
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index 9416d04..73a17ee 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -2028,10 +2028,10 @@ Value is the size of the newly read mail after 
conversion."
                          "the remote server"
                        proto)))
            ((and (file-exists-p tofile)
-                 (/= 0 (nth 7 (file-attributes tofile))))
+                 (/= 0 (file-attribute-size (file-attributes tofile))))
             (message "Getting mail from %s..." tofile))
            ((and (file-exists-p file)
-                 (/= 0 (nth 7 (file-attributes file))))
+                 (/= 0 (file-attribute-size (file-attributes file))))
             (message "Getting mail from %s..." file)))
       ;; Set TOFILE if have not already done so, and
       ;; rename or copy the file FILE to TOFILE if and as appropriate.
diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el
index 50dd810..6fc91a3 100644
--- a/lisp/mail/sendmail.el
+++ b/lisp/mail/sendmail.el
@@ -561,7 +561,8 @@ This also saves the value of `send-mail-function' via 
Customize."
 
 (defun sendmail-sync-aliases ()
   (when mail-personal-alias-file
-    (let ((modtime (nth 5 (file-attributes mail-personal-alias-file))))
+    (let ((modtime (file-attribute-modification-time
+                   (file-attributes mail-personal-alias-file))))
       (or (equal mail-alias-modtime modtime)
          (setq mail-alias-modtime modtime
                mail-aliases t)))))
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index 20d5ad9..7f36988 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -300,7 +300,7 @@
       menu-bar-separator)
 
     (bindings--define-key menu [tags-continue]
-      '(menu-item "Continue Tags Search" tags-loop-continue
+      '(menu-item "Continue Tags Search" multifile-continue
                   :help "Continue last tags search operation"))
     (bindings--define-key menu [tags-srch]
       '(menu-item "Search Tagged Files..." tags-search
@@ -349,7 +349,7 @@
 (defvar menu-bar-replace-menu
   (let ((menu (make-sparse-keymap "Replace")))
     (bindings--define-key menu [tags-repl-continue]
-      '(menu-item "Continue Replace" tags-loop-continue
+      '(menu-item "Continue Replace" multifile-continue
                   :help "Continue last tags replace operation"))
     (bindings--define-key menu [tags-repl]
       '(menu-item "Replace in Tagged Files..." tags-query-replace
@@ -689,7 +689,7 @@ The selected font will be the default on both the existing 
and future frames."
                   debug-on-quit debug-on-error
                   ;; Somehow this works, when tool-bar and menu-bar don't.
                   tooltip-mode window-divider-mode
-                  save-place uniquify-buffer-name-style fringe-mode
+                  save-place-mode uniquify-buffer-name-style fringe-mode
                   indicate-empty-lines indicate-buffer-boundaries
                   case-fold-search font-use-system-font
                   current-language-environment default-input-method
@@ -1409,7 +1409,7 @@ mail status in mode line"))
 
     (bindings--define-key menu [save-place]
       (menu-bar-make-toggle
-       toggle-save-place-globally save-place
+       toggle-save-place-globally save-place-mode
        "Save Place in Files between Sessions"
        "Saving place in files %s"
        "Visit files of previous session when restarting Emacs"
@@ -1417,7 +1417,7 @@ mail status in mode line"))
        ;; Do it by name, to avoid a free-variable
        ;; warning during byte compilation.
        (set-default
-       'save-place (not (symbol-value 'save-place)))))
+       'save-place-mode (not (symbol-value 'save-place-mode)))))
 
     (bindings--define-key menu [uniquify]
       (menu-bar-make-toggle
diff --git a/lisp/mh-e/mh-alias.el b/lisp/mh-e/mh-alias.el
index fa91042..257d6b3 100644
--- a/lisp/mh-e/mh-alias.el
+++ b/lisp/mh-e/mh-alias.el
@@ -78,7 +78,8 @@ If ARG is non-nil, set timestamp with the current time."
                     (function
                      (lambda (file)
                        (when (and file (file-exists-p file))
-                         (setq stamp (nth 5 (file-attributes file)))
+                         (setq stamp (file-attribute-modification-time
+                                     (file-attributes file)))
                          (or (> (car stamp) (car mh-alias-tstamp))
                              (and (= (car stamp) (car mh-alias-tstamp))
                                   (> (cadr stamp) (cadr mh-alias-tstamp)))))))
diff --git a/lisp/mouse.el b/lisp/mouse.el
index d5c132f..cb63ca5 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -327,7 +327,7 @@ This command must be bound to a mouse click."
 (define-obsolete-function-alias 'mouse-tear-off-window 'tear-off-window "24.4")
 (defun tear-off-window (click)
   "Delete the selected window, and create a new frame displaying its buffer."
-  (interactive "e")
+  (interactive (list last-nonmenu-event))
   (mouse-minibuffer-check click)
   (let* ((window (posn-window (event-start click)))
         (buf (window-buffer window))
diff --git a/lisp/multifile.el b/lisp/multifile.el
new file mode 100644
index 0000000..712da5c
--- /dev/null
+++ b/lisp/multifile.el
@@ -0,0 +1,217 @@
+;;; multifile.el --- Operations on multiple files  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018  Free Software Foundation, Inc.
+
+;; Author: Stefan Monnier <address@hidden>
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Support functions for operations like search or query&replace applied to
+;; several files.  This code was largely inspired&extracted from an earlier
+;; version of etags.el.
+
+;; TODO:
+;; - Maybe it would make sense to replace the multifile--* vars with a single
+;;   global var holding a struct, and then stash those structs into a history
+;;   of past operations, so you can perform a multifile-search while in the
+;;   middle of a multifile-replace and later go back to that
+;;   multifile-replace.
+;; - Make multi-isearch work on top of this library (might require changes
+;;   to this library, of course).
+
+;;; Code:
+
+(require 'generator)
+
+(defgroup multifile nil
+  "Operations on multiple files."
+  :group 'tools)
+
+(defcustom multifile-revert-buffers 'silent
+  "Whether to revert files during multifile operation.
+  `silent' means to only do it if `revert-without-query' is applicable;
+  t        means to offer to do it for all applicable files;
+  nil      means never to do it"
+  :type '(choice (const silent) (const t) (const nil)))
+
+;; FIXME: This already exists in GNU ELPA's iterator.el.  Maybe it should move
+;; to generator.el?
+(iter-defun multifile--list-to-iterator (list)
+  (while list (iter-yield (pop list))))
+
+(defvar multifile--iterator iter-empty)
+(defvar multifile--scan-function
+  (lambda () (user-error "No operation in progress")))
+(defvar multifile--operate-function #'ignore)
+(defvar multifile--freshly-initialized nil)
+
+;;;###autoload
+(defun multifile-initialize (files scan-function operate-function)
+  "Initialize a new round of operation on several files.
+FILES can be either a list of file names, or an iterator (used with 
`iter-next')
+which returns a file name at each step.
+SCAN-FUNCTION is a function called with no argument inside a buffer
+and it should return non-nil if that buffer has something on which to operate.
+OPERATE-FUNCTION is a function called with no argument; it is expected
+to perform the operation on the current file buffer and when done
+should return non-nil to mean that we should immediately continue
+operating on the next file and nil otherwise."
+  (setq multifile--iterator
+        (if (and (listp files) (not (functionp files)))
+            (multifile--list-to-iterator files)
+          files))
+  (setq multifile--scan-function scan-function)
+  (setq multifile--operate-function operate-function)
+  (setq multifile--freshly-initialized t))
+
+(defun multifile-next-file (&optional novisit)
+  ;; FIXME: Should we provide an interactive command, like tags-next-file?
+  (let ((next (condition-case nil
+                  (iter-next multifile--iterator)
+                (iter-end-of-sequence nil))))
+    (unless next
+      (and novisit
+          (get-buffer " *next-file*")
+          (kill-buffer " *next-file*"))
+      (user-error "All files processed"))
+    (let* ((buffer (get-file-buffer next))
+          (new (not buffer)))
+      ;; Optionally offer to revert buffers
+      ;; if the files have changed on disk.
+      (and buffer multifile-revert-buffers
+          (not (verify-visited-file-modtime buffer))
+           (if (eq multifile-revert-buffers 'silent)
+               (and (not (buffer-modified-p buffer))
+                    (let ((revertible nil))
+                      (dolist (re revert-without-query)
+                        (when (string-match-p re next)
+                          (setq revertible t)))
+                      revertible))
+            (y-or-n-p
+             (format
+              (if (buffer-modified-p buffer)
+                  "File %s changed on disk.  Discard your edits? "
+                "File %s changed on disk.  Reread from disk? ")
+              next)))
+          (with-current-buffer buffer
+            (revert-buffer t t)))
+      (if (not (and new novisit))
+         (set-buffer (find-file-noselect next))
+        ;; Like find-file, but avoids random warning messages.
+        (set-buffer (get-buffer-create " *next-file*"))
+        (kill-all-local-variables)
+        (erase-buffer)
+        (setq new next)
+        (insert-file-contents new nil))
+      new)))
+
+(defun multifile-continue ()
+  "Continue last multi-file operation."
+  (interactive)
+  (let (new
+       ;; Non-nil means we have finished one file
+       ;; and should not scan it again.
+       file-finished
+       original-point
+       (messaged nil))
+    (while
+       (progn
+         ;; Scan files quickly for the first or next interesting one.
+         ;; This starts at point in the current buffer.
+         (while (or multifile--freshly-initialized file-finished
+                    (save-restriction
+                      (widen)
+                      (not (funcall multifile--scan-function))))
+           ;; If nothing was found in the previous file, and
+           ;; that file isn't in a temp buffer, restore point to
+           ;; where it was.
+           (when original-point
+             (goto-char original-point))
+
+           (setq file-finished nil)
+           (setq new (multifile-next-file t))
+
+           ;; If NEW is non-nil, we got a temp buffer,
+           ;; and NEW is the file name.
+           (when (or messaged
+                     (and (not multifile--freshly-initialized)
+                          (> baud-rate search-slow-speed)
+                          (setq messaged t)))
+             (message "Scanning file %s..." (or new buffer-file-name)))
+
+           (setq multifile--freshly-initialized nil)
+           (setq original-point (if new nil (point)))
+           (goto-char (point-min)))
+
+         ;; If we visited it in a temp buffer, visit it now for real.
+         (if new
+             (let ((pos (point)))
+               (erase-buffer)
+               (set-buffer (find-file-noselect new))
+               (setq new nil)          ;No longer in a temp buffer.
+               (widen)
+               (goto-char pos))
+           (push-mark original-point t))
+
+         (switch-to-buffer (current-buffer))
+
+         ;; Now operate on the file.
+         ;; If value is non-nil, continue to scan the next file.
+          (save-restriction
+            (widen)
+            (funcall multifile--operate-function)))
+      (setq file-finished t))))
+
+;;;###autoload
+(defun multifile-initialize-search (regexp files case-fold)
+  (let ((last-buffer (current-buffer)))
+    (multifile-initialize
+     files
+     (lambda ()
+       (let ((case-fold-search
+              (if (memq case-fold '(t nil)) case-fold case-fold-search)))
+         (re-search-forward regexp nil t)))
+     (lambda ()
+       (unless (eq last-buffer (current-buffer))
+         (setq last-buffer (current-buffer))
+         (message "Scanning file %s...found" buffer-file-name))
+       nil))))
+
+;;;###autoload
+(defun multifile-initialize-replace (from to files case-fold &optional 
delimited)
+  "Initialize a new round of query&replace on several files.
+FROM is a regexp and TO is the replacement to use.
+FILES describes the file, as in `multifile-initialize'.
+CASE-FOLD can be t, nil, or `default', the latter one meaning to obey
+the default setting of `case-fold-search'.
+DELIMITED if non-nil means replace only word-delimited matches."
+  ;; FIXME: Not sure how the delimited-flag interacts with the regexp-flag in
+  ;; `perform-replace', so I just try to mimic the old code.
+  (multifile-initialize
+   files
+   (lambda ()
+     (let ((case-fold-search
+            (if (memql case-fold '(nil t)) case-fold case-fold-search)))
+       (if (re-search-forward from nil t)
+          ;; When we find a match, move back
+          ;; to the beginning of it so perform-replace
+          ;; will see it.
+          (goto-char (match-beginning 0)))))
+   (lambda ()
+     (perform-replace from to t t delimited nil multi-query-replace-map))))
+
+(provide 'multifile)
+;;; multifile.el ends here
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index 2fc7ac2..1aa7944 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -1361,11 +1361,13 @@ only return the directory part of FILE."
                  (ange-ftp-real-expand-file-name ange-ftp-netrc-filename)))
       (setq attr (ange-ftp-real-file-attributes file)))
     (if (and attr                      ; file exists.
-            (not (equal (nth 5 attr) ange-ftp-netrc-modtime))) ; file changed
+            (not (equal (file-attribute-modification-time attr)
+                        ange-ftp-netrc-modtime)))      ; file changed
        (save-match-data
          (if (or ange-ftp-disable-netrc-security-check
-                 (and (eq (nth 2 attr) (user-uid)) ; Same uids.
-                      (string-match ".r..------" (nth 8 attr))))
+                 (and (eq (file-attribute-user-id attr) (user-uid)) ; Same 
uids.
+                      (string-match ".r..------"
+                                    (file-attribute-modes attr))))
              (with-current-buffer
                ;; we are cheating a bit here.  I'm trying to do the equivalent
                ;; of find-file on the .netrc file, but then nuke it afterwards.
@@ -1389,7 +1391,8 @@ only return the directory part of FILE."
            (ange-ftp-message "%s either not owned by you or badly protected."
                              ange-ftp-netrc-filename)
            (sit-for 1))
-         (setq ange-ftp-netrc-modtime (nth 5 attr))))))
+         (setq ange-ftp-netrc-modtime
+               (file-attribute-modification-time attr))))))
 
 ;; Return a list of prefixes of the form 'address@hidden:' to be used when
 ;; completion is done in the root directory.
@@ -3242,7 +3245,8 @@ system TYPE.")
                ;; tell the process filter what size the transfer will be.
                (let ((attr (file-attributes temp)))
                  (if attr
-                     (ange-ftp-set-xfer-size host user (nth 7 attr))))
+                     (ange-ftp-set-xfer-size host user
+                                             (file-attribute-size attr))))
 
                ;; put or append the file.
                (let ((result (ange-ftp-send-cmd host user
@@ -3481,8 +3485,8 @@ system TYPE.")
   (let ((f1-parsed (ange-ftp-ftp-name f1))
         (f2-parsed (ange-ftp-ftp-name f2)))
     (if (or f1-parsed f2-parsed)
-        (let ((f1-mt (nth 5 (file-attributes f1)))
-              (f2-mt (nth 5 (file-attributes f2))))
+        (let ((f1-mt (file-attribute-modification-time (file-attributes f1)))
+              (f2-mt (file-attribute-modification-time (file-attributes f2))))
           (cond ((null f1-mt) nil)
                 ((null f2-mt) t)
                (t (time-less-p f2-mt f1-mt))))
@@ -3782,7 +3786,8 @@ so return the size on the remote host exactly. See RFC 
3659."
            ;; tell the process filter what size the file is.
            (let ((attr (file-attributes (or temp2 filename))))
              (if attr
-                 (ange-ftp-set-xfer-size t-host t-user (nth 7 attr))))
+                 (ange-ftp-set-xfer-size t-host t-user
+                                         (file-attribute-size attr))))
 
            (ange-ftp-send-cmd
             t-host
diff --git a/lisp/net/dbus.el b/lisp/net/dbus.el
index 2d9660d..4397817 100644
--- a/lisp/net/dbus.el
+++ b/lisp/net/dbus.el
@@ -1798,10 +1798,11 @@ GTK+.  It should be used with care for at least the 
`:system' and
 this connection to those buses."
   (or (featurep 'dbusbind)
       (signal 'dbus-error (list "Emacs not compiled with dbus support")))
-  (dbus--init-bus bus private)
-  (dbus-register-signal
-   bus nil dbus-path-local dbus-interface-local
-   "Disconnected" #'dbus-handle-bus-disconnect))
+  (prog1
+      (dbus--init-bus bus private)
+    (dbus-register-signal
+     bus nil dbus-path-local dbus-interface-local
+     "Disconnected" #'dbus-handle-bus-disconnect)))
 
  
 ;; Initialize `:system' and `:session' buses.  This adds their file
diff --git a/lisp/net/eudcb-mab.el b/lisp/net/eudcb-mab.el
index a213484..a69c77b 100644
--- a/lisp/net/eudcb-mab.el
+++ b/lisp/net/eudcb-mab.el
@@ -53,7 +53,8 @@ RETURN-ATTRS is a list of attributes to return, defaulting to
 
   (let ((fmt-string "%ln:%fn:%p:%e")
        (mab-buffer (get-buffer-create " *mab contacts*"))
-       (modified (nth 5 (file-attributes eudc-contacts-file)))
+       (modified (file-attribute-modification-time
+                  (file-attributes eudc-contacts-file)))
        result)
     (with-current-buffer mab-buffer
       (make-local-variable 'eudc-buffer-time)
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index 97fdabd..64cc1a5 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -1667,7 +1667,7 @@ If CHARSET is nil then use UTF-8."
 (defun eww-read-bookmarks ()
   (let ((file (expand-file-name "eww-bookmarks" eww-bookmarks-directory)))
     (setq eww-bookmarks
-         (unless (zerop (or (nth 7 (file-attributes file)) 0))
+         (unless (zerop (or (file-attribute-size (file-attributes file)) 0))
            (with-temp-buffer
              (insert-file-contents file)
              (read (current-buffer)))))))
diff --git a/lisp/net/netrc.el b/lisp/net/netrc.el
index ec743dc..7b974eb 100644
--- a/lisp/net/netrc.el
+++ b/lisp/net/netrc.el
@@ -63,12 +63,14 @@
                        "port"))
              alist elem result pair)
           (if (and netrc-cache
-                  (equal (car netrc-cache) (nth 5 (file-attributes file))))
+                  (equal (car netrc-cache) (file-attribute-modification-time
+                                             (file-attributes file))))
              (insert (base64-decode-string (rot13-string (cdr netrc-cache))))
            (insert-file-contents file)
            (when (string-match "\\.gpg\\'" file)
              ;; Store the contents of the file heavily encrypted in memory.
-             (setq netrc-cache (cons (nth 5 (file-attributes file))
+             (setq netrc-cache (cons (file-attribute-modification-time
+                                       (file-attributes file))
                                      (rot13-string
                                       (base64-encode-string
                                        (buffer-string)))))))
diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el
index 32893d2..b6fbdfb 100644
--- a/lisp/net/newst-backend.el
+++ b/lisp/net/newst-backend.el
@@ -1800,7 +1800,8 @@ download it from URL first."
   (let ((image-name (concat directory feed-name)))
     (if (and (file-exists-p image-name)
              (time-less-p nil
-                          (time-add (nth 5 (file-attributes image-name))
+                          (time-add (file-attribute-modification-time
+                                    (file-attributes image-name))
                                     (seconds-to-time 86400))))
         (newsticker--debug-msg "%s: Getting image for %s skipped"
                                (format-time-string "%A, %H:%M")
diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el
index dab9003..e857e64 100644
--- a/lisp/net/nsm.el
+++ b/lisp/net/nsm.el
@@ -26,7 +26,7 @@
 
 (require 'cl-lib)
 (require 'rmc)                       ; read-multiple-choice
-(require 'subr-x)
+(eval-when-compile (require 'subr-x))
 
 (defvar nsm-permanent-host-settings nil)
 (defvar nsm-temporary-host-settings nil)
@@ -365,29 +365,34 @@ HOST PORT STATUS OPTIONAL-PARAMETER.")
        t))))
 
 (defun nsm-query-user (message args cert)
-  (let ((buffer (get-buffer-create "*Network Security Manager*")))
-    (save-window-excursion
-      ;; First format the certificate and warnings.
-      (with-help-window buffer
-        (with-current-buffer buffer
-          (erase-buffer)
-          (when (> (length cert) 0)
-            (insert cert "\n"))
-          (let ((start (point)))
-            (insert (apply #'format-message message args))
-            (goto-char start)
-            ;; Fill the first line of the message, which usually
-            ;; contains lots of explanatory text.
-            (fill-region (point) (line-end-position)))))
-      ;; Then ask the user what to do about it.
-      (unwind-protect
-          (cadr
-           (read-multiple-choice
-            "Continue connecting?"
-            '((?a "always" "Accept this certificate this session and for all 
future sessions.")
-              (?s "session only" "Accept this certificate this session only.")
-              (?n "no" "Refuse to use this certificate, and close the 
connection."))))
-        (kill-buffer buffer)))))
+  (catch 'return
+    (while t
+      (let ((buffer (get-buffer-create "*Network Security Manager*")))
+        (save-window-excursion
+          ;; First format the certificate and warnings.
+          (with-help-window buffer
+            (with-current-buffer buffer
+              (erase-buffer)
+              (when (> (length cert) 0)
+                (insert cert "\n"))
+              (let ((start (point)))
+                (insert (apply #'format-message message args))
+                (goto-char start)
+                ;; Fill the first line of the message, which usually
+                ;; contains lots of explanatory text.
+                (fill-region (point) (line-end-position)))))
+          ;; Then ask the user what to do about it.
+          (pcase (unwind-protect
+                     (cadr
+                      (read-multiple-choice
+                       "Continue connecting?"
+                       '((?a "always" "Accept this certificate this session 
and for all future sessions.")
+                         (?s "session only" "Accept this certificate this 
session only.")
+                         (?n "no" "Refuse to use this certificate, and close 
the connection.")
+                         (?r "reshow" "Reshow certificate information."))))
+                   (kill-buffer buffer))
+            ("reshow")
+            (val (throw 'return val))))))))
 
 (defun nsm-save-host (host port status what permanency)
   (let* ((id (nsm-id host port))
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index bc86fe5..7ef1e18 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -321,9 +321,9 @@ under point instead."
 
 (defun shr-copy-url (url)
   "Copy the URL under point to the kill ring.
-If IMAGE-URL (the prefix) is non-nil, or there is no link under
-point, but there is an image under point then copy the URL of the
-image under point instead."
+With a prefix argument, or if there is no link under point, but
+there is an image under point then copy the URL of the image
+under point instead."
   (interactive (list (shr-url-at-point current-prefix-arg)))
   (if (not url)
       (message "No URL under point")
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index 35b0fdd..36374f8 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -411,9 +411,9 @@ pass to the OPERATION."
                 ;; no way to handle numeric ids in Androids ash
                 (if (eq id-format 'integer) 0 uid)
                 (if (eq id-format 'integer) 0 gid)
-                '(0 0)                 ; atime
+                tramp-time-dont-know   ; atime
                 (date-to-time date)    ; mtime
-                '(0 0)                 ; ctime
+                tramp-time-dont-know   ; ctime
                 size
                 mod-string
                 ;; fake
@@ -725,7 +725,9 @@ But handle the case, if the \"test\" command is not 
available."
   (with-parsed-tramp-file-name filename nil
     (tramp-flush-file-properties v (file-name-directory localname))
     (tramp-flush-file-properties v localname)
-    (let ((time (if (or (null time) (equal time '(0 0)))
+    (let ((time (if (or (null time)
+                       (tramp-compat-time-equal-p time tramp-time-doesnt-exist)
+                       (tramp-compat-time-equal-p time tramp-time-dont-know))
                    (current-time)
                  time)))
       (tramp-adb-send-command-and-check
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el
index b40a4d7..ebb4254 100644
--- a/lisp/net/tramp-cache.el
+++ b/lisp/net/tramp-cache.el
@@ -118,9 +118,8 @@ Returns DEFAULT if not set."
        (and (consp value)
             (or (null remote-file-name-inhibit-cache)
                 (and (integerp remote-file-name-inhibit-cache)
-                     (<=
-                      (tramp-time-diff (current-time) (car value))
-                      remote-file-name-inhibit-cache))
+                     (<= (tramp-time-diff (current-time) (car value))
+                         remote-file-name-inhibit-cache))
                 (and (consp remote-file-name-inhibit-cache)
                      (time-less-p
                       remote-file-name-inhibit-cache (car value)))))
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el
index 2a5939f..22d3431 100644
--- a/lisp/net/tramp-compat.el
+++ b/lisp/net/tramp-compat.el
@@ -142,15 +142,15 @@ returned."
   (defsubst tramp-compat-file-attribute-modification-time (attributes)
     "The modification time in ATTRIBUTES returned by `file-attributes'.
 This is the time of the last change to the file's contents, and
-is a list of integers (HIGH LOW USEC PSEC) in the same style
-as (current-time)."
+is a Lisp timestamp in the style of `current-time'."
     (nth 5 attributes)))
 
 (if (fboundp 'file-attribute-size)
     (defalias 'tramp-compat-file-attribute-size 'file-attribute-size)
   (defsubst tramp-compat-file-attribute-size (attributes)
     "The size (in bytes) in ATTRIBUTES returned by `file-attributes'.
-This is a floating point number if the size is too large for an integer."
+If the size is too large for a fixnum, this is a bignum in Emacs 27
+and later, and is a float in Emacs 26 and earlier."
     (nth 7 attributes)))
 
 (if (fboundp 'file-attribute-modes)
@@ -272,6 +272,14 @@ This is the simplest safe way to acquire and release a 
mutex."
            (funcall handler 'exec-path)
          exec-path)))))
 
+;; `time-equal-p' has appeared in Emacs 27.1.
+(if (fboundp 'time-equal-p)
+    (defalias 'tramp-compat-time-equal-p 'time-equal-p)
+  (defsubst tramp-compat-time-equal-p (t1 t2)
+    "Return non-nil if time value T1 is equal to time value T2.
+A nil value for either argument stands for the current time."
+    (equal (or t1 (current-time)) (or t2 (current-time)))))
+
 (add-hook 'tramp-unload-hook
          (lambda ()
            (unload-feature 'tramp-loaddefs 'force)
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index f46ddc6..c150edf 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -650,7 +650,7 @@ Return nil for null BYTE-ARRAY."
   (cond
    ((and (consp message) (characterp (car message)))
     (format "%S" (tramp-gvfs-dbus-byte-array-to-string message)))
-   ((and (consp message) (not (consp (cdr message))))
+   ((and (consp message) (atom (cdr message)))
     (cons (tramp-gvfs-stringify-dbus-message (car message))
          (tramp-gvfs-stringify-dbus-message (cdr message))))
    ((consp message)
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index e1c6691..cf5a704 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -1347,13 +1347,10 @@ component is used as the target of the symlink."
            res-uid
            ;; 3. File gid.
            res-gid
-           ;; 4. Last access time, as a list of integers.  Normally
-           ;; this would be in the same format as `current-time', but
-           ;; the subseconds part is not currently implemented, and
-          ;; (0 0) denotes an unknown time.
-           ;; 5. Last modification time, likewise.
-           ;; 6. Last status change time, likewise.
-           '(0 0) '(0 0) '(0 0)                ;CCC how to find out?
+           ;; 4. Last access time.
+           ;; 5. Last modification time.
+           ;; 6. Last status change time.
+           tramp-time-dont-know tramp-time-dont-know tramp-time-dont-know
            ;; 7. Size in bytes (-1, if number is out of range).
            res-size
            ;; 8. File modes, as a string of ten letters or dashes as in ls -l.
@@ -1419,13 +1416,10 @@ component is used as the target of the symlink."
       (with-parsed-tramp-file-name f nil
        (let* ((remote-file-name-inhibit-cache t)
               (attr (file-attributes f))
-              ;; '(-1 65535) means file doesn't exists yet.
               (modtime (or (tramp-compat-file-attribute-modification-time attr)
-                           '(-1 65535))))
+                           tramp-time-doesnt-exist)))
          (setq coding-system-used last-coding-system-used)
-         ;; We use '(0 0) as a don't-know value.  See also
-         ;; `tramp-do-file-attributes-with-ls'.
-         (if (not (equal modtime '(0 0)))
+         (if (not (tramp-compat-time-equal-p modtime tramp-time-dont-know))
              (tramp-run-real-handler 'set-visited-file-modtime (list modtime))
            (progn
              (tramp-send-command
@@ -1454,7 +1448,7 @@ of."
       ;; recorded last modification time, or there is no established
       ;; connection.
       (if (or (not f)
-             (eq (visited-file-modtime) 0)
+             (zerop (visited-file-modtime))
              (not (file-remote-p f nil 'connected)))
          t
        (with-parsed-tramp-file-name f nil
@@ -1465,16 +1459,10 @@ of."
 
            (cond
             ;; File exists, and has a known modtime.
-            ((and attr (not (equal modtime '(0 0))))
-             (< (abs (tramp-time-diff
-                      modtime
-                      ;; For compatibility, deal with both the old
-                      ;; (HIGH . LOW) and the new (HIGH LOW) return
-                      ;; values of `visited-file-modtime'.
-                      (if (atom (cdr mt))
-                          (list (car mt) (cdr mt))
-                        mt)))
-                2))
+            ((and attr
+                  (not
+                   (tramp-compat-time-equal-p modtime tramp-time-dont-know)))
+             (< (abs (tramp-time-diff modtime mt)) 2))
             ;; Modtime has the don't know value.
             (attr
              (tramp-send-command
@@ -1490,7 +1478,7 @@ of."
                v localname "visited-file-modtime-ild" "")))
             ;; If file does not exist, say it is not modified if and
             ;; only if that agrees with the buffer's record.
-            (t (equal mt '(-1 65535))))))))))
+            (t (tramp-compat-time-equal-p mt tramp-time-doesnt-exist)))))))))
 
 (defun tramp-sh-handle-set-file-modes (filename mode)
   "Like `set-file-modes' for Tramp files."
@@ -1509,9 +1497,12 @@ of."
     (when (tramp-get-remote-touch v)
       (tramp-flush-file-properties v (file-name-directory localname))
       (tramp-flush-file-properties v localname)
-      (let ((time (if (or (null time) (equal time '(0 0)))
-                     (current-time)
-                   time)))
+      (let ((time
+            (if (or (null time)
+                    (tramp-compat-time-equal-p time tramp-time-doesnt-exist)
+                    (tramp-compat-time-equal-p time tramp-time-dont-know))
+                (current-time)
+              time)))
        (tramp-send-command-and-check
         v (format
            "env TZ=UTC %s %s %s"
@@ -1680,11 +1671,13 @@ be non-negative integers."
                 (fa2 (file-attributes file2)))
             (if (and
                  (not
-                  (equal (tramp-compat-file-attribute-modification-time fa1)
-                         '(0 0)))
+                  (tramp-compat-time-equal-p
+                   (tramp-compat-file-attribute-modification-time fa1)
+                   tramp-time-dont-know))
                  (not
-                  (equal (tramp-compat-file-attribute-modification-time fa2)
-                         '(0 0))))
+                  (tramp-compat-time-equal-p
+                   (tramp-compat-file-attribute-modification-time fa2)
+                   tramp-time-dont-know)))
                 (> 0 (tramp-time-diff
                       (tramp-compat-file-attribute-modification-time fa2)
                       (tramp-compat-file-attribute-modification-time fa1)))
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 583acbd..a97b801 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -817,18 +817,18 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
            ;; Check result.
            (when entry
              (list (and (string-match "d" (nth 1 entry))
-                        t)        ;0 file type
-                   -1             ;1 link count
-                   uid            ;2 uid
-                   gid            ;3 gid
-                   '(0 0)         ;4 atime
-                   (nth 3 entry)  ;5 mtime
-                   '(0 0)         ;6 ctime
-                   (nth 2 entry)  ;7 size
-                   (nth 1 entry)  ;8 mode
-                   nil            ;9 gid weird
-                   inode          ;10 inode number
-                   device)))))))) ;11 file system number
+                        t)              ;0 file type
+                   -1                   ;1 link count
+                   uid                  ;2 uid
+                   gid                  ;3 gid
+                   tramp-time-dont-know ;4 atime
+                   (nth 3 entry)        ;5 mtime
+                   tramp-time-dont-know ;6 ctime
+                   (nth 2 entry)        ;7 size
+                   (nth 1 entry)        ;8 mode
+                   nil                  ;9 gid weird
+                   inode                ;10 inode number
+                   device))))))))       ;11 file system number
 
 (defun tramp-smb-do-file-attributes-with-stat (vec &optional id-format)
   "Implement `file-attributes' for Tramp files using stat command."
@@ -1085,8 +1085,9 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
                     (or (tramp-compat-file-attribute-group-id attr) "nogroup")
                     (or (tramp-compat-file-attribute-size attr) (nth 2 x))
                     (format-time-string
-                     (if (time-less-p (time-subtract (current-time) (nth 3 x))
-                          tramp-half-a-year)
+                     (if (time-less-p
+                          ;; Half a year.
+                          (time-since (nth 3 x)) (days-to-time 183))
                          "%b %e %R"
                        "%b %e  %Y")
                      (nth 3 x))))) ; date
@@ -1816,7 +1817,7 @@ Result is the list (LOCALNAME MODE SIZE MTIME)."
                 sec min hour day
                 (cdr (assoc (downcase month) parse-time-months))
                 year)
-             '(0 0)))
+             tramp-time-dont-know))
       (list localname mode size mtime))))
 
 (defun tramp-smb-get-cifs-capabilities (vec)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 7425c8d..962549a 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1968,7 +1968,6 @@ For definition of that list see 
`tramp-set-completion-function'."
    ;; The method related defaults.
    (cdr (assoc method tramp-completion-function-alist))))
 
-
 ;;; Fontification of `read-file-name':
 
 (defvar tramp-rfn-eshadow-overlay)
@@ -1978,11 +1977,11 @@ For definition of that list see 
`tramp-set-completion-function'."
   "Set up a minibuffer for `file-name-shadow-mode'.
 Adds another overlay hiding filename parts according to Tramp's
 special handling of `substitute-in-file-name'."
-  (when (symbol-value 'minibuffer-completing-file-name)
+  (when minibuffer-completing-file-name
     (setq tramp-rfn-eshadow-overlay
          (make-overlay (minibuffer-prompt-end) (minibuffer-prompt-end)))
     ;; Copy rfn-eshadow-overlay properties.
-    (let ((props (overlay-properties (symbol-value 'rfn-eshadow-overlay))))
+    (let ((props (overlay-properties rfn-eshadow-overlay)))
       (while props
        ;; The `field' property prevents correct minibuffer
        ;; completion; we exclude it.
@@ -2000,6 +1999,13 @@ special handling of `substitute-in-file-name'."
 (defun tramp-rfn-eshadow-update-overlay-regexp ()
   (format "[^%s/~]*\\(/\\|~\\)" tramp-postfix-host-format))
 
+;; Package rfn-eshadow is preloaded in Emacs, but for some reason,
+;; it only did (defvar rfn-eshadow-overlay) without giving it a global
+;; value, so it was only declared as dynamically-scoped within the
+;; rfn-eshadow.el file.  This is now fixed in Emacs>26.1 but we still need
+;; this defvar here for older releases.
+(defvar rfn-eshadow-overlay)
+
 (defun tramp-rfn-eshadow-update-overlay ()
   "Update `rfn-eshadow-overlay' to cover shadowed part of minibuffer input.
 This is intended to be used as a minibuffer `post-command-hook' for
@@ -2007,26 +2013,25 @@ This is intended to be used as a minibuffer 
`post-command-hook' for
 been set up by `rfn-eshadow-setup-minibuffer'."
   ;; In remote files name, there is a shadowing just for the local part.
   (ignore-errors
-    (let ((end (or (overlay-end (symbol-value 'rfn-eshadow-overlay))
+    (let ((end (or (overlay-end rfn-eshadow-overlay)
                   (minibuffer-prompt-end)))
          ;; We do not want to send any remote command.
          (non-essential t))
       (when
          (tramp-tramp-file-p
           (buffer-substring-no-properties end (point-max)))
-       (save-excursion
-         (save-restriction
-           (narrow-to-region
-            (1+ (or (string-match
-                     (tramp-rfn-eshadow-update-overlay-regexp)
-                     (buffer-string) end)
-                    end))
-            (point-max))
-           (let ((rfn-eshadow-overlay tramp-rfn-eshadow-overlay)
-                 (rfn-eshadow-update-overlay-hook nil)
-                 file-name-handler-alist)
-             (move-overlay rfn-eshadow-overlay (point-max) (point-max))
-             (rfn-eshadow-update-overlay))))))))
+       (save-restriction
+         (narrow-to-region
+          (1+ (or (string-match
+                   (tramp-rfn-eshadow-update-overlay-regexp)
+                   (buffer-string) end)
+                  end))
+          (point-max))
+         (let ((rfn-eshadow-overlay tramp-rfn-eshadow-overlay)
+               (rfn-eshadow-update-overlay-hook nil)
+               file-name-handler-alist)
+           (move-overlay rfn-eshadow-overlay (point-max) (point-max))
+           (rfn-eshadow-update-overlay)))))))
 
 (add-hook 'rfn-eshadow-update-overlay-hook
          'tramp-rfn-eshadow-update-overlay)
@@ -3621,7 +3626,11 @@ support symbolic links."
            (setq filename
                  (concat (file-remote-p filename)
                          (replace-regexp-in-string
-                           "\\`/+" "/" (substitute-in-file-name 
localname)))))))
+                           "\\`/+" "/"
+                          ;; We must disable cygwin-mount file name
+                          ;; handlers and alike.
+                          (tramp-run-real-handler
+                           'substitute-in-file-name (list localname))))))))
       ;; "/m:h:~" does not work for completion.  We use "/m:h:~/".
       (if (and (stringp localname) (string-equal "~" localname))
          (concat filename "/")
@@ -3634,13 +3643,11 @@ support symbolic links."
           (buffer-name)))
   (unless time-list
     (let ((remote-file-name-inhibit-cache t))
-      ;; '(-1 65535) means file doesn't exists yet.
       (setq time-list
            (or (tramp-compat-file-attribute-modification-time
                 (file-attributes (buffer-file-name)))
-               '(-1 65535)))))
-  ;; We use '(0 0) as a don't-know value.
-  (unless (equal time-list '(0 0))
+               tramp-time-doesnt-exist))))
+  (unless (tramp-compat-time-equal-p time-list tramp-time-dont-know)
     (tramp-run-real-handler 'set-visited-file-modtime (list time-list))))
 
 (defun tramp-handle-verify-visited-file-modtime (&optional buf)
@@ -3666,21 +3673,14 @@ of."
 
          (cond
           ;; File exists, and has a known modtime.
-          ((and attr (not (equal modtime '(0 0))))
-           (< (abs (tramp-time-diff
-                    modtime
-                    ;; For compatibility, deal with both the old
-                    ;; (HIGH . LOW) and the new (HIGH LOW) return
-                    ;; values of `visited-file-modtime'.
-                    (if (atom (cdr mt))
-                        (list (car mt) (cdr mt))
-                      mt)))
-              2))
+          ((and attr
+                (not (tramp-compat-time-equal-p modtime tramp-time-dont-know)))
+           (< (abs (tramp-time-diff modtime mt)) 2))
           ;; Modtime has the don't know value.
           (attr t)
           ;; If file does not exist, say it is not modified if and
           ;; only if that agrees with the buffer's record.
-          (t (equal mt '(-1 65535)))))))))
+          (t (tramp-compat-time-equal-p mt tramp-time-doesnt-exist))))))))
 
 ;; This is used in tramp-gvfs.el and tramp-sh.el.
 (defconst tramp-gio-events
@@ -4563,17 +4563,19 @@ Invokes `password-read' if available, `read-passwd' 
else."
        :host ,host-port :port ,method))
     (password-cache-remove (tramp-make-tramp-file-name vec 'noloc 'nohop))))
 
-;; Snarfed code from time-date.el.
+;;;###tramp-autoload
+(defconst tramp-time-dont-know '(0 0 0 1000)
+  "An invalid time value, used as \"Don’t know\" value.")
 
-(defconst tramp-half-a-year '(241 17024)
-"Evaluated by \"(days-to-time 183)\".")
+;;;###tramp-autoload
+(defconst tramp-time-doesnt-exist '(-1 65535)
+  "An invalid time value, used as \"Doesn’t exist\" value.")
 
 ;;;###tramp-autoload
 (defun tramp-time-diff (t1 t2)
   "Return the difference between the two times, in seconds.
 T1 and T2 are time values (as returned by `current-time' for example)."
-  ;; Starting with Emacs 25.1, we could change this to use `time-subtract'.
-  (float-time (tramp-compat-funcall 'subtract-time t1 t2)))
+  (float-time (time-subtract t1 t2)))
 
 (defun tramp-unquote-shell-quote-argument (s)
   "Remove quotation prefix \"/:\" from string S, and quote it then for shell."
@@ -4707,8 +4709,6 @@ Only works for Bourne-like shells."
 ;;   strange when doing zerop, we should kill the process and start
 ;;   again.  (Greg Stark)
 ;;
-;; * Make shadowfile.el grok Tramp filenames.  (Bug#4526, Bug#4846)
-;;
 ;; * I was wondering if it would be possible to use tramp even if I'm
 ;;   actually using sshfs.  But when I launch a command I would like
 ;;   to get it executed on the remote machine where the files really
diff --git a/lisp/nxml/rng-loc.el b/lisp/nxml/rng-loc.el
index a9a1950..75d9831 100644
--- a/lisp/nxml/rng-loc.el
+++ b/lisp/nxml/rng-loc.el
@@ -407,7 +407,7 @@ or nil."
   "Return a list of rules for the schema locating file FILE."
   (setq file (expand-file-name file))
   (let ((cached (assoc file rng-schema-locating-file-alist))
-       (mtime (nth 5 (file-attributes file)))
+       (mtime (file-attribute-modification-time (file-attributes file)))
        parsed)
     (cond ((not mtime)
           (when cached
diff --git a/lisp/obsolete/fast-lock.el b/lisp/obsolete/fast-lock.el
index 41e48c3..21db321 100644
--- a/lisp/obsolete/fast-lock.el
+++ b/lisp/obsolete/fast-lock.el
@@ -441,7 +441,8 @@ See `fast-lock-mode'."
             ;; Only save if user's restrictions are satisfied.
             (and min-size (>= (buffer-size) min-size))
             (or fast-lock-save-others
-                (eq (user-uid) (nth 2 (file-attributes buffer-file-name))))
+                (eq (user-uid) (file-attribute-user-id
+                                (file-attributes buffer-file-name))))
             ;;
             ;; Only save if there are `face' properties to save.
             (text-property-not-all (point-min) (point-max) 'face nil))
diff --git a/lisp/obsolete/vc-arch.el b/lisp/obsolete/vc-arch.el
index 414ae77..9860c9d 100644
--- a/lisp/obsolete/vc-arch.el
+++ b/lisp/obsolete/vc-arch.el
@@ -304,8 +304,9 @@ Only the value `maybe' can be trusted :-(."
                ;; Buh?  Unexpected format.
                'edited
              (let ((ats (file-attributes file)))
-               (if (and (eq (nth 7 ats) (string-to-number (match-string 2)))
-                        (equal (format-time-string "%s" (nth 5 ats))
+               (if (and (eq (file-attribute-size ats) (string-to-number 
(match-string 2)))
+                        (equal (format-time-string
+                                "%s" (file-attribute-modification-time ats))
                                (match-string 1)))
                    'up-to-date
                  'edited)))))))))
@@ -402,7 +403,7 @@ CALLBACK expects (ENTRIES &optional MORE-TO-COME); see
 
 (defun vc-arch-diff3-rej-p (rej)
   (let ((attrs (file-attributes rej)))
-    (and attrs (< (nth 7 attrs) 60)
+    (and attrs (< (file-attribute-size attrs) 60)
         (with-temp-buffer
           (insert-file-contents rej)
           (goto-char (point-min))
diff --git a/lisp/org/ob-eval.el b/lisp/org/ob-eval.el
index 2bfaa08..f8cb285 100644
--- a/lisp/org/ob-eval.el
+++ b/lisp/org/ob-eval.el
@@ -120,7 +120,7 @@ function in various versions of Emacs.
       (delete-file input-file))
 
     (when (and error-file (file-exists-p error-file))
-      (when (< 0 (nth 7 (file-attributes error-file)))
+      (when (< 0 (file-attribute-size (file-attributes error-file)))
        (with-current-buffer (get-buffer-create error-buffer)
          (let ((pos-from-end (- (point-max) (point))))
            (or (bobp)
diff --git a/lisp/org/org-attach.el b/lisp/org/org-attach.el
index 9774e3a..203e71e 100644
--- a/lisp/org/org-attach.el
+++ b/lisp/org/org-attach.el
@@ -352,7 +352,7 @@ This checks for the existence of a \".git\" directory in 
that directory."
                   (shell-command-to-string
                    "git ls-files -zmo --exclude-standard") "\0" t))
           (if (and use-annex
-                   (>= (nth 7 (file-attributes new-or-modified))
+                   (>= (file-attribute-size (file-attributes new-or-modified))
                        org-attach-git-annex-cutoff))
               (call-process "git" nil nil nil "annex" "add" new-or-modified)
             (call-process "git" nil nil nil "add" new-or-modified))
diff --git a/lisp/org/org-macro.el b/lisp/org/org-macro.el
index 1033db2..e50b2f9 100644
--- a/lisp/org/org-macro.el
+++ b/lisp/org/org-macro.el
@@ -159,7 +159,8 @@ function installs the following ones: \"property\",
                          (format "(eval (format-time-string \"$1\" (or (and 
(org-string-nw-p \"$2\") (org-macro--vc-modified-time %s)) '%s)))"
                                  (prin1-to-string visited-file)
                                  (prin1-to-string
-                                  (nth 5 (file-attributes visited-file)))))))))
+                                  (file-attribute-modification-time
+                                   (file-attributes visited-file)))))))))
     ;; Initialize and install "n" macro.
     (org-macro--counter-initialize)
     (funcall update-templates
diff --git a/lisp/org/org.el b/lisp/org/org.el
index 21d9cd8..873ae6b 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -230,8 +230,9 @@ file to byte-code before it is loaded."
   (let* ((age (lambda (file)
                (float-time
                 (time-subtract (current-time)
-                               (nth 5 (or (file-attributes (file-truename 
file))
-                                          (file-attributes file)))))))
+                               (file-attribute-modification-time
+                                (or (file-attributes (file-truename file))
+                                    (file-attributes file)))))))
         (base-name (file-name-sans-extension file))
         (exported-file (concat base-name ".el")))
     ;; tangle if the Org file is newer than the elisp file
@@ -22381,7 +22382,9 @@ returned by, e.g., `current-time'."
        ;; (e.g. HFS+) do not retain any finer granularity.  As
        ;; a consequence, make sure we return non-nil when the two
        ;; times are equal.
-       (not (time-less-p (cl-subseq (nth 5 (file-attributes file)) 0 2)
+       (not (time-less-p (cl-subseq (file-attribute-modification-time
+                                    (file-attributes file))
+                                   0 2)
                         (cl-subseq time 0 2)))))
 
 (defun org-compile-file (source process ext &optional err-msg log-buf spec)
diff --git a/lisp/org/ox-html.el b/lisp/org/ox-html.el
index 39f7d83..6166a4a 100644
--- a/lisp/org/ox-html.el
+++ b/lisp/org/ox-html.el
@@ -1935,7 +1935,8 @@ INFO is a plist used as a communication channel."
       (?c . ,(plist-get info :creator))
       (?C . ,(let ((file (plist-get info :input-file)))
               (format-time-string timestamp-format
-                                  (and file (nth 5 (file-attributes file))))))
+                                  (and file (file-attribute-modification-time
+                                             (file-attributes file))))))
       (?v . ,(or (plist-get info :html-validation-link) "")))))
 
 (defun org-html--build-pre/postamble (type info)
diff --git a/lisp/org/ox-publish.el b/lisp/org/ox-publish.el
index ba5a023..80ef239 100644
--- a/lisp/org/ox-publish.el
+++ b/lisp/org/ox-publish.el
@@ -879,7 +879,8 @@ If FILE is an Org file and provides a DATE keyword use it.  
In
 any other case use the file system's modification time.  Return
 time in `current-time' format."
   (let ((file (org-publish--expand-file-name file project)))
-    (if (file-directory-p file) (nth 5 (file-attributes file))
+    (if (file-directory-p file) (file-attribute-modification-time
+                                 (file-attributes file))
       (let ((date (org-publish-find-property file :date project)))
        ;; DATE is a secondary string.  If it contains a time-stamp,
        ;; convert it to internal format.  Otherwise, use FILE
@@ -889,7 +890,8 @@ time in `current-time' format."
                      (let ((value (org-element-interpret-data ts)))
                        (and (org-string-nw-p value)
                             (org-time-string-to-time value))))))
-             ((file-exists-p file) (nth 5 (file-attributes file)))
+             ((file-exists-p file) (file-attribute-modification-time
+                                     (file-attributes file)))
              (t (error "No such file: \"%s\"" file)))))))
 
 (defun org-publish-sitemap-default-entry (entry style project)
@@ -1348,8 +1350,7 @@ does not exist."
               (expand-file-name (or (file-symlink-p file) file)
                                 (file-name-directory file)))))
     (if (not attr) (error "No such file: \"%s\"" file)
-      (+ (ash (car (nth 5 attr)) 16)
-        (cadr (nth 5 attr))))))
+      (floor (float-time (file-attribute-modification-time attr))))))
 
 
 (provide 'ox-publish)
diff --git a/lisp/pcmpl-gnu.el b/lisp/pcmpl-gnu.el
index 16c9926..c4e5a67 100644
--- a/lisp/pcmpl-gnu.el
+++ b/lisp/pcmpl-gnu.el
@@ -316,7 +316,7 @@
     (while (pcomplete-here
            (if (and complete-within
                      (let* ((fa (file-attributes (pcomplete-arg 1)))
-                            (size (nth 7 fa)))
+                            (size (file-attribute-size fa)))
                        (and (numberp size)
                             (or (null large-file-warning-threshold)
                                 (< size large-file-warning-threshold)))))
diff --git a/lisp/pcmpl-rpm.el b/lisp/pcmpl-rpm.el
index 74ddb8b..7f164c9 100644
--- a/lisp/pcmpl-rpm.el
+++ b/lisp/pcmpl-rpm.el
@@ -71,7 +71,8 @@
   "Return a list of all installed rpm packages."
   (if (and pcmpl-rpm-cache
            pcmpl-rpm-cache-time
-           (let ((mtime (nth 5 (file-attributes pcmpl-rpm-cache-stamp-file))))
+           (let ((mtime (file-attribute-modification-time
+                         (file-attributes pcmpl-rpm-cache-stamp-file))))
              (and mtime (not (time-less-p pcmpl-rpm-cache-time mtime)))))
       pcmpl-rpm-packages
     (message "Getting list of installed rpms...")
diff --git a/lisp/play/bubbles.el b/lisp/play/bubbles.el
index e30838d..a54682f 100644
--- a/lisp/play/bubbles.el
+++ b/lisp/play/bubbles.el
@@ -1,4 +1,4 @@
-;;; bubbles.el --- Puzzle game for Emacs
+;;; bubbles.el --- Puzzle game for Emacs  -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2007-2018 Free Software Foundation, Inc.
 
@@ -144,8 +144,7 @@ images the `ascii' theme will be used."
                 (const :tag "Diamonds" diamonds)
                 (const :tag "Balls" balls)
                 (const :tag "Emacs" emacs)
-                (const :tag "ASCII (no images)" ascii))
-  :group 'bubbles)
+                (const :tag "ASCII (no images)" ascii)))
 
 (defconst bubbles--grid-small '(10 . 10)
   "Predefined small bubbles grid.")
@@ -168,8 +167,7 @@ images the `ascii' theme will be used."
                 (const :tag "Huge" ,bubbles--grid-huge)
                 (cons :tag "User defined"
                       (integer :tag "Width")
-                      (integer :tag "Height")))
-  :group 'bubbles)
+                      (integer :tag "Height"))))
 
 (defconst bubbles--colors-2 '("orange" "violet")
   "Predefined bubbles color list with two colors.")
@@ -194,16 +192,14 @@ types are present."
                 (const :tag "Red, darkgreen, blue, orange" ,bubbles--colors-4)
                 (const :tag "Red, darkgreen, blue, orange, violet"
                        ,bubbles--colors-5)
-                (repeat :tag "User defined" color))
-  :group 'bubbles)
+                (repeat :tag "User defined" color)))
 
 (defcustom bubbles-chars
   '(?+ ?O ?# ?X ?. ?* ?& ?§)
   "Characters used for bubbles.
 Note that the actual number of different bubbles is determined by
 the number of colors, see `bubbles-colors'."
-  :type '(repeat character)
-  :group 'bubbles)
+  :type '(repeat character))
 
 (defcustom bubbles-shift-mode
   'default
@@ -212,12 +208,10 @@ Available modes are `shift-default' and `shift-always'."
   :type '(radio (const :tag "Default" default)
                 (const :tag "Shifter" always)
                 ;;(const :tag "Mega Shifter" mega)
-                )
-  :group 'bubbles)
+                ))
 
 (defcustom bubbles-mode-hook nil
   "Hook run by Bubbles mode."
-  :group 'bubbles
   :type 'hook)
 
 (defun bubbles-customize ()
@@ -250,10 +244,10 @@ Available modes are `shift-default' and `shift-always'."
   "Indicate whether images have been created successfully.")
 
 (defvar bubbles--col-offset 0
-  "Horizontal offset for centering the bubbles grid.")
+  "Horizontal offset for centering the bubbles grid, in pixels.")
 
 (defvar bubbles--row-offset 0
-  "Vertical offset for centering the bubbles grid.")
+  "Vertical offset for centering the bubbles grid, in pixels.")
 
 (defvar bubbles--save-data nil
   "List containing bubbles save data (SCORE BUFFERCONTENTS).")
@@ -898,7 +892,7 @@ static char * dot3d_xpm[] = {
 ;; bubbles mode map
 (defvar bubbles-mode-map
   (let ((map (make-sparse-keymap 'bubbles-mode-map)))
-;;    (suppress-keymap map t)
+    ;; (suppress-keymap map t)
     (define-key map "q" 'bubbles-quit)
     (define-key map "\n" 'bubbles-plop)
     (define-key map " " 'bubbles-plop)
@@ -925,7 +919,7 @@ static char * dot3d_xpm[] = {
   (buffer-disable-undo)
   (force-mode-line-update)
   (redisplay)
-  (add-hook 'post-command-hook 'bubbles--mark-neighborhood t t))
+  (add-hook 'post-command-hook #'bubbles--mark-neighborhood t t))
 
 ;;;###autoload
 (defun bubbles ()
@@ -960,33 +954,26 @@ columns on its right towards the left.
 (defun bubbles--compute-offsets ()
   "Update horizontal and vertical offsets for centering the bubbles grid.
 Set `bubbles--col-offset' and `bubbles--row-offset'."
-  (cond ((and (display-images-p)
-              bubbles--images-ok
-              (not (eq bubbles-graphics-theme 'ascii))
-              (fboundp 'window-inside-pixel-edges))
-         ;; compute offset in units of pixels
-         (let ((bubbles--image-size
-                (car (image-size (car bubbles--images) t))))
-           (setq bubbles--col-offset
-                 (list
-                  (max 0 (/ (- (nth 2 (window-inside-pixel-edges))
-                               (nth 0 (window-inside-pixel-edges))
-                               (* ( + bubbles--image-size 2) ;; margin
-                                  (bubbles--grid-width))) 2))))
-           (setq bubbles--row-offset
-                 (list
-                  (max 0 (/ (- (nth 3 (window-inside-pixel-edges))
-                               (nth 1 (window-inside-pixel-edges))
-                               (* (+ bubbles--image-size 1) ;; margin
-                                  (bubbles--grid-height))) 2))))))
-        (t
-         ;; compute offset in units of chars
-         (setq bubbles--col-offset
-               (max 0 (/ (- (window-width)
-                            (bubbles--grid-width)) 2)))
-         (setq bubbles--row-offset
-               (max 0 (/ (- (window-height)
-                            (bubbles--grid-height) 2) 2))))))
+  (let* ((use-images-p (and (display-images-p)
+                            bubbles--images-ok
+                            (not (eq bubbles-graphics-theme 'ascii))))
+         (bubbles--image-size
+          (if use-images-p (car (image-size (car bubbles--images) t)) 1))
+         ;; In GUI mode, leave thin margins around the images.
+         (image-hor-size
+          (if use-images-p (+ bubbles--image-size 2) bubbles--image-size))
+         (image-vert-size
+          (if use-images-p (1+ bubbles--image-size) bubbles--image-size)))
+    (setq bubbles--col-offset
+          (max 0 (/ (- (nth 2 (window-body-pixel-edges))
+                       (nth 0 (window-body-pixel-edges))
+                       (* image-hor-size (bubbles--grid-width)))
+                    2)))
+    (setq bubbles--row-offset
+          (max 0 (/ (- (nth 3 (window-body-pixel-edges))
+                       (nth 1 (window-body-pixel-edges))
+                       (* image-vert-size (bubbles--grid-height)))
+                    2)))))
 
 (defun bubbles--remove-overlays ()
   "Remove all overlays."
@@ -1007,16 +994,18 @@ Set `bubbles--col-offset' and `bubbles--row-offset'."
     (insert " ")
     (put-text-property (point-min) (point)
                        'display
-                       (cons 'space (list :height bubbles--row-offset)))
+                       (cons 'space (list :height
+                                          (list bubbles--row-offset))))
     (insert "\n")
     (let ((max-char (length (bubbles--colors))))
-      (dotimes (i (bubbles--grid-height))
+      (dotimes (_ (bubbles--grid-height))
         (let ((p (point)))
           (insert " ")
           (put-text-property p (point)
                              'display
-                             (cons 'space (list :width bubbles--col-offset))))
-        (dotimes (j (bubbles--grid-width))
+                             (cons 'space (list :width
+                                                (list bubbles--col-offset)))))
+        (dotimes (_ (bubbles--grid-width))
           (let* ((index (random max-char))
                  (char (nth index bubbles-chars)))
             (insert char)
@@ -1025,7 +1014,8 @@ Set `bubbles--col-offset' and `bubbles--row-offset'."
       (insert "\n ")
       (put-text-property (1- (point)) (point)
                          'display
-                         (cons 'space (list :width bubbles--col-offset))))
+                         (cons 'space (list :width
+                                            (list bubbles--col-offset)))))
     (put-text-property (point-min) (point-max) 'pointer 'arrow))
   (bubbles-mode)
   (bubbles--reset-score)
@@ -1177,7 +1167,7 @@ Use optional parameter POS instead of point if given."
       (insert " ")
       (put-text-property (1- (point)) (point)
                          'display
-                         (cons 'space (list :width bubbles--col-offset)))
+                         (cons 'space (list :width (list 
bubbles--col-offset))))
       (insert (format "Score:    %4d" bubbles--score))
       (put-text-property pos (point) 'status t))))
 
@@ -1197,7 +1187,7 @@ Use optional parameter POS instead of point if given."
     (insert "\n ")
     (put-text-property (1- (point)) (point)
                        'display
-                       (cons 'space (list :width bubbles--col-offset)))
+                       (cons 'space (list :width (list bubbles--col-offset))))
     (insert "Game Over!"))
   ;; save score
   (gamegrid-add-score (format "bubbles-%s-%d-%d-%d-scores"
@@ -1272,7 +1262,7 @@ Use optional parameter POS instead of point if given."
                      (while (get-text-property (point) 'removed)
                        (setq shifted-cols (1+ shifted-cols))
                        (bubbles--shift 'right (1- (bubbles--grid-height)) j))
-                     (dotimes (k shifted-cols)
+                     (dotimes (_ shifted-cols)
                        (let ((i (- (bubbles--grid-height) 2)))
                          (while (>= i 0)
                            (setq shifted (or (bubbles--shift 'right i j)
@@ -1426,8 +1416,8 @@ Return t if new char is non-empty."
         (goto-char (point-min))
         (forward-line 1)
         (let ((inhibit-read-only t))
-          (dotimes (i (bubbles--grid-height))
-            (dotimes (j (bubbles--grid-width))
+          (dotimes (_ (bubbles--grid-height))
+            (dotimes (_ (bubbles--grid-width))
               (forward-char 1)
               (let ((index (or (get-text-property (point) 'index) -1)))
                 (let ((img bubbles--empty-image))
diff --git a/lisp/play/cookie1.el b/lisp/play/cookie1.el
index 5ae2cb4..7a6a56b 100644
--- a/lisp/play/cookie1.el
+++ b/lisp/play/cookie1.el
@@ -125,7 +125,8 @@ and subsequent calls on the same file won't go to disk."
   (setq phrase-file (cookie-check-file phrase-file))
   (let ((sym (intern-soft phrase-file cookie-cache)))
     (and sym (not (equal (symbol-function sym)
-                        (nth 5 (file-attributes phrase-file))))
+                        (file-attribute-modification-time
+                          (file-attributes phrase-file))))
         (yes-or-no-p (concat phrase-file
                              " has changed.  Read new contents? "))
         (setq sym nil))
@@ -133,7 +134,8 @@ and subsequent calls on the same file won't go to disk."
        (symbol-value sym)
       (setq sym (intern phrase-file cookie-cache))
       (if startmsg (message "%s" startmsg))
-      (fset sym (nth 5 (file-attributes phrase-file)))
+      (fset sym (file-attribute-modification-time
+                 (file-attributes phrase-file)))
       (let (result)
        (with-temp-buffer
          (insert-file-contents (expand-file-name phrase-file))
diff --git a/lisp/progmodes/ada-mode.el b/lisp/progmodes/ada-mode.el
index 76c9be9..fd6a2b0 100644
--- a/lisp/progmodes/ada-mode.el
+++ b/lisp/progmodes/ada-mode.el
@@ -4519,6 +4519,7 @@ Moves to `begin' if in a declarative part."
   (define-key ada-mode-map "\C-c\C-n" 'ada-make-subprogram-body)
 
   ;; Use predefined function of Emacs19 for comments (RE)
+  ;; FIXME: Made redundant with Emacs-21's standard comment-dwim binding on M-;
   (define-key ada-mode-map "\C-c;"    'comment-region)
   (define-key ada-mode-map "\C-c:"    'ada-uncomment-region)
 
@@ -4756,16 +4757,17 @@ Moves to `begin' if in a declarative part."
 ;;  function for justifying the comments.
 ;; -------------------------------------------------------
 
-(defadvice comment-region (before ada-uncomment-anywhere disable)
-  (if (and (consp arg)  ;;  a prefix with \C-u is of the form '(4), whereas
-                      ;;  \C-u 2  sets arg to '2'  (fixed by S.Leake)
-          (derived-mode-p 'ada-mode))
-      (save-excursion
-       (let ((cs (concat "^[ \t]*" (regexp-quote comment-start))))
-         (goto-char beg)
-         (while (re-search-forward cs end t)
-           (replace-match comment-start))
-         ))))
+(when (or (<= emacs-major-version 20) (featurep 'xemacs))
+  (defadvice comment-region (before ada-uncomment-anywhere disable)
+    (if (and (consp arg) ;;  a prefix with \C-u is of the form '(4), whereas
+            ;;  \C-u 2  sets arg to '2'  (fixed by S.Leake)
+            (derived-mode-p 'ada-mode))
+        (save-excursion
+         (let ((cs (concat "^[ \t]*" (regexp-quote comment-start))))
+           (goto-char beg)
+           (while (re-search-forward cs end t)
+             (replace-match comment-start))
+           )))))
 
 (defun ada-uncomment-region (beg end &optional arg)
   "Uncomment region BEG .. END.
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 278ade0..3ec7dbc 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -4295,6 +4295,41 @@ comment at the start of cc-engine.el for more info."
       "\\w\\|\\s_\\|\\s\"\\|\\s|"
     "\\w\\|\\s_\\|\\s\""))
 
+(defun c-forward-over-token (&optional balanced)
+  "Move forward over a token.
+Return t if we moved, nil otherwise (i.e. we were at EOB, or a
+non-token or BALANCED is non-nil and we can't move).  If we
+are at syntactic whitespace, move over this in place of a token.
+
+If BALANCED is non-nil move over any balanced parens we are at, and never move
+out of an enclosing paren."
+  (let ((jump-syntax (if balanced
+                        c-jump-syntax-balanced
+                      c-jump-syntax-unbalanced))
+       (here (point)))
+    (condition-case nil
+       (cond
+        ((/= (point)
+             (progn (c-forward-syntactic-ws) (point)))
+         ;; If we're at whitespace, count this as the token.
+         t)
+        ((eobp) nil)
+        ((looking-at jump-syntax)
+         (goto-char (scan-sexps (point) 1))
+         t)
+        ((looking-at c-nonsymbol-token-regexp)
+         (goto-char (match-end 0))
+         t)
+        ((save-restriction
+           (widen)
+           (looking-at c-nonsymbol-token-regexp))
+         nil)
+        (t
+         (forward-char)
+         t))
+      (error (goto-char here)
+            nil))))
+
 (defun c-forward-over-token-and-ws (&optional balanced)
   "Move forward over a token and any following whitespace
 Return t if we moved, nil otherwise (i.e. we were at EOB, or a
@@ -4306,35 +4341,8 @@ out of an enclosing paren.
 
 This function differs from `c-forward-token-2' in that it will move forward
 over the final token in a buffer, up to EOB."
-  (let ((jump-syntax (if balanced
-                        c-jump-syntax-balanced
-                      c-jump-syntax-unbalanced))
-       (here (point)))
-    (when
-       (condition-case nil
-           (cond
-            ((/= (point)
-                 (progn (c-forward-syntactic-ws) (point)))
-             ;; If we're at whitespace, count this as the token.
-             t)
-            ((eobp) nil)
-            ((looking-at jump-syntax)
-             (goto-char (scan-sexps (point) 1))
-             t)
-            ((looking-at c-nonsymbol-token-regexp)
-             (goto-char (match-end 0))
-             t)
-            ((save-restriction
-               (widen)
-               (looking-at c-nonsymbol-token-regexp))
-             nil)
-            (t
-             (forward-char)
-             t))
-         (error (goto-char here)
-                nil))
-      (c-forward-syntactic-ws)
-      t)))
+  (prog1 (c-forward-over-token balanced)
+    (c-forward-syntactic-ws)))
 
 (defun c-forward-token-2 (&optional count balanced limit)
   "Move forward by tokens.
@@ -7662,7 +7670,7 @@ comment at the start of cc-engine.el for more info."
                     (c-record-type-id id-range))
                   (unless res
                     (setq res 'found)))
-              (setq res (if (c-check-type id-start id-end)
+              (setq res (if (c-check-qualified-type id-start)
                             ;; It's an identifier that has been used as
                             ;; a type somewhere else.
                             'found
@@ -7674,7 +7682,7 @@ comment at the start of cc-engine.el for more info."
             (c-forward-syntactic-ws)
             (setq res
                   (if (eq (char-after) ?\()
-                      (if (c-check-type id-start id-end)
+                      (if (c-check-qualified-type id-start)
                           ;; It's an identifier that has been used as
                           ;; a type somewhere else.
                           'found
@@ -7799,6 +7807,37 @@ comment at the start of cc-engine.el for more info."
      (prog1 (car ,ps)
        (setq ,ps (cdr ,ps)))))
 
+(defun c-forward-over-compound-identifier ()
+  ;; Go over a possibly compound identifier, such as C++'s Foo::Bar::Baz,
+  ;; returning that identifier (with any syntactic WS removed).  Return nil if
+  ;; we're not at an identifier.
+  (when (c-on-identifier)
+    (let ((consolidated "") (consolidated-:: "")
+         start end)
+      (while
+       (progn
+        (setq start (point))
+        (c-forward-over-token)
+        (setq consolidated
+              (concat consolidated-::
+                      (buffer-substring-no-properties start (point))))
+        (c-forward-syntactic-ws)
+        (and c-opt-identifier-concat-key
+             (looking-at c-opt-identifier-concat-key)
+             (progn
+               (setq start (point))
+               (c-forward-over-token)
+               (setq end (point))
+               (c-forward-syntactic-ws)
+               (and
+                (c-on-identifier)
+                (setq consolidated-::
+                      (concat consolidated
+                              (buffer-substring-no-properties start end))))))))
+      (if (equal consolidated "")
+         nil
+       consolidated))))
+
 (defun c-back-over-compound-identifier ()
   ;; Point is putatively just after a "compound identifier", i.e. something
   ;; looking (in C++) like this "FQN::of::base::Class".  Move to the start of
@@ -7823,6 +7862,21 @@ comment at the start of cc-engine.el for more info."
       (goto-char end)
       t)))
 
+(defun c-check-qualified-type (from)
+  ;; Look up successive tails of a (possibly) qualified type in
+  ;; `c-found-types'.  If one of them matches, return it, else return nil.
+  (save-excursion
+    (goto-char from)
+    (let ((compound (c-forward-over-compound-identifier)))
+      (when compound
+       (while (and c-opt-identifier-concat-key
+                   (> (length compound) 0)
+                   (not (gethash compound c-found-types))
+                   (string-match c-opt-identifier-concat-key compound))
+         (setq compound (substring compound (match-end 0))))
+        (and (gethash compound c-found-types)
+             compound)))))
+
 (defun c-back-over-member-initializer-braces ()
   ;; Point is just after a closing brace/parenthesis.  Try to parse this as a
   ;; C++ member initializer list, going back to just after the introducing ":"
diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el
index 742ac80..7dcfb10 100644
--- a/lisp/progmodes/cmacexp.el
+++ b/lisp/progmodes/cmacexp.el
@@ -383,7 +383,8 @@ Optional arg DISPLAY non-nil means show messages in the 
echo area."
                       (not (member (file-name-nondirectory shell-file-name)
                                    msdos-shells)))
                   (eq exit-status 0))
-             (zerop (nth 7 (file-attributes (expand-file-name tempname))))
+             (zerop (file-attribute-size
+                     (file-attributes (expand-file-name tempname))))
              (progn
                (goto-char (point-min))
                ;; Put the messages inside a comment, so they won't get in
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index 4f07fe9..6844e9b 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -26,9 +26,17 @@
 
 ;;; Code:
 
+;; The namespacing of this package is a mess:
+;; - The file name is "etags", but the "exported" functionality doesn't use
+;;   this name
+;; - Uses "etags-", "tags-", and "tag-" prefixes.
+;; - Many functions use "-tag-" or "-tags-", or even "-etags-" not as
+;;   prefixes but somewhere within the name.
+
 (require 'ring)
 (require 'button)
 (require 'xref)
+(require 'multifile)
 
 ;;;###autoload
 (defvar tags-file-name nil
@@ -49,7 +57,6 @@ Use the `etags' program to make a tags table file.")
   "Whether tags operations should be case-sensitive.
 A value of t means case-insensitive, a value of nil means case-sensitive.
 Any other value means use the setting of `case-fold-search'."
-  :group 'etags
   :type '(choice (const :tag "Case-sensitive" nil)
                 (const :tag "Case-insensitive" t)
                 (other :tag "Use default" default))
@@ -63,7 +70,6 @@ An element that is a directory means the file \"TAGS\" in 
that directory.
 To switch to a new list of tags tables, setting this variable is sufficient.
 If you set this variable, do not also set `tags-file-name'.
 Use the `etags' program to make a tags table file."
-  :group 'etags
   :type '(repeat file))
 
 ;;;###autoload
@@ -72,8 +78,7 @@ Use the `etags' program to make a tags table file."
   "List of extensions tried by etags when `auto-compression-mode' is on.
 An empty string means search the non-compressed file."
   :version "24.1"                      ; added xz
-  :type  '(repeat string)
-  :group 'etags)
+  :type  '(repeat string))
 
 ;; !!! tags-compression-info-list should probably be replaced by access
 ;; to directory list and matching jka-compr-compression-info-list. Currently,
@@ -91,14 +96,12 @@ An empty string means search the non-compressed file."
 t means do; nil means don't (always start a new list).
 Any other value means ask the user whether to add a new tags table
 to the current list (as opposed to starting a new list)."
-  :group 'etags
   :type '(choice (const :tag "Do" t)
                 (const :tag "Don't" nil)
                 (other :tag "Ask" ask-user)))
 
 (defcustom tags-revert-without-query nil
   "Non-nil means reread a TAGS table without querying, if it has changed."
-  :group 'etags
   :type 'boolean)
 
 (defvar tags-table-computed-list nil
@@ -131,7 +134,6 @@ Each element is a list of strings which are file names.")
   "Hook to be run by \\[find-tag] after finding a tag.  See `run-hooks'.
 The value in the buffer in which \\[find-tag] is done is used,
 not the value in the buffer \\[find-tag] goes to."
-  :group 'etags
   :type 'hook)
 
 ;;;###autoload
@@ -140,7 +142,6 @@ not the value in the buffer \\[find-tag] goes to."
 If nil, and the symbol that is the value of `major-mode'
 has a `find-tag-default-function' property (see `put'), that is used.
 Otherwise, `find-tag-default' is used."
-  :group 'etags
   :type '(choice (const nil) function))
 
 (define-obsolete-variable-alias 'find-tag-marker-ring-length
@@ -148,13 +149,11 @@ Otherwise, `find-tag-default' is used."
 
 (defcustom tags-tag-face 'default
   "Face for tags in the output of `tags-apropos'."
-  :group 'etags
   :type 'face
   :version "21.1")
 
 (defcustom tags-apropos-verbose nil
   "If non-nil, print the name of the tags file in the *Tags List* buffer."
-  :group 'etags
   :type 'boolean
   :version "21.1")
 
@@ -175,7 +174,6 @@ Example value:
    ((\"Emacs Lisp\" Info-goto-emacs-command-node obarray)
     (\"Common Lisp\" common-lisp-hyperspec common-lisp-hyperspec-obarray)
     (\"SCWM\" scwm-documentation scwm-obarray))"
-  :group 'etags
   :type '(repeat (list (string :tag "Title")
                       function
                       (sexp :tag "Tags to search")))
@@ -209,9 +207,6 @@ use function `tags-table-files' to do so.")
 
 (defvar tags-included-tables nil
   "List of tags tables included by the current tags table.")
-
-(defvar next-file-list nil
-  "List of files for \\[next-file] to process.")
 
 ;; Hooks for file formats.
 
@@ -328,10 +323,10 @@ file the tag was in."
 
 (defun tags-table-check-computed-list ()
   "Compute `tags-table-computed-list' from `tags-table-list' if necessary."
-  (let ((expanded-list (mapcar 'tags-expand-table-name tags-table-list)))
+  (let ((expanded-list (mapcar #'tags-expand-table-name tags-table-list)))
     (or (equal tags-table-computed-list-for expanded-list)
        ;; The list (or default-directory) has changed since last computed.
-       (let* ((compute-for (mapcar 'copy-sequence expanded-list))
+       (let* ((compute-for (mapcar #'copy-sequence expanded-list))
               (tables (copy-sequence compute-for)) ;Mutated in the loop.
               (computed nil)
               table-buffer)
@@ -351,7 +346,7 @@ file the tag was in."
                     (if (tags-included-tables)
                         ;; Insert the included tables into the list we
                         ;; are processing.
-                        (setcdr tables (nconc (mapcar 'tags-expand-table-name
+                        (setcdr tables (nconc (mapcar #'tags-expand-table-name
                                                       (tags-included-tables))
                                               (cdr tables))))))
              ;; This table is not in core yet.  Insert a placeholder
@@ -502,7 +497,7 @@ buffers.  If CORE-ONLY is nil, it is ignored."
          ;; Select the tags table buffer and get the file list up to date.
          (let ((tags-file-name (car tables)))
            (visit-tags-table-buffer 'same)
-           (if (member this-file (mapcar 'expand-file-name
+           (if (member this-file (mapcar #'expand-file-name
                                          (tags-table-files)))
                ;; Found it.
                (setq found tables))))
@@ -853,7 +848,7 @@ If no tags table is loaded, do nothing and return nil."
 (defun find-tag--default ()
   (funcall (or find-tag-default-function
                (get major-mode 'find-tag-default-function)
-               'find-tag-default)))
+               #'find-tag-default)))
 
 (defvar last-tag nil
   "Last tag found by \\[find-tag].")
@@ -1698,18 +1693,14 @@ Point should be just after a string that matches TAG."
     (let ((bol (point)))
       (and (search-forward "\177" (line-end-position) t)
           (re-search-backward re bol t)))))
-
-(defcustom tags-loop-revert-buffers nil
-  "Non-nil means tags-scanning loops should offer to reread changed files.
-These loops normally read each file into Emacs, but when a file
-is already visited, they use the existing buffer.
-When this flag is non-nil, they offer to revert the existing buffer
-in the case where the file has changed since you visited it."
-  :type 'boolean
-  :group 'etags)
+(define-obsolete-variable-alias 'tags-loop-revert-buffers 
'multifile-revert-buffers "27.1")
 
 ;;;###autoload
-(defun next-file (&optional initialize novisit)
+(defalias 'next-file 'tags-next-file)
+(make-obsolete 'next-file
+               "use tags-next-file or multifile-initialize and 
multifile-next-file instead" "27.1")
+;;;###autoload
+(defun tags-next-file (&optional initialize novisit)
   "Select next file among files in current tags table.
 
 A first argument of t (prefix arg, if interactive) initializes to the
@@ -1723,71 +1714,39 @@ Value is nil if the file was already visited;
 if the file was newly read in, the value is the filename."
   ;; Make the interactive arg t if there was any prefix arg.
   (interactive (list (if current-prefix-arg t)))
-  (cond ((not initialize)
-        ;; Not the first run.
-        )
-       ((eq initialize t)
-        ;; Initialize the list from the tags table.
-        (save-excursion
-           (let ((cbuf (current-buffer)))
-             ;; Visit the tags table buffer to get its list of files.
-             (visit-tags-table-buffer)
-             ;; Copy the list so we can setcdr below, and expand the file
-             ;; names while we are at it, in this buffer's default directory.
-             (setq next-file-list (mapcar 'expand-file-name 
(tags-table-files)))
-             ;; Iterate over all the tags table files, collecting
-             ;; a complete list of referenced file names.
-             (while (visit-tags-table-buffer t cbuf)
-               ;; Find the tail of the working list and chain on the new
-               ;; sublist for this tags table.
-               (let ((tail next-file-list))
-                 (while (cdr tail)
-                   (setq tail (cdr tail)))
-                 ;; Use a copy so the next loop iteration will not modify the
-                 ;; list later returned by (tags-table-files).
-                 (if tail
-                     (setcdr tail (mapcar 'expand-file-name 
(tags-table-files)))
-                   (setq next-file-list (mapcar 'expand-file-name
-                                                (tags-table-files)))))))))
-       (t
-        ;; Initialize the list by evalling the argument.
-        (setq next-file-list (eval initialize))))
-  (unless next-file-list
-    (and novisit
-        (get-buffer " *next-file*")
-        (kill-buffer " *next-file*"))
-    (user-error "All files processed"))
-  (let* ((next (car next-file-list))
-        (buffer (get-file-buffer next))
-        (new (not buffer)))
-    ;; Advance the list before trying to find the file.
-    ;; If we get an error finding the file, don't get stuck on it.
-    (setq next-file-list (cdr next-file-list))
-    ;; Optionally offer to revert buffers
-    ;; if the files have changed on disk.
-    (and buffer tags-loop-revert-buffers
-        (not (verify-visited-file-modtime buffer))
-        (y-or-n-p
-         (format
-          (if (buffer-modified-p buffer)
-              "File %s changed on disk.  Discard your edits? "
-            "File %s changed on disk.  Reread from disk? ")
-          next))
-        (with-current-buffer buffer
-          (revert-buffer t t)))
-    (if (not (and new novisit))
-       (find-file next)
-      ;; Like find-file, but avoids random warning messages.
-      (switch-to-buffer (get-buffer-create " *next-file*"))
-      (kill-all-local-variables)
-      (erase-buffer)
-      (setq new next)
-      (insert-file-contents new nil))
-    new))
+  (when initialize ;; Not the first run.
+    (tags--compat-initialize initialize))
+  (multifile-next-file novisit)
+  (switch-to-buffer (current-buffer)))
 
+(defun tags--all-files ()
+  (save-excursion
+    (let ((cbuf (current-buffer))
+          (files nil))
+      ;; Visit the tags table buffer to get its list of files.
+      (visit-tags-table-buffer)
+      ;; Copy the list so we can setcdr below, and expand the file
+      ;; names while we are at it, in this buffer's default directory.
+      (setq files (mapcar #'expand-file-name (tags-table-files)))
+      ;; Iterate over all the tags table files, collecting
+      ;; a complete list of referenced file names.
+      (while (visit-tags-table-buffer t cbuf)
+        ;; Find the tail of the working list and chain on the new
+        ;; sublist for this tags table.
+        (let ((tail files))
+          (while (cdr tail)
+            (setq tail (cdr tail)))
+          ;; Use a copy so the next loop iteration will not modify the
+          ;; list later returned by (tags-table-files).
+          (setf (if tail (cdr tail) files)
+                (mapcar #'expand-file-name (tags-table-files)))))
+      files)))
+
+(make-obsolete-variable 'tags-loop-operate 'multifile-initialize "27.1")
 (defvar tags-loop-operate nil
   "Form for `tags-loop-continue' to eval to change one file.")
 
+(make-obsolete-variable 'tags-loop-scan 'multifile-initialize "27.1")
 (defvar tags-loop-scan
   '(user-error "%s"
               (substitute-command-keys
@@ -1805,121 +1764,84 @@ Bind `case-fold-search' during the evaluation, 
depending on the value of
                            case-fold-search)))
     (eval form)))
 
+(defun tags--compat-files (files)
+  (cond
+   ((eq files t) (tags--all-files)) ;; Initialize the list from the tags table.
+   ((functionp files) files)
+   ((stringp (car-safe files)) files)
+   (t
+    ;; Backward compatibility <27.1
+    ;; Initialize the list by evalling the argument.
+    (eval files))))
+
+(defun tags--compat-initialize (initialize)
+  (multifile-initialize
+   (tags--compat-files initialize)
+   (if tags-loop-operate
+       (lambda () (tags-loop-eval tags-loop-operate))
+     (lambda () (message "Scanning file %s...found" buffer-file-name) nil))
+   (lambda () (tags-loop-eval tags-loop-scan))))
 
 ;;;###autoload
 (defun tags-loop-continue (&optional first-time)
   "Continue last \\[tags-search] or \\[tags-query-replace] command.
 Used noninteractively with non-nil argument to begin such a command (the
-argument is passed to `next-file', which see).
-
-Two variables control the processing we do on each file: the value of
-`tags-loop-scan' is a form to be executed on each file to see if it is
-interesting (it returns non-nil if so) and `tags-loop-operate' is a form to
-evaluate to operate on an interesting file.  If the latter evaluates to
-nil, we exit; otherwise we scan the next file."
+argument is passed to `next-file', which see)."
+  ;; Two variables control the processing we do on each file: the value of
+  ;; `tags-loop-scan' is a form to be executed on each file to see if it is
+  ;; interesting (it returns non-nil if so) and `tags-loop-operate' is a form 
to
+  ;; evaluate to operate on an interesting file.  If the latter evaluates to
+  ;; nil, we exit; otherwise we scan the next file.
+  (declare (obsolete multifile-continue "27.1"))
   (interactive)
-  (let (new
-       ;; Non-nil means we have finished one file
-       ;; and should not scan it again.
-       file-finished
-       original-point
-       (messaged nil))
-    (while
-       (progn
-         ;; Scan files quickly for the first or next interesting one.
-         ;; This starts at point in the current buffer.
-         (while (or first-time file-finished
-                    (save-restriction
-                      (widen)
-                      (not (tags-loop-eval tags-loop-scan))))
-           ;; If nothing was found in the previous file, and
-           ;; that file isn't in a temp buffer, restore point to
-           ;; where it was.
-           (when original-point
-             (goto-char original-point))
-
-           (setq file-finished nil)
-           (setq new (next-file first-time t))
-
-           ;; If NEW is non-nil, we got a temp buffer,
-           ;; and NEW is the file name.
-           (when (or messaged
-                     (and (not first-time)
-                          (> baud-rate search-slow-speed)
-                          (setq messaged t)))
-             (message "Scanning file %s..." (or new buffer-file-name)))
-
-           (setq first-time nil)
-           (setq original-point (if new nil (point)))
-           (goto-char (point-min)))
+  (when first-time ;; Backward compatibility.
+    (tags--compat-initialize first-time))
+  (multifile-continue))
 
-         ;; If we visited it in a temp buffer, visit it now for real.
-         (if new
-             (let ((pos (point)))
-               (erase-buffer)
-               (set-buffer (find-file-noselect new))
-               (setq new nil)          ;No longer in a temp buffer.
-               (widen)
-               (goto-char pos))
-           (push-mark original-point t))
-
-         (switch-to-buffer (current-buffer))
-
-         ;; Now operate on the file.
-         ;; If value is non-nil, continue to scan the next file.
-          (save-restriction
-            (widen)
-            (tags-loop-eval tags-loop-operate)))
-      (setq file-finished t))
-    (and messaged
-        (null tags-loop-operate)
-        (message "Scanning file %s...found" buffer-file-name))))
+;; We use it to detect when the last loop was a tags-search.
+(defvar tags--last-search-operate-function nil)
 
 ;;;###autoload
-(defun tags-search (regexp &optional file-list-form)
+(defun tags-search (regexp &optional files)
   "Search through all files listed in tags table for match for REGEXP.
 Stops when a match is found.
 To continue searching for next match, use command \\[tags-loop-continue].
 
-If FILE-LIST-FORM is non-nil, it should be a form that, when
-evaluated, will return a list of file names.  The search will be
-restricted to these files.
+If FILES if non-nil should be a list or an iterator returning the files to 
search.
+The search will be restricted to these files.
 
 Also see the documentation of the `tags-file-name' variable."
   (interactive "sTags search (regexp): ")
-  (if (and (equal regexp "")
-          (eq (car tags-loop-scan) 're-search-forward)
-          (null tags-loop-operate))
-      ;; Continue last tags-search as if by M-,.
-      (tags-loop-continue nil)
-    (setq tags-loop-scan `(re-search-forward ',regexp nil t)
-         tags-loop-operate nil)
-    (tags-loop-continue (or file-list-form t))))
+  (unless (and (equal regexp "")
+               ;; FIXME: If some other multifile operation took place,
+               ;; rather than search for "", we should repeat the last search!
+              (eq multifile--operate-function
+                   tags--last-search-operate-function))
+    (multifile-initialize-search
+     regexp
+     (tags--compat-files (or files t))
+     tags-case-fold-search)
+    ;; Store it, so we can detect if some other multifile operation took
+    ;; place since the last search!
+    (setq tags--last-search-operate-function multifile--operate-function))
+  (multifile-continue))
 
 ;;;###autoload
-(defun tags-query-replace (from to &optional delimited file-list-form)
+(defun tags-query-replace (from to &optional delimited files)
   "Do `query-replace-regexp' of FROM with TO on all files listed in tags table.
 Third arg DELIMITED (prefix arg) means replace only word-delimited matches.
 If you exit (\\[keyboard-quit], RET or q), you can resume the query replace
 with the command \\[tags-loop-continue].
-Fourth arg FILE-LIST-FORM non-nil means initialize the replacement loop.
-
-If FILE-LIST-FORM is non-nil, it is a form to evaluate to
-produce the list of files to search.
-
-See also the documentation of the variable `tags-file-name'."
+For non-interactive use, superceded by `multifile-initialize-replace'."
+  (declare (advertised-calling-convention (from to &optional delimited) 
"27.1"))
   (interactive (query-replace-read-args "Tags query replace (regexp)" t t))
-  (setq tags-loop-scan `(let ,(unless (equal from (downcase from))
-                               '((case-fold-search nil)))
-                         (if (re-search-forward ',from nil t)
-                             ;; When we find a match, move back
-                             ;; to the beginning of it so perform-replace
-                             ;; will see it.
-                             (goto-char (match-beginning 0))))
-       tags-loop-operate `(perform-replace ',from ',to t t ',delimited
-                                           nil multi-query-replace-map))
-  (tags-loop-continue (or file-list-form t)))
-
+  (multifile-initialize-replace
+   from to
+   (tags--compat-files (or files t))
+   (if (equal from (downcase from)) nil 'default)
+   delimited)
+  (multifile-continue))
+
 (defun tags-complete-tags-table-file (string predicate what) ; Doc string?
   (save-excursion
     ;; If we need to ask for the tag table, allow that.
@@ -1976,7 +1898,8 @@ directory specification."
          (funcall tags-apropos-function regexp))))
     (etags-tags-apropos-additional regexp))
   (with-current-buffer "*Tags List*"
-    (eval-and-compile (require 'apropos))
+    (require 'apropos)
+    (declare-function apropos-mode "apropos")
     (apropos-mode)
     ;; apropos-mode is derived from fundamental-mode and it kills
     ;; all local variables.
@@ -2006,14 +1929,14 @@ see the doc of that variable if you want to add names 
to the list."
     (when tags-table-list
       (setq desired-point (point-marker))
       (setq b (point))
-      (princ (mapcar 'abbreviate-file-name tags-table-list) (current-buffer))
+      (princ (mapcar #'abbreviate-file-name tags-table-list) (current-buffer))
       (make-text-button b (point) 'type 'tags-select-tags-table
                         'etags-table (car tags-table-list))
       (insert "\n"))
     (while set-list
       (unless (eq (car set-list) tags-table-list)
        (setq b (point))
-       (princ (mapcar 'abbreviate-file-name (car set-list)) (current-buffer))
+       (princ (mapcar #'abbreviate-file-name (car set-list)) (current-buffer))
        (make-text-button b (point) 'type 'tags-select-tags-table
                           'etags-table (car (car set-list)))
        (insert "\n"))
@@ -2027,9 +1950,9 @@ see the doc of that variable if you want to add names to 
the list."
                         'etags-table tags-file-name)
       (insert "\n"))
     (setq set-list (delete tags-file-name
-                          (apply 'nconc (cons (copy-sequence tags-table-list)
-                                              (mapcar 'copy-sequence
-                                                      tags-table-set-list)))))
+                          (apply #'nconc (cons (copy-sequence tags-table-list)
+                                               (mapcar #'copy-sequence
+                                                       tags-table-set-list)))))
     (while set-list
       (setq b (point))
       (insert (abbreviate-file-name (car set-list)))
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 6fee895..da979de 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -1780,9 +1780,10 @@ static char *magick[] = {
 (defvar gdb-control-commands-regexp
   (concat
    "^\\("
-   "commands\\|if\\|while\\|define\\|document\\|"
+   "comm\\(a\\(n\\(ds?\\)?\\)?\\)?\\|if\\|while"
+   "\\|def\\(i\\(ne?\\)?\\)?\\|doc\\(u\\(m\\(e\\(nt?\\)?\\)?\\)?\\)?\\|"
    gdb-python-guile-commands-regexp
-   "\\|while-stepping\\|stepping\\|ws\\|actions"
+   "\\|while-stepping\\|stepp\\(i\\(ng?\\)?\\)?\\|ws\\|actions"
    "\\)\\([[:blank:]]+\\([^[:blank:]]*\\)\\)?$")
   "Regexp matching GDB commands that enter a recursive reading loop.
 As long as GDB is in the recursive reading loop, it does not expect
diff --git a/lisp/progmodes/idlw-shell.el b/lisp/progmodes/idlw-shell.el
index 616341b..46e2eca 100644
--- a/lisp/progmodes/idlw-shell.el
+++ b/lisp/progmodes/idlw-shell.el
@@ -1,4 +1,4 @@
-;; idlw-shell.el --- run IDL as an inferior process of Emacs.
+;; idlw-shell.el --- run IDL as an inferior process of Emacs.  -*- 
lexical-binding:t -*-
 
 ;; Copyright (C) 1999-2018 Free Software Foundation, Inc.
 
@@ -1115,8 +1115,7 @@ IDL has currently stepped.")
        (setq idlwave-shell-display-wframe
              (if (eq (selected-frame) idlwave-shell-idl-wframe)
                  (or
-                  (let ((flist (visible-frame-list))
-                        (frame (selected-frame)))
+                  (let ((flist (visible-frame-list)))
                     (catch 'exit
                       (while flist
                         (if (not (eq (car flist)
@@ -1142,7 +1141,7 @@ IDL has currently stepped.")
              (make-frame idlwave-shell-frame-parameters)))))
 
 ;;;###autoload
-(defun idlwave-shell (&optional arg quick)
+(defun idlwave-shell (&optional arg)
   "Run an inferior IDL, with I/O through buffer `(idlwave-shell-buffer)'.
 If buffer exists but shell process is not running, start new IDL.
 If buffer exists and shell process is running, just switch to the buffer.
@@ -1881,10 +1880,10 @@ directory."
                              'idlwave-shell-filter-directory
                              'hide 'wait))
 
-(defun idlwave-shell-retall (&optional arg)
+(defun idlwave-shell-retall ()
   "Return from the entire calling stack.
 Also get rid of widget events in the queue."
-  (interactive "P")
+  (interactive)
   (save-selected-window
     ;;if (widget_info(/MANAGED))[0] gt 0 then for 
i=0,n_elements(widget_info(/MANAGED))-1 do 
widget_control,(widget_info(/MANAGED))[i],/clear_events &
     (idlwave-shell-send-command "retall" nil
@@ -1892,9 +1891,9 @@ Also get rid of widget events in the queue."
                                nil t)
     (idlwave-shell-display-line nil)))
 
-(defun idlwave-shell-closeall (&optional arg)
+(defun idlwave-shell-closeall ()
   "Close all open files."
-  (interactive "P")
+  (interactive)
   (idlwave-shell-send-command "close,/all" nil
                              (idlwave-shell-hide-p 'misc) nil t))
 
@@ -2157,7 +2156,7 @@ keywords."
       (if entry (setq idlw-help-link (cdr entry)))) ; setting dynamic variable!
      (t (error "This should not happen")))))
 
-(defun idlwave-shell-complete-filename (&optional arg)
+(defun idlwave-shell-complete-filename ()
   "Complete a file name at point if after a file name.
 We assume that we are after a file name when completing one of the
 args of an executive .run, .rnew or .compile."
@@ -2739,10 +2738,9 @@ Runs to the last statement and then steps 1 statement.  
Use the .out command."
         (bp-alist idlwave-shell-bp-alist)
         (orig-func (if (> dir 0) '> '<))
         (closer-func (if (> dir 0) '< '>))
-        bp got-bp bp-line cur-line)
+        bp bp-line cur-line)
     (while (setq bp (pop bp-alist))
       (when (string= file (car (car bp)))
-       (setq got-bp 1)
        (setq cur-line (nth 1 (car bp)))
        (if (and
             (funcall orig-func cur-line orig-bp-line)
@@ -2759,6 +2757,8 @@ Runs to the last statement and then steps 1 statement.  
Use the .out command."
   (interactive "P")
   (idlwave-shell-print arg 'help))
 
+(defvar zmacs-regions)
+
 (defmacro idlwave-shell-mouse-examine (help &optional ev)
   "Create a function for generic examination of expressions."
   `(lambda (event)
@@ -2782,7 +2782,7 @@ Runs to the last statement and then steps 1 statement.  
Use the .out command."
 
 ;; Begin terrible hack section -- XEmacs tests for button2 explicitly
 ;; on drag events, calling drag-n-drop code if detected.  Ughhh...
-(defun idlwave-default-mouse-track-event-is-with-button (event n)
+(defun idlwave-default-mouse-track-event-is-with-button (_event _n)
   t)
 
 (defun idlwave-xemacs-hack-mouse-track (event)
@@ -3193,22 +3193,20 @@ size(___,/DIMENSIONS)"
                      output-begin output-end buffer))))
 
 (defun idlwave-shell-delete-output-overlay ()
-  (unless (or (eq this-command 'idlwave-shell-mouse-nop)
-             (eq this-command 'handle-switch-frame))
+  (unless (memql this-command '(ignore handle-switch-frame))
     (condition-case nil
        (if idlwave-shell-output-overlay
            (delete-overlay idlwave-shell-output-overlay))
       (error nil))
-    (remove-hook 'pre-command-hook 'idlwave-shell-delete-output-overlay)))
+    (remove-hook 'pre-command-hook #'idlwave-shell-delete-output-overlay)))
 
 (defun idlwave-shell-delete-expression-overlay ()
-  (unless (or (eq this-command 'idlwave-shell-mouse-nop)
-             (eq this-command 'handle-switch-frame))
+  (unless (memql this-command '(ignore handle-switch-frame))
     (condition-case nil
        (if idlwave-shell-expression-overlay
            (delete-overlay idlwave-shell-expression-overlay))
       (error nil))
-    (remove-hook 'pre-command-hook 'idlwave-shell-delete-expression-overlay)))
+    (remove-hook 'pre-command-hook #'idlwave-shell-delete-expression-overlay)))
 
 (defvar idlwave-shell-bp-alist nil
   "Alist of breakpoints.
@@ -3591,7 +3589,7 @@ Existing overlays are recycled, in order to minimize 
consumption."
          (bp-list idlwave-shell-bp-alist)
          (use-glyph (and (memq idlwave-shell-mark-breakpoints '(t glyph))
                          idlwave-shell-bp-glyph))
-         ov ov-list bp buf old-buffers win)
+         ov ov-list bp buf old-buffers)
 
       ;; Delete the old overlays from their buffers
       (if ov-alist
@@ -3798,9 +3796,9 @@ only for glyphs)."
         (t
          (message "Unimplemented: %s" select))))))
 
-(defun idlwave-shell-edit-default-command-line (arg)
+(defun idlwave-shell-edit-default-command-line ()
   "Edit the current execute command."
-  (interactive "P")
+  (interactive)
   (setq idlwave-shell-command-line-to-execute
        (read-string "IDL> " idlwave-shell-command-line-to-execute)))
 
@@ -4057,9 +4055,56 @@ Otherwise, just expand the file name."
 
 ;; Keybindings ------------------------------------------------------------
 
-(defvar idlwave-shell-mode-map (copy-keymap comint-mode-map)
+(defvar idlwave-shell-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map comint-mode-map)
+
+    ;;(define-key map "\M-?" 'comint-dynamic-list-completions)
+    ;;(define-key map "\t" 'comint-dynamic-complete)
+
+    (define-key map "\C-w"     'comint-kill-region)
+    (define-key map "\t"       'idlwave-shell-complete)
+    (define-key map "\M-\t"    'idlwave-shell-complete)
+    (define-key map "\C-c\C-s" 'idlwave-shell)
+    (define-key map "\C-c?"    'idlwave-routine-info)
+    (define-key map "\C-g"     'idlwave-keyboard-quit)
+    (define-key map "\M-?"     'idlwave-context-help)
+    (define-key map [(control meta ?\?)]
+      'idlwave-help-assistant-help-with-topic)
+    (define-key map "\C-c\C-i" 'idlwave-update-routine-info)
+    (define-key map "\C-c\C-y" 'idlwave-shell-char-mode-loop)
+    (define-key map "\C-c\C-x" 'idlwave-shell-send-char)
+    (define-key map "\C-c="    'idlwave-resolve)
+    (define-key map "\C-c\C-v" 'idlwave-find-module)
+    (define-key map "\C-c\C-k" 'idlwave-kill-autoloaded-buffers)
+    (define-key map idlwave-shell-prefix-key
+      'idlwave-shell-debug-map)
+    (define-key map [(up)]  'idlwave-shell-up-or-history)
+    (define-key map [(down)] 'idlwave-shell-down-or-history)
+    (define-key idlwave-shell-mode-map
+      (if (featurep 'xemacs) [(shift button3)] [(shift mouse-3)])
+      'idlwave-mouse-context-help)
+    map)
   "Keymap for `idlwave-mode'.")
-(defvar idlwave-shell-electric-debug-mode-map (make-sparse-keymap))
+
+(defvar idlwave-shell-electric-debug-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;; A few extras in the electric debug map
+    (define-key map " " 'idlwave-shell-step)
+    (define-key map "+" 'idlwave-shell-stack-up)
+    (define-key map "=" 'idlwave-shell-stack-up)
+    (define-key map "-" 'idlwave-shell-stack-down)
+    (define-key map "_" 'idlwave-shell-stack-down)
+    (define-key map "e" (lambda () (interactive) (idlwave-shell-print '(16))))
+    (define-key map "q" 'idlwave-shell-retall)
+    (define-key map "t"
+      (lambda () (interactive) (idlwave-shell-send-command "help,/TRACE")))
+    (define-key map [(control ??)]  'idlwave-shell-electric-debug-help)
+    (define-key map "x"
+      (lambda (arg) (interactive "P")
+        (idlwave-shell-print arg nil nil t)))
+    map))
+
 (defvar idlwave-shell-mode-prefix-map (make-sparse-keymap))
 (fset 'idlwave-shell-mode-prefix-map idlwave-shell-mode-prefix-map)
 (defvar idlwave-mode-prefix-map (make-sparse-keymap))
@@ -4069,29 +4114,6 @@ Otherwise, just expand the file name."
   "Define a key in both the shell and buffer mode maps."
   (define-key idlwave-mode-map key hook)
   (define-key idlwave-shell-mode-map key hook))
-
-;(define-key idlwave-shell-mode-map "\M-?" 'comint-dynamic-list-completions)
-;(define-key idlwave-shell-mode-map "\t" 'comint-dynamic-complete)
-
-(define-key idlwave-shell-mode-map "\C-w"     'comint-kill-region)
-(define-key idlwave-shell-mode-map "\t"       'idlwave-shell-complete)
-(define-key idlwave-shell-mode-map "\M-\t"    'idlwave-shell-complete)
-(define-key idlwave-shell-mode-map "\C-c\C-s" 'idlwave-shell)
-(define-key idlwave-shell-mode-map "\C-c?"    'idlwave-routine-info)
-(define-key idlwave-shell-mode-map "\C-g"     'idlwave-keyboard-quit)
-(define-key idlwave-shell-mode-map "\M-?"     'idlwave-context-help)
-(define-key idlwave-shell-mode-map [(control meta ?\?)]
-  'idlwave-help-assistant-help-with-topic)
-(define-key idlwave-shell-mode-map "\C-c\C-i" 'idlwave-update-routine-info)
-(define-key idlwave-shell-mode-map "\C-c\C-y" 'idlwave-shell-char-mode-loop)
-(define-key idlwave-shell-mode-map "\C-c\C-x" 'idlwave-shell-send-char)
-(define-key idlwave-shell-mode-map "\C-c="    'idlwave-resolve)
-(define-key idlwave-shell-mode-map "\C-c\C-v" 'idlwave-find-module)
-(define-key idlwave-shell-mode-map "\C-c\C-k" 'idlwave-kill-autoloaded-buffers)
-(define-key idlwave-shell-mode-map idlwave-shell-prefix-key
-  'idlwave-shell-debug-map)
-(define-key idlwave-shell-mode-map [(up)]  'idlwave-shell-up-or-history)
-(define-key idlwave-shell-mode-map [(down)] 'idlwave-shell-down-or-history)
 (define-key idlwave-mode-map "\C-c\C-y" 'idlwave-shell-char-mode-loop)
 (define-key idlwave-mode-map "\C-c\C-x" 'idlwave-shell-send-char)
 
@@ -4112,22 +4134,12 @@ Otherwise, just expand the file name."
    [(control shift down-mouse-2)])
  'idlwave-shell-examine-select)
 ;; Add this one from the idlwave-mode-map
-(define-key idlwave-shell-mode-map
-  (if (featurep 'xemacs)
-      [(shift button3)]
-    [(shift mouse-3)])
-  'idlwave-mouse-context-help)
-
 ;; For Emacs, we need to turn off the button release events.
-(defun idlwave-shell-mouse-nop (event)
-  (interactive "e"))
+
 (unless (featurep 'xemacs)
-  (idlwave-shell-define-key-both
-   [(shift mouse-2)] 'idlwave-shell-mouse-nop)
-  (idlwave-shell-define-key-both
-   [(shift control mouse-2)] 'idlwave-shell-mouse-nop)
-  (idlwave-shell-define-key-both
-   [(control meta mouse-2)] 'idlwave-shell-mouse-nop))
+  (idlwave-shell-define-key-both [(shift mouse-2)] 'ignore)
+  (idlwave-shell-define-key-both [(shift control mouse-2)] 'ignore)
+  (idlwave-shell-define-key-both [(control meta mouse-2)] 'ignore))
 
 
 ;; The following set of bindings is used to bind the debugging keys.
@@ -4207,26 +4219,6 @@ Otherwise, just expand the file name."
        (define-key idlwave-shell-electric-debug-mode-map (char-to-string c2)
          cmd))))
 
-;; A few extras in the electric debug map
-(define-key idlwave-shell-electric-debug-mode-map " " 'idlwave-shell-step)
-(define-key idlwave-shell-electric-debug-mode-map "+" 'idlwave-shell-stack-up)
-(define-key idlwave-shell-electric-debug-mode-map "=" 'idlwave-shell-stack-up)
-(define-key idlwave-shell-electric-debug-mode-map "-"
-  'idlwave-shell-stack-down)
-(define-key idlwave-shell-electric-debug-mode-map "_"
-  'idlwave-shell-stack-down)
-(define-key idlwave-shell-electric-debug-mode-map "e"
-  (lambda () (interactive) (idlwave-shell-print '(16))))
-(define-key idlwave-shell-electric-debug-mode-map "q" 'idlwave-shell-retall)
-(define-key idlwave-shell-electric-debug-mode-map "t"
-  (lambda () (interactive) (idlwave-shell-send-command "help,/TRACE")))
-(define-key idlwave-shell-electric-debug-mode-map [(control ??)]
-  'idlwave-shell-electric-debug-help)
-(define-key idlwave-shell-electric-debug-mode-map "x"
-  (lambda (arg) (interactive "P")
-    (idlwave-shell-print arg nil nil t)))
-
-
 ; Enter the prefix map in two places.
 (fset 'idlwave-debug-map       idlwave-mode-prefix-map)
 (fset 'idlwave-shell-debug-map idlwave-shell-mode-prefix-map)
@@ -4254,43 +4246,32 @@ Otherwise, just expand the file name."
 
 When Idlwave Shell Electric Debug mode is enabled, the Idlwave
 Shell debugging commands are available as single key sequences."
-  nil " *Debugging*" idlwave-shell-electric-debug-mode-map)
-
-(add-hook
- 'idlwave-shell-electric-debug-mode-on-hook
- (lambda ()
-   (set (make-local-variable 'idlwave-shell-electric-debug-read-only)
-       buffer-read-only)
-   (setq buffer-read-only t)
-   (add-to-list 'idlwave-shell-electric-debug-buffers (current-buffer))
-   (if idlwave-shell-stop-line-overlay
-       (overlay-put idlwave-shell-stop-line-overlay 'face
-                   idlwave-shell-electric-stop-line-face))
-   (if (facep 'fringe)
-       (set-face-foreground 'fringe idlwave-shell-electric-stop-color
-                           (selected-frame)))))
-
-(add-hook
- 'idlwave-shell-electric-debug-mode-off-hook
- (lambda ()
-   ;; Return to previous read-only state
-   (setq buffer-read-only (if (boundp 'idlwave-shell-electric-debug-read-only)
-                             idlwave-shell-electric-debug-read-only))
-   (setq idlwave-shell-electric-debug-buffers
-        (delq (current-buffer) idlwave-shell-electric-debug-buffers))
-   (if idlwave-shell-stop-line-overlay
-       (overlay-put idlwave-shell-stop-line-overlay 'face
-                   idlwave-shell-stop-line-face)
-     (if (facep 'fringe)
-        (set-face-foreground 'fringe (face-foreground 'default))))))
-
-;; easy-mmode defines electric-debug-mode for us, so we need to advise it.
-(defadvice idlwave-shell-electric-debug-mode (after print-enter activate)
-  "Print out an entrance message."
-  (when idlwave-shell-electric-debug-mode
+  :lighter " *Debugging*"
+  (cond
+   (idlwave-shell-electric-debug-mode
+    (set (make-local-variable 'idlwave-shell-electric-debug-read-only)
+        buffer-read-only)
+    (setq buffer-read-only t)
+    (add-to-list 'idlwave-shell-electric-debug-buffers (current-buffer))
+    (if idlwave-shell-stop-line-overlay
+        (overlay-put idlwave-shell-stop-line-overlay 'face
+                    idlwave-shell-electric-stop-line-face))
+    (if (facep 'fringe)
+        (set-face-foreground 'fringe idlwave-shell-electric-stop-color
+                            (selected-frame)))
     (message
      "Electric Debugging mode entered.  Press [C-?] for help, [q] to quit"))
-  (force-mode-line-update))
+   (t
+    ;; Return to previous read-only state
+    (setq buffer-read-only (if (boundp 'idlwave-shell-electric-debug-read-only)
+                              idlwave-shell-electric-debug-read-only))
+    (setq idlwave-shell-electric-debug-buffers
+         (delq (current-buffer) idlwave-shell-electric-debug-buffers))
+    (if idlwave-shell-stop-line-overlay
+        (overlay-put idlwave-shell-stop-line-overlay 'face
+                    idlwave-shell-stop-line-face)
+      (if (facep 'fringe)
+         (set-face-foreground 'fringe (face-foreground 'default)))))))
 
 ;; Turn it off in all relevant buffers
 (defvar idlwave-shell-electric-debug-buffers nil)
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index f30e591..3ce5af4 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -2368,23 +2368,22 @@ i.e., customize JSX element indentation with 
`sgml-basic-offset',
 
 ;; FIXME: Such redefinitions are bad style.  We should try and use some other
 ;; way to get the same result.
-(defadvice c-forward-sws (around js-fill-paragraph activate)
-  (if js--filling-paragraph
-      (setq ad-return-value (js--forward-syntactic-ws (ad-get-arg 0)))
-    ad-do-it))
-
-(defadvice c-backward-sws (around js-fill-paragraph activate)
-  (if js--filling-paragraph
-      (setq ad-return-value (js--backward-syntactic-ws (ad-get-arg 0)))
-    ad-do-it))
-
-(defadvice c-beginning-of-macro (around js-fill-paragraph activate)
-  (if js--filling-paragraph
-      (setq ad-return-value (js--beginning-of-macro (ad-get-arg 0)))
-    ad-do-it))
-
-(defun js-c-fill-paragraph (&optional justify)
-  "Fill the paragraph with `c-fill-paragraph'."
+(defun js--fill-c-advice (js-fun)
+  (lambda (orig-fun &rest args)
+    (if js--filling-paragraph
+        (funcall js-fun (car args))
+      (apply orig-fun args))))
+
+(advice-add 'c-forward-sws
+            :around (js--fill-c-advice #'js--forward-syntactic-ws))
+(advice-add 'c-backward-sws
+            :around (js--fill-c-advice #'js--backward-syntactic-ws))
+(advice-add 'c-beginning-of-macro
+            :around (js--fill-c-advice #'js--beginning-of-macro))
+
+(define-obsolete-function-alias 'js-c-fill-paragraph #'js-fill-paragraph 
"27.1")
+(defun js-fill-paragraph (&optional justify)
+  "Fill the paragraph for Javascript code."
   (interactive "*P")
   (let ((js--filling-paragraph t)
         (fill-paragraph-function #'c-fill-paragraph))
@@ -3875,7 +3874,7 @@ If one hasn't been set, or if it's stale, prompt for a 
new one."
   ;; Comments
   (setq-local comment-start "// ")
   (setq-local comment-end "")
-  (setq-local fill-paragraph-function #'js-c-fill-paragraph)
+  (setq-local fill-paragraph-function #'js-fill-paragraph)
   (setq-local normal-auto-fill-function #'js-do-auto-fill)
 
   ;; Parse cache
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index eab24e1..f3f29cb 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -189,6 +189,18 @@ to find the list of ignores for each directory."
 (cl-defmethod project-roots ((project (head transient)))
   (list (cdr project)))
 
+(cl-defgeneric project-files (project &optional dirs)
+  "Return a list of files in directories DIRS in PROJECT.
+DIRS is a list of absolute directories; it should be some
+subset of the project roots and external roots."
+  ;; This default implementation only works if project-file-completion-table
+  ;; returns a "flat" completion table.
+  ;; FIXME: Maybe we should do the reverse: implement the default
+  ;; `project-file-completion-table' on top of `project-files'.
+  (all-completions
+   "" (project-file-completion-table
+       project (or dirs (project-roots project)))))
+
 (defgroup project-vc nil
   "Project implementation using the VC package."
   :version "25.1"
@@ -389,12 +401,17 @@ recognized."
   ;; removing it when it has no matches.  Neither seems natural
   ;; enough.  Removal is confusing; early expansion makes the prompt
   ;; too long.
-  (let* ((new-prompt (if default
+  (let* (;; (initial-input
+         ;;  (let ((common-prefix (try-completion "" collection)))
+         ;;    (if (> (length common-prefix) 0)
+         ;;        (file-name-directory common-prefix))))
+         (new-prompt (if default
                          (format "%s (default %s): " prompt default)
                        (format "%s: " prompt)))
          (res (completing-read new-prompt
                                collection predicate t
-                               nil hist default inherit-input-method)))
+                               nil ;; initial-input
+                               hist default inherit-input-method)))
     (if (and (equal res default)
              (not (test-completion res collection predicate)))
         (completing-read (format "%s: " prompt)
@@ -402,5 +419,30 @@ recognized."
                          inherit-input-method)
       res)))
 
+(declare-function multifile-continue "multifile" ())
+
+;;;###autoload
+(defun project-search (regexp)
+  "Search for REGEXP in all the files of the project.
+Stops when a match is found.
+To continue searching for next match, use command \\[multifile-continue]."
+  (interactive "sSearch (regexp): ")
+  (multifile-initialize-search
+   regexp (project-files (project-current t)) 'default)
+  (multifile-continue))
+
+;;;###autoload
+(defun project-query-replace (from to)
+  "Search for REGEXP in all the files of the project.
+Stops when a match is found.
+To continue searching for next match, use command \\[multifile-continue]."
+  (interactive
+   (pcase-let ((`(,from ,to)
+                (query-replace-read-args "Query replace (regexp)" t t)))
+     (list from to)))
+  (multifile-initialize-replace
+   from to (project-files (project-current t)) 'default)
+  (multifile-continue))
+
 (provide 'project)
 ;;; project.el ends here
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index a895a77..3bcc9be 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -480,12 +480,6 @@ Legal values:
 
 ;; Keyboard
 
-(defcustom prolog-hungry-delete-key-flag nil
-  "Non-nil means delete key consumes all preceding spaces."
-  :version "24.1"
-  :group 'prolog-keyboard
-  :type 'boolean)
-
 (defcustom prolog-electric-dot-flag nil
   "Non-nil means make dot key electric.
 Electric dot appends newline or inserts head of a new clause.
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index c85fe67..c7ae40e 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -323,21 +323,23 @@ backward."
 (defcustom xref-prompt-for-identifier '(not xref-find-definitions
                                             xref-find-definitions-other-window
                                             xref-find-definitions-other-frame)
-  "When t, always prompt for the identifier name.
+  "If non-nil, prompt for the identifier to find.
+
+When t, always prompt for the identifier name.
 
 When nil, prompt only when there's no value at point we can use,
 or when the command has been called with the prefix argument.
 
-Otherwise, it's a list of xref commands which will prompt
-anyway (the value at point, if any, will be used as the default).
-
+Otherwise, it's a list of xref commands which will always prompt,
+with the identifier at point, if any, used as the default.
 If the list starts with `not', the meaning of the rest of the
-elements is negated."
-  :type '(choice (const :tag "always" t)
-                 (const :tag "auto" nil)
-                 (set :menu-tag "command specific" :tag "commands"
+elements is negated: these commands will NOT prompt."
+  :type '(choice (const :tag "Always prompt for identifier" t)
+                 (const :tag "Prompt if no identifier at point" nil)
+                 (set :menu-tag "Prompt according to command"
+                      :tag "Prompt according to command"
                      :value (not)
-                     (const :tag "Except" not)
+                     (const :tag "Except for commands listed below" not)
                      (repeat :inline t (symbol :tag "command")))))
 
 (defcustom xref-after-jump-hook '(recenter
diff --git a/lisp/ps-bdf.el b/lisp/ps-bdf.el
index 301142e..f9632f0 100644
--- a/lisp/ps-bdf.el
+++ b/lisp/ps-bdf.el
@@ -70,13 +70,12 @@ for BDFNAME."
 
 (defsubst bdf-file-mod-time (filename)
   "Return modification time of FILENAME.
-The value is a list of integers in the same format as `current-time'."
-  (nth 5 (file-attributes filename)))
+The value is a timestamp in the same format as `current-time'."
+  (file-attribute-modification-time (file-attributes filename)))
 
 (defun bdf-file-newer-than-time (filename mod-time)
   "Return non-nil if and only if FILENAME is newer than MOD-TIME.
-MOD-TIME is a modification time as a list of integers in the same
-format as `current-time'."
+MOD-TIME is a modification time in the same format as `current-time'."
   (let ((new-mod-time (bdf-file-mod-time filename)))
     (time-less-p mod-time new-mod-time)))
 
@@ -168,8 +167,7 @@ FONT-INFO is a list of the following format:
     (BDFFILE MOD-TIME FONT-BOUNDING-BOX
      RELATIVE-COMPOSE BASELINE-OFFSET CODE-RANGE MAXLEN OFFSET-VECTOR)
 
-MOD-TIME is last modification time as a list of integers in the
-same format as `current-time'.
+MOD-TIME is last modification time in the same format as `current-time'.
 
 SIZE is a size of the font on 72 dpi device.  This value is got
 from SIZE record of the font.
diff --git a/lisp/replace.el b/lisp/replace.el
index 20b868a..00b2cee 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1206,9 +1206,34 @@ To return to ordinary Occur mode, use 
\\[occur-cease-edit]."
            (move-to-column col)))))))
 
 
+(defun occur--parse-occur-buffer()
+  "Retrieve a list of the form (BEG END ORIG-LINE BUFFER).
+BEG and END define the region.
+ORIG-LINE and BUFFER are the line and the buffer from which
+the user called `occur'."
+  (save-excursion
+    (goto-char (point-min))
+    (let ((buffer (get-text-property (point) 'occur-title))
+          (beg-pos (get-text-property (point) 'region-start))
+          (end-pos (get-text-property (point) 'region-end))
+          (orig-line (get-text-property (point) 'current-line)))
+      (list beg-pos end-pos orig-line buffer))))
+
 (defun occur-revert-function (_ignore1 _ignore2)
   "Handle `revert-buffer' for Occur mode buffers."
-  (apply 'occur-1 (append occur-revert-arguments (list (buffer-name)))))
+  (if (cdr (nth 2 occur-revert-arguments)) ; multi-occur
+      (apply 'occur-1 (append occur-revert-arguments (list (buffer-name))))
+    (pcase-let ((`(,region-start ,region-end ,orig-line ,buffer)
+                 (occur--parse-occur-buffer))
+                (regexp (car occur-revert-arguments)))
+      (with-current-buffer buffer
+        (when (wholenump orig-line)
+          (goto-char (point-min))
+          (forward-line (1- orig-line)))
+        (save-excursion
+          (if (or region-start region-end)
+              (occur regexp nil (list (cons region-start region-end)))
+            (apply 'occur-1 (append occur-revert-arguments (list 
(buffer-name))))))))))
 
 (defun occur-mode-find-occurrence ()
   (let ((pos (get-text-property (point) 'occur-target)))
@@ -1651,7 +1676,7 @@ See also `multi-occur'."
                (matches 0)             ;; count of matches
                (curr-line              ;; line count
                 (or occur--region-start-line 1))
-               (orig-line occur--orig-line)
+               (orig-line (or occur--orig-line 1))
                (orig-line-shown-p)
                (prev-line nil)         ;; line number of prev match endpt
                (prev-after-lines nil)  ;; context lines of prev match
@@ -1701,6 +1726,8 @@ See also `multi-occur'."
                          (setq matches (1+ matches)))
                        (when (and list-matching-lines-jump-to-current-line
                                   (not multi-occur-p))
+                         (or orig-line (setq orig-line 1))
+                         (or nlines (setq nlines (line-number-at-pos 
(point-max))))
                          (when (= curr-line orig-line)
                            (add-face-text-property
                             0 len list-matching-lines-current-line-face nil 
curstring)
@@ -1859,7 +1886,9 @@ See also `multi-occur'."
                                       ""))
                             'read-only t))
                    (setq end (point))
-                   (add-text-properties beg end `(occur-title ,buf))
+                   (add-text-properties beg end `(occur-title ,buf 
current-line ,orig-line
+                                                              region-start 
,occur--region-start
+                                                              region-end 
,occur--region-end))
                    (when title-face
                      (add-face-text-property beg end title-face))
                    (goto-char (if (and list-matching-lines-jump-to-current-line
diff --git a/lisp/rfn-eshadow.el b/lisp/rfn-eshadow.el
index 41fd8b5..d6e9a1e 100644
--- a/lisp/rfn-eshadow.el
+++ b/lisp/rfn-eshadow.el
@@ -132,9 +132,7 @@ system, `file-name-shadow-properties' is used instead."
 
 ;; An overlay covering the shadowed part of the filename (local to the
 ;; minibuffer).
-(defvar rfn-eshadow-overlay)
-(make-variable-buffer-local 'rfn-eshadow-overlay)
-
+(defvar-local rfn-eshadow-overlay nil)
 
 ;;; Hook functions
 
diff --git a/lisp/saveplace.el b/lisp/saveplace.el
index 9d3f10a..f8f15ca 100644
--- a/lisp/saveplace.el
+++ b/lisp/saveplace.el
@@ -27,7 +27,7 @@
 ;; Automatically save place in files, so that visiting them later
 ;; (even during a different Emacs session) automatically moves point
 ;; to the saved position, when the file is first found.  Uses the
-;; value of buffer-local variable save-place to determine whether to
+;; value of buffer-local variable save-place-mode to determine whether to
 ;; save position or not.
 ;;
 ;; Thanks to Stefan Schoef, who sent a patch with the
@@ -176,7 +176,7 @@ file:
 
 (defun save-place-to-alist ()
   ;; put filename and point in a cons box and then cons that onto the
-  ;; front of the save-place-alist, if save-place is non-nil.
+  ;; front of the save-place-alist, if save-place-mode is non-nil.
   ;; Otherwise, just delete that file from the alist.
   ;; first check to make sure alist has been loaded in from the master
   ;; file.  If not, do so, then feel free to modify the alist.  It
@@ -306,8 +306,8 @@ may have changed) back to `save-place-alist'."
           nil))))
 
 (defun save-places-to-alist ()
-  ;; go through buffer-list, saving places to alist if save-place is
-  ;; non-nil, deleting them from alist if it is nil.
+  ;; go through buffer-list, saving places to alist if save-place-mode
+  ;; is non-nil, deleting them from alist if it is nil.
   (let ((buf-list (buffer-list)))
     (while buf-list
       ;; put this into a save-excursion in case someone is counting on
@@ -332,7 +332,7 @@ may have changed) back to `save-place-alist'."
              (and (integerp (cdr cell))
                   (goto-char (cdr cell))))
           ;; and make sure it will be saved again for later
-          (setq save-place t)))))
+          (setq save-place-mode t)))))
 
 (declare-function dired-goto-file "dired" (file))
 
@@ -357,7 +357,7 @@ may have changed) back to `save-place-alist'."
               ((and (listp (cdr cell)) (assq 'dired-filename (cdr cell)))
                (dired-goto-file (cdr (assq 'dired-filename (cdr cell)))))))
           ;; and make sure it will be saved again for later
-          (setq save-place t)))))
+          (setq save-place-mode t)))))
 
 (defun save-place-kill-emacs-hook ()
   ;; First update the alist.  This loads the old save-place-file if nec.
diff --git a/lisp/server.el b/lisp/server.el
index fd02448..50684a2 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -540,13 +540,13 @@ Creates the directory if necessary and makes sure:
       (setq attrs (file-attributes dir 'integer)))
 
     ;; Check that it's safe for use.
-    (let* ((uid (nth 2 attrs))
+    (let* ((uid (file-attribute-user-id attrs))
           (w32 (eq system-type 'windows-nt))
            (unsafe (cond
-                    ((not (eq t (car attrs)))
+                    ((not (eq t (file-attribute-type attrs)))
                      (if (null attrs) "its attributes can't be checked"
                        (format "it is a %s"
-                               (if (stringp (car attrs))
+                               (if (stringp (file-attribute-type attrs))
                                    "symlink" "file"))))
                     ((and w32 (zerop uid)) ; on FAT32?
                      (display-warning
diff --git a/lisp/simple.el b/lisp/simple.el
index 60fdfd4..9b40a55 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -385,7 +385,11 @@ select the source buffer."
   (interactive "p")
   (let ((next-error-highlight next-error-highlight-no-select))
     (next-error n))
-  (pop-to-buffer next-error-last-buffer))
+  (let ((display-buffer-overriding-action '(display-buffer-reuse-window)))
+    ;; Override user customization such as display-buffer-same-window
+    ;; and use display-buffer-reuse-window to ensure next-error-last-buffer
+    ;; is displayed somewhere, not necessarily in the same window (bug#32607).
+    (pop-to-buffer next-error-last-buffer)))
 
 (defun previous-error-no-select (&optional n)
   "Move point to the previous error in the `next-error' buffer and highlight 
match.
@@ -3823,7 +3827,8 @@ interactively, this is t."
             ;; No output; error?
               (let ((output
                      (if (and error-file
-                              (< 0 (nth 7 (file-attributes error-file))))
+                              (< 0 (file-attribute-size
+                                   (file-attributes error-file))))
                          (format "some error output%s"
                                  (if shell-command-default-error-buffer
                                      (format " to the \"%s\" buffer"
@@ -3846,7 +3851,7 @@ interactively, this is t."
               )))))
 
     (when (and error-file (file-exists-p error-file))
-      (if (< 0 (nth 7 (file-attributes error-file)))
+      (if (< 0 (file-attribute-size (file-attributes error-file)))
          (with-current-buffer (get-buffer-create error-buffer)
            (let ((pos-from-end (- (point-max) (point))))
              (or (bobp)
@@ -4394,7 +4399,7 @@ ring directly.")
 A non-nil value ensures that Emacs kill operations do not
 irrevocably overwrite existing clipboard text by saving it to the
 `kill-ring' prior to the kill.  Such text can subsequently be
-retrieved via \\[yank] \\[yank-pop]]."
+retrieved via \\[yank] \\[yank-pop]."
   :type 'boolean
   :group 'killing
   :version "23.2")
diff --git a/lisp/speedbar.el b/lisp/speedbar.el
index 48829d4..f3ea048 100644
--- a/lisp/speedbar.el
+++ b/lisp/speedbar.el
@@ -1466,9 +1466,10 @@ Return nil if not applicable.  If FILENAME, then use that
 instead of reading it from the speedbar buffer."
   (let* ((item (or filename (speedbar-line-file)))
         (attr (if item (file-attributes item) nil)))
-    (if (and item attr) (dframe-message "%s %-6d %s" (nth 8 attr)
-                                         (nth 7 attr) item)
-      nil)))
+    (if (and item attr)
+       (dframe-message "%s %-6d %s"
+                       (file-attribute-modes attr)
+                       (file-attribute-size attr) item))))
 
 (defun speedbar-item-info-tag-helper ()
   "Display info about a tag that is on the current line.
@@ -3008,13 +3009,13 @@ the file being checked."
                                              (cdr (car oa))))))
          nil
        ;; Find out if the object is out of date or not.
-       (let ((date1 (nth 5 (file-attributes fulln)))
-             (date2 (nth 5 (file-attributes (concat
-                                             (file-name-sans-extension fulln)
-                                              (cdr (car oa)))))))
-         (if (or (< (car date1) (car date2))
-                 (and (= (car date1) (car date2))
-                      (< (nth 1 date1) (nth 1 date2))))
+       (let ((date1 (file-attribute-modification-time
+                     (file-attributes fulln)))
+             (date2 (file-attribute-modification-time
+                     (file-attributes (concat
+                                       (file-name-sans-extension fulln)
+                                       (cdr (car oa)))))))
+         (if (time-less-p date1 date2)
              (car speedbar-obj-indicator)
            (cdr speedbar-obj-indicator)))))))
 
diff --git a/lisp/subr.el b/lisp/subr.el
index 8d04da8..755cd29 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1923,11 +1923,15 @@ Only affects hooks run in the current buffer."
 ;; PUBLIC: find if the current mode derives from another.
 
 (defun provided-mode-derived-p (mode &rest modes)
-  "Non-nil if MODE is derived from one of MODES.
+  "Non-nil if MODE is derived from one of MODES or their aliases.
 Uses the `derived-mode-parent' property of the symbol to trace backwards.
 If you just want to check `major-mode', use `derived-mode-p'."
-  (while (and (not (memq mode modes))
-              (setq mode (get mode 'derived-mode-parent))))
+  (while
+      (and
+       (not (memq mode modes))
+       (let* ((parent (get mode 'derived-mode-parent))
+              (parentfn (symbol-function parent)))
+         (setq mode (if (and parentfn (symbolp parentfn)) parentfn parent)))))
   mode)
 
 (defun derived-mode-p (&rest modes)
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el
index f6a809b..37f2245 100644
--- a/lisp/textmodes/flyspell.el
+++ b/lisp/textmodes/flyspell.el
@@ -68,6 +68,12 @@ Detection of repeated words is not implemented in
   :group 'flyspell
   :type 'boolean)
 
+(defcustom flyspell-case-fold-duplications t
+  "Non-nil means Flyspell matches duplicate words case-insensitively."
+  :group 'flyspell
+  :type 'boolean
+  :version "27.1")
+
 (defcustom flyspell-mark-duplications-exceptions
   '((nil . ("that" "had")) ; Common defaults for English.
     ("\\`francais" . ("nous" "vous")))
@@ -1154,7 +1160,8 @@ spell-check."
                              (- (save-excursion
                                    (skip-chars-backward " \t\n\f")))))
                          (p (when (>= bound (point-min))
-                              (flyspell-word-search-backward word bound t))))
+                              (flyspell-word-search-backward
+                                word bound flyspell-case-fold-duplications))))
                     (and p (/= p start)))))
            ;; yes, this is a doublon
            (flyspell-highlight-incorrect-region start end 'doublon)
diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el
index 679401e..5f9de9a 100644
--- a/lisp/thingatpt.el
+++ b/lisp/thingatpt.el
@@ -222,17 +222,15 @@ The bounds of THING are determined by 
`bounds-of-thing-at-point'."
 
 (defun thing-at-point-bounds-of-list-at-point ()
   "Return the bounds of the list at point.
+Prefer the enclosing list with fallback on sexp at point.
 \[Internal function used by `bounds-of-thing-at-point'.]"
   (save-excursion
-    (let* ((st (parse-partial-sexp (point-min) (point)))
-           (beg (or (and (eq 4 (car (syntax-after (point))))
-                         (not (nth 8 st))
-                         (point))
-                    (nth 1 st))))
-      (when beg
-        (goto-char beg)
-        (forward-sexp)
-        (cons beg (point))))))
+    (if (ignore-errors (up-list -1))
+       (ignore-errors (cons (point) (progn (forward-sexp) (point))))
+      (let ((bound (bounds-of-thing-at-point 'sexp)))
+       (and bound
+            (<= (car bound) (point)) (< (point) (cdr bound))
+            bound)))))
 
 ;; Defuns
 
@@ -636,8 +634,13 @@ Signal an error if the entire string was not used."
 
 (put 'number 'thing-at-point 'number-at-point)
 ;;;###autoload
-(defun list-at-point ()
-  "Return the Lisp list at point, or nil if none is found."
-  (form-at-point 'list 'listp))
+(defun list-at-point (&optional ignore-comment-or-string)
+  "Return the Lisp list at point, or nil if none is found.
+If IGNORE-COMMENT-OR-STRING is non-nil comments and strings are
+treated as white space."
+  (let ((ppss (and ignore-comment-or-string (syntax-ppss))))
+    (save-excursion
+      (goto-char (or (nth 8 ppss) (point)))
+      (form-at-point 'list 'listp))))
 
 ;;; thingatpt.el ends here
diff --git a/lisp/thread.el b/lisp/thread.el
index 1c5dccf..7974a26 100644
--- a/lisp/thread.el
+++ b/lisp/thread.el
@@ -25,10 +25,10 @@
 
 ;;; Code:
 
-(require 'cl-lib)
+(eval-when-compile (require 'cl-lib))
 (require 'backtrace)
-(require 'pcase)
-(require 'subr-x)
+(eval-when-compile (require 'pcase))
+(eval-when-compile (require 'subr-x))
 
 ;;;###autoload
 (defun thread-handle-event (event)
diff --git a/lisp/thumbs.el b/lisp/thumbs.el
index 26c9935..067a32b 100644
--- a/lisp/thumbs.el
+++ b/lisp/thumbs.el
@@ -210,7 +210,9 @@ reached."
           (mapcar
            (lambda (f)
              (let ((fattribs-list (file-attributes f)))
-               `(,(nth 4 fattribs-list) ,(nth 7 fattribs-list) ,f)))
+               `(,(file-attribute-access-time fattribs-list)
+                 ,(file-attribute-size fattribs-list)
+                 ,f)))
            (directory-files (thumbs-thumbsdir) t (image-file-name-regexp)))
           (lambda (l1 l2) (time-less-p (car l1) (car l2)))))
         (dirsize (apply '+ (mapcar (lambda (x) (cadr x)) files-list))))
diff --git a/lisp/time.el b/lisp/time.el
index 94f7009..bfecba9 100644
--- a/lisp/time.el
+++ b/lisp/time.el
@@ -336,15 +336,10 @@ would give mode line times like `94/12/30 21:07:48 
(UTC)'."
         (next-time (timer-relative-time
                     (list (aref timer 1) (aref timer 2) (aref timer 3))
                     (* 5 (aref timer 4)) 0)))
-    ;; If the activation time is far in the past,
+    ;; If the activation time is not in the future,
     ;; skip executions until we reach a time in the future.
     ;; This avoids a long pause if Emacs has been suspended for hours.
-    (or (> (nth 0 next-time) (nth 0 current))
-       (and (= (nth 0 next-time) (nth 0 current))
-            (> (nth 1 next-time) (nth 1 current)))
-       (and (= (nth 0 next-time) (nth 0 current))
-            (= (nth 1 next-time) (nth 1 current))
-            (> (nth 2 next-time) (nth 2 current)))
+    (or (time-less-p current next-time)
        (progn
          (timer-set-time timer (timer-next-integral-multiple-of-time
                                 current display-time-interval)
@@ -365,7 +360,8 @@ Switches from the 1 to 5 to 15 minute load average, and 
then back to 1."
     (while (and mail-files (= size 0))
       ;; Count size of regular files only.
       (setq size (+ size (or (and (file-regular-p (car mail-files))
-                                 (nth 7 (file-attributes (car mail-files))))
+                                 (file-attribute-size
+                                  (file-attributes (car mail-files))))
                             0)))
       (setq mail-files (cdr mail-files)))
     (if (> size 0)
@@ -438,23 +434,16 @@ update which can wait for the next redisplay."
                ((and (stringp mail-spool-file)
                      (or (null display-time-server-down-time)
                          ;; If have been down for 20 min, try again.
-                         (> (- (nth 1 now) display-time-server-down-time)
-                            1200)
-                         (and (< (nth 1 now) display-time-server-down-time)
-                              (> (- (nth 1 now)
-                                    display-time-server-down-time)
-                                 -64336))))
-                (let ((start-time (current-time)))
+                         (< 1200 (- (float-time now)
+                                    display-time-server-down-time))))
+                (let ((start-time (float-time)))
                   (prog1
                       (display-time-file-nonempty-p mail-spool-file)
-                    (if (> (- (nth 1 (current-time))
-                              (nth 1 start-time))
-                           20)
-                        ;; Record that mail file is not accessible.
-                        (setq display-time-server-down-time
-                              (nth 1 (current-time)))
-                      ;; Record that mail file is accessible.
-                      (setq display-time-server-down-time nil)))))))
+                    ;; Record whether mail file is accessible.
+                    (setq display-time-server-down-time
+                          (let ((end-time (float-time)))
+                            (and (< 20 (- end-time start-time))
+                                 end-time))))))))
          (24-hours (substring time 11 13))
          (hour (string-to-number 24-hours))
          (12-hours (int-to-string (1+ (% (+ hour 11) 12))))
@@ -483,7 +472,8 @@ update which can wait for the next redisplay."
 (defun display-time-file-nonempty-p (file)
   (let ((remote-file-name-inhibit-cache (- display-time-interval 5)))
     (and (file-exists-p file)
-        (< 0 (nth 7 (file-attributes (file-chase-links file)))))))
+        (< 0 (file-attribute-size
+              (file-attributes (file-chase-links file)))))))
 
 ;;;###autoload
 (define-minor-mode display-time-mode
diff --git a/lisp/url/url-auth.el b/lisp/url/url-auth.el
index 67e701e..401baec 100644
--- a/lisp/url/url-auth.el
+++ b/lisp/url/url-auth.el
@@ -192,7 +192,9 @@ key cache `url-digest-auth-storage'."
 (defun url-digest-auth-make-cnonce ()
   "Compute a new unique client nonce value."
   (base64-encode-string
-   (apply 'format "%016x%04x%04x%05x%05x" (random) (current-time)) t))
+   (apply #'format "%016x%08x%08x" (random)
+         (read (format-time-string "(%s %N)")))
+   t))
 
 (defun url-digest-auth-nonce-count (_nonce)
   "The number requests sent to server with the given NONCE.
diff --git a/lisp/url/url-cache.el b/lisp/url/url-cache.el
index 309c96c..3765d9d 100644
--- a/lisp/url/url-cache.el
+++ b/lisp/url/url-cache.el
@@ -86,10 +86,10 @@ FILE can be created or overwritten."
 The actual return value is the last modification time of the cache file."
   (let* ((fname (url-cache-create-filename url))
         (attribs (file-attributes fname)))
-    (and fname                         ; got a filename
-        (file-exists-p fname)          ; file exists
-        (not (eq (nth 0 attribs) t))   ; Its not a directory
-        (nth 5 attribs))))             ; Can get last mod-time
+    (and fname
+        (file-exists-p fname)
+        (not (eq (file-attribute-type attribs) t))
+        (file-attribute-modification-time attribs))))
 
 (defun url-cache-create-filename-human-readable (url)
   "Return a filename in the local cache for URL."
@@ -226,7 +226,7 @@ considered \"expired\"."
              (setq deleted-files (1+ deleted-files))))
           ((time-less-p
             (time-add
-             (nth 5 (file-attributes file))
+             (file-attribute-modification-time (file-attributes file))
              (seconds-to-time url-cache-expire-time))
             now)
            (delete-file file)
diff --git a/lisp/url/url-file.el b/lisp/url/url-file.el
index 1c7c20e..02542cc 100644
--- a/lisp/url/url-file.el
+++ b/lisp/url/url-file.el
@@ -70,7 +70,7 @@ to them."
            buff func
            func args
            args efs))
-  (let ((size (nth 7 (file-attributes name))))
+  (let ((size (file-attribute-size (file-attributes name))))
     (with-current-buffer buff
       (goto-char (point-max))
       (if (/= -1 size)
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index b91a2ba..6c189c1 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -1450,7 +1450,7 @@ modified lines of the diff."
   ;; can just remove the file altogether.  Very handy for .rej files if we
   ;; remove hunks as we apply them.
   (when (and buffer-file-name
-            (eq 0 (nth 7 (file-attributes buffer-file-name))))
+            (eq 0 (file-attribute-size (file-attributes buffer-file-name))))
     (delete-file buffer-file-name)))
 
 (defun diff-delete-empty-files ()
diff --git a/lisp/vc/pcvs-info.el b/lisp/vc/pcvs-info.el
index edcfc6e..2947733 100644
--- a/lisp/vc/pcvs-info.el
+++ b/lisp/vc/pcvs-info.el
@@ -451,7 +451,8 @@ DIR can also be a file."
               ((not (file-exists-p (concat dir f))) (setq type 'MISSING))
               ((equal rev "0") (setq type 'ADDED rev nil))
               ((equal date "Result of merge") (setq subtype 'MERGED))
-              ((let ((mtime (nth 5 (file-attributes (concat dir f))))
+              ((let ((mtime (file-attribute-modification-time
+                             (file-attributes (concat dir f))))
                      (system-time-locale "C"))
                  (setq timestamp (format-time-string "%c" mtime t))
                  ;; Solaris sometimes uses "Wed Sep 05", not "Wed Sep  5".
diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el
index 630932f..8e1a6be 100644
--- a/lisp/vc/vc-bzr.el
+++ b/lisp/vc/vc-bzr.el
@@ -268,8 +268,8 @@ in the repository root directory of FILE."
                  ;; If file is in dirstate, can only be added (b#8025).
                  ((or (not (match-beginning 4))
                       (eq (char-after (match-beginning 4)) ?a)) 'added)
-                 ((or (and (eq (string-to-number (match-string 3))
-                               (nth 7 (file-attributes file)))
+                 ((or (and (eql (string-to-number (match-string 3))
+                               (file-attribute-size (file-attributes file)))
                            (equal (match-string 5)
                                   (save-match-data (vc-bzr-sha1 file)))
                            ;; For a file, does the executable state match?
@@ -281,7 +281,8 @@ in the repository root directory of FILE."
                                        ?x
                                        (mapcar
                                         'identity
-                                        (nth 8 (file-attributes file))))))
+                                       (file-attribute-modes
+                                        (file-attributes file))))))
                                  (if (eq (char-after (match-beginning 7))
                                          ?y)
                                      exe
@@ -291,8 +292,8 @@ in the repository root directory of FILE."
                        ;; checkouts \2 is empty and we need to
                        ;; look for size in \6.
                        (eq (match-beginning 2) (match-end 2))
-                       (eq (string-to-number (match-string 6))
-                           (nth 7 (file-attributes file)))
+                       (eql (string-to-number (match-string 6))
+                            (file-attribute-size (file-attributes file)))
                        (equal (match-string 5)
                               (vc-bzr-sha1 file))))
                   'up-to-date)
@@ -694,7 +695,6 @@ or a superior directory.")
 (defvar log-view-message-re)
 (defvar log-view-file-re)
 (defvar log-view-font-lock-keywords)
-(defvar log-view-current-tag-function)
 (defvar log-view-per-file-logs)
 (defvar log-view-expanded-log-entry-function)
 
diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el
index 54ece6c..ac98d99 100644
--- a/lisp/vc/vc-cvs.el
+++ b/lisp/vc/vc-cvs.el
@@ -57,7 +57,7 @@
                     ;; (We actually shouldn't trust this, but there is
                     ;; no other way to learn this from CVS at the
                     ;; moment (version 1.9).)
-                    (string-match "r-..-..-." (nth 8 attrib)))
+                   (string-match "r-..-..-." (file-attribute-modes attrib)))
                'announce
              'implicit))))))
 
@@ -257,7 +257,7 @@ See also variable `vc-cvs-sticky-date-format-string'."
   ;; If the file has not changed since checkout, consider it `up-to-date'.
   ;; Otherwise consider it `edited'.
   (let ((checkout-time (vc-file-getprop file 'vc-checkout-time))
-        (lastmod (nth 5 (file-attributes file))))
+        (lastmod (file-attribute-modification-time (file-attributes file))))
     (cond
      ((equal checkout-time lastmod) 'up-to-date)
      ((string= (vc-working-revision file) "0") 'added)
@@ -524,7 +524,8 @@ The changes are between FIRST-REVISION and SECOND-REVISION."
                     (string= (match-string 1) "P "))
                 (vc-file-setprop file 'vc-state 'up-to-date)
                 (vc-file-setprop file 'vc-checkout-time
-                                 (nth 5 (file-attributes file)))
+                                (file-attribute-modification-time
+                                 (file-attributes file)))
                 0);; indicate success to the caller
                ;; Merge successful, but our own changes are still in the file
                ((string= (match-string 1) "M ")
@@ -748,7 +749,8 @@ If UPDATE is non-nil, then update (resynch) any affected 
buffers."
                    (vc-file-setprop file 'vc-state 'up-to-date)
                    (vc-file-setprop file 'vc-working-revision nil)
                    (vc-file-setprop file 'vc-checkout-time
-                                    (nth 5 (file-attributes file))))
+                                    (file-attribute-modification-time
+                                     (file-attributes file))))
                   ((or (string= state "M")
                        (string= state "C"))
                    (vc-file-setprop file 'vc-state 'edited)
@@ -931,7 +933,8 @@ state."
         (cond
          ((string-match "Up-to-date" status)
           (vc-file-setprop file 'vc-checkout-time
-                           (nth 5 (file-attributes file)))
+                           (file-attribute-modification-time
+                            (file-attributes file)))
           'up-to-date)
          ((string-match "Locally Modified" status)             'edited)
          ((string-match "Needs Merge" status)                  'needs-merge)
@@ -1174,7 +1177,7 @@ is non-nil."
     ;; (which is based on textual comparison), because there can be problems
     ;; generating a time string that looks exactly like the one from CVS.
     (let* ((time (match-string 2))
-           (mtime (nth 5 (file-attributes file)))
+           (mtime (file-attribute-modification-time (file-attributes file)))
            (parsed-time (progn (require 'parse-time)
                                (parse-time-string (concat time " +0000")))))
       (cond ((and (not (string-match "\\+" time))
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 69d6295..4ea7ea5 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -1440,8 +1440,7 @@ This command shares argument histories with \\[rgrep] and 
\\[grep]."
      (cond
       ((equal current-prefix-arg '(16))
        (list (read-from-minibuffer "Run: " "git grep"
-                                  nil nil 'grep-history)
-            nil))
+                                  nil nil 'grep-history)))
       (t (let* ((regexp (grep-read-regexp))
                (files
                  (mapconcat #'shell-quote-argument
@@ -1451,6 +1450,8 @@ This command shares argument histories with \\[rgrep] and 
\\[grep]."
           (list regexp files dir))))))
   (require 'grep)
   (when (and (stringp regexp) (> (length regexp) 0))
+    (unless (and dir (file-accessible-directory-p dir))
+      (setq dir default-directory))
     (let ((command regexp))
       (if (null files)
          (if (string= command "git grep")
@@ -1479,7 +1480,7 @@ This command shares argument histories with \\[rgrep] and 
\\[grep]."
   (interactive "sStash name: ")
   (let ((root (vc-git-root default-directory)))
     (when root
-      (vc-git--call nil "stash" "save" name)
+      (apply #'vc-git--call nil "stash" "push" "-m" name (vc-dir-marked-files))
       (vc-resynch-buffer root t t))))
 
 (defvar vc-git-stash-read-history nil
@@ -1627,8 +1628,15 @@ The difference to vc-do-command is that this function 
always invokes
          (or coding-system-for-read vc-git-log-output-coding-system))
        (coding-system-for-write
          (or coding-system-for-write vc-git-commits-coding-system))
-       (process-environment (cons "PAGER=" process-environment)))
-    (push "GIT_DIR" process-environment)
+       (process-environment
+        (append
+         `("GIT_DIR"
+           "PAGER="
+           ;; Avoid repository locking during background operations
+           ;; (bug#21559).
+           ,@(when revert-buffer-in-progress-p
+               '("GIT_OPTIONAL_LOCKS=0")))
+         process-environment)))
     (apply 'process-file vc-git-program nil buffer nil command args)))
 
 (defun vc-git--out-ok (command &rest args)
diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el
index 76eec88..3696573 100644
--- a/lisp/vc/vc-hg.el
+++ b/lisp/vc/vc-hg.el
@@ -833,7 +833,7 @@ if we don't understand a construct, we signal
     (with-temp-buffer
       (let ((attr (file-attributes hgignore)))
         (when attr (insert-file-contents hgignore))
-        (push (list hgignore (nth 5 attr) (nth 7 attr))
+        (push (list hgignore (file-attribute-modification-time attr) 
(file-attribute-size attr))
               vc-hg--hgignore-filenames))
       (while (not (eobp))
         ;; This list of pattern-file commands isn't complete, but it
@@ -897,8 +897,8 @@ REPO must be the directory name of an hg repository."
              (saved-mtime (nth 1 fs))
              (saved-size (nth 2 fs))
              (attr (file-attributes (nth 0 fs)))
-             (current-mtime (nth 5 attr))
-             (current-size (nth 7 attr)))
+             (current-mtime (file-attribute-modification-time attr))
+             (current-size (file-attribute-size attr)))
         (unless (and (equal saved-mtime current-mtime)
                      (equal saved-size current-size))
           (setf valid nil))))
@@ -968,8 +968,8 @@ Avoids the need to repeatedly scan dirstate on repeated 
calls to
 `vc-hg-state', as we see during registration queries.")
 
 (defun vc-hg--cached-dirstate-search (dirstate dirstate-attr ascii-fname)
-  (let* ((mtime (nth 5 dirstate-attr))
-         (size (nth 7 dirstate-attr))
+  (let* ((mtime (file-attribute-modification-time dirstate-attr))
+         (size (file-attribute-size dirstate-attr))
          (cache vc-hg--dirstate-scan-cache)
          )
     (if (and cache
@@ -1012,7 +1012,7 @@ hg binary."
          ;; Repository must be in an understood format
          (not (vc-hg--requirements-understood-p repo))
          ;; Dirstate too small to be valid
-         (< (nth 7 dirstate-attr) 40)
+         (< (file-attribute-size dirstate-attr) 40)
          (progn
            (setf repo-relative-filename
                  (file-relative-name truename repo))
@@ -1036,8 +1036,9 @@ hg binary."
               ((eq state ?n)
                (let ((vc-hg-size (nth 2 dirstate-entry))
                      (vc-hg-mtime (nth 3 dirstate-entry))
-                     (fs-size (nth 7 stat))
-                     (fs-mtime (vc-hg--time-to-integer (nth 5 stat))))
+                     (fs-size (file-attribute-size stat))
+                     (fs-mtime (vc-hg--time-to-integer
+                               (file-attribute-modification-time stat))))
                  (if (and (eql vc-hg-size fs-size) (eql vc-hg-mtime fs-mtime))
                      'up-to-date
                    'edited)))
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index f88ced8..5dc80c3 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -658,7 +658,7 @@ Before doing that, check if there are any old backups and 
get rid of them."
       ;; If the file was saved in the same second in which it was
       ;; checked out, clear the checkout-time to avoid confusion.
       (if (equal (vc-file-getprop file 'vc-checkout-time)
-                (nth 5 (file-attributes file)))
+                (file-attribute-modification-time (file-attributes file)))
          (vc-file-setprop file 'vc-checkout-time nil))
       (if (vc-state-refresh file backend)
          (vc-mode-line file backend)))
diff --git a/lisp/vc/vc-rcs.el b/lisp/vc/vc-rcs.el
index 9fa52bf..51a4443 100644
--- a/lisp/vc/vc-rcs.el
+++ b/lisp/vc/vc-rcs.el
@@ -955,11 +955,10 @@ Uses `rcs2log' which only works for RCS and CVS."
   "Return non-nil if FILE is newer than its RCS master.
 This likely means that FILE has been changed with respect
 to its master version."
-  (let ((file-time (nth 5 (file-attributes file)))
-       (master-time (nth 5 (file-attributes (vc-master-name file)))))
-    (or (> (nth 0 file-time) (nth 0 master-time))
-       (and (= (nth 0 file-time) (nth 0 master-time))
-            (> (nth 1 file-time) (nth 1 master-time))))))
+  (let ((file-time (file-attribute-modification-time (file-attributes file)))
+       (master-time (file-attribute-modification-time
+                     (file-attributes (vc-master-name file)))))
+    (time-less-p master-time file-time)))
 
 (defun vc-rcs-find-most-recent-rev (branch)
   "Find most recent revision on BRANCH."
diff --git a/lisp/vc/vc-svn.el b/lisp/vc/vc-svn.el
index 2cbf34b..4b1a34b 100644
--- a/lisp/vc/vc-svn.el
+++ b/lisp/vc/vc-svn.el
@@ -479,7 +479,8 @@ The changes are between FIRST-VERSION and SECOND-VERSION."
                ((string= (match-string 2) "U")
                 (vc-file-setprop file 'vc-state 'up-to-date)
                 (vc-file-setprop file 'vc-checkout-time
-                                 (nth 5 (file-attributes file)))
+                                 (file-attribute-modification-time
+                                 (file-attributes file)))
                 0);; indicate success to the caller
                ;; Merge successful, but our own changes are still in the file
                ((string= (match-string 2) "G")
@@ -729,7 +730,8 @@ Set file properties accordingly.  If FILENAME is non-nil, 
return its status."
           (if (eq (char-after (match-beginning 1)) ?*)
               'needs-update
              (vc-file-setprop file 'vc-checkout-time
-                              (nth 5 (file-attributes file)))
+                              (file-attribute-modification-time
+                              (file-attributes file)))
             'up-to-date))
          ((eq status ?A)
           ;; If the file was actually copied, (match-string 2) is "-".
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 487594b..d3d66d6 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1481,7 +1481,8 @@ After check-out, runs the normal hook `vc-checkout-hook'."
                              nil)
                         'up-to-date
                        'edited))
-        (vc-checkout-time . ,(nth 5 (file-attributes file))))))
+        (vc-checkout-time . ,(file-attribute-modification-time
+                             (file-attributes file))))))
   (vc-resynch-buffer file t t)
   (run-hooks 'vc-checkout-hook))
 
@@ -1558,7 +1559,8 @@ Runs the normal hooks `vc-before-checkin-hook' and 
`vc-checkin-hook'."
          (vc-call-backend backend 'checkin files comment rev)
          (mapc 'vc-delete-automatic-version-backups files))
        `((vc-state . up-to-date)
-         (vc-checkout-time . ,(nth 5 (file-attributes file)))
+         (vc-checkout-time . ,(file-attribute-modification-time
+                              (file-attributes file)))
          (vc-working-revision . nil)))
      (message "Checking in %s...done" (vc-delistify files)))
    'vc-checkin-hook
@@ -2568,7 +2570,8 @@ its name; otherwise return nil."
        (vc-delete-automatic-version-backups file))
      (vc-call revert file backup-file))
    `((vc-state . up-to-date)
-     (vc-checkout-time . ,(nth 5 (file-attributes file)))))
+     (vc-checkout-time . ,(file-attribute-modification-time
+                          (file-attributes file)))))
   (vc-resynch-buffer file t t))
 
 ;;;###autoload
diff --git a/lisp/wdired.el b/lisp/wdired.el
index be0bde2..3157e88 100644
--- a/lisp/wdired.el
+++ b/lisp/wdired.el
@@ -607,15 +607,22 @@ Optional arguments are ignored."
 (defun wdired--restore-dired-filename-prop (beg end _len)
   (save-match-data
     (save-excursion
-      (beginning-of-line)
-      (when (re-search-forward directory-listing-before-filename-regexp
-                               (line-end-position) t)
-        (setq beg (point)
-              end (if (and (file-symlink-p (dired-get-filename))
-                           (search-forward " -> " (line-end-position) t))
-                      (goto-char (match-beginning 0))
-                    (line-end-position)))
-        (put-text-property beg end 'dired-filename t)))))
+      (let ((lep (line-end-position)))
+        (beginning-of-line)
+        (when (re-search-forward
+               directory-listing-before-filename-regexp lep t)
+          (setq beg (point)
+                ;; If the file is a symlink, put the dired-filename
+                ;; property only on the link name.  (Using
+                ;; (file-symlink-p (dired-get-filename)) fails in
+                ;; wdired-mode, bug#32673.)
+                end (if (and (re-search-backward
+                              dired-permission-flags-regexp nil t)
+                             (looking-at "l")
+                             (search-forward " -> " lep t))
+                        (goto-char (match-beginning 0))
+                      lep))
+          (put-text-property beg end 'dired-filename t))))))
 
 (defun wdired-next-line (arg)
   "Move down lines then position at filename or the current column.
diff --git a/lisp/window.el b/lisp/window.el
index 76de420..0a42dae 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -201,7 +201,7 @@ argument replaces this)."
 
 (defmacro with-current-buffer-window (buffer-or-name action quit-function 
&rest body)
   "Evaluate BODY with a buffer BUFFER-OR-NAME current and show that buffer.
-This construct is like `with-temp-buffer-window' but unlike that
+This construct is like `with-temp-buffer-window' but unlike that,
 makes the buffer specified by BUFFER-OR-NAME current for running
 BODY."
   (declare (debug t))
@@ -224,7 +224,7 @@ BODY."
 
 (defmacro with-displayed-buffer-window (buffer-or-name action quit-function 
&rest body)
   "Show a buffer BUFFER-OR-NAME and evaluate BODY in that buffer.
-This construct is like `with-current-buffer-window' but unlike that
+This construct is like `with-current-buffer-window' but unlike that,
 displays the buffer specified by BUFFER-OR-NAME before running BODY."
   (declare (debug t))
   (let ((buffer (make-symbol "buffer"))
@@ -992,16 +992,16 @@ and may be called only if no window on SIDE exists yet."
 ALIST is an association list of symbols and values.  The
 following special symbols can be used in ALIST.
 
-`side' denotes the side of the frame where the new window shall
-  be located.  Valid values are `bottom', `right', `top' and
-  `left'.  The default is `bottom'.
+ `side' denotes the side of the frame where the new window shall
+   be located.  Valid values are `bottom', `right', `top' and
+   `left'.  The default is `bottom'.
 
-`slot' if non-nil, specifies the window slot where to display
-  BUFFER.  A value of zero or nil means use the middle slot on
-  the specified side.  A negative value means use a slot
-  preceding (that is, above or on the left of) the middle slot.
-  A positive value means use a slot following (that is, below or
-  on the right of) the middle slot.  The default is zero.
+ `slot' if non-nil, specifies the window slot where to display
+   BUFFER.  A value of zero or nil means use the middle slot on
+   the specified side.  A negative value means use a slot
+   preceding (that is, above or on the left of) the middle slot.
+   A positive value means use a slot following (that is, below or
+   on the right of) the middle slot.  The default is zero.
 
 If the current frame size or the settings of `window-sides-slots'
 do not permit making a new window, a suitable existing window may
@@ -6384,7 +6384,7 @@ See also `same-window-buffer-names'."
   :group 'windows)
 
 (defun same-window-p (buffer-name)
-  "Return non-nil if a buffer named BUFFER-NAME would be shown in the \"same\" 
window.
+  "Return non-nil if buffer BUFFER-NAME would be shown in the \"same\" window.
 This function returns non-nil if `display-buffer' or
 `pop-to-buffer' would show a buffer named BUFFER-NAME in the
 selected rather than (as usual) some other window.  See
@@ -6822,16 +6822,22 @@ The actual non-nil value of this variable will be 
copied to the
   "Custom type for `display-buffer' actions.")
 
 (defvar display-buffer-overriding-action '(nil . nil)
-  "Overriding action to perform to display a buffer.
-It should be a cons cell (FUNCTION . ALIST), where FUNCTION is a
-function or a list of functions.  Each function should accept two
-arguments: a buffer to display and an alist similar to ALIST.
+  "User-defined overriding action to perform to display a buffer.
+This action overrides all the other actions in the action variables
+and arguments passed to `display-buffer'.
+Value should be a cons cell (FUNCTION . ALIST), where FUNCTION is
+a function or a list of functions.  Each function should accept
+two arguments: a buffer to display and an alist similar to ALIST.
+The default value is empty.
 See `display-buffer' for details.")
 (put 'display-buffer-overriding-action 'risky-local-variable t)
 
 (defcustom display-buffer-alist nil
-  "Alist of conditional actions for `display-buffer'.
-This is a list of elements (CONDITION . ACTION), where:
+  "Alist of uder-defined conditional actions for `display-buffer'.
+Its value takes effect before `display-buffer-base-action'
+and `display-buffer-fallback-action', but after
+`display-buffer-overriding-action', which see.
+If non-nil, this is a list of elements (CONDITION . ACTION), where:
 
  CONDITION is either a regexp matching buffer names, or a
   function that takes two arguments - a buffer name and the
@@ -6857,9 +6863,13 @@ associated action to the list of actions it will try."
 
 (defcustom display-buffer-base-action '(nil . nil)
   "User-specified default action for `display-buffer'.
+This is the default action used by `display-buffer' if no other
+actions are specified or all fail, before falling back on
+`display-buffer-fallback-action'.
 It should be a cons cell (FUNCTION . ALIST), where FUNCTION is a
 function or a list of functions.  Each function should accept two
 arguments: a buffer to display and an alist similar to ALIST.
+The default value is empty.
 See `display-buffer' for details."
   :type display-buffer--action-custom-type
   :risky t
@@ -6877,12 +6887,16 @@ See `display-buffer' for details."
   "Default fallback action for `display-buffer'.
 This is the action used by `display-buffer' if no other actions
 specified, e.g. by the user options `display-buffer-alist' or
-`display-buffer-base-action'.  See `display-buffer'.")
+`display-buffer-base-action', or they all fail.  See `display-buffer'.")
 (put 'display-buffer-fallback-action 'risky-local-variable t)
 
 (defun display-buffer-assq-regexp (buffer-name alist action)
   "Retrieve ALIST entry corresponding to BUFFER-NAME.
-ACTION is the action argument passed to `display-buffer'."
+This returns the cdr of the ALIST entry if either its key is a
+string that matches BUFFER-NAME, as reported by `string-match-p';
+or if the key is a function that returns a non-nil when called
+with 3 arguments: the ALIST key, BUFFER-NAME, and ACTION.
+ACTION should have the form of the action argument passed to `display-buffer'."
   (catch 'match
     (dolist (entry alist)
       (let ((key (car entry)))
@@ -6895,7 +6909,8 @@ ACTION is the action argument passed to `display-buffer'."
 (defvar display-buffer--same-window-action
   '(display-buffer-same-window
     (inhibit-same-window . nil))
-  "A `display-buffer' action for displaying in the same window.")
+  "A `display-buffer' action for displaying in the same window.
+Specifies to call `display-buffer-same-window'.")
 (put 'display-buffer--same-window-action 'risky-local-variable t)
 
 (defvar display-buffer--other-frame-action
@@ -6903,7 +6918,9 @@ ACTION is the action argument passed to `display-buffer'."
      display-buffer-pop-up-frame)
     (reusable-frames . 0)
     (inhibit-same-window . t))
-  "A `display-buffer' action for displaying in another frame.")
+  "A `display-buffer' action for displaying in another frame.
+Specifies to call `display-buffer-reuse-window', and if that
+fails, call `display-buffer-pop-up-frame'.")
 (put 'display-buffer--other-frame-action 'risky-local-variable t)
 
 (defun display-buffer (buffer-or-name &optional action frame)
@@ -6924,7 +6941,7 @@ If ACTION is non-nil, it should have the form (FUNCTION . 
ALIST),
 where FUNCTION is either a function or a list of functions, and
 ALIST is an arbitrary association list (alist).
 
-Each such FUNCTION should accept two arguments: the buffer to
+Each such function should accept two arguments: the buffer to
 display and an alist.  Based on those arguments, it should
 display the buffer and return the window.  If the caller is
 prepared to handle the case of not displaying the buffer
@@ -7048,6 +7065,9 @@ argument, ACTION is t."
 
 (defun display-buffer-other-frame (buffer)
   "Display buffer BUFFER preferably in another frame.
+This function attempts to look for a window displaying BUFFER,
+on all the frames on the current terminal, skipping the selected
+window; if that fails, it pops up a new frame.
 This uses the function `display-buffer' as a subroutine; see
 its documentation for additional customization information."
   (interactive "BDisplay buffer in other frame: ")
@@ -7091,10 +7111,10 @@ that allows the selected frame)."
 
 (defun display-buffer-same-window (buffer alist)
   "Display BUFFER in the selected window.
-This fails if ALIST has a non-nil `inhibit-same-window' entry, or
-if the selected window is a minibuffer window or is dedicated to
-another buffer; in that case, return nil.  Otherwise, return the
-selected window."
+This fails if ALIST has an `inhibit-same-window' element whose
+value is non-nil, or if the selected window is a minibuffer
+window or is dedicated to another buffer; in that case, return nil.
+Otherwise, return the selected window."
   (unless (or (cdr (assq 'inhibit-same-window alist))
              (window-minibuffer-p)
              (window-dedicated-p))
@@ -7581,7 +7601,12 @@ Optional argument NORECORD, if non-nil means do not put 
this
 buffer at the front of the list of recently selected ones.
 
 Unlike `pop-to-buffer', this function prefers using the selected
-window over popping up a new window or frame."
+window over popping up a new window or frame.  Specifically, if
+the selected window is neither a minibuffer window (as reported
+by `window-minibuffer-p'), nor is dedicated to another buffer
+(see `window-dedicated-p'), BUFFER will be displayed in the
+currently selected window; otherwise it will be displayed in
+another window."
   (pop-to-buffer buffer display-buffer--same-window-action norecord))
 
 (defun read-buffer-to-switch (prompt)
diff --git a/lisp/xdg.el b/lisp/xdg.el
index a896eb8..f818324 100644
--- a/lisp/xdg.el
+++ b/lisp/xdg.el
@@ -295,7 +295,9 @@ Results are cached in `xdg-mime-table'."
               (files ()))
     (let ((mtim1 (get 'xdg-mime-table 'mtime))
           (mtim2 (cl-loop for f in caches when (file-readable-p f)
-                          maximize (float-time (nth 5 (file-attributes f))))))
+                          maximize (float-time
+                                   (file-attribute-modification-time
+                                    (file-attributes f))))))
       ;; If one of the MIME/Desktop cache files has been modified:
       (when (or (null mtim1) (time-less-p mtim1 mtim2))
         (setq xdg-mime-table nil)))
diff --git a/lwlib/Makefile.in b/lwlib/Makefile.in
index 6bd2608..ed71270 100644
--- a/lwlib/Makefile.in
+++ b/lwlib/Makefile.in
@@ -111,7 +111,7 @@ $(globals_h):
 .PHONY: mostlyclean clean distclean bootstrap-clean maintainer-clean
 
 clean mostlyclean:
-       rm -f *.o liblw.a \#* $(DEPDIR)/*
+       rm -f ./*.o liblw.a \#* $(DEPDIR)/*
 
 distclean: clean
        rm -f Makefile
diff --git a/m4/limits-h.m4 b/m4/limits-h.m4
index 8388663..3a2cd91 100644
--- a/m4/limits-h.m4
+++ b/m4/limits-h.m4
@@ -11,14 +11,18 @@ AC_DEFUN_ONCE([gl_LIMITS_H],
 [
   gl_CHECK_NEXT_HEADERS([limits.h])
 
-  AC_CACHE_CHECK([whether limits.h has ULLONG_WIDTH etc.],
+  AC_CACHE_CHECK([whether limits.h has LLONG_MAX, WORD_BIT, ULLONG_WIDTH etc.],
     [gl_cv_header_limits_width],
     [AC_COMPILE_IFELSE(
-       [AC_LANG_PROGRAM([[#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
-                           #define __STDC_WANT_IEC_60559_BFP_EXT__ 1
-                          #endif
-                          #include <limits.h>
-                          int ullw = ULLONG_WIDTH;]])],
+       [AC_LANG_PROGRAM(
+          [[#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+             #define __STDC_WANT_IEC_60559_BFP_EXT__ 1
+            #endif
+            #include <limits.h>
+            long long llm = LLONG_MAX;
+            int wb = WORD_BIT;
+            int ullw = ULLONG_WIDTH;
+          ]])],
        [gl_cv_header_limits_width=yes],
        [gl_cv_header_limits_width=no])])
   if test "$gl_cv_header_limits_width" = yes; then
diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4
index ba3d201..07b040a 100644
--- a/m4/stddef_h.m4
+++ b/m4/stddef_h.m4
@@ -1,5 +1,5 @@
 dnl A placeholder for <stddef.h>, for platforms that have issues.
-# stddef_h.m4 serial 5
+# stddef_h.m4 serial 6
 dnl Copyright (C) 2009-2018 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -10,13 +10,33 @@ AC_DEFUN([gl_STDDEF_H],
   AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
   AC_REQUIRE([gt_TYPE_WCHAR_T])
   STDDEF_H=
-  AC_CHECK_TYPE([max_align_t], [], [HAVE_MAX_ALIGN_T=0; STDDEF_H=stddef.h],
-    [[#include <stddef.h>
-    ]])
+
+  dnl Test whether the type max_align_t exists and whether its alignment
+  dnl "is as great as is supported by the implementation in all contexts".
+  AC_CACHE_CHECK([for good max_align_t],
+    [gl_cv_type_max_align_t],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <stddef.h>
+            unsigned int s = sizeof (max_align_t);
+            #if defined __GNUC__ || defined __IBM__ALIGNOF__
+            int check1[2 * (__alignof__ (double) <= __alignof__ (max_align_t)) 
- 1];
+            int check2[2 * (__alignof__ (long double) <= __alignof__ 
(max_align_t)) - 1];
+            #endif
+          ]])],
+       [gl_cv_type_max_align_t=yes],
+       [gl_cv_type_max_align_t=no])
+    ])
+  if test $gl_cv_type_max_align_t = no; then
+    HAVE_MAX_ALIGN_T=0
+    STDDEF_H=stddef.h
+  fi
+
   if test $gt_cv_c_wchar_t = no; then
     HAVE_WCHAR_T=0
     STDDEF_H=stddef.h
   fi
+
   AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions],
     [gl_cv_decl_null_works],
     [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h>
@@ -28,6 +48,7 @@ AC_DEFUN([gl_STDDEF_H],
     REPLACE_NULL=1
     STDDEF_H=stddef.h
   fi
+
   AC_SUBST([STDDEF_H])
   AM_CONDITIONAL([GL_GENERATE_STDDEF_H], [test -n "$STDDEF_H"])
   if test -n "$STDDEF_H"; then
diff --git a/oldXMenu/Makefile.in b/oldXMenu/Makefile.in
index d795038..211bac9 100644
--- a/oldXMenu/Makefile.in
+++ b/oldXMenu/Makefile.in
@@ -138,7 +138,7 @@ libXMenu11.a: $(OBJS) $(EXTRA)
 .PHONY: mostlyclean clean distclean bootstrap-clean maintainer-clean
 
 clean mostlyclean:
-       rm -f libXMenu11.a *.o $(DEPDIR)/*
+       rm -f libXMenu11.a ./*.o $(DEPDIR)/*
 
 bootstrap-clean maintainer-clean distclean: clean
        rm -f Makefile
diff --git a/src/Makefile.in b/src/Makefile.in
index 7d9c236..72f5689 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -645,12 +645,12 @@ ns-app: emacs$(EXEEXT)
 .PHONY: versionclean extraclean
 
 mostlyclean:
-       rm -f temacs$(EXEEXT) core *.core \#* *.o
+       rm -f temacs$(EXEEXT) core ./*.core \#* ./*.o
        rm -f ../etc/DOC
        rm -f bootstrap-emacs$(EXEEXT) emacs-$(version)$(EXEEXT)
        rm -f buildobj.h
        rm -f globals.h gl-stamp
-       rm -f *.res *.tmp
+       rm -f ./*.res ./*.tmp
 clean: mostlyclean
        rm -f emacs-*.*.*[0-9]$(EXEEXT) emacs$(EXEEXT) $(DEPDIR)/*
 
@@ -674,7 +674,7 @@ maintainer-clean: distclean
 versionclean:
        -rm -f emacs$(EXEEXT) emacs-*.*.*[0-9]$(EXEEXT) ../etc/DOC*
 extraclean: distclean
-       -rm -f *~ \#*
+       -rm -f ./*~ \#*
 
 
 ETAGS = ../lib-src/etags${EXEEXT}
diff --git a/src/alloc.c b/src/alloc.c
index abb98a9..3b15079 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2425,7 +2425,7 @@ LENGTH must be a number.  INIT matters only in whether it 
is t or nil.  */)
 
 DEFUN ("bool-vector", Fbool_vector, Sbool_vector, 0, MANY, 0,
        doc: /* Return a new bool-vector with specified arguments as elements.
-Any number of arguments, even zero arguments, are allowed.
+Allows any number of arguments, including zero.
 usage: (bool-vector &rest OBJECTS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
@@ -2872,7 +2872,7 @@ listn (enum constype type, ptrdiff_t count, Lisp_Object 
arg, ...)
 
 DEFUN ("list", Flist, Slist, 0, MANY, 0,
        doc: /* Return a newly created list with specified arguments as 
elements.
-Any number of arguments, even zero arguments, are allowed.
+Allows any number of arguments, including zero.
 usage: (list &rest OBJECTS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
@@ -3497,7 +3497,7 @@ See also the function `vector'.  */)
 
 DEFUN ("vector", Fvector, Svector, 0, MANY, 0,
        doc: /* Return a newly created vector with specified arguments as 
elements.
-Any number of arguments, even zero arguments, are allowed.
+Allows any number of arguments, including zero.
 usage: (vector &rest OBJECTS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
@@ -3729,7 +3729,7 @@ build_marker (struct buffer *buf, ptrdiff_t charpos, 
ptrdiff_t bytepos)
    elements.  If all the arguments are characters that can fit
    in a string of events, make a string; otherwise, make a vector.
 
-   Any number of arguments, even zero arguments, are allowed.  */
+   Allows any number of arguments, including zero.  */
 
 Lisp_Object
 make_event_array (ptrdiff_t nargs, Lisp_Object *args)
@@ -7120,14 +7120,6 @@ verify_alloca (void)
 
 #endif /* ENABLE_CHECKING && USE_STACK_LISP_OBJECTS */
 
-/* Memory allocation for GMP.  */
-
-void
-range_error (void)
-{
-  xsignal0 (Qrange_error);
-}
-
 /* Initialization.  */
 
 void
diff --git a/src/atimer.c b/src/atimer.c
index 97f0736..505f6bc 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -113,10 +113,10 @@ start_atimer (enum atimer_type type, struct timespec 
timestamp,
   sigset_t oldset;
 
   /* Round TIMESTAMP up to the next full second if we don't have itimers.  */
-#ifndef HAVE_SETITIMER
+#if ! (defined HAVE_ITIMERSPEC || defined HAVE_SETITIMER)
   if (timestamp.tv_nsec != 0 && timestamp.tv_sec < TYPE_MAXIMUM (time_t))
     timestamp = make_timespec (timestamp.tv_sec + 1, 0);
-#endif /* not HAVE_SETITIMER */
+#endif
 
   /* Get an atimer structure from the free-list, or allocate
      a new one.  */
@@ -494,15 +494,14 @@ debug_timer_callback (struct atimer *t)
     r->intime = 0;
   else if (result >= 0)
     {
-#ifdef HAVE_SETITIMER
+      bool intime = true;
+#if defined HAVE_ITIMERSPEC || defined HAVE_SETITIMER
       struct timespec delta = timespec_sub (now, r->expected);
       /* Too late if later than expected + 0.02s.  FIXME:
         this should depend from system clock resolution.  */
-      if (timespec_cmp (delta, make_timespec (0, 20000000)) > 0)
-       r->intime = 0;
-      else
-#endif /* HAVE_SETITIMER */
-       r->intime = 1;
+      intime = timespec_cmp (delta, make_timespec (0, 20000000)) <= 0;
+#endif
+      r->intime = intime;
     }
 }
 
diff --git a/src/bignum.c b/src/bignum.c
index 35894f5..1e78d98 100644
--- a/src/bignum.c
+++ b/src/bignum.c
@@ -23,6 +23,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 #include "lisp.h"
 
+#include <math.h>
 #include <stdlib.h>
 
 /* mpz global temporaries.  Making them global saves the trouble of
@@ -61,13 +62,16 @@ init_bignum (void)
 double
 bignum_to_double (Lisp_Object n)
 {
-  return mpz_get_d (XBIGNUM (n)->value);
+  return mpz_get_d_rounded (XBIGNUM (n)->value);
 }
 
-/* Return D, converted to a bignum.  Discard any fraction.  */
+/* Return D, converted to a Lisp integer.  Discard any fraction.
+   Signal an error if D cannot be converted.  */
 Lisp_Object
-double_to_bignum (double d)
+double_to_integer (double d)
 {
+  if (!isfinite (d))
+    overflow_error ();
   mpz_set_d (mpz[0], d);
   return make_integer_mpz ();
 }
@@ -80,7 +84,7 @@ make_bignum_bits (size_t bits)
   /* The documentation says integer-width should be nonnegative, so
      a single comparison suffices even though 'bits' is unsigned.  */
   if (integer_width < bits)
-    range_error ();
+    overflow_error ();
 
   struct Lisp_Bignum *b = ALLOCATE_PSEUDOVECTOR (struct Lisp_Bignum, value,
                                                 PVEC_BIGNUM);
@@ -247,12 +251,40 @@ bignum_to_uintmax (Lisp_Object x)
 }
 
 /* Yield an upper bound on the buffer size needed to contain a C
-   string representing the bignum NUM in base BASE.  This includes any
+   string representing the NUM in base BASE.  This includes any
    preceding '-' and the terminating null.  */
+static ptrdiff_t
+mpz_bufsize (mpz_t const num, int base)
+{
+  return mpz_sizeinbase (num, base) + 2;
+}
 ptrdiff_t
 bignum_bufsize (Lisp_Object num, int base)
 {
-  return mpz_sizeinbase (XBIGNUM (num)->value, base) + 2;
+  return mpz_bufsize (XBIGNUM (num)->value, base);
+}
+
+/* Convert NUM to a nearest double, as opposed to mpz_get_d which
+   truncates toward zero.  */
+double
+mpz_get_d_rounded (mpz_t const num)
+{
+  ptrdiff_t size = mpz_bufsize (num, 10);
+
+  /* Use mpz_get_d as a shortcut for a bignum so small that rounding
+     errors cannot occur, which is possible if EMACS_INT (not counting
+     sign) has fewer bits than a double significand.  */
+  if (! ((FLT_RADIX == 2 && DBL_MANT_DIG <= FIXNUM_BITS - 1)
+        || (FLT_RADIX == 16 && DBL_MANT_DIG * 4 <= FIXNUM_BITS - 1))
+      && size <= DBL_DIG + 2)
+    return mpz_get_d (num);
+
+  USE_SAFE_ALLOCA;
+  char *buf = SAFE_ALLOCA (size);
+  mpz_get_str (buf, 10, num);
+  double result = strtod (buf, NULL);
+  SAFE_FREE ();
+  return result;
 }
 
 /* Store into BUF (of size SIZE) the value of NUM as a base-BASE string.
diff --git a/src/bignum.h b/src/bignum.h
index 6551549..e9cd5c0 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -46,6 +46,7 @@ extern mpz_t mpz[4];
 extern void init_bignum (void);
 extern Lisp_Object make_integer_mpz (void);
 extern void mpz_set_intmax_slow (mpz_t, intmax_t) ARG_NONNULL ((1));
+extern double mpz_get_d_rounded (mpz_t const);
 
 INLINE_HEADER_BEGIN
 
diff --git a/src/buffer.c b/src/buffer.c
index 878844d..024e64f 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -4516,23 +4516,6 @@ report_overlay_modification (Lisp_Object start, 
Lisp_Object end, bool after,
     Lisp_Object *copy;
     ptrdiff_t i;
 
-    if (size)
-      {
-       Lisp_Object ovl
-         = XVECTOR (last_overlay_modification_hooks)->contents[1];
-
-       /* If the buffer of the first overlay in the array doesn't
-          match the current buffer, then these modification hooks
-          should not be run in this buffer.  This could happen when
-          some code calls some insdel functions, such as del_range_1,
-          with the PREPARE argument false -- in that case this
-          function is never called to record the overlay modification
-          hook functions in the last_overlay_modification_hooks
-          array, so anything we find there is not ours.  */
-       if (XMARKER (OVERLAY_START (ovl))->buffer != current_buffer)
-         return;
-      }
-
     USE_SAFE_ALLOCA;
     SAFE_ALLOCA_LISP (copy, size);
     memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
@@ -4543,7 +4526,12 @@ report_overlay_modification (Lisp_Object start, 
Lisp_Object end, bool after,
        Lisp_Object prop_i, overlay_i;
        prop_i = copy[i++];
        overlay_i = copy[i++];
-       call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
+       /* It is possible that the recorded overlay has been deleted
+          (which makes it's markers' buffers be nil), or that (due to
+          some bug) it belongs to a different buffer.  Only run this
+          hook if the overlay belongs to the current buffer.  */
+       if (XMARKER (OVERLAY_START (overlay_i))->buffer == current_buffer)
+         call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
       }
 
     SAFE_FREE ();
@@ -6022,11 +6010,11 @@ An entry (TEXT . POSITION) represents the deletion of 
the string TEXT
 from (abs POSITION).  If POSITION is positive, point was at the front
 of the text being deleted; if negative, point was at the end.
 
-An entry (t HIGH LOW USEC PSEC) indicates that the buffer was previously
-unmodified; (HIGH LOW USEC PSEC) is in the same style as (current-time)
-and is the visited file's modification time, as of that time.  If the
-modification time of the most recent save is different, this entry is
-obsolete.
+An entry (t . TIMESTAMP), where TIMESTAMP is in the style of
+`current-time', indicates that the buffer was previously unmodified;
+TIMESTAMP is the visited file's modification time, as of that time.
+If the modification time of the most recent save is different, this
+entry is obsolete.
 
 An entry (t . 0) means the buffer was previously unmodified but
 its time stamp was unknown because it was not associated with a file.
diff --git a/src/charset.c b/src/charset.c
index 6e2bf17..c1a2378 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1892,7 +1892,7 @@ Return nil if CHARSET doesn't support CH.  */)
      can fit in 22bit.  Yet we encode GB-10830's chars in a sparse way
      (we just take the 4byte sequences as a 32bit int), so some
      GB-10830 chars (such as 0x81308130 in etc/charsets/gb108304.map) end
-     up represented as bignums here.  */
+     up represented as bignums if EMACS_INT is 32 bits.  */
   return INT_TO_INTEGER (code);
 }
 
diff --git a/src/data.c b/src/data.c
index 66f69e7..750d494 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2407,7 +2407,7 @@ static void
 emacs_mpz_mul (mpz_t rop, mpz_t const op1, mpz_t const op2)
 {
   if (NLIMBS_LIMIT - emacs_mpz_size (op1) < emacs_mpz_size (op2))
-    range_error ();
+    overflow_error ();
   mpz_mul (rop, op1, op2);
 }
 
@@ -2421,7 +2421,7 @@ emacs_mpz_mul_2exp (mpz_t rop, mpz_t const op1, 
mp_bitcnt_t op2)
 
   mp_bitcnt_t op2limbs = op2 / GMP_NUMB_BITS;
   if (lim - emacs_mpz_size (op1) < op2limbs)
-    range_error ();
+    overflow_error ();
   mpz_mul_2exp (rop, op1, op2);
 }
 
@@ -2435,7 +2435,7 @@ emacs_mpz_pow_ui (mpz_t rop, mpz_t const base, unsigned 
long exp)
 
   int nbase = emacs_mpz_size (base), n;
   if (INT_MULTIPLY_WRAPV (nbase, exp, &n) || lim < n)
-    range_error ();
+    overflow_error ();
   mpz_pow_ui (rop, base, exp);
 }
 
@@ -2920,8 +2920,8 @@ bignum_arith_driver (enum arithop code, ptrdiff_t nargs, 
Lisp_Object *args,
       val = args[argnum];
       CHECK_NUMBER_COERCE_MARKER (val);
       if (FLOATP (val))
-       float_arith_driver (code, nargs, args, argnum,
-                           mpz_get_d (*accum), val);
+       return float_arith_driver (code, nargs, args, argnum,
+                                  mpz_get_d_rounded (*accum), val);
     }
 }
 
@@ -3292,7 +3292,7 @@ expt_integer (Lisp_Object x, Lisp_Object y)
           && mpz_fits_ulong_p (XBIGNUM (y)->value))
     exp = mpz_get_ui (XBIGNUM (y)->value);
   else
-    range_error ();
+    overflow_error ();
 
   emacs_mpz_pow_ui (mpz[0], *bignum_integer (&mpz[0], x), exp);
   return make_integer_mpz ();
diff --git a/src/dired.c b/src/dired.c
index 70c5bb2..7ad401c 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -347,7 +347,7 @@ DEFUN ("directory-files-and-attributes", 
Fdirectory_files_and_attributes,
        doc: /* Return a list of names of files and their attributes in 
DIRECTORY.
 Value is a list of the form:
 
-  ((FILE1 FILE1-ATTRS) (FILE2 FILE2-ATTRS) ...)
+  ((FILE1 . FILE1-ATTRS) (FILE2 . FILE2-ATTRS) ...)
 
 where each FILEn-ATTRS is the attributes of FILEn as returned
 by `file-attributes'.
@@ -866,26 +866,22 @@ provided: `file-attribute-type', 
`file-attribute-link-number',
 Elements of the attribute list are:
  0. t for directory, string (name linked to) for symbolic link, or nil.
  1. Number of links to file.
- 2. File uid as a string or a number.  If a string value cannot be
-  looked up, an integer value is returned, which could be a fixnum,
-  if it's small enough, otherwise a bignum.
+ 2. File uid as a string or (if ID-FORMAT is `integer' or a string value
+  cannot be looked up) as an integer.
  3. File gid, likewise.
- 4. Last access time, as a list of integers (HIGH LOW USEC PSEC) in the
-  same style as (current-time).
+ 4. Last access time, in the style of `current-time'.
   (See a note below about access time on FAT-based filesystems.)
  5. Last modification time, likewise.  This is the time of the last
   change to the file's contents.
  6. Last status change time, likewise.  This is the time of last change
   to the file's attributes: owner and group, access mode bits, etc.
- 7. Size in bytes, which could be a fixnum, if it's small enough,
-  otherwise a bignum.
+ 7. Size in bytes, as an integer.
  8. File modes, as a string of ten letters or dashes as in ls -l.
  9. An unspecified value, present only for backward compatibility.
-10. inode number, which could be a fixnum, if it's small enough,
-  otherwise a bignum.
-11. Filesystem device number.  If it is larger than what a fixnum
-  can hold, it is a bignum.
+10. inode number, as a nonnegative integer.
+11. Filesystem device number, as an integer.
 
+Large integers are bignums, so `eq' might not work on them.
 On most filesystems, the combination of the inode and the device
 number uniquely identifies the file.
 
diff --git a/src/editfns.c b/src/editfns.c
index f19c3f1..47509c2 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1589,13 +1589,21 @@ time_subtract (struct lisp_time ta, struct lisp_time tb)
 }
 
 static Lisp_Object
-time_arith (Lisp_Object a, Lisp_Object b,
-           struct lisp_time (*op) (struct lisp_time, struct lisp_time))
+time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
 {
+  if (FLOATP (a) && !isfinite (XFLOAT_DATA (a)))
+    {
+      double da = XFLOAT_DATA (a);
+      double db = XFLOAT_DATA (Ffloat_time (b));
+      return make_float (subtract ? da - db : da + db);
+    }
+  if (FLOATP (b) && !isfinite (XFLOAT_DATA (b)))
+    return subtract ? make_float (-XFLOAT_DATA (b)) : b;
+
   int alen, blen;
   struct lisp_time ta = lisp_time_struct (a, &alen);
   struct lisp_time tb = lisp_time_struct (b, &blen);
-  struct lisp_time t = op (ta, tb);
+  struct lisp_time t = (subtract ? time_subtract : time_add) (ta, tb);
   if (FIXNUM_OVERFLOW_P (t.hi))
     time_overflow ();
   Lisp_Object val = Qnil;
@@ -1623,7 +1631,7 @@ A nil value for either argument stands for the current 
time.
 See `current-time-string' for the various forms of a time value.  */)
   (Lisp_Object a, Lisp_Object b)
 {
-  return time_arith (a, b, time_add);
+  return time_arith (a, b, false);
 }
 
 DEFUN ("time-subtract", Ftime_subtract, Stime_subtract, 2, 2, 0,
@@ -1633,7 +1641,30 @@ A nil value for either argument stands for the current 
time.
 See `current-time-string' for the various forms of a time value.  */)
   (Lisp_Object a, Lisp_Object b)
 {
-  return time_arith (a, b, time_subtract);
+  return time_arith (a, b, true);
+}
+
+/* Return negative, 0, positive if a < b, a == b, a > b respectively.
+   Return positive if either a or b is a NaN; this is good enough
+   for the current callers.  */
+static int
+time_cmp (Lisp_Object a, Lisp_Object b)
+{
+  if ((FLOATP (a) && !isfinite (XFLOAT_DATA (a)))
+      || (FLOATP (b) && !isfinite (XFLOAT_DATA (b))))
+    {
+      double da = FLOATP (a) ? XFLOAT_DATA (a) : 0;
+      double db = FLOATP (b) ? XFLOAT_DATA (b) : 0;
+      return da < db ? -1 : da != db;
+    }
+
+  int alen, blen;
+  struct lisp_time ta = lisp_time_struct (a, &alen);
+  struct lisp_time tb = lisp_time_struct (b, &blen);
+  return (ta.hi != tb.hi ? (ta.hi < tb.hi ? -1 : 1)
+         : ta.lo != tb.lo ? (ta.lo < tb.lo ? -1 : 1)
+         : ta.us != tb.us ? (ta.us < tb.us ? -1 : 1)
+         : ta.ps < tb.ps ? -1 : ta.ps != tb.ps);
 }
 
 DEFUN ("time-less-p", Ftime_less_p, Stime_less_p, 2, 2, 0,
@@ -1642,22 +1673,23 @@ A nil value for either argument stands for the current 
time.
 See `current-time-string' for the various forms of a time value.  */)
   (Lisp_Object t1, Lisp_Object t2)
 {
-  int t1len, t2len;
-  struct lisp_time a = lisp_time_struct (t1, &t1len);
-  struct lisp_time b = lisp_time_struct (t2, &t2len);
-  return ((a.hi != b.hi ? a.hi < b.hi
-          : a.lo != b.lo ? a.lo < b.lo
-          : a.us != b.us ? a.us < b.us
-          : a.ps < b.ps)
-         ? Qt : Qnil);
+  return time_cmp (t1, t2) < 0 ? Qt : Qnil;
+}
+
+DEFUN ("time-equal-p", Ftime_equal_p, Stime_equal_p, 2, 2, 0,
+       doc: /* Return non-nil if T1 and T2 are equal time values.
+A nil value for either argument stands for the current time.
+See `current-time-string' for the various forms of a time value.  */)
+  (Lisp_Object t1, Lisp_Object t2)
+{
+  return time_cmp (t1, t2) == 0 ? Qt : Qnil;
 }
 
 
 DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time,
        0, 0, 0,
        doc: /* Return the current run time used by Emacs.
-The time is returned as a list (HIGH LOW USEC PSEC), using the same
-style as (current-time).
+The time is returned as in the style of `current-time'.
 
 On systems that can't determine the run time, `get-internal-run-time'
 does the same thing as `current-time'.  */)
@@ -2165,7 +2197,8 @@ between 0 and 23.  DAY is an integer between 1 and 31.  
MONTH is an
 integer between 1 and 12.  YEAR is an integer indicating the
 four-digit year.  DOW is the day of week, an integer between 0 and 6,
 where 0 is Sunday.  DST is t if daylight saving time is in effect,
-otherwise nil.  UTCOFF is an integer indicating the UTC offset in
+nil if it is not in effect, and -1 if this information is
+not available.  UTCOFF is an integer indicating the UTC offset in
 seconds, i.e., the number of seconds east of Greenwich.  (Note that
 Common Lisp has different meanings for DOW and UTCOFF.)
 
@@ -2194,7 +2227,8 @@ usage: (decode-time &optional TIME ZONE)  */)
                make_fixnum (local_tm.tm_mon + 1),
                make_fixnum (local_tm.tm_year + tm_year_base),
                make_fixnum (local_tm.tm_wday),
-               local_tm.tm_isdst ? Qt : Qnil,
+               (local_tm.tm_isdst < 0 ? make_fixnum (-1)
+                : local_tm.tm_isdst == 0 ? Qnil : Qt),
                (HAVE_TM_GMTOFF
                 ? make_fixnum (tm_gmtoff (&local_tm))
                 : gmtime_r (&time_spec, &gmt_tm)
@@ -4657,7 +4691,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool 
message)
 
              /* Characters to be inserted after spaces and before
                 leading zeros.  This can occur with bignums, since
-                string_to_bignum does only leading '-'.  */
+                bignum_to_string does only leading '-'.  */
              char prefix[sizeof "-0x" - 1];
              int prefixlen = 0;
 
@@ -5733,6 +5767,7 @@ it to be non-nil.  */);
   defsubr (&Scurrent_time);
   defsubr (&Stime_add);
   defsubr (&Stime_subtract);
+  defsubr (&Stime_equal_p);
   defsubr (&Stime_less_p);
   defsubr (&Sget_internal_run_time);
   defsubr (&Sformat_time_string);
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 6155535..0dcd7f0 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -304,7 +304,7 @@ module_make_global_ref (emacs_env *env, emacs_value ref)
       Lisp_Object value = HASH_VALUE (h, i);
       EMACS_INT refcount = XFIXNAT (value) + 1;
       if (MOST_POSITIVE_FIXNUM < refcount)
-       xsignal0 (Qoverflow_error);
+       overflow_error ();
       value = make_fixed_natnum (refcount);
       set_hash_value_slot (h, i, value);
     }
@@ -475,7 +475,7 @@ module_funcall (emacs_env *env, emacs_value fun, ptrdiff_t 
nargs,
   USE_SAFE_ALLOCA;
   ptrdiff_t nargs1;
   if (INT_ADD_WRAPV (nargs, 1, &nargs1))
-    xsignal0 (Qoverflow_error);
+    overflow_error ();
   SAFE_ALLOCA_LISP (newargs, nargs1);
   newargs[0] = value_to_lisp (fun);
   for (ptrdiff_t i = 0; i < nargs; i++)
@@ -583,7 +583,7 @@ module_make_string (emacs_env *env, const char *str, 
ptrdiff_t length)
 {
   MODULE_FUNCTION_BEGIN (module_nil);
   if (! (0 <= length && length <= STRING_BYTES_BOUND))
-    xsignal0 (Qoverflow_error);
+    overflow_error ();
   /* FIXME: AUTO_STRING_WITH_LEN requires STR to be null-terminated,
      but we shouldn't require that.  */
   AUTO_STRING_WITH_LEN (lstr, str, length);
@@ -747,11 +747,7 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0,
   maybe_quit ();
 
   if (r != 0)
-    {
-      if (FIXNUM_OVERFLOW_P (r))
-        xsignal0 (Qoverflow_error);
-      xsignal2 (Qmodule_init_failed, file, make_fixnum (r));
-    }
+    xsignal2 (Qmodule_init_failed, file, INT_TO_INTEGER (r));
 
   module_signal_or_throw (&env_priv);
   return unbind_to (count, Qt);
diff --git a/src/eval.c b/src/eval.c
index 60dd6f1..5e25caa 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1238,8 +1238,10 @@ Each element of HANDLERS looks like (CONDITION-NAME 
BODY...)
 where the BODY is made of Lisp expressions.
 
 A handler is applicable to an error if CONDITION-NAME is one of the
-error's condition names.  A CONDITION-NAME of t applies to any error
-symbol.  If an error happens, the first applicable handler is run.
+error's condition names.  Handlers may also apply when non-error
+symbols are signaled (e.g., `quit').  A CONDITION-NAME of t applies to
+any symbol, including non-error symbols.  If multiple handlers are
+applicable, only the first one runs.
 
 The car of a handler may be a list of condition names instead of a
 single condition name; then it handles all of them.  If the special
@@ -1765,6 +1767,14 @@ signal_error (const char *s, Lisp_Object arg)
   xsignal (Qerror, Fcons (build_string (s), arg));
 }
 
+/* Use this for arithmetic overflow, e.g., when an integer result is
+   too large even for a bignum.  */
+void
+overflow_error (void)
+{
+  xsignal0 (Qoverflow_error);
+}
+
 
 /* Return true if LIST is a non-nil atom or
    a list containing one of CONDITIONS.  */
diff --git a/src/fileio.c b/src/fileio.c
index 5ca7c59..7fb8658 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5454,10 +5454,9 @@ See Info node `(elisp)Modification Time' for more 
details.  */)
 DEFUN ("visited-file-modtime", Fvisited_file_modtime,
        Svisited_file_modtime, 0, 0, 0,
        doc: /* Return the current buffer's recorded visited file modification 
time.
-The value is a list of the form (HIGH LOW USEC PSEC), like the time values that
-`file-attributes' returns.  If the current buffer has no recorded file
-modification time, this function returns 0.  If the visited file
-doesn't exist, return -1.
+Return a Lisp timestamp (as in `current-time') if the current buffer
+has a recorded file modification time, 0 if it doesn't, and -1 if the
+visited file doesn't exist.
 See Info node `(elisp)Modification Time' for more details.  */)
   (void)
 {
@@ -5473,9 +5472,8 @@ DEFUN ("set-visited-file-modtime", 
Fset_visited_file_modtime,
 Useful if the buffer was not read from the file normally
 or if the file itself has been changed for some known benign reason.
 An argument specifies the modification time value to use
-\(instead of that of the visited file), in the form of a list
-\(HIGH LOW USEC PSEC) or an integer flag as returned by
-`visited-file-modtime'.  */)
+\(instead of that of the visited file), in the form of a time value as
+in `current-time' or an integer flag as returned by `visited-file-modtime'.  
*/)
   (Lisp_Object time_flag)
 {
   if (!NILP (time_flag))
diff --git a/src/floatfns.c b/src/floatfns.c
index dc72363..9003925 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -332,6 +332,18 @@ This is the same as the exponent of a float.  */)
   return make_fixnum (value);
 }
 
+/* True if A is exactly representable as an integer.  */
+
+static bool
+integer_value (Lisp_Object a)
+{
+  if (FLOATP (a))
+    {
+      double d = XFLOAT_DATA (a);
+      return d == floor (d) && isfinite (d);
+    }
+  return true;
+}
 
 /* the rounding functions  */
 
@@ -339,8 +351,7 @@ static Lisp_Object
 rounding_driver (Lisp_Object arg, Lisp_Object divisor,
                 double (*double_round) (double),
                 void (*int_divide) (mpz_t, mpz_t const, mpz_t const),
-                EMACS_INT (*fixnum_divide) (EMACS_INT, EMACS_INT),
-                const char *name)
+                EMACS_INT (*fixnum_divide) (EMACS_INT, EMACS_INT))
 {
   CHECK_NUMBER (arg);
 
@@ -354,10 +365,16 @@ rounding_driver (Lisp_Object arg, Lisp_Object divisor,
   else
     {
       CHECK_NUMBER (divisor);
-      if (!FLOATP (arg) && !FLOATP (divisor))
+      if (integer_value (arg) && integer_value (divisor))
        {
          /* Divide as integers.  Converting to double might lose
             info, even for fixnums; also see the FIXME below.  */
+
+         if (FLOATP (arg))
+           arg = double_to_integer (XFLOAT_DATA (arg));
+         if (FLOATP (divisor))
+           divisor = double_to_integer (XFLOAT_DATA (divisor));
+
          if (FIXNUMP (divisor))
            {
              if (XFIXNUM (divisor) == 0)
@@ -391,7 +408,7 @@ rounding_driver (Lisp_Object arg, Lisp_Object divisor,
       if (! FIXNUM_OVERFLOW_P (ir))
        return make_fixnum (ir);
     }
-  return double_to_bignum (dr);
+  return double_to_integer (dr);
 }
 
 static EMACS_INT
@@ -474,7 +491,7 @@ This rounds the value towards +inf.
 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR.  
*/)
   (Lisp_Object arg, Lisp_Object divisor)
 {
-  return rounding_driver (arg, divisor, ceil, mpz_cdiv_q, ceiling2, "ceiling");
+  return rounding_driver (arg, divisor, ceil, mpz_cdiv_q, ceiling2);
 }
 
 DEFUN ("floor", Ffloor, Sfloor, 1, 2, 0,
@@ -483,7 +500,7 @@ This rounds the value towards -inf.
 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. 
 */)
   (Lisp_Object arg, Lisp_Object divisor)
 {
-  return rounding_driver (arg, divisor, floor, mpz_fdiv_q, floor2, "floor");
+  return rounding_driver (arg, divisor, floor, mpz_fdiv_q, floor2);
 }
 
 DEFUN ("round", Fround, Sround, 1, 2, 0,
@@ -496,8 +513,7 @@ your machine.  For example, (round 2.5) can return 3 on some
 systems, but 2 on others.  */)
   (Lisp_Object arg, Lisp_Object divisor)
 {
-  return rounding_driver (arg, divisor, emacs_rint, rounddiv_q, round2,
-                         "round");
+  return rounding_driver (arg, divisor, emacs_rint, rounddiv_q, round2);
 }
 
 /* Since rounding_driver truncates anyway, no need to call 'trunc'.  */
@@ -513,8 +529,7 @@ Rounds ARG toward zero.
 With optional DIVISOR, truncate ARG/DIVISOR.  */)
   (Lisp_Object arg, Lisp_Object divisor)
 {
-  return rounding_driver (arg, divisor, identity, mpz_tdiv_q, truncate2,
-                         "truncate");
+  return rounding_driver (arg, divisor, identity, mpz_tdiv_q, truncate2);
 }
 
 
diff --git a/src/gnutls.c b/src/gnutls.c
index a48d998..d36b637 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -38,6 +38,23 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
    So, require 3.5.1.  */
 #if GNUTLS_VERSION_NUMBER >= 0x030501
 # define HAVE_GNUTLS_AEAD
+#elif GNUTLS_VERSION_NUMBER < 0x030202
+/* gnutls_cipher_get_tag_size was introduced in 3.2.2, but it's only
+   relevant for AEAD ciphers.  */
+# define gnutls_cipher_get_tag_size(cipher) 0
+#endif
+
+#if GNUTLS_VERSION_NUMBER < 0x030200
+/* gnutls_cipher_get_iv_size was introduced in 3.2.0.  For the ciphers
+   available in previous versions, block size is equivalent.  */
+#define gnutls_cipher_get_iv_size(cipher) gnutls_cipher_get_block_size (cipher)
+#endif
+
+#if GNUTLS_VERSION_NUMBER < 0x030202
+/* gnutls_digest_list and gnutls_digest_get_name were added in 3.2.2.
+   For previous versions, the mac algorithms are equivalent.  */
+# define gnutls_digest_list() ((const gnutls_digest_algorithm_t *) 
gnutls_mac_list ())
+# define gnutls_digest_get_name(id) gnutls_mac_get_name 
((gnutls_mac_algorithm_t) id)
 #endif
 
 /* gnutls_mac_get_nonce_size was added in GnuTLS 3.2.0, but was
@@ -206,13 +223,21 @@ DEF_DLL_FN (const gnutls_mac_algorithm_t *, 
gnutls_mac_list, (void));
 DEF_DLL_FN (size_t, gnutls_mac_get_nonce_size, (gnutls_mac_algorithm_t));
 #   endif
 DEF_DLL_FN (size_t, gnutls_mac_get_key_size, (gnutls_mac_algorithm_t));
+#   ifndef gnutls_digest_list
 DEF_DLL_FN (const gnutls_digest_algorithm_t *, gnutls_digest_list, (void));
+#   endif
+#   ifndef gnutls_digest_get_name
 DEF_DLL_FN (const char *, gnutls_digest_get_name, (gnutls_digest_algorithm_t));
+#   endif
 DEF_DLL_FN (gnutls_cipher_algorithm_t *, gnutls_cipher_list, (void));
+#   ifndef gnutls_cipher_get_iv_size
 DEF_DLL_FN (int, gnutls_cipher_get_iv_size, (gnutls_cipher_algorithm_t));
+#   endif
 DEF_DLL_FN (size_t, gnutls_cipher_get_key_size, (gnutls_cipher_algorithm_t));
 DEF_DLL_FN (int, gnutls_cipher_get_block_size, (gnutls_cipher_algorithm_t));
+#   ifndef gnutls_cipher_get_tag_size
 DEF_DLL_FN (int, gnutls_cipher_get_tag_size, (gnutls_cipher_algorithm_t));
+#   endif
 DEF_DLL_FN (int, gnutls_cipher_init,
            (gnutls_cipher_hd_t *, gnutls_cipher_algorithm_t,
             const gnutls_datum_t *, const gnutls_datum_t *));
@@ -340,13 +365,21 @@ init_gnutls_functions (void)
   LOAD_DLL_FN (library, gnutls_mac_get_nonce_size);
 #   endif
   LOAD_DLL_FN (library, gnutls_mac_get_key_size);
+#   ifndef gnutls_digest_list
   LOAD_DLL_FN (library, gnutls_digest_list);
+#   endif
+#   ifndef gnutls_digest_get_name
   LOAD_DLL_FN (library, gnutls_digest_get_name);
+#   endif
   LOAD_DLL_FN (library, gnutls_cipher_list);
+#   ifndef gnutls_cipher_get_iv_size
   LOAD_DLL_FN (library, gnutls_cipher_get_iv_size);
+#   endif
   LOAD_DLL_FN (library, gnutls_cipher_get_key_size);
   LOAD_DLL_FN (library, gnutls_cipher_get_block_size);
+#   ifndef gnutls_cipher_get_tag_size
   LOAD_DLL_FN (library, gnutls_cipher_get_tag_size);
+#   endif
   LOAD_DLL_FN (library, gnutls_cipher_init);
   LOAD_DLL_FN (library, gnutls_cipher_set_iv);
   LOAD_DLL_FN (library, gnutls_cipher_encrypt2);
@@ -456,13 +489,21 @@ init_gnutls_functions (void)
 #    define gnutls_mac_get_nonce_size fn_gnutls_mac_get_nonce_size
 #   endif
 #  define gnutls_mac_get_key_size fn_gnutls_mac_get_key_size
-#  define gnutls_digest_list fn_gnutls_digest_list
-#  define gnutls_digest_get_name fn_gnutls_digest_get_name
+#  ifndef gnutls_digest_list
+#   define gnutls_digest_list fn_gnutls_digest_list
+#  endif
+#  ifndef gnutls_digest_get_name
+#   define gnutls_digest_get_name fn_gnutls_digest_get_name
+#  endif
 #  define gnutls_cipher_list fn_gnutls_cipher_list
-#  define gnutls_cipher_get_iv_size fn_gnutls_cipher_get_iv_size
+#  ifndef gnutls_cipher_get_iv_size
+#   define gnutls_cipher_get_iv_size fn_gnutls_cipher_get_iv_size
+#  endif
 #  define gnutls_cipher_get_key_size fn_gnutls_cipher_get_key_size
 #  define gnutls_cipher_get_block_size fn_gnutls_cipher_get_block_size
-#  define gnutls_cipher_get_tag_size fn_gnutls_cipher_get_tag_size
+#  ifndef gnutls_cipher_get_tag_size
+#   define gnutls_cipher_get_tag_size fn_gnutls_cipher_get_tag_size
+#  endif
 #  define gnutls_cipher_init fn_gnutls_cipher_init
 #  define gnutls_cipher_set_iv fn_gnutls_cipher_set_iv
 #  define gnutls_cipher_encrypt2 fn_gnutls_cipher_encrypt2
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 4250355..6212e1a 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1867,7 +1867,7 @@ xg_maybe_add_timer (gpointer data)
   if (timespec_valid_p (next_time))
     {
       time_t s = next_time.tv_sec;
-      int per_ms = TIMESPEC_RESOLUTION / 1000;
+      int per_ms = TIMESPEC_HZ / 1000;
       int ms = (next_time.tv_nsec + per_ms - 1) / per_ms;
       if (s <= ((guint) -1 - ms) / 1000)
        dd->timerid = g_timeout_add (s * 1000 + ms, xg_maybe_add_timer, dd);
diff --git a/src/json.c b/src/json.c
index 976783d..17cc096 100644
--- a/src/json.c
+++ b/src/json.c
@@ -488,10 +488,14 @@ lisp_to_json (Lisp_Object lisp, struct json_configuration 
*conf)
     return json_check (json_false ());
   else if (EQ (lisp, Qt))
     return json_check (json_true ());
-  else if (FIXNUMP (lisp))
+  else if (INTEGERP (lisp))
     {
-      CHECK_TYPE_RANGED_INTEGER (json_int_t, lisp);
-      return json_check (json_integer (XFIXNUM (lisp)));
+      intmax_t low = TYPE_MINIMUM (json_int_t);
+      intmax_t high = TYPE_MAXIMUM (json_int_t);
+      intmax_t value;
+      if (! integer_to_intmax (lisp, &value) || value < low || high < value)
+        args_out_of_range_3 (lisp, make_int (low), make_int (high));
+      return json_check (json_integer (value));
     }
   else if (FLOATP (lisp))
     return json_check (json_real (XFLOAT_DATA (lisp)));
@@ -736,7 +740,7 @@ json_to_lisp (json_t *json, struct json_configuration *conf)
           xsignal0 (Qjson_object_too_deep);
         size_t size = json_array_size (json);
         if (FIXNUM_OVERFLOW_P (size))
-          xsignal0 (Qoverflow_error);
+          overflow_error ();
         Lisp_Object result = Fmake_vector (make_fixed_natnum (size), Qunbound);
         for (ptrdiff_t i = 0; i < size; ++i)
           ASET (result, i,
@@ -755,7 +759,7 @@ json_to_lisp (json_t *json, struct json_configuration *conf)
             {
               size_t size = json_object_size (json);
               if (FIXNUM_OVERFLOW_P (size))
-                xsignal0 (Qoverflow_error);
+                overflow_error ();
               result = CALLN (Fmake_hash_table, QCtest, Qequal, QCsize,
                               make_fixed_natnum (size));
               struct Lisp_Hash_Table *h = XHASH_TABLE (result);
diff --git a/src/keyboard.c b/src/keyboard.c
index 008d3b9..1c1f151 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4377,8 +4377,8 @@ timer_check (void)
 
 DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
        doc: /* Return the current length of Emacs idleness, or nil.
-The value when Emacs is idle is a list of four integers (HIGH LOW USEC PSEC)
-in the same style as (current-time).
+The value when Emacs is idle is a Lisp timestamp in the style of
+`current-time'.
 
 The value when Emacs is not idle is nil.
 
diff --git a/src/keymap.c b/src/keymap.c
index 79dce15..3a79bf4 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -2216,10 +2216,12 @@ push_key_description (EMACS_INT ch, char *p)
 
 DEFUN ("single-key-description", Fsingle_key_description,
        Ssingle_key_description, 1, 2, 0,
-       doc: /* Return a pretty description of command character KEY.
+       doc: /* Return a pretty description of a character event KEY.
 Control characters turn into C-whatever, etc.
 Optional argument NO-ANGLES non-nil means don't put angle brackets
-around function keys and event symbols.  */)
+around function keys and event symbols.
+
+See `text-char-description' for describing character codes.  */)
   (Lisp_Object key, Lisp_Object no_angles)
 {
   USE_SAFE_ALLOCA;
@@ -2293,11 +2295,13 @@ push_text_char_description (register unsigned int c, 
register char *p)
 /* This function cannot GC.  */
 
 DEFUN ("text-char-description", Ftext_char_description, 
Stext_char_description, 1, 1, 0,
-       doc: /* Return a pretty description of file-character CHARACTER.
-Control characters turn into "^char", etc.  This differs from
-`single-key-description' which turns them into "C-char".
-Also, this function recognizes the 2**7 bit as the Meta character,
-whereas `single-key-description' uses the 2**27 bit for Meta.
+       doc: /* Return the description of CHARACTER in standard Emacs notation.
+CHARACTER must be a valid character code that passes the `characterp' test.
+Control characters turn into "^char", and characters with Meta and other
+modifiers signal an error, as they are not valid character codes.
+This differs from `single-key-description' which accepts character events,
+and thus doesn't enforce the `characterp' condition, turns control
+characters into "C-char", and uses the 2**27 bit for Meta.
 See Info node `(elisp)Describing Characters' for examples.  */)
   (Lisp_Object character)
 {
diff --git a/src/lisp.h b/src/lisp.h
index f2a3ac9..bb190b6 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3327,7 +3327,7 @@ extern ptrdiff_t bignum_bufsize (Lisp_Object, int);
 extern ptrdiff_t bignum_to_c_string (char *, ptrdiff_t, Lisp_Object, int);
 extern Lisp_Object bignum_to_string (Lisp_Object, int);
 extern Lisp_Object make_bignum_str (char const *, int);
-extern Lisp_Object double_to_bignum (double);
+extern Lisp_Object double_to_integer (double);
 
 /* Converthe integer NUM to *N.  Return true if successful, false
    (possibly setting *N) otherwise.  */
@@ -3751,7 +3751,6 @@ extern void display_malloc_warning (void);
 extern ptrdiff_t inhibit_garbage_collection (void);
 extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
 extern void free_cons (struct Lisp_Cons *);
-extern _Noreturn void range_error (void);
 extern void init_alloc_once (void);
 extern void init_alloc (void);
 extern void syms_of_alloc (void);
@@ -3888,6 +3887,7 @@ extern _Noreturn void xsignal2 (Lisp_Object, Lisp_Object, 
Lisp_Object);
 extern _Noreturn void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object,
                                Lisp_Object);
 extern _Noreturn void signal_error (const char *, Lisp_Object);
+extern _Noreturn void overflow_error (void);
 extern bool FUNCTIONP (Lisp_Object);
 extern Lisp_Object funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, 
Lisp_Object *arg_vector);
 extern Lisp_Object eval_sub (Lisp_Object form);
diff --git a/src/lread.c b/src/lread.c
index e43929a..73e38d8 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -741,10 +741,14 @@ read_filtered_event (bool no_switch_frame, bool 
ascii_required,
 }
 
 DEFUN ("read-char", Fread_char, Sread_char, 0, 3, 0,
-       doc: /* Read a character from the command input (keyboard or macro).
+       doc: /* Read a character event from the command input (keyboard or 
macro).
 It is returned as a number.
-If the character has modifiers, they are resolved and reflected to the
-character code if possible (e.g. C-SPC -> 0).
+If the event has modifiers, they are resolved and reflected in the
+returned character code if possible (e.g. C-SPC yields 0 and C-a yields 97).
+If some of the modifiers cannot be reflected in the character code, the
+returned value will include those modifiers, and will not be a valid
+character code: it will fail the `characterp' test.  Use `event-basic-type'
+to recover the character code with the modifiers removed.
 
 If the user generates an event which is not a character (i.e. a mouse
 click or function key event), `read-char' signals an error.  As an
@@ -791,10 +795,14 @@ floating-point value.  */)
 }
 
 DEFUN ("read-char-exclusive", Fread_char_exclusive, Sread_char_exclusive, 0, 
3, 0,
-       doc: /* Read a character from the command input (keyboard or macro).
+       doc: /* Read a character event from the command input (keyboard or 
macro).
 It is returned as a number.  Non-character events are ignored.
-If the character has modifiers, they are resolved and reflected to the
-character code if possible (e.g. C-SPC -> 0).
+If the event has modifiers, they are resolved and reflected in the
+returned character code if possible (e.g. C-SPC yields 0 and C-a yields 97).
+If some of the modifiers cannot be reflected in the character code, the
+returned value will include those modifiers, and will not be a valid
+character code: it will fail the `characterp' test.  Use `event-basic-type'
+to recover the character code with the modifiers removed.
 
 If the optional argument PROMPT is non-nil, display that as a prompt.
 If the optional argument INHERIT-INPUT-METHOD is non-nil and some
diff --git a/src/process.c b/src/process.c
index ebaaf33..a9638df 100644
--- a/src/process.c
+++ b/src/process.c
@@ -252,7 +252,7 @@ static EMACS_INT update_tick;
 # define HAVE_SEQPACKET
 #endif
 
-#define READ_OUTPUT_DELAY_INCREMENT (TIMESPEC_RESOLUTION / 100)
+#define READ_OUTPUT_DELAY_INCREMENT (TIMESPEC_HZ / 100)
 #define READ_OUTPUT_DELAY_MAX       (READ_OUTPUT_DELAY_INCREMENT * 5)
 #define READ_OUTPUT_DELAY_MAX_MAX   (READ_OUTPUT_DELAY_INCREMENT * 7)
 
@@ -3331,11 +3331,9 @@ static void
 connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
                         Lisp_Object use_external_socket_p)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
   int s = -1, outch, inch;
   int xerrno = 0;
   int family;
-  struct sockaddr *sa = NULL;
   int ret;
   ptrdiff_t addrlen UNINIT;
   struct Lisp_Process *p = XPROCESS (proc);
@@ -3354,6 +3352,11 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 
addrinfos,
   /* Do this in case we never enter the while-loop below.  */
   s = -1;
 
+  struct sockaddr *sa = NULL;
+  ptrdiff_t count = SPECPDL_INDEX ();
+  record_unwind_protect_nothing ();
+  ptrdiff_t count1 = SPECPDL_INDEX ();
+
   while (!NILP (addrinfos))
     {
       Lisp_Object addrinfo = XCAR (addrinfos);
@@ -3366,9 +3369,8 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 
addrinfos,
 #endif
 
       addrlen = get_lisp_to_sockaddr_size (ip_address, &family);
-      if (sa)
-       free (sa);
-      sa = xmalloc (addrlen);
+      sa = xrealloc (sa, addrlen);
+      set_unwind_protect_ptr (count, xfree, sa);
       conv_lisp_to_sockaddr (family, ip_address, sa, addrlen);
 
       s = socket_to_use;
@@ -3530,7 +3532,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 
addrinfos,
 #endif /* !WINDOWSNT */
 
       /* Discard the unwind protect closing S.  */
-      specpdl_ptr = specpdl + count;
+      specpdl_ptr = specpdl + count1;
       emacs_close (s);
       s = -1;
       if (0 <= socket_to_use)
@@ -3601,6 +3603,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 
addrinfos,
          Lisp_Object data = get_file_errno_data (err, contact, xerrno);
 
          pset_status (p, list2 (Fcar (data), Fcdr (data)));
+         unbind_to (count, Qnil);
          return;
        }
 
@@ -3620,7 +3623,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 
addrinfos,
   p->outfd = outch;
 
   /* Discard the unwind protect for closing S, if any.  */
-  specpdl_ptr = specpdl + count;
+  specpdl_ptr = specpdl + count1;
 
   if (p->is_server && p->socktype != SOCK_DGRAM)
     pset_status (p, Qlisten);
@@ -3681,6 +3684,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object 
addrinfos,
     }
 #endif
 
+  unbind_to (count, Qnil);
 }
 
 /* Create a network stream/datagram client/server process.  Treated
@@ -5474,7 +5478,7 @@ wait_reading_process_output (intmax_t time_limit, int 
nsecs, int read_kbd,
              have waited a long amount of time due to repeated
              timers.  */
          struct timespec huge_timespec
-           = make_timespec (TYPE_MAXIMUM (time_t), 2 * TIMESPEC_RESOLUTION);
+           = make_timespec (TYPE_MAXIMUM (time_t), 2 * TIMESPEC_HZ);
          struct timespec cmp_time = huge_timespec;
          if (wait < TIMEOUT
               || (wait_proc
@@ -7930,8 +7934,7 @@ integer or floating point values.
  majflt  -- number of major page faults (number)
  cminflt -- cumulative number of minor page faults (number)
  cmajflt -- cumulative number of major page faults (number)
- utime   -- user time used by the process, in (current-time) format,
-              which is a list of integers (HIGH LOW USEC PSEC)
+ utime   -- user time used by the process, in `current-time' format
  stime   -- system time used by the process (current-time)
  time    -- sum of utime and stime (current-time)
  cutime  -- user time used by the process and its children (current-time)
@@ -7943,7 +7946,7 @@ integer or floating point values.
  start   -- time the process started (current-time)
  vsize   -- virtual memory size of the process in KB's (number)
  rss     -- resident set size of the process in KB's (number)
- etime   -- elapsed time the process is running, in (HIGH LOW USEC PSEC) format
+ etime   -- elapsed time the process is running (current-time)
  pcpu    -- percents of CPU time used by the process (floating-point number)
  pmem    -- percents of total physical memory used by process's resident set
               (floating-point number)
diff --git a/src/sysdep.c b/src/sysdep.c
index 52afa2f..722d813 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -3078,16 +3078,15 @@ time_from_jiffies (unsigned long long tval, long hz)
 
   if (TYPE_MAXIMUM (time_t) < s)
     time_overflow ();
-  if (LONG_MAX - 1 <= ULLONG_MAX / TIMESPEC_RESOLUTION
-      || frac <= ULLONG_MAX / TIMESPEC_RESOLUTION)
-    ns = frac * TIMESPEC_RESOLUTION / hz;
+  if (LONG_MAX - 1 <= ULLONG_MAX / TIMESPEC_HZ
+      || frac <= ULLONG_MAX / TIMESPEC_HZ)
+    ns = frac * TIMESPEC_HZ / hz;
   else
     {
       /* This is reachable only in the unlikely case that HZ * HZ
         exceeds ULLONG_MAX.  It calculates an approximation that is
         guaranteed to be in range.  */
-      long hz_per_ns = (hz / TIMESPEC_RESOLUTION
-                       + (hz % TIMESPEC_RESOLUTION != 0));
+      long hz_per_ns = hz / TIMESPEC_HZ + (hz % TIMESPEC_HZ != 0);
       ns = frac / hz_per_ns;
     }
 
@@ -3112,27 +3111,26 @@ get_up_time (void)
 
   if (fup)
     {
-      unsigned long long upsec, upfrac, idlesec, idlefrac;
-      int upfrac_start, upfrac_end, idlefrac_start, idlefrac_end;
+      unsigned long long upsec, upfrac;
+      int upfrac_start, upfrac_end;
 
-      if (fscanf (fup, "%llu.%n%llu%n %llu.%n%llu%n",
-                 &upsec, &upfrac_start, &upfrac, &upfrac_end,
-                 &idlesec, &idlefrac_start, &idlefrac, &idlefrac_end)
-         == 4)
+      if (fscanf (fup, "%llu.%n%llu%n",
+                 &upsec, &upfrac_start, &upfrac, &upfrac_end)
+         == 2)
        {
          if (TYPE_MAXIMUM (time_t) < upsec)
            {
              upsec = TYPE_MAXIMUM (time_t);
-             upfrac = TIMESPEC_RESOLUTION - 1;
+             upfrac = TIMESPEC_HZ - 1;
            }
          else
            {
              int upfraclen = upfrac_end - upfrac_start;
-             for (; upfraclen < LOG10_TIMESPEC_RESOLUTION; upfraclen++)
+             for (; upfraclen < LOG10_TIMESPEC_HZ; upfraclen++)
                upfrac *= 10;
-             for (; LOG10_TIMESPEC_RESOLUTION < upfraclen; upfraclen--)
+             for (; LOG10_TIMESPEC_HZ < upfraclen; upfraclen--)
                upfrac /= 10;
-             upfrac = min (upfrac, TIMESPEC_RESOLUTION - 1);
+             upfrac = min (upfrac, TIMESPEC_HZ - 1);
            }
          up = make_timespec (upsec, upfrac);
        }
diff --git a/src/systime.h b/src/systime.h
index b2f8937..ad5ab85 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -23,12 +23,10 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 INLINE_HEADER_BEGIN
 
-#ifdef emacs
-# ifdef HAVE_X_WINDOWS
-#  include <X11/X.h>
-# else
+#ifdef HAVE_X_WINDOWS
+# include <X11/X.h>
+#else
 typedef unsigned long Time;
-# endif
 #endif
 
 /* On some configurations (hpux8.0, X11R4), sys/time.h and X11/Xos.h
@@ -58,23 +56,14 @@ invalid_timespec (void)
 }
 
 /* Return true if TIME is a valid timespec.  This currently doesn't worry
-   about whether tv_nsec is less than TIMESPEC_RESOLUTION; leap seconds
-   might cause a problem if it did.  */
+   about whether tv_nsec is less than TIMESPEC_HZ; leap seconds might
+   cause a problem if it did.  */
 INLINE bool
 timespec_valid_p (struct timespec t)
 {
   return t.tv_nsec >= 0;
 }
 
-/* Return current system time.  */
-INLINE struct timespec
-current_timespec (void)
-{
-  struct timespec r;
-  gettime (&r);
-  return r;
-}
-
 /* defined in sysdep.c */
 extern int set_file_times (int, const char *, struct timespec, struct 
timespec);
 extern struct timeval make_timeval (struct timespec) ATTRIBUTE_CONST;
@@ -82,10 +71,6 @@ extern struct timeval make_timeval (struct timespec) 
ATTRIBUTE_CONST;
 /* defined in keyboard.c */
 extern void set_waiting_for_input (struct timespec *);
 
-/* When lisp.h is not included Lisp_Object is not defined (this can
-   happen when this file is used outside the src directory).  */
-#ifdef emacs
-
 /* Emacs uses the integer list (HI LO US PS) to represent the time
    (HI << LO_TIME_BITS) + LO + US / 1e6 + PS / 1e12.  */
 enum { LO_TIME_BITS = 16 };
@@ -103,7 +88,6 @@ extern int decode_time_components (Lisp_Object, Lisp_Object, 
Lisp_Object,
                                   Lisp_Object, struct lisp_time *, double *);
 extern struct timespec lisp_to_timespec (struct lisp_time);
 extern struct timespec lisp_time_argument (Lisp_Object);
-#endif
 
 INLINE_HEADER_END
 
diff --git a/src/thread.h b/src/thread.h
index 28d8d86..464506d 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -30,7 +30,6 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #endif
 
 #include "sysselect.h"         /* FIXME */
-#include "systime.h"           /* FIXME */
 #include "systhread.h"
 
 struct thread_state
diff --git a/src/w32common.h b/src/w32common.h
index 4981bdf..e860dbc 100644
--- a/src/w32common.h
+++ b/src/w32common.h
@@ -55,6 +55,7 @@ typedef void (* VOIDFNPTR) (void);
 /* Load a function address from a DLL.  Cast the result via VOIDFNPTR
    to pacify -Wcast-function-type in GCC 8.1.  The return value must
    be cast to the correct function pointer type.  */
+INLINE VOIDFNPTR get_proc_addr (HINSTANCE, LPCSTR);
 INLINE VOIDFNPTR
 get_proc_addr (HINSTANCE handle, LPCSTR fname)
 {
diff --git a/src/xdisp.c b/src/xdisp.c
index 47286e2..93cd54a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10417,6 +10417,13 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool 
nlflag, bool multibyte)
          ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
          printmax_t dups;
 
+          /* Since we call del_range_both passing false for PREPARE,
+             we aren't prepared to run modification hooks (we could
+             end up calling modification hooks from another buffer and
+             only with AFTER=t, Bug#21824).  */
+          ptrdiff_t count = SPECPDL_INDEX ();
+          specbind (Qinhibit_modification_hooks, Qt);
+
          insert_1_both ("\n", 1, 1, true, false, false);
 
          scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, false);
@@ -10462,6 +10469,8 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool 
nlflag, bool multibyte)
                            -XFIXNAT (Vmessage_log_max) - 1, false);
              del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, false);
            }
+
+          unbind_to (count, Qnil);
        }
       BEGV = marker_position (oldbegv);
       BEGV_BYTE = marker_byte_position (oldbegv);
diff --git a/src/xfns.c b/src/xfns.c
index e19fcff..c4cf59d 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -5075,7 +5075,7 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
   int menu_bar_height = 0, menu_bar_width = 0;
   int tool_bar_height = 0, tool_bar_width = 0;
 
-  if (FRAME_INITIAL_P (f) || !FRAME_X_P (f))
+  if (FRAME_INITIAL_P (f) || !FRAME_X_P (f) || !FRAME_OUTER_WINDOW (f))
     return Qnil;
 
   block_input ();
diff --git a/test/Makefile.in b/test/Makefile.in
index a1f4388..adb316c 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -307,7 +307,7 @@ endif
 
 mostlyclean:
        address@hidden f in ${LOGFILES}; do test ! -f $$f || mv $$f $$f~; done
-       rm -f *.tmp
+       rm -f ./*.tmp
 
 clean:
        find . '(' -name '*.log' -o -name '*.log~' ')' $(FIND_DELETE)
diff --git a/test/lisp/autorevert-tests.el b/test/lisp/autorevert-tests.el
index b378c9b..9710600 100644
--- a/test/lisp/autorevert-tests.el
+++ b/test/lisp/autorevert-tests.el
@@ -181,7 +181,10 @@ This expects `auto-revert--messages' to be bound by
             ;; modifying `before-revert-hook'.
             (add-hook
              'before-revert-hook
-             (lambda () (delete-file buffer-file-name))
+             (lambda ()
+               ;; Temporarily.
+               (message "%s deleted" buffer-file-name)
+               (delete-file buffer-file-name))
              nil t)
 
             (ert-with-message-capture auto-revert--messages
diff --git a/test/lisp/calendar/icalendar-tests.el 
b/test/lisp/calendar/icalendar-tests.el
index 2fecabc..617e886 100644
--- a/test/lisp/calendar/icalendar-tests.el
+++ b/test/lisp/calendar/icalendar-tests.el
@@ -57,17 +57,16 @@
 
 (ert-deftest icalendar--create-uid ()
   "Test for `icalendar--create-uid'."
-  (let* ((icalendar-uid-format "xxx-%t-%c-%h-%u-%s")
+  (let* ((icalendar-uid-format "xxx-%c-%h-%u-%s")
          (icalendar--uid-count 77)
          (entry-full "30.06.1964 07:01 blahblah")
          (hash (format "%d" (abs (sxhash entry-full))))
          (contents "DTSTART:19640630T070100\nblahblah")
          (username (or user-login-name "UNKNOWN_USER")))
-    (cl-letf (((symbol-function 'current-time) (lambda () '(1 2 3))))
-      (should (= 77 icalendar--uid-count))
-      (should (string=  (concat "xxx-123-77-" hash "-" username "-19640630")
-                        (icalendar--create-uid entry-full contents)))
-      (should (= 78 icalendar--uid-count)))
+    (should (= 77 icalendar--uid-count))
+    (should (string= (concat "xxx-77-" hash "-" username "-19640630")
+                     (icalendar--create-uid entry-full contents)))
+    (should (= 78 icalendar--uid-count))
     (setq contents "blahblah")
     (setq icalendar-uid-format "yyy%syyy")
     (should (string=  (concat "yyyDTSTARTyyy")
diff --git a/test/lisp/calendar/parse-time-tests.el 
b/test/lisp/calendar/parse-time-tests.el
index 3a956a5..ca71ff7 100644
--- a/test/lisp/calendar/parse-time-tests.el
+++ b/test/lisp/calendar/parse-time-tests.el
@@ -28,35 +28,51 @@
 
 (ert-deftest parse-time-tests ()
   (should (equal (parse-time-string "Mon, 22 Feb 2016 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 1 nil 3600)))
+                 '(42 35 19 22 2 2016 1 -1 3600)))
   (should (equal (parse-time-string "22 Feb 2016 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 nil nil 3600)))
+                 '(42 35 19 22 2 2016 nil -1 3600)))
   (should (equal (parse-time-string "22 Feb 2016 +0100")
-                 '(nil nil nil 22 2 2016 nil nil 3600)))
+                 '(nil nil nil 22 2 2016 nil -1 3600)))
   (should (equal (parse-time-string "Mon, 22 Feb 16 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 1 nil 3600)))
+                 '(42 35 19 22 2 2016 1 -1 3600)))
   (should (equal (parse-time-string "Mon, 22 February 2016 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 1 nil 3600)))
+                 '(42 35 19 22 2 2016 1 -1 3600)))
   (should (equal (parse-time-string "Mon, 22 feb 2016 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 1 nil 3600)))
+                 '(42 35 19 22 2 2016 1 -1 3600)))
   (should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 1 nil 3600)))
-  (should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 PDT")
-                 '(42 35 19 22 2 2016 1 t -25200)))
-  (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54-0200")
-                 '(13818 33666)))
-  (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54-0230")
-                 '(13818 35466)))
-  (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54-02:00")
-                 '(13818 33666)))
-  (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54-02")
-                 '(13818 33666)))
-  (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54+0230")
-                 '(13818 17466)))
-  (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54+02")
-                 '(13818 19266)))
-  (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54Z")
-                 '(13818 26466)))
+                 '(42 35 19 22 2 2016 1 -1 3600)))
+  (should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 PST")
+                 '(42 35 19 22 2 2016 1 nil -28800)))
+  (should (equal (parse-time-string "Friday, 21 Sep 2018 13:47:58 PDT")
+                 '(58 47 13 21 9 2018 5 t -25200)))
+  (should (equal (format-time-string
+                 "%Y-%m-%d %H:%M:%S"
+                 (parse-iso8601-time-string "1998-09-12T12:21:54-0200") t)
+                "1998-09-12 14:21:54"))
+  (should (equal (format-time-string
+                 "%Y-%m-%d %H:%M:%S"
+                 (parse-iso8601-time-string "1998-09-12T12:21:54-0230") t)
+                "1998-09-12 14:51:54"))
+  (should (equal (format-time-string
+                 "%Y-%m-%d %H:%M:%S"
+                 (parse-iso8601-time-string "1998-09-12T12:21:54-02:00") t)
+                "1998-09-12 14:21:54"))
+  (should (equal (format-time-string
+                 "%Y-%m-%d %H:%M:%S"
+                 (parse-iso8601-time-string "1998-09-12T12:21:54-02") t)
+                "1998-09-12 14:21:54"))
+  (should (equal (format-time-string
+                 "%Y-%m-%d %H:%M:%S"
+                 (parse-iso8601-time-string "1998-09-12T12:21:54+0230") t)
+                "1998-09-12 09:51:54"))
+  (should (equal (format-time-string
+                 "%Y-%m-%d %H:%M:%S"
+                 (parse-iso8601-time-string "1998-09-12T12:21:54+02") t)
+                "1998-09-12 10:21:54"))
+  (should (equal (format-time-string
+                 "%Y-%m-%d %H:%M:%S"
+                 (parse-iso8601-time-string "1998-09-12T12:21:54Z") t)
+                "1998-09-12 12:21:54"))
   (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54")
                  (encode-time 54 21 12 12 9 1998))))
 
diff --git a/test/lisp/emacs-lisp/timer-tests.el 
b/test/lisp/emacs-lisp/timer-tests.el
index fa92c1b..c5971ee 100644
--- a/test/lisp/emacs-lisp/timer-tests.el
+++ b/test/lisp/emacs-lisp/timer-tests.el
@@ -40,8 +40,8 @@
       (should (debug-timer-check)) t))
 
 (ert-deftest timer-test-multiple-of-time ()
-  (should (equal
-           (timer-next-integral-multiple-of-time '(0 0 0 1) (1+ (ash 1 53)))
-           (list (ash 1 (- 53 16)) 1 0 0))))
+  (should (time-equal-p
+          (timer-next-integral-multiple-of-time '(0 0 0 1) (1+ (ash 1 53)))
+          (list (ash 1 (- 53 16)) 1))))
 
 ;;; timer-tests.el ends here
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index d72ca2c..1575d4f 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -2882,16 +2882,17 @@ This tests also `file-readable-p', `file-regular-p' and
            ;; able to return the date correctly.  They say "don't know".
            (dolist (elt attr)
              (unless
-                 (equal
+                 (tramp-compat-time-equal-p
                   (nth
                    5 (file-attributes (expand-file-name (car elt) tmp-name2)))
-                  '(0 0))
+                  tramp-time-dont-know)
                (should
                 (equal (file-attributes (expand-file-name (car elt) tmp-name2))
                        (cdr elt)))))
            (setq attr (directory-files-and-attributes tmp-name2 'full))
            (dolist (elt attr)
-             (unless (equal (nth 5 (file-attributes (car elt))) '(0 0))
+             (unless (tramp-compat-time-equal-p
+                      (nth 5 (file-attributes (car elt))) tramp-time-dont-know)
                (should
                 (equal (file-attributes (car elt)) (cdr elt)))))
            (setq attr (directory-files-and-attributes tmp-name2 nil "^b"))
@@ -3215,14 +3216,13 @@ This tests also `make-symbolic-link', `file-truename' 
and `add-name-to-file'."
            (write-region "foo" nil tmp-name1)
            (should (file-exists-p tmp-name1))
            (should (consp (nth 5 (file-attributes tmp-name1))))
-           ;; '(0 0) means don't know, and will be replaced by
-           ;; `current-time'.  Therefore, we use '(0 1).  We skip the
-           ;; test, if the remote handler is not able to set the
-           ;; correct time.
+           ;; Skip the test, if the remote handler is not able to set
+           ;; the correct time.
            (skip-unless (set-file-times tmp-name1 (seconds-to-time 1)))
            ;; Dumb remote shells without perl(1) or stat(1) are not
            ;; able to return the date correctly.  They say "don't know".
-           (unless (equal (nth 5 (file-attributes tmp-name1)) '(0 0))
+           (unless (tramp-compat-time-equal-p
+                    (nth 5 (file-attributes tmp-name1)) tramp-time-dont-know)
              (should
               (equal (nth 5 (file-attributes tmp-name1)) (seconds-to-time 1)))
              (write-region "bla" nil tmp-name2)
@@ -3250,9 +3250,17 @@ This tests also `make-symbolic-link', `file-truename' 
and `add-name-to-file'."
            (with-temp-buffer
              (insert-file-contents tmp-name)
              (should (verify-visited-file-modtime))
-             (set-visited-file-modtime '(0 1))
+              (set-visited-file-modtime (seconds-to-time 1))
              (should (verify-visited-file-modtime))
-             (should (equal (visited-file-modtime) '(0 1 0 0)))))
+             (should (= 1 (float-time (visited-file-modtime))))
+
+             ;; Checks with deleted file.
+             (delete-file tmp-name)
+             (dired-uncache tmp-name)
+             (should (verify-visited-file-modtime))
+              (set-visited-file-modtime (seconds-to-time 1))
+             (should (verify-visited-file-modtime))
+             (should (= 1 (float-time (visited-file-modtime))))))
 
        ;; Cleanup.
        (ignore-errors (delete-file tmp-name))))))
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index 86938d5..f218a76 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -61,6 +61,18 @@
                      (quote
                       (0 font-lock-keyword-face))))))))
 
+(ert-deftest provided-mode-derived-p ()
+  ;; base case: `derived-mode' directly derives `prog-mode'
+  (should (progn
+            (define-derived-mode derived-mode prog-mode "test")
+            (provided-mode-derived-p 'derived-mode 'prog-mode)))
+  ;; edge case: `derived-mode' derives an alias of `prog-mode'
+  (should (progn
+            (defalias 'parent-mode
+              (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
+            (define-derived-mode derived-mode parent-mode "test")
+            (provided-mode-derived-p 'derived-mode 'prog-mode))))
+
 (ert-deftest number-sequence-test ()
   (should (= (length
               (number-sequence (1- most-positive-fixnum) most-positive-fixnum))
diff --git a/test/lisp/thingatpt-tests.el b/test/lisp/thingatpt-tests.el
index b4a5fd9..aa29924 100644
--- a/test/lisp/thingatpt-tests.el
+++ b/test/lisp/thingatpt-tests.el
@@ -87,41 +87,43 @@ position to retrieve THING.")
       (goto-char (nth 1 test))
       (should (equal (thing-at-point (nth 2 test)) (nth 3 test))))))
 
-;; These tests reflect the actual behavior of
-;; `thing-at-point-bounds-of-list-at-point'.
-(ert-deftest thing-at-point-bug24627 ()
-  "Test for https://debbugs.gnu.org/24627 ."
-  (let ((string-result '(("(a \"b\" c)" . (a "b" c))
-                         (";(a \"b\" c)")
-                         ("(a \"b\" c\n)" . (a "b" c))
-                         ("\"(a b c)\"")
-                         ("(a ;(b c d)\ne)" . (a e))
-                         ("(foo\n(a ;(b c d)\ne) bar)" . (a e))
-                         ("(foo\na ;(b c d)\ne bar)" . (foo a e bar))
-                         ("(foo\n(a \"(b c d)\"\ne) bar)" . (a "(b c d)" e))
-                         ("(b\n(a ;(foo c d)\ne) bar)" . (a e))
-                         ("(princ \"(a b c)\")" . (princ "(a b c)"))
-                         ("(defun foo ()\n  \"Test function.\"\n  ;;(a b)\n  
nil)" . (defun foo nil "Test function." nil))))
-        (file
-         (expand-file-name "lisp/thingatpt.el" source-directory))
-        buf)
-    ;; Test for `thing-at-point'.
-    (when (file-exists-p file)
-      (unwind-protect
-          (progn
-            (setq buf (find-file file))
-            (goto-char (point-max))
-            (forward-line -1)
-            (should-not (thing-at-point 'list)))
-        (kill-buffer buf)))
-    ;; Tests for `list-at-point'.
-    (dolist (str-res string-result)
-      (with-temp-buffer
-        (emacs-lisp-mode)
-        (insert (car str-res))
-        (re-search-backward "\\((a\\|^a\\)")
-        (should (equal (list-at-point)
-                       (cdr str-res)))))))
+;; See bug#24627 and bug#31772.
+(ert-deftest thing-at-point-bounds-of-list-at-point ()
+  (cl-macrolet ((with-test-buffer (str &rest body)
+                  `(with-temp-buffer
+                     (emacs-lisp-mode)
+                     (insert ,str)
+                     (search-backward "|")
+                     (delete-char 1)
+                     ,@body)))
+    (let ((tests1
+           '(("|(a \"b\" c)" (a "b" c))
+             (";|(a \"b\" c)" (a "b" c) nil)
+             ("|(a \"b\" c\n)" (a "b" c))
+             ("\"|(a b c)\"" (a b c) nil)
+             ("|(a ;(b c d)\ne)" (a e))
+             ("(foo\n|(a ;(b c d)\ne) bar)" (foo (a e) bar))
+             ("(foo\n|a ;(b c d)\ne bar)" (foo a e bar))
+             ("(foo\n|(a \"(b c d)\"\ne) bar)" (foo (a "(b c d)" e) bar))
+             ("(b\n|(a ;(foo c d)\ne) bar)" (b (a e) bar))
+             ("(princ \"|(a b c)\")" (a b c) (princ "(a b c)"))
+             ("(defun foo ()\n  \"Test function.\"\n  ;;|(a b)\n  nil)"
+              (defun foo nil "Test function." nil)
+              (defun foo nil "Test function." nil))))
+          (tests2
+           '(("|list-at-point" . "list-at-point")
+             ("list-|at-point" . "list-at-point")
+             ("list-at-point|" . nil)
+             ("|(a b c)" . "(a b c)")
+             ("(a b c)|" . nil))))
+      (dolist (test tests1)
+        (with-test-buffer (car test)
+          (should (equal (list-at-point) (cl-second test)))
+          (when (cddr test)
+            (should (equal (list-at-point t) (cl-third test))))))
+      (dolist (test tests2)
+        (with-test-buffer (car test)
+          (should (equal (thing-at-point 'list) (cdr test))))))))
 
 (ert-deftest thing-at-point-url-in-comment ()
   (with-temp-buffer
diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el
index d115e66..0e4fd36 100644
--- a/test/src/buffer-tests.el
+++ b/test/src/buffer-tests.el
@@ -45,6 +45,25 @@ with parameters from the *Messages* buffer modification."
             (should (eq buf (current-buffer))))
         (when msg-ov (delete-overlay msg-ov))))))
 
+(ert-deftest overlay-modification-hooks-deleted-overlay ()
+  "Test for bug#30823."
+  (let ((check-point nil)
+       (ov-delete nil)
+       (ov-set nil))
+    (with-temp-buffer
+      (insert "abc")
+      (setq ov-set (make-overlay 1 3))
+      (overlay-put ov-set 'modification-hooks
+                  (list (lambda (_o after &rest _args)
+                          (and after (setq check-point t)))))
+      (setq ov-delete (make-overlay 1 3))
+      (overlay-put ov-delete 'modification-hooks
+                  (list (lambda (o after &rest _args)
+                          (and (not after) (delete-overlay o)))))
+      (goto-char 2)
+      (insert "1")
+      (should (eq check-point t)))))
+
 (ert-deftest test-generate-new-buffer-name-bug27966 ()
   (should-not (string-equal "nil"
                             (progn (get-buffer-create "nil")
diff --git a/test/src/data-tests.el b/test/src/data-tests.el
index 701e579..3cd4802 100644
--- a/test/src/data-tests.el
+++ b/test/src/data-tests.el
@@ -547,6 +547,16 @@ comparing the subr with a much slower lisp implementation."
     (should (<= b-1 b0))
     (should (<= b-1 b-1))
 
+    (should (= (+ f0 b0) (+ b0 f0)))
+    (should (= (+ f0 b-1) (+ b-1 f0)))
+    (should (= (+ f-1 b0) (+ b0 f-1)))
+    (should (= (+ f-1 b-1) (+ b-1 f-1)))
+
+    (should (= (* f0 b0) (* b0 f0)))
+    (should (= (* f0 b-1) (* b-1 f0)))
+    (should (= (* f-1 b0) (* b0 f-1)))
+    (should (= (* f-1 b-1) (* b-1 f-1)))
+
     (should (= b0 f0))
     (should (= b0 b0))
 
diff --git a/test/src/floatfns-tests.el b/test/src/floatfns-tests.el
index 9a38205..61b1c25 100644
--- a/test/src/floatfns-tests.el
+++ b/test/src/floatfns-tests.el
@@ -35,6 +35,12 @@
   (should-error (fround 0) :type 'wrong-type-argument))
 
 (ert-deftest bignum-to-float ()
+  ;; 122 because we want to go as big as possible to provoke a rounding error,
+  ;; but not too big: 2**122 < 10**37 < 2**123, and the C standard says
+  ;; 10**37 <= DBL_MAX so 2**122 cannot overflow as a double.
+  (let ((a (1- (ash 1 122))))
+    (should (or (eql a (1- (floor (float a))))
+                (eql a (floor (float a))))))
   (should (eql (float (+ most-positive-fixnum 1))
                (+ (float most-positive-fixnum) 1))))
 
@@ -94,4 +100,23 @@
                       (or (/= cdelta fdelta)
                           (zerop (% (round n d) 2)))))))))))
 
+(ert-deftest special-round ()
+  (let ((ns '(-1e+INF 1e+INF -1 1 -1e+NaN 1e+NaN)))
+    (dolist (n ns)
+      (unless (<= (abs n) 1)
+        (should-error (ceiling n))
+        (should-error (floor n))
+        (should-error (round n))
+        (should-error (truncate n)))
+      (dolist (d ns)
+        (unless (<= (abs (/ n d)) 1)
+          (should-error (ceiling n d))
+          (should-error (floor n d))
+          (should-error (round n d))
+          (should-error (truncate n d)))))))
+
+(ert-deftest big-round ()
+  (should (= (floor 54043195528445955 3)
+             (floor 54043195528445955 3.0))))
+
 (provide 'floatfns-tests)
diff --git a/test/src/json-tests.el b/test/src/json-tests.el
index 8bd679b..911bc49 100644
--- a/test/src/json-tests.el
+++ b/test/src/json-tests.el
@@ -278,5 +278,13 @@ Test with both unibyte and multibyte strings."
        :type 'no-catch)
       (should (equal calls 1)))))
 
+(ert-deftest json-serialize/bignum ()
+  (skip-unless (fboundp 'json-serialize))
+  (should (equal (json-serialize (vector (1+ most-positive-fixnum)
+                                         (1- most-negative-fixnum)))
+                 (format "[%d,%d]"
+                         (1+ most-positive-fixnum)
+                         (1- most-negative-fixnum)))))
+
 (provide 'json-tests)
 ;;; json-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]