emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master df1a712 6/7: Merge branch 'master' of git.sv.gnu.or


From: Michael Mauger
Subject: [Emacs-diffs] master df1a712 6/7: Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Date: Sun, 6 Aug 2017 20:59:21 -0400 (EDT)

branch: master
commit df1a71272e5cdd10b511e2ffd702ca50ddd8a773
Merge: eb27fc4 32daa3c
Author: Michael R. Mauger <address@hidden>
Commit: Michael R. Mauger <address@hidden>

    Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
---
 .gitignore                                         |    2 +-
 .gitlab-ci.yml                                     |    2 +-
 CONTRIBUTE                                         |  170 ++--
 admin/merge-gnulib                                 |    6 +-
 admin/notes/hydra                                  |   25 +-
 admin/notes/unicode                                |    3 +-
 admin/unidata/BidiBrackets.txt                     |    8 +-
 admin/unidata/BidiMirroring.txt                    |   24 +-
 admin/unidata/Blocks.txt                           |   17 +-
 admin/unidata/IVD_Sequences.txt                    |   34 +-
 admin/unidata/NormalizationTest.txt                |   30 +-
 admin/unidata/README                               |   18 +-
 admin/unidata/SpecialCasing.txt                    |    8 +-
 admin/unidata/UnicodeData.txt                      | 1028 +++++++++++++++++++-
 build-aux/config.guess                             |    6 +-
 configure.ac                                       |  109 ++-
 doc/emacs/basic.texi                               |    3 +-
 doc/emacs/custom.texi                              |    2 +-
 doc/emacs/dired.texi                               |    2 +-
 doc/emacs/display.texi                             |   62 +-
 doc/emacs/fixit.texi                               |    1 +
 doc/emacs/frames.texi                              |    3 +-
 doc/emacs/maintaining.texi                         |    1 +
 doc/emacs/modes.texi                               |    8 +-
 doc/emacs/mule.texi                                |   40 +-
 doc/emacs/search.texi                              |   15 +-
 doc/emacs/xresources.texi                          |    5 +
 doc/lispref/display.texi                           |   57 ++
 doc/lispref/elisp.texi                             |    1 +
 doc/lispref/lists.texi                             |   42 +-
 doc/lispref/text.texi                              |  201 ++++
 doc/misc/ses.texi                                  |   29 +-
 doc/misc/texinfo.tex                               |   14 +-
 doc/misc/tramp.texi                                |  263 +++--
 doc/misc/trampver.texi                             |    2 +-
 etc/NEWS                                           |  154 ++-
 etc/NEWS.21                                        |    2 +-
 etc/themes/leuven-theme.el                         |   11 +-
 etc/themes/manoj-dark-theme.el                     |   22 +-
 etc/themes/tango-dark-theme.el                     |   10 +
 etc/themes/tango-theme.el                          |   10 +
 etc/themes/tsdh-dark-theme.el                      |   20 +-
 etc/themes/tsdh-light-theme.el                     |    9 +
 etc/themes/wheatgrass-theme.el                     |    4 +-
 etc/themes/whiteboard-theme.el                     |   10 +
 lib-src/etags.c                                    |   29 +-
 lib-src/make-docfile.c                             |    4 +-
 lib/explicit_bzero.c                               |   48 +
 lib/fpending.c                                     |    4 +-
 lib/getdtablesize.c                                |    2 +-
 lib/gnulib.mk.in                                   |   39 +-
 lib/{strftime.c => nstrftime.c}                    |    0
 lib/stdio-impl.h                                   |    2 +
 lib/string.in.h                                    |   17 +
 lib/xalloc-oversized.h                             |    2 +-
 lisp/calendar/todo-mode.el                         |  291 +++---
 lisp/cus-start.el                                  |   32 +
 lisp/dired-aux.el                                  |    8 +-
 lisp/dired-x.el                                    |    8 +-
 lisp/dired.el                                      |   13 +-
 lisp/display-line-numbers.el                       |  106 ++
 lisp/electric.el                                   |   94 +-
 lisp/emacs-lisp/bytecomp.el                        |   43 +-
 lisp/emacs-lisp/cl-generic.el                      |   16 +-
 lisp/emacs-lisp/cl-lib.el                          |   10 +-
 lisp/emacs-lisp/edebug.el                          |    2 +-
 lisp/emacs-lisp/eldoc.el                           |   49 +-
 lisp/emacs-lisp/ert.el                             |   15 +-
 lisp/emacs-lisp/gv.el                              |    6 +-
 lisp/emacs-lisp/map.el                             |   19 +-
 lisp/emacs-lisp/nadvice.el                         |   12 +
 lisp/emacs-lisp/pcase.el                           |    1 -
 lisp/emacs-lisp/rx.el                              |   56 ++
 lisp/eshell/em-prompt.el                           |   15 +-
 lisp/faces.el                                      |   34 +-
 lisp/files.el                                      |    7 +-
 lisp/frame.el                                      |   15 +-
 lisp/gnus/gnus-sum.el                              |    7 +-
 lisp/help-fns.el                                   |    1 -
 lisp/help.el                                       |    3 +
 lisp/international/characters.el                   |   22 +-
 lisp/international/fontset.el                      |    4 +
 lisp/international/mule-cmds.el                    |    6 +-
 lisp/kmacro.el                                     |   11 +-
 lisp/leim/quail/latin-alt.el                       |   16 +-
 lisp/loadhist.el                                   |   95 +-
 lisp/ls-lisp.el                                    |    6 +-
 lisp/mail/rmail.el                                 |    2 -
 lisp/menu-bar.el                                   |   64 +-
 lisp/net/shr.el                                    |    3 +-
 lisp/net/tramp-cache.el                            |   12 +-
 lisp/net/tramp-sh.el                               |    7 +-
 lisp/net/tramp.el                                  |   12 +
 lisp/net/trampver.el                               |    6 +-
 lisp/progmodes/cc-cmds.el                          |   27 +-
 lisp/progmodes/cc-defs.el                          |   12 +
 lisp/progmodes/cc-engine.el                        |   21 +-
 lisp/progmodes/cc-mode.el                          |   66 +-
 lisp/progmodes/cperl-mode.el                       |    4 +-
 lisp/progmodes/executable.el                       |   36 +-
 lisp/progmodes/grep.el                             |  104 +-
 lisp/progmodes/ld-script.el                        |    9 +-
 lisp/progmodes/perl-mode.el                        |   43 +-
 lisp/progmodes/xref.el                             |   33 +-
 lisp/ses.el                                        |  232 ++++-
 lisp/simple.el                                     |   21 +-
 lisp/startup.el                                    |    1 +
 lisp/subr.el                                       |   12 +-
 lisp/vc/vc-src.el                                  |    2 +-
 lisp/wid-edit.el                                   |   20 +-
 lisp/window.el                                     |    6 +-
 m4/dirfd.m4                                        |    9 +-
 m4/explicit_bzero.m4                               |   22 +
 m4/getdtablesize.m4                                |   54 +-
 m4/gettimeofday.m4                                 |    4 +-
 m4/gnulib-comp.m4                                  |   17 +-
 m4/lstat.m4                                        |    6 +-
 m4/mktime.m4                                       |   10 +-
 m4/{strftime.m4 => nstrftime.m4}                   |    0
 m4/pselect.m4                                      |    5 +-
 m4/putenv.m4                                       |    4 +-
 m4/stdint.m4                                       |  108 +-
 m4/string_h.m4                                     |    2 +
 m4/strtoimax.m4                                    |   12 +-
 m4/utimes.m4                                       |   22 +-
 nextstep/INSTALL                                   |   16 +-
 src/alloc.c                                        |    6 +-
 src/bidi.c                                         |   29 +-
 src/buffer.c                                       |   88 +-
 src/buffer.h                                       |    6 +
 src/charset.c                                      |   90 +-
 src/coding.c                                       |    6 +-
 src/dbusbind.c                                     |    6 +-
 src/dispextern.h                                   |   22 +-
 src/emacs-module.c                                 |   22 +-
 src/eval.c                                         |    9 +-
 src/fns.c                                          |  160 ++-
 src/font.c                                         |    2 +-
 src/fontset.c                                      |    2 +-
 src/ftcrfont.c                                     |    6 +-
 src/gfilenotify.c                                  |    2 +-
 src/gnutls.c                                       |  811 ++++++++++++++-
 src/gnutls.h                                       |    5 +
 src/gtkutil.c                                      |   63 +-
 src/gtkutil.h                                      |    5 +-
 src/image.c                                        |   99 +-
 src/indent.c                                       |   70 +-
 src/intervals.c                                    |   66 +-
 src/intervals.h                                    |    3 +-
 src/keyboard.c                                     |    2 +
 src/keymap.c                                       |    2 +-
 src/lisp.h                                         |    7 +-
 src/lread.c                                        |  239 +++--
 src/nsfns.m                                        |   20 +
 src/nsterm.m                                       |   31 +
 src/print.c                                        |    8 +-
 src/process.c                                      |    2 +-
 src/sysdep.c                                       |    2 +-
 src/term.c                                         |    8 +-
 src/thread.c                                       |   10 +-
 src/thread.h                                       |   10 +-
 src/w32fns.c                                       |    2 +-
 src/w32font.c                                      |    2 +-
 src/w32notify.c                                    |    4 +-
 src/w32proc.c                                      |   63 +-
 src/w32term.c                                      |    2 +-
 src/xdisp.c                                        |  620 +++++++++++-
 src/xfns.c                                         |    4 +-
 src/xfont.c                                        |    3 +-
 src/xmenu.c                                        |    5 +
 test/Makefile.in                                   |    3 +-
 test/data/emacs-module/mod-test.c                  |   23 +
 test/lisp/dired-tests.el                           |  105 +-
 test/lisp/electric-tests.el                        |    4 +
 .../eieio-tests/eieio-test-methodinvoke.el         |    2 +-
 test/lisp/emacs-lisp/eieio-tests/eieio-tests.el    |    2 +-
 test/lisp/emacs-lisp/map-tests.el                  |   12 +
 test/lisp/emacs-lisp/rx-tests.el                   |   10 +
 test/lisp/filenotify-tests.el                      |    4 +-
 test/lisp/ibuffer-tests.el                         |   34 +-
 test/lisp/international/ucs-normalize-tests.el     |  247 +++--
 test/lisp/net/gnutls-tests.el                      |  295 ++++++
 test/lisp/net/network-stream-tests.el              |    7 +-
 test/lisp/net/tramp-tests.el                       |   82 +-
 test/lisp/ses-tests.el                             |  175 ++++
 test/lisp/subr-tests.el                            |    6 +-
 test/manual/BidiCharacterTest.txt                  |    6 +-
 test/manual/etags/CTAGS.good                       |    8 +
 test/manual/etags/ETAGS.good_1                     |   26 +-
 test/manual/etags/ETAGS.good_2                     |   26 +-
 test/manual/etags/ETAGS.good_3                     |   26 +-
 test/manual/etags/ETAGS.good_4                     |   26 +-
 test/manual/etags/ETAGS.good_5                     |   26 +-
 test/manual/etags/ETAGS.good_6                     |   26 +-
 test/manual/etags/Makefile                         |    3 +-
 test/manual/etags/el-src/TAGTEST.EL                |    1 +
 test/manual/etags/scm-src/test.scm                 |   20 +
 test/manual/image-size-tests.el                    |   10 +-
 test/manual/indent/perl.perl                       |    8 +
 test/src/emacs-module-tests.el                     |   87 +-
 test/src/fns-tests.el                              |    6 +
 test/src/lread-tests.el                            |   23 +
 202 files changed, 6978 insertions(+), 1694 deletions(-)

diff --git a/.gitignore b/.gitignore
index 46ed4a1..9229297 100644
--- a/.gitignore
+++ b/.gitignore
@@ -111,7 +111,6 @@ lisp/mh-e/mh-autoloads.el
 lisp/subdirs.el
 
 # Dependencies.
-.deps/
 deps/
 
 # Logs and temporaries.
@@ -138,6 +137,7 @@ gmon.out
 oo/
 oo-spd/
 src/*.map
+vgcore.*[0-9]
 
 # Tests.
 test/manual/biditest.txt
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9b25ead..5fcd54f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -28,7 +28,7 @@ image: debian:unstable
 
 before_script:
   - apt update -qq
-  - apt install -y -qq build-essential autoconf automake libncurses-dev 
gnutls-dev
+  - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y -qq 
-o=Dpkg::Use-Pty=0 libc-dev gcc make autoconf automake libncurses-dev gnutls-dev
 
 stages:
   - test
diff --git a/CONTRIBUTE b/CONTRIBUTE
index 3ed587c..365e423 100644
--- a/CONTRIBUTE
+++ b/CONTRIBUTE
@@ -26,6 +26,7 @@ admin/notes/git-workflow.
 
 ** Getting involved with development
 
+Discussion about Emacs development takes place on address@hidden
 You can subscribe to the address@hidden mailing list, paying
 attention to postings with subject lines containing "emacs-announce",
 as these discuss important events like feature freezes.  See
@@ -35,11 +36,85 @@ own copy of the repository, and discuss proposed changes on 
the
 mailing list.  Frequent contributors to Emacs can request write access
 there.
 
-** Committing changes by others
+Bug reports and fixes, feature requests and patches/implementations
+should be sent to address@hidden, the bug/feature list.  This
+is coupled to the http://debbugs.gnu.org tracker.  It is best to use
+the command 'M-x report-emacs-bug RET' to report issues to the tracker
+(described below).  Be prepared to receive comments and requests for
+changes in your patches, following your submission.
 
-If committing changes written by someone else, commit in their name,
-not yours.  You can use 'git commit --author="AUTHOR"' to specify a
-change's author.
+The Savannah info page http://savannah.gnu.org/mail/?group=emacs
+describes how to subscribe to the mailing lists, or see the list
+archives.
+
+To email a patch you can use a shell command like 'git format-patch -1'
+to create a file, and then attach the file to your email.  This nicely
+packages the patch's commit message and changes.  To send just one
+such patch without additional remarks, you can use a command like
+'git send-email address@hidden 0001-DESCRIPTION.patch'.
+
+** Issue tracker (a.k.a. "bug tracker")
+
+The Emacs issue tracker at http://debbugs.gnu.org lets you view bug
+reports and search the database for bugs matching several criteria.
+Messages posted to the address@hidden mailing list, mentioned
+above, are recorded by the tracker with the corresponding bugs/issues.
+
+GNU ELPA has a 'debbugs' package that allows accessing the tracker
+database from Emacs.
+
+Bugs needs regular attention.  A large backlog of bugs is
+disheartening to the developers, and a culture of ignoring bugs is
+harmful to users, who expect software that works.  Bugs have to be
+regularly looked at and acted upon.  Not all bugs are critical, but at
+the least, each bug needs to be regularly re-reviewed to make sure it
+is still reproducible.
+
+The process of going through old or new bugs and acting on them is
+called bug triage.  This process is described in the file
+admin/notes/bug-triage.
+
+** Documenting your changes
+
+Any change that matters to end-users should have an entry in etc/NEWS.
+
+Doc-strings should be updated together with the code.
+
+Think about whether your change requires updating the manuals.  If you
+know it does not, mark the NEWS entry with "---".  If you know
+that *all* the necessary documentation updates have been made, mark
+the entry with "+++".  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
+http://www.gnu.org/software/texinfo/manual/texinfo/html_node/Predefined-Indices.html
+or run the shell command 'info "(texinfo)Predefined Indices"'.
+
+For more specific tips on Emacs's doc style, see
+http://www.gnu.org/software/emacs/manual/html_node/elisp/Documentation-Tips.html
+Use 'checkdoc' to check for documentation errors before submitting a patch.
+
+** Testing your changes
+
+Please test your changes before committing them or sending them to the
+list.  If possible, add a new test along with any bug fix or new
+functionality you commit (of course, some changes cannot be easily
+tested).
+
+Emacs uses ERT, Emacs Lisp Regression Testing, for testing.  See
+http://www.gnu.org/software/emacs/manual/html_node/ert/
+or run 'info "(ert)"' for for more information on writing and running
+tests.
+
+If your test lasts longer than some few seconds, mark it in its
+'ert-deftest' definition with ":tags '(:expensive-test)".
+
+To run tests on the entire Emacs tree, run "make check" from the
+top-level directory.  Most tests are in the directory "test/".  From
+the "test/" directory, run "make <filename>" to run the tests for
+<filename>.el(c).  See "test/README" for more information.
 
 ** Commit messages
 
@@ -176,6 +251,12 @@ them right the first time, so here are guidelines for 
formatting them:
   with Emacs commands like 'C-x 4 a', and commit the change using the
   shell command 'vc-dwim --commit'.  Type 'vc-dwim --help' for more.
 
+** Committing changes by others
+
+If committing changes written by someone else, commit in their name,
+not yours.  You can use 'git commit --author="AUTHOR"' to specify a
+change's author.
+
 ** Branches
 
 Future development normally takes place on the master branch.
@@ -218,87 +299,6 @@ This repository does not contain the Emacs Lisp package 
archive
 (elpa.gnu.org).  See admin/notes/elpa for how to access the GNU ELPA
 repository.
 
-** Emacs Mailing lists.
-
-Discussion about Emacs development takes place on address@hidden
-
-Bug reports and fixes, feature requests and implementations should be
-sent to address@hidden, the bug/feature list.  This is coupled
-to the http://debbugs.gnu.org tracker.
-
-The Savannah info page http://savannah.gnu.org/mail/?group=emacs
-describes how to subscribe to the mailing lists, or see the list
-archives.
-
-To email a patch you can use a shell command like 'git format-patch -1'
-to create a file, and then attach the file to your email.  This nicely
-packages the patch's commit message and changes.  To send just one
-such patch without additional remarks, you can use a command like
-'git send-email address@hidden 0001-DESCRIPTION.patch'.
-
-** Issue tracker (a.k.a. "bug tracker")
-
-The Emacs issue tracker at http://debbugs.gnu.org lets you view bug
-reports and search the database for bugs matching several criteria.
-Messages posted to the address@hidden mailing list, mentioned
-above, are recorded by the tracker with the corresponding bugs/issues.
-
-GNU ELPA has a 'debbugs' package that allows accessing the tracker
-database from Emacs.
-
-Bugs needs regular attention.  A large backlog of bugs is
-disheartening to the developers, and a culture of ignoring bugs is
-harmful to users, who expect software that works.  Bugs have to be
-regularly looked at and acted upon.  Not all bugs are critical, but at
-the least, each bug needs to be regularly re-reviewed to make sure it
-is still reproducible.
-
-The process of going through old or new bugs and acting on them is
-called bug triage.  This process is described in the file
-admin/notes/bug-triage.
-
-** Documenting your changes
-
-Any change that matters to end-users should have an entry in etc/NEWS.
-
-Doc-strings should be updated together with the code.
-
-Think about whether your change requires updating the manuals.  If you
-know it does not, mark the NEWS entry with "---".  If you know
-that *all* the necessary documentation updates have been made, mark
-the entry with "+++".  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
-http://www.gnu.org/software/texinfo/manual/texinfo/html_node/Predefined-Indices.html
-or run the shell command 'info "(texinfo)Predefined Indices"'.
-
-For more specific tips on Emacs's doc style, see
-http://www.gnu.org/software/emacs/manual/html_node/elisp/Documentation-Tips.html
-Use 'checkdoc' to check for documentation errors before submitting a patch.
-
-** Testing your changes
-
-Please test your changes before committing them or sending them to the
-list.  If possible, add a new test along with any bug fix or new
-functionality you commit (of course, some changes cannot be easily
-tested).
-
-Emacs uses ERT, Emacs Lisp Regression Testing, for testing.  See
-http://www.gnu.org/software/emacs/manual/html_node/ert/
-or run 'info "(ert)"' for for more information on writing and running
-tests.
-
-If your test lasts longer than some few seconds, mark it in its
-'ert-deftest' definition with ":tags '(:expensive-test)".
-
-To run tests on the entire Emacs tree, run "make check" from the
-top-level directory.  Most tests are in the directory "test/".  From
-the "test/" directory, run "make <filename>" to run the tests for
-<filename>.el(c).  See "test/README" for more information.
-
 ** Understanding Emacs internals
 
 The best way to understand Emacs internals is to read the code.  Some
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 85921ba..18c9ee8 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -30,15 +30,15 @@ GNULIB_MODULES='
   careadlinkat close-stream
   count-leading-zeros count-one-bits count-trailing-zeros
   crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512
-  diffseq dtoastr dtotimespec dup2 environ execinfo faccessat
+  diffseq dtoastr dtotimespec dup2 environ execinfo explicit_bzero faccessat
   fcntl fcntl-h fdatasync fdopendir
   filemode filevercmp flexmember fstatat fsync
   getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog
   ignore-value intprops largefile lstat
-  manywarnings memrchr minmax mkostemp mktime
+  manywarnings memrchr minmax mkostemp mktime nstrftime
   pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat
   sig2str socklen stat-time std-gnu11 stdalign stddef stdio
-  stpcpy strftime strtoimax symlink sys_stat
+  stpcpy strtoimax symlink sys_stat
   sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub
   update-copyright unlocked-io utimens
   vla warnings
diff --git a/admin/notes/hydra b/admin/notes/hydra
index d595935..4c1944a 100644
--- a/admin/notes/hydra
+++ b/admin/notes/hydra
@@ -6,13 +6,12 @@ See the end of the file for license conditions.
 NOTES FOR EMACS CONTINUOUS BUILD ON HYDRA
 
 A continuous build for Emacs can be found at
-http://hydra.nixos.org/jobset/gnu/emacs-trunk
-http://hydra.nixos.org/jobset/gnu/emacs-24
+https://hydra.nixos.org/jobset/gnu/emacs-trunk
 
 * It builds Emacs on various platforms.
 Sometimes jobs fail due to hydra problems rather than Emacs problems.
-Eg it seems like the cygwin build will never work again.
-http://lists.gnu.org/archive/html/hydra-users/2013-08/msg00000.html
+Eg it seems like the darwin build will never work again.
+https://lists.gnu.org/archive/html/hydra-users/2016-01/msg00000.html
 
 * Mail notifications
 In addition to the web interface, Hydra can send notifications by
@@ -21,7 +20,7 @@ SUCCEEDED to FAILED.  It sends notifications about build 
status in
 Emacs trunk to address@hidden
 
 If you want to receive these notifications, please subscribe at
-http://lists.gnu.org/mailman/listinfo/emacs-buildstatus
+https://lists.gnu.org/mailman/listinfo/emacs-buildstatus
 
 * The Emacs jobset consists of the following jobs:
 
@@ -31,23 +30,29 @@ by running make-dist to create a tarball.  If this job 
fails, all the
 others will too (because they use the tarball as input).
 
 ** The 'build' job
-which starts from the tarball and does a normal build
+which starts from the tarball and does a normal build.
 
 ** The 'coverage' job
-does a gcov build and then runs 'make check'.  Fails if any test fails.
+does a gcov build and then runs 'make check-expensive'.  Fails if any
+test fails.
 
 * Nix expressions
 The recipe for GNU Emacs are available via Git:
-http://git.savannah.gnu.org/cgit/hydra-recipes.git/tree/emacs
+https://git.savannah.gnu.org/cgit/hydra-recipes.git/tree/emacs
 
 To modify the build job, email the patch to address@hidden  The
 build recipes are written in the Nix language.
 
+* Identifying hydra
+Lisp packages, Makefiles, scripts, and other software could determine
+whether they run on hydra by checking for the environment variable
+EMACS_HYDRA_CI.
+
 * Other Information
 For a list of other GNU packages that have a continuous build on
-Hydra, see http://hydra.nixos.org/project/gnu
+Hydra, see https://hydra.nixos.org/project/gnu
 
-See http://www.gnu.org/software/devel.html#Hydra for more information.
+See https://www.gnu.org/software/devel.html#Hydra for more information.
 
 
 This file is part of GNU Emacs.
diff --git a/admin/notes/unicode b/admin/notes/unicode
index 0d6c6af..8284e1b 100644
--- a/admin/notes/unicode
+++ b/admin/notes/unicode
@@ -15,9 +15,10 @@ Emacs uses the following files from the Unicode Character 
Database
   . BidiBrackets.txt
   . IVD_Sequences.txt
   . NormalizationTest.txt
+  . SpecialCasing.txt
   . BidiCharacterTest.txt
 
-First, the first 6 files need to be copied into admin/unidata/, and
+First, the first 7 files need to be copied into admin/unidata/, and
 then Emacs should be rebuilt for them to take effect.  Rebuilding
 Emacs updates several derived files elsewhere in the Emacs source
 tree, mainly in lisp/international/.
diff --git a/admin/unidata/BidiBrackets.txt b/admin/unidata/BidiBrackets.txt
index eb02a24..2114e63 100644
--- a/admin/unidata/BidiBrackets.txt
+++ b/admin/unidata/BidiBrackets.txt
@@ -1,6 +1,6 @@
-# BidiBrackets-9.0.0.txt
-# Date: 2016-06-07, 22:30:00 GMT [AG, LI, KW]
-# © 2016 Unicode®, Inc.
+# BidiBrackets-10.0.0.txt
+# Date: 2017-04-12, 17:30:00 GMT [AG, LI, KW]
+# © 2017 Unicode®, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in 
the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
@@ -8,7 +8,7 @@
 # For documentation, see http://www.unicode.org/reports/tr44/
 #
 # Bidi_Paired_Bracket and Bidi_Paired_Bracket_Type Properties
-# 
+#
 # This file is a normative contributory data file in the Unicode
 # Character Database.
 #
diff --git a/admin/unidata/BidiMirroring.txt b/admin/unidata/BidiMirroring.txt
index 68142c5..cbb61c4 100644
--- a/admin/unidata/BidiMirroring.txt
+++ b/admin/unidata/BidiMirroring.txt
@@ -1,13 +1,13 @@
-# BidiMirroring-9.0.0.txt
-# Date: 2016-01-21, 22:00:00 GMT [KW, LI]
-# © 2016 Unicode®, Inc.
+# BidiMirroring-10.0.0.txt
+# Date: 2017-04-12, 17:30:00 GMT [KW, LI]
+# © 2017 Unicode®, Inc.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
 # Unicode Character Database
 # For documentation, see http://www.unicode.org/reports/tr44/
 #
 # Bidi_Mirroring_Glyph Property
-# 
+#
 # This file is an informative contributory data file in the
 # Unicode Character Database.
 #
@@ -15,20 +15,20 @@
 # value, for which there is another Unicode character that typically has a 
glyph
 # that is the mirror image of the original character's glyph.
 #
-# The repertoire covered by the file is Unicode 9.0.0.
-# 
+# The repertoire covered by the file is Unicode 10.0.0.
+#
 # The file contains a list of lines with mappings from one code point
 # to another one for character-based mirroring.
 # Note that for "real" mirroring, a rendering engine needs to select
 # appropriate alternative glyphs, and that many Unicode characters do not
 # have a mirror-image Unicode character.
-# 
+#
 # Each mapping line contains two fields, separated by a semicolon (';').
 # Each of the two fields contains a code point represented as a
 # variable-length hexadecimal value with 4 to 6 digits.
 # A comment indicates where the characters are "BEST FIT" mirroring.
-# 
-# Code points for which Bidi_Mirrored=Yes, but for which no appropriate 
+#
+# Code points for which Bidi_Mirrored=Yes, but for which no appropriate
 # characters exist with mirrored glyphs, are
 # listed as comments at the end of the file.
 #
@@ -38,14 +38,14 @@
 # point has the default value for the Bidi_Mirroring_Glyph property,
 # that means that no other character exists whose glyph is suitable
 # for character-based mirroring.
-# 
+#
 # For information on bidi mirroring, see UAX #9: Unicode Bidirectional 
Algorithm,
 # at http://www.unicode.org/unicode/reports/tr9/
-# 
+#
 # This file was originally created by Markus Scherer.
 # Extended for Unicode 3.2, 4.0, 4.1, 5.0, 5.1, 5.2, and 6.0 by Ken Whistler,
 # and for subsequent versions by Ken Whistler and Laurentiu Iancu.
-# 
+#
 # ############################################################
 #
 # Property:    Bidi_Mirroring_Glyph
diff --git a/admin/unidata/Blocks.txt b/admin/unidata/Blocks.txt
index 74c41e5..a4f851b 100644
--- a/admin/unidata/Blocks.txt
+++ b/admin/unidata/Blocks.txt
@@ -1,6 +1,6 @@
-# Blocks-9.0.0.txt
-# Date: 2016-02-05, 23:48:00 GMT [KW]
-# © 2016 Unicode®, Inc.
+# Blocks-10.0.0.txt
+# Date: 2017-04-12, 17:30:00 GMT [KW]
+# © 2017 Unicode®, Inc.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
 # Unicode Character Database
@@ -14,12 +14,12 @@
 # Note:   When comparing block names, casing, whitespace, hyphens,
 #         and underbars are ignored.
 #         For example, "Latin Extended-A" and "latin extended a" are 
equivalent.
-#         For more information on the comparison of property values, 
+#         For more information on the comparison of property values,
 #            see UAX #44: http://www.unicode.org/reports/tr44/
 #
 #  All block ranges start with a value where (cp MOD 16) = 0,
 #  and end with a value where (cp MOD 16) = 15. In other words,
-#  the last hexadecimal digit of the start of range is ...0 
+#  the last hexadecimal digit of the start of range is ...0
 #  and the last hexadecimal digit of the end of range is ...F.
 #  This constraint on block ranges guarantees that allocations
 #  are done in terms of whole columns, and that code chart display
@@ -51,6 +51,7 @@
 07C0..07FF; NKo
 0800..083F; Samaritan
 0840..085F; Mandaic
+0860..086F; Syriac Supplement
 08A0..08FF; Arabic Extended-A
 0900..097F; Devanagari
 0980..09FF; Bengali
@@ -253,9 +254,12 @@ FFF0..FFFF; Specials
 11680..116CF; Takri
 11700..1173F; Ahom
 118A0..118FF; Warang Citi
+11A00..11A4F; Zanabazar Square
+11A50..11AAF; Soyombo
 11AC0..11AFF; Pau Cin Hau
 11C00..11C6F; Bhaiksuki
 11C70..11CBF; Marchen
+11D00..11D5F; Masaram Gondi
 12000..123FF; Cuneiform
 12400..1247F; Cuneiform Numbers and Punctuation
 12480..1254F; Early Dynastic Cuneiform
@@ -270,6 +274,8 @@ FFF0..FFFF; Specials
 17000..187FF; Tangut
 18800..18AFF; Tangut Components
 1B000..1B0FF; Kana Supplement
+1B100..1B12F; Kana Extended-A
+1B170..1B2FF; Nushu
 1BC00..1BC9F; Duployan
 1BCA0..1BCAF; Shorthand Format Controls
 1D000..1D0FF; Byzantine Musical Symbols
@@ -300,6 +306,7 @@ FFF0..FFFF; Specials
 2A700..2B73F; CJK Unified Ideographs Extension C
 2B740..2B81F; CJK Unified Ideographs Extension D
 2B820..2CEAF; CJK Unified Ideographs Extension E
+2CEB0..2EBEF; CJK Unified Ideographs Extension F
 2F800..2FA1F; CJK Compatibility Ideographs Supplement
 E0000..E007F; Tags
 E0100..E01EF; Variation Selectors Supplement
diff --git a/admin/unidata/IVD_Sequences.txt b/admin/unidata/IVD_Sequences.txt
index fdf21e8..304bf91 100644
--- a/admin/unidata/IVD_Sequences.txt
+++ b/admin/unidata/IVD_Sequences.txt
@@ -2,6 +2,9 @@
 #
 # History:
 #
+# 2016-08-15 Combined registration of the MSARG collection and of
+#            sequences in that collection.
+#
 # 2014-05-16 Combined registration of the Moji_Joho collection and of
 #            sequences in that collection.
 #
@@ -11,17 +14,17 @@
 #            collection. Registration of additional sequences in the
 #            Hanyo-Denshi collection.
 #
-# 2010-11-14 Combined registration of the Hanyo-Denshi collection and of
-#            sequences in that collection.
+# 2010-11-14 Combined registration of the Hanyo-Denshi collection and
+#            of sequences in that collection.
 #
-# 2007-12-14 Combined registration of the Adobe-Japan1 collection and of
-#            sequences in that collection.
+# 2007-12-14 Combined registration of the Adobe-Japan1 collection and
+#            of sequences in that collection.
 #
 # This file is part of the Unicode Ideographic Variation Database (IVD).
 # For more details on the IVD, see UTS #37:
 # http://www.unicode.org/reports/tr37/
 #
-# Copyright 2006-2014 Unicode, Inc.
+# Copyright 2006-2016 Unicode, Inc.
 # For terms of use, see: http://www.unicode.org/terms_of_use.html
 #
 3402 E0100; Adobe-Japan1; CID+13698
@@ -268,6 +271,9 @@
 36C3 E0100; Hanyo-Denshi; IA1426
 36C3 E0101; Hanyo-Denshi; TK01020180
 36C3 E0102; Hanyo-Denshi; TK01020240
+36C7 E0100; MSARG; MA_9856
+36C7 E0101; MSARG; ME_36C7_001
+36C7 E0102; MSARG; ME_36C7_002
 36CF E0100; Adobe-Japan1; CID+17494
 36EE E0100; Moji_Joho; MJ000648
 36EE E0101; Moji_Joho; MJ000649
@@ -4847,6 +4853,8 @@
 5554 E0101; Hanyo-Denshi; TK01014490
 5556 E0100; Adobe-Japan1; CID+4394
 5557 E0100; Adobe-Japan1; CID+4395
+5557 E0101; MSARG; MB_B0E8
+5557 E0102; MSARG; ME_5557_001
 5558 E0100; Adobe-Japan1; CID+21280
 555A E0100; Adobe-Japan1; CID+21281
 555A E0101; Hanyo-Denshi; JB2162
@@ -8319,6 +8327,8 @@
 5EF8 E0100; Adobe-Japan1; CID+4762
 5EF8 E0101; Moji_Joho; MJ011106
 5EF8 E0102; Moji_Joho; MJ011107
+5EF8 E0103; MSARG; MA_9059
+5EF8 E0104; MSARG; ME_5EF8_001
 5EF9 E0100; Adobe-Japan1; CID+16853
 5EF9 E0101; Moji_Joho; MJ011108
 5EF9 E0102; Moji_Joho; MJ011109
@@ -8529,6 +8539,8 @@
 5F55 E0100; Moji_Joho; MJ011232
 5F55 E0101; Hanyo-Denshi; KS112100
 5F55 E0101; Moji_Joho; MJ057475
+5F55 E0102; MSARG; MD_5F55
+5F55 E0103; MSARG; ME_5F55_001
 5F56 E0100; Adobe-Japan1; CID+4780
 5F56 E0101; Hanyo-Denshi; JA5533
 5F56 E0101; Moji_Joho; MJ011233
@@ -26361,6 +26373,8 @@
 8846 E0105; Hanyo-Denshi; KS386520
 8846 E0105; Moji_Joho; MJ058677
 8846 E0106; Hanyo-Denshi; TK01083450
+8846 E0107; MSARG; MA_8FBC
+8846 E0108; MSARG; ME_8846_001
 8848 E0100; Adobe-Japan1; CID+22465
 8849 E0100; Adobe-Japan1; CID+22466
 884A E0100; Adobe-Japan1; CID+18635
@@ -31073,6 +31087,8 @@
 93C5 E0101; Hanyo-Denshi; JB6930
 93C5 E0102; Hanyo-Denshi; TK01093900
 93C6 E0100; Adobe-Japan1; CID+8679
+93C6 E0101; MSARG; MA_9264
+93C6 E0102; MSARG; ME_93C6_001
 93C7 E0100; Adobe-Japan1; CID+18865
 93C8 E0100; Adobe-Japan1; CID+7029
 93C8 E0101; Hanyo-Denshi; JA7926
@@ -32678,6 +32694,8 @@
 98EB E0102; Moji_Joho; MJ028359
 98EB E0103; Hanyo-Denshi; FT2689
 98EB E0103; Moji_Joho; MJ028358
+98EC E0100; MSARG; MA_914B
+98EC E0101; MSARG; ME_98EC_001
 98ED E0100; Adobe-Japan1; CID+4289
 98ED E0101; Hanyo-Denshi; JA5012
 98ED E0101; Moji_Joho; MJ028362
@@ -33545,6 +33563,8 @@
 9AE3 E0100; Adobe-Japan1; CID+7278
 9AE4 E0100; Adobe-Japan1; CID+22934
 9AE5 E0100; Adobe-Japan1; CID+19007
+9AE5 E0101; MSARG; MD_9AE5
+9AE5 E0102; MSARG; ME_9AE5_001
 9AE6 E0100; Adobe-Japan1; CID+7279
 9AE7 E0100; Adobe-Japan1; CID+22935
 9AE9 E0100; Adobe-Japan1; CID+19008
@@ -35487,6 +35507,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
 20C50 E0101; Moji_Joho; MJ057161
 20C74 E0100; Hanyo-Denshi; KS041540
 20C74 E0101; Hanyo-Denshi; TK01014200
+20C98 E0100; MSARG; MD_20C98
+20C98 E0101; MSARG; ME_20C98_001
 20C9C E0100; Hanyo-Denshi; TK01014280
 20C9C E0101; Hanyo-Denshi; TK01014620
 20D45 E0100; Adobe-Japan1; CID+17359
@@ -35689,6 +35711,8 @@ FA29 E0100; Adobe-Japan1; CID+8687
 21A41 E0101; Hanyo-Denshi; TK01022390
 21A62 E0100; Hanyo-Denshi; KS082510
 21A62 E0101; Hanyo-Denshi; TK01022590
+21A74 E0100; MSARG; MD_21A74
+21A74 E0101; MSARG; ME_21A74_001
 21AA2 E0100; Moji_Joho; MJ034079
 21AA2 E0101; Moji_Joho; MJ034080
 21B33 E0100; Hanyo-Denshi; KS084630
diff --git a/admin/unidata/NormalizationTest.txt 
b/admin/unidata/NormalizationTest.txt
index e133fa8..71f2371 100644
--- a/admin/unidata/NormalizationTest.txt
+++ b/admin/unidata/NormalizationTest.txt
@@ -1,6 +1,6 @@
-# NormalizationTest-9.0.0.txt
-# Date: 2016-04-04, 11:41:55 GMT
-# © 2016 Unicode®, Inc.
+# NormalizationTest-10.0.0.txt
+# Date: 2017-03-08, 08:41:55 GMT
+# © 2017 Unicode®, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in 
the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
@@ -17653,6 +17653,10 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) 
HALFWIDTH WHITE CIRCLE
 0061 0CBC 3099 093C 0334 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 
093C 3099 0062;0061 0334 0CBC 093C 3099 0062;0061 0334 0CBC 093C 3099 0062; # 
(a◌಼◌゙◌़◌̴b; a◌̴◌಼◌़◌゙b; a◌̴◌಼◌़◌゙b; a◌̴◌಼◌़◌゙b; a◌̴◌಼◌़◌゙b; ) LATIN SMALL 
LETTER A, KANNADA SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, 
DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
 0061 05B0 094D 3099 0CCD 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 
0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062;0061 3099 094D 0CCD 05B0 0062; # 
(a◌ְ◌्◌゙◌್b; a◌゙◌्◌್◌ְb; a◌゙◌्◌್◌ְb; a◌゙◌्◌್◌ְb; a◌゙◌्◌್◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, KANNADA SIGN VIRAMA, LATIN SMALL LETTER B
 0061 0CCD 05B0 094D 3099 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 
094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062;0061 3099 0CCD 094D 05B0 0062; # 
(a◌್◌ְ◌्◌゙b; a◌゙◌್◌्◌ְb; a◌゙◌್◌्◌ְb; a◌゙◌್◌्◌ְb; a◌゙◌್◌्◌ְb; ) LATIN SMALL 
LETTER A, KANNADA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, 
COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0D3B 0062;0061 3099 094D 0D3B 05B0 0062;0061 3099 094D 
0D3B 05B0 0062;0061 3099 094D 0D3B 05B0 0062;0061 3099 094D 0D3B 05B0 0062; # 
(a◌ְ◌्◌゙◌഻b; a◌゙◌्◌഻◌ְb; a◌゙◌्◌഻◌ְb; a◌゙◌्◌഻◌ְb; a◌゙◌्◌഻◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, MALAYALAM SIGN VERTICAL BAR VIRAMA, LATIN 
SMALL LETTER B
+0061 0D3B 05B0 094D 3099 0062;0061 3099 0D3B 094D 05B0 0062;0061 3099 0D3B 
094D 05B0 0062;0061 3099 0D3B 094D 05B0 0062;0061 3099 0D3B 094D 05B0 0062; # 
(a◌഻◌ְ◌्◌゙b; a◌゙◌഻◌्◌ְb; a◌゙◌഻◌्◌ְb; a◌゙◌഻◌्◌ְb; a◌゙◌഻◌्◌ְb; ) LATIN SMALL 
LETTER A, MALAYALAM SIGN VERTICAL BAR VIRAMA, HEBREW POINT SHEVA, DEVANAGARI 
SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 0D3C 0062;0061 3099 094D 0D3C 05B0 0062;0061 3099 094D 
0D3C 05B0 0062;0061 3099 094D 0D3C 05B0 0062;0061 3099 094D 0D3C 05B0 0062; # 
(a◌ְ◌्◌゙◌഼b; a◌゙◌्◌഼◌ְb; a◌゙◌्◌഼◌ְb; a◌゙◌्◌഼◌ְb; a◌゙◌्◌഼◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, MALAYALAM SIGN CIRCULAR VIRAMA, LATIN 
SMALL LETTER B
+0061 0D3C 05B0 094D 3099 0062;0061 3099 0D3C 094D 05B0 0062;0061 3099 0D3C 
094D 05B0 0062;0061 3099 0D3C 094D 05B0 0062;0061 3099 0D3C 094D 05B0 0062; # 
(a◌഼◌ְ◌्◌゙b; a◌゙◌഼◌्◌ְb; a◌゙◌഼◌्◌ְb; a◌゙◌഼◌्◌ְb; a◌゙◌഼◌्◌ְb; ) LATIN SMALL 
LETTER A, MALAYALAM SIGN CIRCULAR VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN 
VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
 0061 05B0 094D 3099 0D4D 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 
0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062;0061 3099 094D 0D4D 05B0 0062; # 
(a◌ְ◌्◌゙◌്b; a◌゙◌्◌്◌ְb; a◌゙◌्◌്◌ְb; a◌゙◌्◌്◌ְb; a◌゙◌्◌്◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, MALAYALAM SIGN VIRAMA, LATIN SMALL LETTER B
 0061 0D4D 05B0 094D 3099 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 
094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062;0061 3099 0D4D 094D 05B0 0062; # 
(a◌്◌ְ◌्◌゙b; a◌゙◌്◌्◌ְb; a◌゙◌്◌्◌ְb; a◌゙◌്◌्◌ְb; a◌゙◌്◌्◌ְb; ) LATIN SMALL 
LETTER A, MALAYALAM SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, 
COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
 0061 05B0 094D 3099 0DCA 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 
0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062;0061 3099 094D 0DCA 05B0 0062; # 
(a◌ְ◌्◌゙◌්b; a◌゙◌्◌්◌ְb; a◌゙◌्◌්◌ְb; a◌゙◌्◌්◌ְb; a◌゙◌्◌්◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, SINHALA SIGN AL-LAKUNA, LATIN SMALL LETTER 
B
@@ -17999,6 +18003,14 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) 
HALFWIDTH WHITE CIRCLE
 0061 1DF4 0315 0300 05AE 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 
0300 0315 0062;0061 05AE 1DF4 0300 0315 0062;0061 05AE 1DF4 0300 0315 0062; # 
(a◌ᷴ◌̕◌̀◌֮b; a◌֮◌ᷴ◌̀◌̕b; a◌֮◌ᷴ◌̀◌̕b; a◌֮◌ᷴ◌̀◌̕b; a◌֮◌ᷴ◌̀◌̕b; ) LATIN SMALL 
LETTER A, COMBINING LATIN SMALL LETTER U WITH DIAERESIS, COMBINING COMMA ABOVE 
RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
 0061 0315 0300 05AE 1DF5 0062;00E0 05AE 1DF5 0315 0062;0061 05AE 0300 1DF5 
0315 0062;00E0 05AE 1DF5 0315 0062;0061 05AE 0300 1DF5 0315 0062; # 
(a◌̕◌̀◌֮◌᷵b; à◌֮◌᷵◌̕b; a◌֮◌̀◌᷵◌̕b; à◌֮◌᷵◌̕b; a◌֮◌̀◌᷵◌̕b; ) LATIN SMALL LETTER 
A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, 
COMBINING UP TACK ABOVE, LATIN SMALL LETTER B
 0061 1DF5 0315 0300 05AE 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 
0300 0315 0062;0061 05AE 1DF5 0300 0315 0062;0061 05AE 1DF5 0300 0315 0062; # 
(a◌᷵◌̕◌̀◌֮b; a◌֮◌᷵◌̀◌̕b; a◌֮◌᷵◌̀◌̕b; a◌֮◌᷵◌̀◌̕b; a◌֮◌᷵◌̀◌̕b; ) LATIN SMALL 
LETTER A, COMBINING UP TACK ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE 
ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 035C 0315 0300 1DF6 0062;00E0 0315 1DF6 035C 0062;0061 0300 0315 1DF6 
035C 0062;00E0 0315 1DF6 035C 0062;0061 0300 0315 1DF6 035C 0062; # 
(a◌͜◌̕◌̀◌᷶b; à◌̕◌᷶◌͜b; a◌̀◌̕◌᷶◌͜b; à◌̕◌᷶◌͜b; a◌̀◌̕◌᷶◌͜b; ) LATIN SMALL LETTER 
A, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE 
ACCENT, COMBINING KAVYKA ABOVE RIGHT, LATIN SMALL LETTER B
+0061 1DF6 035C 0315 0300 0062;00E0 1DF6 0315 035C 0062;0061 0300 1DF6 0315 
035C 0062;00E0 1DF6 0315 035C 0062;0061 0300 1DF6 0315 035C 0062; # 
(a◌᷶◌͜◌̕◌̀b; à◌᷶◌̕◌͜b; a◌̀◌᷶◌̕◌͜b; à◌᷶◌̕◌͜b; a◌̀◌᷶◌̕◌͜b; ) LATIN SMALL LETTER 
A, COMBINING KAVYKA ABOVE RIGHT, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA 
ABOVE RIGHT, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
+0061 0300 05AE 1D16D 1DF7 0062;00E0 1D16D 05AE 1DF7 0062;0061 1D16D 05AE 1DF7 
0300 0062;00E0 1D16D 05AE 1DF7 0062;0061 1D16D 05AE 1DF7 0300 0062; # 
(a◌̀◌𝅭֮◌᷷b; à𝅭◌֮◌᷷b; a𝅭◌֮◌᷷◌̀b; à𝅭◌֮◌᷷b; a𝅭◌֮◌᷷◌̀b; ) LATIN SMALL LETTER A, 
COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING 
AUGMENTATION DOT, COMBINING KAVYKA ABOVE LEFT, LATIN SMALL LETTER B
+0061 1DF7 0300 05AE 1D16D 0062;00E0 1D16D 1DF7 05AE 0062;0061 1D16D 1DF7 05AE 
0300 0062;00E0 1D16D 1DF7 05AE 0062;0061 1D16D 1DF7 05AE 0300 0062; # 
(a◌᷷◌̀◌𝅭֮b; à𝅭◌᷷◌֮b; a𝅭◌᷷◌֮◌̀b; à𝅭◌᷷◌֮b; a𝅭◌᷷◌֮◌̀b; ) LATIN SMALL LETTER A, 
COMBINING KAVYKA ABOVE LEFT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, 
MUSICAL SYMBOL COMBINING AUGMENTATION DOT, LATIN SMALL LETTER B
+0061 0300 05AE 1D16D 1DF8 0062;00E0 1D16D 05AE 1DF8 0062;0061 1D16D 05AE 1DF8 
0300 0062;00E0 1D16D 05AE 1DF8 0062;0061 1D16D 05AE 1DF8 0300 0062; # 
(a◌̀◌𝅭֮◌᷸b; à𝅭◌֮◌᷸b; a𝅭◌֮◌᷸◌̀b; à𝅭◌֮◌᷸b; a𝅭◌֮◌᷸◌̀b; ) LATIN SMALL LETTER A, 
COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL SYMBOL COMBINING 
AUGMENTATION DOT, COMBINING DOT ABOVE LEFT, LATIN SMALL LETTER B
+0061 1DF8 0300 05AE 1D16D 0062;00E0 1D16D 1DF8 05AE 0062;0061 1D16D 1DF8 05AE 
0300 0062;00E0 1D16D 1DF8 05AE 0062;0061 1D16D 1DF8 05AE 0300 0062; # 
(a◌᷸◌̀◌𝅭֮b; à𝅭◌᷸◌֮b; a𝅭◌᷸◌֮◌̀b; à𝅭◌᷸◌֮b; a𝅭◌᷸◌֮◌̀b; ) LATIN SMALL LETTER A, 
COMBINING DOT ABOVE LEFT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, MUSICAL 
SYMBOL COMBINING AUGMENTATION DOT, LATIN SMALL LETTER B
+0061 059A 0316 302A 1DF9 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 
1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062;0061 302A 0316 1DF9 059A 0062; # 
(a◌֚◌̖◌〪◌᷹b; a◌〪◌̖◌᷹◌֚b; a◌〪◌̖◌᷹◌֚b; a◌〪◌̖◌᷹◌֚b; a◌〪◌̖◌᷹◌֚b; ) LATIN SMALL 
LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL 
TONE MARK, COMBINING WIDE INVERTED BRIDGE BELOW, LATIN SMALL LETTER B
+0061 1DF9 059A 0316 302A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 
0316 059A 0062;0061 302A 1DF9 0316 059A 0062;0061 302A 1DF9 0316 059A 0062; # 
(a◌᷹◌֚◌̖◌〪b; a◌〪◌᷹◌̖◌֚b; a◌〪◌᷹◌̖◌֚b; a◌〪◌᷹◌̖◌֚b; a◌〪◌᷹◌̖◌֚b; ) LATIN SMALL 
LETTER A, COMBINING WIDE INVERTED BRIDGE BELOW, HEBREW ACCENT YETIV, COMBINING 
GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B
 0061 0315 0300 05AE 1DFB 0062;00E0 05AE 1DFB 0315 0062;0061 05AE 0300 1DFB 
0315 0062;00E0 05AE 1DFB 0315 0062;0061 05AE 0300 1DFB 0315 0062; # 
(a◌̕◌̀◌֮◌᷻b; à◌֮◌᷻◌̕b; a◌֮◌̀◌᷻◌̕b; à◌֮◌᷻◌̕b; a◌֮◌̀◌᷻◌̕b; ) LATIN SMALL LETTER 
A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, 
COMBINING DELETION MARK, LATIN SMALL LETTER B
 0061 1DFB 0315 0300 05AE 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 
0300 0315 0062;0061 05AE 1DFB 0300 0315 0062;0061 05AE 1DFB 0300 0315 0062; # 
(a◌᷻◌̕◌̀◌֮b; a◌֮◌᷻◌̀◌̕b; a◌֮◌᷻◌̀◌̕b; a◌֮◌᷻◌̀◌̕b; a◌֮◌᷻◌̀◌̕b; ) LATIN SMALL 
LETTER A, COMBINING DELETION MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE 
ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
 0061 035D 035C 0315 1DFC 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 
1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062;0061 0315 035C 1DFC 035D 0062; # 
(a◌͝◌͜◌̕◌᷼b; a◌̕◌͜◌᷼◌͝b; a◌̕◌͜◌᷼◌͝b; a◌̕◌͜◌᷼◌͝b; a◌̕◌͜◌᷼◌͝b; ) LATIN SMALL 
LETTER A, COMBINING DOUBLE BREVE, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA 
ABOVE RIGHT, COMBINING DOUBLE INVERTED BREVE BELOW, LATIN SMALL LETTER B
@@ -18397,8 +18409,20 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) 
HALFWIDTH WHITE CIRCLE
 0061 116B7 3099 093C 0334 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 
093C 3099 0062;0061 0334 116B7 093C 3099 0062;0061 0334 116B7 093C 3099 0062; # 
(a◌𑚷◌゙◌़◌̴b; a◌̴◌𑚷◌़◌゙b; a◌̴◌𑚷◌़◌゙b; a◌̴◌𑚷◌़◌゙b; a◌̴◌𑚷◌़◌゙b; ) LATIN SMALL 
LETTER A, TAKRI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, 
DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
 0061 05B0 094D 3099 1172B 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 
1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062;0061 3099 094D 1172B 05B0 0062; 
# (a◌ְ◌्◌゙◌𑜫b; a◌゙◌्◌𑜫◌ְb; a◌゙◌्◌𑜫◌ְb; a◌゙◌्◌𑜫◌ְb; a◌゙◌्◌𑜫◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, AHOM SIGN KILLER, LATIN SMALL LETTER B
 0061 1172B 05B0 094D 3099 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 
094D 05B0 0062;0061 3099 1172B 094D 05B0 0062;0061 3099 1172B 094D 05B0 0062; # 
(a◌𑜫◌ְ◌्◌゙b; a◌゙◌𑜫◌्◌ְb; a◌゙◌𑜫◌्◌ְb; a◌゙◌𑜫◌्◌ְb; a◌゙◌𑜫◌्◌ְb; ) LATIN SMALL 
LETTER A, AHOM SIGN KILLER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, 
COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11A34 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 
11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062; 
# (a◌ְ◌्◌゙◌𑨴b; a◌゙◌्◌𑨴◌ְb; a◌゙◌्◌𑨴◌ְb; a◌゙◌्◌𑨴◌ְb; a◌゙◌्◌𑨴◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, ZANABAZAR SQUARE SIGN VIRAMA, LATIN SMALL 
LETTER B
+0061 11A34 05B0 094D 3099 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 
094D 05B0 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062; # 
(a◌𑨴◌ְ◌्◌゙b; a◌゙◌𑨴◌्◌ְb; a◌゙◌𑨴◌्◌ְb; a◌゙◌𑨴◌्◌ְb; a◌゙◌𑨴◌्◌ְb; ) LATIN SMALL 
LETTER A, ZANABAZAR SQUARE SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN 
VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11A47 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 
11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062; 
# (a◌ְ◌्◌゙◌𑩇b; a◌゙◌्◌𑩇◌ְb; a◌゙◌्◌𑩇◌ְb; a◌゙◌्◌𑩇◌ְb; a◌゙◌्◌𑩇◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, ZANABAZAR SQUARE SUBJOINER, LATIN SMALL 
LETTER B
+0061 11A47 05B0 094D 3099 0062;0061 3099 11A47 094D 05B0 0062;0061 3099 11A47 
094D 05B0 0062;0061 3099 11A47 094D 05B0 0062;0061 3099 11A47 094D 05B0 0062; # 
(a◌𑩇◌ְ◌्◌゙b; a◌゙◌𑩇◌्◌ְb; a◌゙◌𑩇◌्◌ְb; a◌゙◌𑩇◌्◌ְb; a◌゙◌𑩇◌्◌ְb; ) LATIN SMALL 
LETTER A, ZANABAZAR SQUARE SUBJOINER, HEBREW POINT SHEVA, DEVANAGARI SIGN 
VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11A99 0062;0061 3099 094D 11A99 05B0 0062;0061 3099 094D 
11A99 05B0 0062;0061 3099 094D 11A99 05B0 0062;0061 3099 094D 11A99 05B0 0062; 
# (a◌ְ◌्◌゙◌𑪙b; a◌゙◌्◌𑪙◌ְb; a◌゙◌्◌𑪙◌ְb; a◌゙◌्◌𑪙◌ְb; a◌゙◌्◌𑪙◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, SOYOMBO SUBJOINER, LATIN SMALL LETTER B
+0061 11A99 05B0 094D 3099 0062;0061 3099 11A99 094D 05B0 0062;0061 3099 11A99 
094D 05B0 0062;0061 3099 11A99 094D 05B0 0062;0061 3099 11A99 094D 05B0 0062; # 
(a◌𑪙◌ְ◌्◌゙b; a◌゙◌𑪙◌्◌ְb; a◌゙◌𑪙◌्◌ְb; a◌゙◌𑪙◌्◌ְb; a◌゙◌𑪙◌्◌ְb; ) LATIN SMALL 
LETTER A, SOYOMBO SUBJOINER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, 
COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
 0061 05B0 094D 3099 11C3F 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 
11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062;0061 3099 094D 11C3F 05B0 0062; 
# (a◌ְ◌्◌゙◌𑰿b; a◌゙◌्◌𑰿◌ְb; a◌゙◌्◌𑰿◌ְb; a◌゙◌्◌𑰿◌ְb; a◌゙◌्◌𑰿◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, BHAIKSUKI SIGN VIRAMA, LATIN SMALL LETTER B
 0061 11C3F 05B0 094D 3099 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 
094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062;0061 3099 11C3F 094D 05B0 0062; # 
(a◌𑰿◌ְ◌्◌゙b; a◌゙◌𑰿◌्◌ְb; a◌゙◌𑰿◌्◌ְb; a◌゙◌𑰿◌्◌ְb; a◌゙◌𑰿◌्◌ְb; ) LATIN SMALL 
LETTER A, BHAIKSUKI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, 
COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 3099 093C 0334 11D42 0062;0061 0334 093C 11D42 3099 0062;0061 0334 093C 
11D42 3099 0062;0061 0334 093C 11D42 3099 0062;0061 0334 093C 11D42 3099 0062; 
# (a◌゙◌़◌̴◌𑵂b; a◌̴◌़◌𑵂◌゙b; a◌̴◌़◌𑵂◌゙b; a◌̴◌़◌𑵂◌゙b; a◌̴◌़◌𑵂◌゙b; ) LATIN SMALL 
LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, 
COMBINING TILDE OVERLAY, MASARAM GONDI SIGN NUKTA, LATIN SMALL LETTER B
+0061 11D42 3099 093C 0334 0062;0061 0334 11D42 093C 3099 0062;0061 0334 11D42 
093C 3099 0062;0061 0334 11D42 093C 3099 0062;0061 0334 11D42 093C 3099 0062; # 
(a◌𑵂◌゙◌़◌̴b; a◌̴◌𑵂◌़◌゙b; a◌̴◌𑵂◌़◌゙b; a◌̴◌𑵂◌़◌゙b; a◌̴◌𑵂◌़◌゙b; ) LATIN SMALL 
LETTER A, MASARAM GONDI SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND 
MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11D44 0062;0061 3099 094D 11D44 05B0 0062;0061 3099 094D 
11D44 05B0 0062;0061 3099 094D 11D44 05B0 0062;0061 3099 094D 11D44 05B0 0062; 
# (a◌ְ◌्◌゙◌𑵄b; a◌゙◌्◌𑵄◌ְb; a◌゙◌्◌𑵄◌ְb; a◌゙◌्◌𑵄◌ְb; a◌゙◌्◌𑵄◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, MASARAM GONDI SIGN HALANTA, LATIN SMALL 
LETTER B
+0061 11D44 05B0 094D 3099 0062;0061 3099 11D44 094D 05B0 0062;0061 3099 11D44 
094D 05B0 0062;0061 3099 11D44 094D 05B0 0062;0061 3099 11D44 094D 05B0 0062; # 
(a◌𑵄◌ְ◌्◌゙b; a◌゙◌𑵄◌्◌ְb; a◌゙◌𑵄◌्◌ְb; a◌゙◌𑵄◌्◌ְb; a◌゙◌𑵄◌्◌ְb; ) LATIN SMALL 
LETTER A, MASARAM GONDI SIGN HALANTA, HEBREW POINT SHEVA, DEVANAGARI SIGN 
VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11D45 0062;0061 3099 094D 11D45 05B0 0062;0061 3099 094D 
11D45 05B0 0062;0061 3099 094D 11D45 05B0 0062;0061 3099 094D 11D45 05B0 0062; 
# (a◌ְ◌्◌゙◌𑵅b; a◌゙◌्◌𑵅◌ְb; a◌゙◌्◌𑵅◌ְb; a◌゙◌्◌𑵅◌ְb; a◌゙◌्◌𑵅◌ְb; ) LATIN SMALL 
LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING 
KATAKANA-HIRAGANA VOICED SOUND MARK, MASARAM GONDI VIRAMA, LATIN SMALL LETTER B
+0061 11D45 05B0 094D 3099 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 
094D 05B0 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 094D 05B0 0062; # 
(a◌𑵅◌ְ◌्◌゙b; a◌゙◌𑵅◌्◌ְb; a◌゙◌𑵅◌्◌ְb; a◌゙◌𑵅◌्◌ְb; a◌゙◌𑵅◌्◌ְb; ) LATIN SMALL 
LETTER A, MASARAM GONDI VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, 
COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
 0061 093C 0334 16AF0 0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 
0062;0061 0334 16AF0 093C 0062;0061 0334 16AF0 093C 0062; # (a◌़◌̴◌𖫰b; 
a◌̴◌𖫰◌़b; a◌̴◌𖫰◌़b; a◌̴◌𖫰◌़b; a◌̴◌𖫰◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN 
NUKTA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING HIGH TONE, LATIN SMALL 
LETTER B
 0061 16AF0 093C 0334 0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 
0062;0061 16AF0 0334 093C 0062;0061 16AF0 0334 093C 0062; # (a◌𖫰◌़◌̴b; 
a◌𖫰◌̴◌़b; a◌𖫰◌̴◌़b; a◌𖫰◌̴◌़b; a◌𖫰◌̴◌़b; ) LATIN SMALL LETTER A, BASSA VAH 
COMBINING HIGH TONE, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN 
SMALL LETTER B
 0061 093C 0334 16AF1 0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 
0062;0061 0334 16AF1 093C 0062;0061 0334 16AF1 093C 0062; # (a◌़◌̴◌𖫱b; 
a◌̴◌𖫱◌़b; a◌̴◌𖫱◌़b; a◌̴◌𖫱◌़b; a◌̴◌𖫱◌़b; ) LATIN SMALL LETTER A, DEVANAGARI SIGN 
NUKTA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING LOW TONE, LATIN SMALL 
LETTER B
diff --git a/admin/unidata/README b/admin/unidata/README
index 06a6666..f5881a1 100644
--- a/admin/unidata/README
+++ b/admin/unidata/README
@@ -5,26 +5,30 @@ copyright.html.
 
 The names, URLs, and dates for these files are as follows.
 
+BidiBrackets.txt
+http://www.unicode.org/Public/UNIDATA/BidiBrackets.txt
+2017-04-20
+
 BidiMirroring.txt
 http://www.unicode.org/Public/UNIDATA/BidiMirroring.txt
-2013-12-17
+2017-04-20
 
 IVD_Sequences.txt
-http://www.unicode.org/ivd/data/2014-05-16/IVD_Sequences.txt
-2014-05-16
+http://www.unicode.org/ivd/
+2016-08-15
 
 UnicodeData.txt
 http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
-2014-03-10
+2017-03-07
 
 Blocks.txt
 http://www.unicode.org/Public/8.0.0/ucd/Blocks.txt
-2014-11-10
+2017-04-20
 
 NormalizationTest.txt
 http://www.unicode.org/Public/UNIDATA/NormalizationTest.txt
-2016-07-16
+2017-03-08
 
 SpecialCasing.txt
 http://unicode.org/Public/UNIDATA/SpecialCasing.txt
-2016-03-03
+2017-04-20
diff --git a/admin/unidata/SpecialCasing.txt b/admin/unidata/SpecialCasing.txt
index b23fa7f..b9ba0d8 100644
--- a/admin/unidata/SpecialCasing.txt
+++ b/admin/unidata/SpecialCasing.txt
@@ -1,6 +1,6 @@
-# SpecialCasing-9.0.0.txt
-# Date: 2016-03-02, 18:55:13 GMT
-# © 2016 Unicode®, Inc.
+# SpecialCasing-10.0.0.txt
+# Date: 2017-04-14, 05:40:43 GMT
+# © 2017 Unicode®, Inc.
 # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in 
the U.S. and other countries.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
@@ -197,7 +197,7 @@ FB17; FB17; 0544 056D; 0544 053D; # ARMENIAN SMALL LIGATURE 
MEN XEH
 
 # 
================================================================================
 # Conditional Mappings
-# The remainder of this file provides conditional casing data used to produce 
+# The remainder of this file provides conditional casing data used to produce
 # full case mappings.
 # 
================================================================================
 # Language-Insensitive Mappings
diff --git a/admin/unidata/UnicodeData.txt b/admin/unidata/UnicodeData.txt
index a756976..d89c64f 100644
--- a/admin/unidata/UnicodeData.txt
+++ b/admin/unidata/UnicodeData.txt
@@ -2072,6 +2072,17 @@
 085A;MANDAIC VOCALIZATION MARK;Mn;220;NSM;;;;;N;;;;;
 085B;MANDAIC GEMINATION MARK;Mn;220;NSM;;;;;N;;;;;
 085E;MANDAIC PUNCTUATION;Po;0;R;;;;;N;;;;;
+0860;SYRIAC LETTER MALAYALAM NGA;Lo;0;AL;;;;;N;;;;;
+0861;SYRIAC LETTER MALAYALAM JA;Lo;0;AL;;;;;N;;;;;
+0862;SYRIAC LETTER MALAYALAM NYA;Lo;0;AL;;;;;N;;;;;
+0863;SYRIAC LETTER MALAYALAM TTA;Lo;0;AL;;;;;N;;;;;
+0864;SYRIAC LETTER MALAYALAM NNA;Lo;0;AL;;;;;N;;;;;
+0865;SYRIAC LETTER MALAYALAM NNNA;Lo;0;AL;;;;;N;;;;;
+0866;SYRIAC LETTER MALAYALAM BHA;Lo;0;AL;;;;;N;;;;;
+0867;SYRIAC LETTER MALAYALAM RA;Lo;0;AL;;;;;N;;;;;
+0868;SYRIAC LETTER MALAYALAM LLA;Lo;0;AL;;;;;N;;;;;
+0869;SYRIAC LETTER MALAYALAM LLLA;Lo;0;AL;;;;;N;;;;;
+086A;SYRIAC LETTER MALAYALAM SSA;Lo;0;AL;;;;;N;;;;;
 08A0;ARABIC LETTER BEH WITH SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
 08A1;ARABIC LETTER BEH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;
 08A2;ARABIC LETTER JEEM WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
@@ -2366,6 +2377,8 @@
 09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;;
 09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;;
 09FB;BENGALI GANDA MARK;Sc;0;ET;;;;;N;;;;;
+09FC;BENGALI LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;;
+09FD;BENGALI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
 0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;;
 0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;;
 0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
@@ -2530,6 +2543,12 @@
 0AF0;GUJARATI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
 0AF1;GUJARATI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
 0AF9;GUJARATI LETTER ZHA;Lo;0;L;;;;;N;;;;;
+0AFA;GUJARATI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;;
+0AFB;GUJARATI SIGN SHADDA;Mn;0;NSM;;;;;N;;;;;
+0AFC;GUJARATI SIGN MADDAH;Mn;0;NSM;;;;;N;;;;;
+0AFD;GUJARATI SIGN THREE-DOT NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;;
+0AFE;GUJARATI SIGN CIRCLE NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;;
+0AFF;GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;;
 0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
 0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
 0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
@@ -2876,6 +2895,7 @@
 0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
 0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
 0CF2;KANNADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+0D00;MALAYALAM SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;;
 0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
 0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
 0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;
@@ -2931,6 +2951,8 @@
 0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;;
 0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;;
 0D3A;MALAYALAM LETTER TTTA;Lo;0;L;;;;;N;;;;;
+0D3B;MALAYALAM SIGN VERTICAL BAR VIRAMA;Mn;9;NSM;;;;;N;;;;;
+0D3C;MALAYALAM SIGN CIRCULAR VIRAMA;Mn;9;NSM;;;;;N;;;;;
 0D3D;MALAYALAM SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
 0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
 0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
@@ -6413,6 +6435,7 @@
 1CF4;VEDIC TONE CANDRA ABOVE;Mn;230;NSM;;;;;N;;;;;
 1CF5;VEDIC SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
 1CF6;VEDIC SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+1CF7;VEDIC SIGN ATIKRAMA;Mc;0;L;;;;;N;;;;;
 1CF8;VEDIC TONE RING ABOVE;Mn;230;NSM;;;;;N;;;;;
 1CF9;VEDIC TONE DOUBLE RING ABOVE;Mn;230;NSM;;;;;N;;;;;
 1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;;
@@ -6661,6 +6684,10 @@
 1DF3;COMBINING LATIN SMALL LETTER O WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;
 1DF4;COMBINING LATIN SMALL LETTER U WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;
 1DF5;COMBINING UP TACK ABOVE;Mn;230;NSM;;;;;N;;;;;
+1DF6;COMBINING KAVYKA ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;;
+1DF7;COMBINING KAVYKA ABOVE LEFT;Mn;228;NSM;;;;;N;;;;;
+1DF8;COMBINING DOT ABOVE LEFT;Mn;228;NSM;;;;;N;;;;;
+1DF9;COMBINING WIDE INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;;;;;
 1DFB;COMBINING DELETION MARK;Mn;230;NSM;;;;;N;;;;;
 1DFC;COMBINING DOUBLE INVERTED BREVE BELOW;Mn;233;NSM;;;;;N;;;;;
 1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;;
@@ -7339,6 +7366,7 @@
 20BC;MANAT SIGN;Sc;0;ET;;;;;N;;;;;
 20BD;RUBLE SIGN;Sc;0;ET;;;;;N;;;;;
 20BE;LARI SIGN;Sc;0;ET;;;;;N;;;;;
+20BF;BITCOIN SIGN;Sc;0;ET;;;;;N;;;;;
 20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON 
ABOVE;;;;
 20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON 
ABOVE;;;;
 20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG 
VERTICAL BAR OVERLAY;;;;
@@ -8135,6 +8163,7 @@
 23FC;POWER ON-OFF SYMBOL;So;0;ON;;;;;N;;;;;
 23FD;POWER ON SYMBOL;So;0;ON;;;;;N;;;;;
 23FE;POWER SLEEP SYMBOL;So;0;ON;;;;;N;;;;;
+23FF;OBSERVER EYE SYMBOL;So;0;ON;;;;;N;;;;;
 2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;;
 2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;;
 2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;;
@@ -10083,6 +10112,7 @@
 2BCF;ROTATED WHITE FOUR POINTED CUSP;So;0;ON;;;;;N;;;;;
 2BD0;SQUARE POSITION INDICATOR;So;0;ON;;;;;N;;;;;
 2BD1;UNCERTAINTY SIGN;So;0;ON;;;;;N;;;;;
+2BD2;GROUP MARK;So;0;ON;;;;;N;;;;;
 2BEC;LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
 2BED;UPWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
 2BEE;RIGHTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;
@@ -10615,6 +10645,11 @@
 2E42;DOUBLE LOW-REVERSED-9 QUOTATION MARK;Ps;0;ON;;;;;N;;;;;
 2E43;DASH WITH LEFT UPTURN;Po;0;ON;;;;;N;;;;;
 2E44;DOUBLE SUSPENSION MARK;Po;0;ON;;;;;N;;;;;
+2E45;INVERTED LOW KAVYKA;Po;0;ON;;;;;N;;;;;
+2E46;INVERTED LOW KAVYKA WITH KAVYKA ABOVE;Po;0;ON;;;;;N;;;;;
+2E47;LOW KAVYKA;Po;0;ON;;;;;N;;;;;
+2E48;LOW KAVYKA WITH DOT;Po;0;ON;;;;;N;;;;;
+2E49;DOUBLE STACKED COMMA;Po;0;ON;;;;;N;;;;;
 2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;
 2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;
 2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;
@@ -11250,6 +11285,7 @@
 312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;;
 312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;;
 312D;BOPOMOFO LETTER IH;Lo;0;L;;;;;N;;;;;
+312E;BOPOMOFO LETTER O WITH DOT ABOVE;Lo;0;L;;;;;N;;;;;
 3131;HANGUL LETTER KIYEOK;Lo;0;L;<compat> 1100;;;;N;HANGUL LETTER GIYEOG;;;;
 3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L;<compat> 1101;;;;N;HANGUL LETTER SSANG 
GIYEOG;;;;
 3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<compat> 11AA;;;;N;HANGUL LETTER GIYEOG 
SIOS;;;;
@@ -12016,7 +12052,7 @@
 4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;;
 4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;;
 4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
-9FD5;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+9FEA;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
 A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;
 A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;
 A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;
@@ -17093,6 +17129,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;;
 10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;;
 10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;;
+1032D;OLD ITALIC LETTER YE;Lo;0;L;;;;;N;;;;;
+1032E;OLD ITALIC LETTER NORTHERN TSE;Lo;0;L;;;;;N;;;;;
+1032F;OLD ITALIC LETTER SOUTHERN TSE;Lo;0;L;;;;;N;;;;;
 10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;;
 10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;;
 10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;;
@@ -20068,6 +20107,158 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 118F1;WARANG CITI NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
 118F2;WARANG CITI NUMBER NINETY;No;0;L;;;;90;N;;;;;
 118FF;WARANG CITI OM;Lo;0;L;;;;;N;;;;;
+11A00;ZANABAZAR SQUARE LETTER A;Lo;0;L;;;;;N;;;;;
+11A01;ZANABAZAR SQUARE VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11A02;ZANABAZAR SQUARE VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+11A03;ZANABAZAR SQUARE VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11A04;ZANABAZAR SQUARE VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11A05;ZANABAZAR SQUARE VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;
+11A06;ZANABAZAR SQUARE VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11A07;ZANABAZAR SQUARE VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+11A08;ZANABAZAR SQUARE VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+11A09;ZANABAZAR SQUARE VOWEL SIGN REVERSED I;Mn;0;NSM;;;;;N;;;;;
+11A0A;ZANABAZAR SQUARE VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
+11A0B;ZANABAZAR SQUARE LETTER KA;Lo;0;L;;;;;N;;;;;
+11A0C;ZANABAZAR SQUARE LETTER KHA;Lo;0;L;;;;;N;;;;;
+11A0D;ZANABAZAR SQUARE LETTER GA;Lo;0;L;;;;;N;;;;;
+11A0E;ZANABAZAR SQUARE LETTER GHA;Lo;0;L;;;;;N;;;;;
+11A0F;ZANABAZAR SQUARE LETTER NGA;Lo;0;L;;;;;N;;;;;
+11A10;ZANABAZAR SQUARE LETTER CA;Lo;0;L;;;;;N;;;;;
+11A11;ZANABAZAR SQUARE LETTER CHA;Lo;0;L;;;;;N;;;;;
+11A12;ZANABAZAR SQUARE LETTER JA;Lo;0;L;;;;;N;;;;;
+11A13;ZANABAZAR SQUARE LETTER NYA;Lo;0;L;;;;;N;;;;;
+11A14;ZANABAZAR SQUARE LETTER TTA;Lo;0;L;;;;;N;;;;;
+11A15;ZANABAZAR SQUARE LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11A16;ZANABAZAR SQUARE LETTER DDA;Lo;0;L;;;;;N;;;;;
+11A17;ZANABAZAR SQUARE LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11A18;ZANABAZAR SQUARE LETTER NNA;Lo;0;L;;;;;N;;;;;
+11A19;ZANABAZAR SQUARE LETTER TA;Lo;0;L;;;;;N;;;;;
+11A1A;ZANABAZAR SQUARE LETTER THA;Lo;0;L;;;;;N;;;;;
+11A1B;ZANABAZAR SQUARE LETTER DA;Lo;0;L;;;;;N;;;;;
+11A1C;ZANABAZAR SQUARE LETTER DHA;Lo;0;L;;;;;N;;;;;
+11A1D;ZANABAZAR SQUARE LETTER NA;Lo;0;L;;;;;N;;;;;
+11A1E;ZANABAZAR SQUARE LETTER PA;Lo;0;L;;;;;N;;;;;
+11A1F;ZANABAZAR SQUARE LETTER PHA;Lo;0;L;;;;;N;;;;;
+11A20;ZANABAZAR SQUARE LETTER BA;Lo;0;L;;;;;N;;;;;
+11A21;ZANABAZAR SQUARE LETTER BHA;Lo;0;L;;;;;N;;;;;
+11A22;ZANABAZAR SQUARE LETTER MA;Lo;0;L;;;;;N;;;;;
+11A23;ZANABAZAR SQUARE LETTER TSA;Lo;0;L;;;;;N;;;;;
+11A24;ZANABAZAR SQUARE LETTER TSHA;Lo;0;L;;;;;N;;;;;
+11A25;ZANABAZAR SQUARE LETTER DZA;Lo;0;L;;;;;N;;;;;
+11A26;ZANABAZAR SQUARE LETTER DZHA;Lo;0;L;;;;;N;;;;;
+11A27;ZANABAZAR SQUARE LETTER ZHA;Lo;0;L;;;;;N;;;;;
+11A28;ZANABAZAR SQUARE LETTER ZA;Lo;0;L;;;;;N;;;;;
+11A29;ZANABAZAR SQUARE LETTER -A;Lo;0;L;;;;;N;;;;;
+11A2A;ZANABAZAR SQUARE LETTER YA;Lo;0;L;;;;;N;;;;;
+11A2B;ZANABAZAR SQUARE LETTER RA;Lo;0;L;;;;;N;;;;;
+11A2C;ZANABAZAR SQUARE LETTER LA;Lo;0;L;;;;;N;;;;;
+11A2D;ZANABAZAR SQUARE LETTER VA;Lo;0;L;;;;;N;;;;;
+11A2E;ZANABAZAR SQUARE LETTER SHA;Lo;0;L;;;;;N;;;;;
+11A2F;ZANABAZAR SQUARE LETTER SSA;Lo;0;L;;;;;N;;;;;
+11A30;ZANABAZAR SQUARE LETTER SA;Lo;0;L;;;;;N;;;;;
+11A31;ZANABAZAR SQUARE LETTER HA;Lo;0;L;;;;;N;;;;;
+11A32;ZANABAZAR SQUARE LETTER KSSA;Lo;0;L;;;;;N;;;;;
+11A33;ZANABAZAR SQUARE FINAL CONSONANT MARK;Mn;0;NSM;;;;;N;;;;;
+11A34;ZANABAZAR SQUARE SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11A35;ZANABAZAR SQUARE SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11A36;ZANABAZAR SQUARE SIGN CANDRABINDU WITH ORNAMENT;Mn;0;NSM;;;;;N;;;;;
+11A37;ZANABAZAR SQUARE SIGN CANDRA WITH ORNAMENT;Mn;0;NSM;;;;;N;;;;;
+11A38;ZANABAZAR SQUARE SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11A39;ZANABAZAR SQUARE SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11A3A;ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;;
+11A3B;ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA;Mn;0;NSM;;;;;N;;;;;
+11A3C;ZANABAZAR SQUARE CLUSTER-FINAL LETTER RA;Mn;0;NSM;;;;;N;;;;;
+11A3D;ZANABAZAR SQUARE CLUSTER-FINAL LETTER LA;Mn;0;NSM;;;;;N;;;;;
+11A3E;ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA;Mn;0;NSM;;;;;N;;;;;
+11A3F;ZANABAZAR SQUARE INITIAL HEAD MARK;Po;0;L;;;;;N;;;;;
+11A40;ZANABAZAR SQUARE CLOSING HEAD MARK;Po;0;L;;;;;N;;;;;
+11A41;ZANABAZAR SQUARE MARK TSHEG;Po;0;L;;;;;N;;;;;
+11A42;ZANABAZAR SQUARE MARK SHAD;Po;0;L;;;;;N;;;;;
+11A43;ZANABAZAR SQUARE MARK DOUBLE SHAD;Po;0;L;;;;;N;;;;;
+11A44;ZANABAZAR SQUARE MARK LONG TSHEG;Po;0;L;;;;;N;;;;;
+11A45;ZANABAZAR SQUARE INITIAL DOUBLE-LINED HEAD MARK;Po;0;L;;;;;N;;;;;
+11A46;ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK;Po;0;L;;;;;N;;;;;
+11A47;ZANABAZAR SQUARE SUBJOINER;Mn;9;NSM;;;;;N;;;;;
+11A50;SOYOMBO LETTER A;Lo;0;L;;;;;N;;;;;
+11A51;SOYOMBO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11A52;SOYOMBO VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
+11A53;SOYOMBO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11A54;SOYOMBO VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11A55;SOYOMBO VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11A56;SOYOMBO VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;
+11A57;SOYOMBO VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+11A58;SOYOMBO VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+11A59;SOYOMBO VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+11A5A;SOYOMBO VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
+11A5B;SOYOMBO VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
+11A5C;SOYOMBO LETTER KA;Lo;0;L;;;;;N;;;;;
+11A5D;SOYOMBO LETTER KHA;Lo;0;L;;;;;N;;;;;
+11A5E;SOYOMBO LETTER GA;Lo;0;L;;;;;N;;;;;
+11A5F;SOYOMBO LETTER GHA;Lo;0;L;;;;;N;;;;;
+11A60;SOYOMBO LETTER NGA;Lo;0;L;;;;;N;;;;;
+11A61;SOYOMBO LETTER CA;Lo;0;L;;;;;N;;;;;
+11A62;SOYOMBO LETTER CHA;Lo;0;L;;;;;N;;;;;
+11A63;SOYOMBO LETTER JA;Lo;0;L;;;;;N;;;;;
+11A64;SOYOMBO LETTER JHA;Lo;0;L;;;;;N;;;;;
+11A65;SOYOMBO LETTER NYA;Lo;0;L;;;;;N;;;;;
+11A66;SOYOMBO LETTER TTA;Lo;0;L;;;;;N;;;;;
+11A67;SOYOMBO LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11A68;SOYOMBO LETTER DDA;Lo;0;L;;;;;N;;;;;
+11A69;SOYOMBO LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11A6A;SOYOMBO LETTER NNA;Lo;0;L;;;;;N;;;;;
+11A6B;SOYOMBO LETTER TA;Lo;0;L;;;;;N;;;;;
+11A6C;SOYOMBO LETTER THA;Lo;0;L;;;;;N;;;;;
+11A6D;SOYOMBO LETTER DA;Lo;0;L;;;;;N;;;;;
+11A6E;SOYOMBO LETTER DHA;Lo;0;L;;;;;N;;;;;
+11A6F;SOYOMBO LETTER NA;Lo;0;L;;;;;N;;;;;
+11A70;SOYOMBO LETTER PA;Lo;0;L;;;;;N;;;;;
+11A71;SOYOMBO LETTER PHA;Lo;0;L;;;;;N;;;;;
+11A72;SOYOMBO LETTER BA;Lo;0;L;;;;;N;;;;;
+11A73;SOYOMBO LETTER BHA;Lo;0;L;;;;;N;;;;;
+11A74;SOYOMBO LETTER MA;Lo;0;L;;;;;N;;;;;
+11A75;SOYOMBO LETTER TSA;Lo;0;L;;;;;N;;;;;
+11A76;SOYOMBO LETTER TSHA;Lo;0;L;;;;;N;;;;;
+11A77;SOYOMBO LETTER DZA;Lo;0;L;;;;;N;;;;;
+11A78;SOYOMBO LETTER ZHA;Lo;0;L;;;;;N;;;;;
+11A79;SOYOMBO LETTER ZA;Lo;0;L;;;;;N;;;;;
+11A7A;SOYOMBO LETTER -A;Lo;0;L;;;;;N;;;;;
+11A7B;SOYOMBO LETTER YA;Lo;0;L;;;;;N;;;;;
+11A7C;SOYOMBO LETTER RA;Lo;0;L;;;;;N;;;;;
+11A7D;SOYOMBO LETTER LA;Lo;0;L;;;;;N;;;;;
+11A7E;SOYOMBO LETTER VA;Lo;0;L;;;;;N;;;;;
+11A7F;SOYOMBO LETTER SHA;Lo;0;L;;;;;N;;;;;
+11A80;SOYOMBO LETTER SSA;Lo;0;L;;;;;N;;;;;
+11A81;SOYOMBO LETTER SA;Lo;0;L;;;;;N;;;;;
+11A82;SOYOMBO LETTER HA;Lo;0;L;;;;;N;;;;;
+11A83;SOYOMBO LETTER KSSA;Lo;0;L;;;;;N;;;;;
+11A86;SOYOMBO CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;;
+11A87;SOYOMBO CLUSTER-INITIAL LETTER LA;Lo;0;L;;;;;N;;;;;
+11A88;SOYOMBO CLUSTER-INITIAL LETTER SHA;Lo;0;L;;;;;N;;;;;
+11A89;SOYOMBO CLUSTER-INITIAL LETTER SA;Lo;0;L;;;;;N;;;;;
+11A8A;SOYOMBO FINAL CONSONANT SIGN G;Mn;0;NSM;;;;;N;;;;;
+11A8B;SOYOMBO FINAL CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;;
+11A8C;SOYOMBO FINAL CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;
+11A8D;SOYOMBO FINAL CONSONANT SIGN D;Mn;0;NSM;;;;;N;;;;;
+11A8E;SOYOMBO FINAL CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;
+11A8F;SOYOMBO FINAL CONSONANT SIGN B;Mn;0;NSM;;;;;N;;;;;
+11A90;SOYOMBO FINAL CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;;
+11A91;SOYOMBO FINAL CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;
+11A92;SOYOMBO FINAL CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;;
+11A93;SOYOMBO FINAL CONSONANT SIGN SH;Mn;0;NSM;;;;;N;;;;;
+11A94;SOYOMBO FINAL CONSONANT SIGN S;Mn;0;NSM;;;;;N;;;;;
+11A95;SOYOMBO FINAL CONSONANT SIGN -A;Mn;0;NSM;;;;;N;;;;;
+11A96;SOYOMBO SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11A97;SOYOMBO SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11A98;SOYOMBO GEMINATION MARK;Mn;0;NSM;;;;;N;;;;;
+11A99;SOYOMBO SUBJOINER;Mn;9;NSM;;;;;N;;;;;
+11A9A;SOYOMBO MARK TSHEG;Po;0;L;;;;;N;;;;;
+11A9B;SOYOMBO MARK SHAD;Po;0;L;;;;;N;;;;;
+11A9C;SOYOMBO MARK DOUBLE SHAD;Po;0;L;;;;;N;;;;;
+11A9E;SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME;Po;0;L;;;;;N;;;;;
+11A9F;SOYOMBO HEAD MARK WITH MOON AND SUN AND FLAME;Po;0;L;;;;;N;;;;;
+11AA0;SOYOMBO HEAD MARK WITH MOON AND SUN;Po;0;L;;;;;N;;;;;
+11AA1;SOYOMBO TERMINAL MARK-1;Po;0;L;;;;;N;;;;;
+11AA2;SOYOMBO TERMINAL MARK-2;Po;0;L;;;;;N;;;;;
 11AC0;PAU CIN HAU LETTER PA;Lo;0;L;;;;;N;;;;;
 11AC1;PAU CIN HAU LETTER KA;Lo;0;L;;;;;N;;;;;
 11AC2;PAU CIN HAU LETTER LA;Lo;0;L;;;;;N;;;;;
@@ -20290,6 +20481,81 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 11CB4;MARCHEN VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
 11CB5;MARCHEN SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
 11CB6;MARCHEN SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11D00;MASARAM GONDI LETTER A;Lo;0;L;;;;;N;;;;;
+11D01;MASARAM GONDI LETTER AA;Lo;0;L;;;;;N;;;;;
+11D02;MASARAM GONDI LETTER I;Lo;0;L;;;;;N;;;;;
+11D03;MASARAM GONDI LETTER II;Lo;0;L;;;;;N;;;;;
+11D04;MASARAM GONDI LETTER U;Lo;0;L;;;;;N;;;;;
+11D05;MASARAM GONDI LETTER UU;Lo;0;L;;;;;N;;;;;
+11D06;MASARAM GONDI LETTER E;Lo;0;L;;;;;N;;;;;
+11D08;MASARAM GONDI LETTER AI;Lo;0;L;;;;;N;;;;;
+11D09;MASARAM GONDI LETTER O;Lo;0;L;;;;;N;;;;;
+11D0B;MASARAM GONDI LETTER AU;Lo;0;L;;;;;N;;;;;
+11D0C;MASARAM GONDI LETTER KA;Lo;0;L;;;;;N;;;;;
+11D0D;MASARAM GONDI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11D0E;MASARAM GONDI LETTER GA;Lo;0;L;;;;;N;;;;;
+11D0F;MASARAM GONDI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11D10;MASARAM GONDI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11D11;MASARAM GONDI LETTER CA;Lo;0;L;;;;;N;;;;;
+11D12;MASARAM GONDI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11D13;MASARAM GONDI LETTER JA;Lo;0;L;;;;;N;;;;;
+11D14;MASARAM GONDI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11D15;MASARAM GONDI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11D16;MASARAM GONDI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11D17;MASARAM GONDI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11D18;MASARAM GONDI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11D19;MASARAM GONDI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11D1A;MASARAM GONDI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11D1B;MASARAM GONDI LETTER TA;Lo;0;L;;;;;N;;;;;
+11D1C;MASARAM GONDI LETTER THA;Lo;0;L;;;;;N;;;;;
+11D1D;MASARAM GONDI LETTER DA;Lo;0;L;;;;;N;;;;;
+11D1E;MASARAM GONDI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11D1F;MASARAM GONDI LETTER NA;Lo;0;L;;;;;N;;;;;
+11D20;MASARAM GONDI LETTER PA;Lo;0;L;;;;;N;;;;;
+11D21;MASARAM GONDI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11D22;MASARAM GONDI LETTER BA;Lo;0;L;;;;;N;;;;;
+11D23;MASARAM GONDI LETTER BHA;Lo;0;L;;;;;N;;;;;
+11D24;MASARAM GONDI LETTER MA;Lo;0;L;;;;;N;;;;;
+11D25;MASARAM GONDI LETTER YA;Lo;0;L;;;;;N;;;;;
+11D26;MASARAM GONDI LETTER RA;Lo;0;L;;;;;N;;;;;
+11D27;MASARAM GONDI LETTER LA;Lo;0;L;;;;;N;;;;;
+11D28;MASARAM GONDI LETTER VA;Lo;0;L;;;;;N;;;;;
+11D29;MASARAM GONDI LETTER SHA;Lo;0;L;;;;;N;;;;;
+11D2A;MASARAM GONDI LETTER SSA;Lo;0;L;;;;;N;;;;;
+11D2B;MASARAM GONDI LETTER SA;Lo;0;L;;;;;N;;;;;
+11D2C;MASARAM GONDI LETTER HA;Lo;0;L;;;;;N;;;;;
+11D2D;MASARAM GONDI LETTER LLA;Lo;0;L;;;;;N;;;;;
+11D2E;MASARAM GONDI LETTER KSSA;Lo;0;L;;;;;N;;;;;
+11D2F;MASARAM GONDI LETTER JNYA;Lo;0;L;;;;;N;;;;;
+11D30;MASARAM GONDI LETTER TRA;Lo;0;L;;;;;N;;;;;
+11D31;MASARAM GONDI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
+11D32;MASARAM GONDI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11D33;MASARAM GONDI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+11D34;MASARAM GONDI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11D35;MASARAM GONDI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+11D36;MASARAM GONDI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+11D3A;MASARAM GONDI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+11D3C;MASARAM GONDI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+11D3D;MASARAM GONDI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
+11D3F;MASARAM GONDI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
+11D40;MASARAM GONDI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11D41;MASARAM GONDI SIGN VISARGA;Mn;0;NSM;;;;;N;;;;;
+11D42;MASARAM GONDI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+11D43;MASARAM GONDI SIGN CANDRA;Mn;0;NSM;;;;;N;;;;;
+11D44;MASARAM GONDI SIGN HALANTA;Mn;9;NSM;;;;;N;;;;;
+11D45;MASARAM GONDI VIRAMA;Mn;9;NSM;;;;;N;;;;;
+11D46;MASARAM GONDI REPHA;Lo;0;L;;;;;N;;;;;
+11D47;MASARAM GONDI RA-KARA;Mn;0;NSM;;;;;N;;;;;
+11D50;MASARAM GONDI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11D51;MASARAM GONDI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11D52;MASARAM GONDI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11D53;MASARAM GONDI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11D54;MASARAM GONDI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11D55;MASARAM GONDI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11D56;MASARAM GONDI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11D57;MASARAM GONDI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11D58;MASARAM GONDI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11D59;MASARAM GONDI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
 12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;;
 12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;;
 12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;;
@@ -24087,6 +24353,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 16F9E;MIAO LETTER REFORMED TONE-6;Lm;0;L;;;;;N;;;;;
 16F9F;MIAO LETTER REFORMED TONE-8;Lm;0;L;;;;;N;;;;;
 16FE0;TANGUT ITERATION MARK;Lm;0;L;;;;;N;;;;;
+16FE1;NUSHU ITERATION MARK;Lm;0;L;;;;;N;;;;;
 17000;<Tangut Ideograph, First>;Lo;0;L;;;;;N;;;;;
 187EC;<Tangut Ideograph, Last>;Lo;0;L;;;;;N;;;;;
 18800;TANGUT COMPONENT-001;Lo;0;L;;;;;N;;;;;
@@ -24846,6 +25113,687 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 18AF2;TANGUT COMPONENT-755;Lo;0;L;;;;;N;;;;;
 1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;;
 1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
+1B002;HENTAIGANA LETTER A-1;Lo;0;L;;;;;N;;;;;
+1B003;HENTAIGANA LETTER A-2;Lo;0;L;;;;;N;;;;;
+1B004;HENTAIGANA LETTER A-3;Lo;0;L;;;;;N;;;;;
+1B005;HENTAIGANA LETTER A-WO;Lo;0;L;;;;;N;;;;;
+1B006;HENTAIGANA LETTER I-1;Lo;0;L;;;;;N;;;;;
+1B007;HENTAIGANA LETTER I-2;Lo;0;L;;;;;N;;;;;
+1B008;HENTAIGANA LETTER I-3;Lo;0;L;;;;;N;;;;;
+1B009;HENTAIGANA LETTER I-4;Lo;0;L;;;;;N;;;;;
+1B00A;HENTAIGANA LETTER U-1;Lo;0;L;;;;;N;;;;;
+1B00B;HENTAIGANA LETTER U-2;Lo;0;L;;;;;N;;;;;
+1B00C;HENTAIGANA LETTER U-3;Lo;0;L;;;;;N;;;;;
+1B00D;HENTAIGANA LETTER U-4;Lo;0;L;;;;;N;;;;;
+1B00E;HENTAIGANA LETTER U-5;Lo;0;L;;;;;N;;;;;
+1B00F;HENTAIGANA LETTER E-2;Lo;0;L;;;;;N;;;;;
+1B010;HENTAIGANA LETTER E-3;Lo;0;L;;;;;N;;;;;
+1B011;HENTAIGANA LETTER E-4;Lo;0;L;;;;;N;;;;;
+1B012;HENTAIGANA LETTER E-5;Lo;0;L;;;;;N;;;;;
+1B013;HENTAIGANA LETTER E-6;Lo;0;L;;;;;N;;;;;
+1B014;HENTAIGANA LETTER O-1;Lo;0;L;;;;;N;;;;;
+1B015;HENTAIGANA LETTER O-2;Lo;0;L;;;;;N;;;;;
+1B016;HENTAIGANA LETTER O-3;Lo;0;L;;;;;N;;;;;
+1B017;HENTAIGANA LETTER KA-1;Lo;0;L;;;;;N;;;;;
+1B018;HENTAIGANA LETTER KA-2;Lo;0;L;;;;;N;;;;;
+1B019;HENTAIGANA LETTER KA-3;Lo;0;L;;;;;N;;;;;
+1B01A;HENTAIGANA LETTER KA-4;Lo;0;L;;;;;N;;;;;
+1B01B;HENTAIGANA LETTER KA-5;Lo;0;L;;;;;N;;;;;
+1B01C;HENTAIGANA LETTER KA-6;Lo;0;L;;;;;N;;;;;
+1B01D;HENTAIGANA LETTER KA-7;Lo;0;L;;;;;N;;;;;
+1B01E;HENTAIGANA LETTER KA-8;Lo;0;L;;;;;N;;;;;
+1B01F;HENTAIGANA LETTER KA-9;Lo;0;L;;;;;N;;;;;
+1B020;HENTAIGANA LETTER KA-10;Lo;0;L;;;;;N;;;;;
+1B021;HENTAIGANA LETTER KA-11;Lo;0;L;;;;;N;;;;;
+1B022;HENTAIGANA LETTER KA-KE;Lo;0;L;;;;;N;;;;;
+1B023;HENTAIGANA LETTER KI-1;Lo;0;L;;;;;N;;;;;
+1B024;HENTAIGANA LETTER KI-2;Lo;0;L;;;;;N;;;;;
+1B025;HENTAIGANA LETTER KI-3;Lo;0;L;;;;;N;;;;;
+1B026;HENTAIGANA LETTER KI-4;Lo;0;L;;;;;N;;;;;
+1B027;HENTAIGANA LETTER KI-5;Lo;0;L;;;;;N;;;;;
+1B028;HENTAIGANA LETTER KI-6;Lo;0;L;;;;;N;;;;;
+1B029;HENTAIGANA LETTER KI-7;Lo;0;L;;;;;N;;;;;
+1B02A;HENTAIGANA LETTER KI-8;Lo;0;L;;;;;N;;;;;
+1B02B;HENTAIGANA LETTER KU-1;Lo;0;L;;;;;N;;;;;
+1B02C;HENTAIGANA LETTER KU-2;Lo;0;L;;;;;N;;;;;
+1B02D;HENTAIGANA LETTER KU-3;Lo;0;L;;;;;N;;;;;
+1B02E;HENTAIGANA LETTER KU-4;Lo;0;L;;;;;N;;;;;
+1B02F;HENTAIGANA LETTER KU-5;Lo;0;L;;;;;N;;;;;
+1B030;HENTAIGANA LETTER KU-6;Lo;0;L;;;;;N;;;;;
+1B031;HENTAIGANA LETTER KU-7;Lo;0;L;;;;;N;;;;;
+1B032;HENTAIGANA LETTER KE-1;Lo;0;L;;;;;N;;;;;
+1B033;HENTAIGANA LETTER KE-2;Lo;0;L;;;;;N;;;;;
+1B034;HENTAIGANA LETTER KE-3;Lo;0;L;;;;;N;;;;;
+1B035;HENTAIGANA LETTER KE-4;Lo;0;L;;;;;N;;;;;
+1B036;HENTAIGANA LETTER KE-5;Lo;0;L;;;;;N;;;;;
+1B037;HENTAIGANA LETTER KE-6;Lo;0;L;;;;;N;;;;;
+1B038;HENTAIGANA LETTER KO-1;Lo;0;L;;;;;N;;;;;
+1B039;HENTAIGANA LETTER KO-2;Lo;0;L;;;;;N;;;;;
+1B03A;HENTAIGANA LETTER KO-3;Lo;0;L;;;;;N;;;;;
+1B03B;HENTAIGANA LETTER KO-KI;Lo;0;L;;;;;N;;;;;
+1B03C;HENTAIGANA LETTER SA-1;Lo;0;L;;;;;N;;;;;
+1B03D;HENTAIGANA LETTER SA-2;Lo;0;L;;;;;N;;;;;
+1B03E;HENTAIGANA LETTER SA-3;Lo;0;L;;;;;N;;;;;
+1B03F;HENTAIGANA LETTER SA-4;Lo;0;L;;;;;N;;;;;
+1B040;HENTAIGANA LETTER SA-5;Lo;0;L;;;;;N;;;;;
+1B041;HENTAIGANA LETTER SA-6;Lo;0;L;;;;;N;;;;;
+1B042;HENTAIGANA LETTER SA-7;Lo;0;L;;;;;N;;;;;
+1B043;HENTAIGANA LETTER SA-8;Lo;0;L;;;;;N;;;;;
+1B044;HENTAIGANA LETTER SI-1;Lo;0;L;;;;;N;;;;;
+1B045;HENTAIGANA LETTER SI-2;Lo;0;L;;;;;N;;;;;
+1B046;HENTAIGANA LETTER SI-3;Lo;0;L;;;;;N;;;;;
+1B047;HENTAIGANA LETTER SI-4;Lo;0;L;;;;;N;;;;;
+1B048;HENTAIGANA LETTER SI-5;Lo;0;L;;;;;N;;;;;
+1B049;HENTAIGANA LETTER SI-6;Lo;0;L;;;;;N;;;;;
+1B04A;HENTAIGANA LETTER SU-1;Lo;0;L;;;;;N;;;;;
+1B04B;HENTAIGANA LETTER SU-2;Lo;0;L;;;;;N;;;;;
+1B04C;HENTAIGANA LETTER SU-3;Lo;0;L;;;;;N;;;;;
+1B04D;HENTAIGANA LETTER SU-4;Lo;0;L;;;;;N;;;;;
+1B04E;HENTAIGANA LETTER SU-5;Lo;0;L;;;;;N;;;;;
+1B04F;HENTAIGANA LETTER SU-6;Lo;0;L;;;;;N;;;;;
+1B050;HENTAIGANA LETTER SU-7;Lo;0;L;;;;;N;;;;;
+1B051;HENTAIGANA LETTER SU-8;Lo;0;L;;;;;N;;;;;
+1B052;HENTAIGANA LETTER SE-1;Lo;0;L;;;;;N;;;;;
+1B053;HENTAIGANA LETTER SE-2;Lo;0;L;;;;;N;;;;;
+1B054;HENTAIGANA LETTER SE-3;Lo;0;L;;;;;N;;;;;
+1B055;HENTAIGANA LETTER SE-4;Lo;0;L;;;;;N;;;;;
+1B056;HENTAIGANA LETTER SE-5;Lo;0;L;;;;;N;;;;;
+1B057;HENTAIGANA LETTER SO-1;Lo;0;L;;;;;N;;;;;
+1B058;HENTAIGANA LETTER SO-2;Lo;0;L;;;;;N;;;;;
+1B059;HENTAIGANA LETTER SO-3;Lo;0;L;;;;;N;;;;;
+1B05A;HENTAIGANA LETTER SO-4;Lo;0;L;;;;;N;;;;;
+1B05B;HENTAIGANA LETTER SO-5;Lo;0;L;;;;;N;;;;;
+1B05C;HENTAIGANA LETTER SO-6;Lo;0;L;;;;;N;;;;;
+1B05D;HENTAIGANA LETTER SO-7;Lo;0;L;;;;;N;;;;;
+1B05E;HENTAIGANA LETTER TA-1;Lo;0;L;;;;;N;;;;;
+1B05F;HENTAIGANA LETTER TA-2;Lo;0;L;;;;;N;;;;;
+1B060;HENTAIGANA LETTER TA-3;Lo;0;L;;;;;N;;;;;
+1B061;HENTAIGANA LETTER TA-4;Lo;0;L;;;;;N;;;;;
+1B062;HENTAIGANA LETTER TI-1;Lo;0;L;;;;;N;;;;;
+1B063;HENTAIGANA LETTER TI-2;Lo;0;L;;;;;N;;;;;
+1B064;HENTAIGANA LETTER TI-3;Lo;0;L;;;;;N;;;;;
+1B065;HENTAIGANA LETTER TI-4;Lo;0;L;;;;;N;;;;;
+1B066;HENTAIGANA LETTER TI-5;Lo;0;L;;;;;N;;;;;
+1B067;HENTAIGANA LETTER TI-6;Lo;0;L;;;;;N;;;;;
+1B068;HENTAIGANA LETTER TI-7;Lo;0;L;;;;;N;;;;;
+1B069;HENTAIGANA LETTER TU-1;Lo;0;L;;;;;N;;;;;
+1B06A;HENTAIGANA LETTER TU-2;Lo;0;L;;;;;N;;;;;
+1B06B;HENTAIGANA LETTER TU-3;Lo;0;L;;;;;N;;;;;
+1B06C;HENTAIGANA LETTER TU-4;Lo;0;L;;;;;N;;;;;
+1B06D;HENTAIGANA LETTER TU-TO;Lo;0;L;;;;;N;;;;;
+1B06E;HENTAIGANA LETTER TE-1;Lo;0;L;;;;;N;;;;;
+1B06F;HENTAIGANA LETTER TE-2;Lo;0;L;;;;;N;;;;;
+1B070;HENTAIGANA LETTER TE-3;Lo;0;L;;;;;N;;;;;
+1B071;HENTAIGANA LETTER TE-4;Lo;0;L;;;;;N;;;;;
+1B072;HENTAIGANA LETTER TE-5;Lo;0;L;;;;;N;;;;;
+1B073;HENTAIGANA LETTER TE-6;Lo;0;L;;;;;N;;;;;
+1B074;HENTAIGANA LETTER TE-7;Lo;0;L;;;;;N;;;;;
+1B075;HENTAIGANA LETTER TE-8;Lo;0;L;;;;;N;;;;;
+1B076;HENTAIGANA LETTER TE-9;Lo;0;L;;;;;N;;;;;
+1B077;HENTAIGANA LETTER TO-1;Lo;0;L;;;;;N;;;;;
+1B078;HENTAIGANA LETTER TO-2;Lo;0;L;;;;;N;;;;;
+1B079;HENTAIGANA LETTER TO-3;Lo;0;L;;;;;N;;;;;
+1B07A;HENTAIGANA LETTER TO-4;Lo;0;L;;;;;N;;;;;
+1B07B;HENTAIGANA LETTER TO-5;Lo;0;L;;;;;N;;;;;
+1B07C;HENTAIGANA LETTER TO-6;Lo;0;L;;;;;N;;;;;
+1B07D;HENTAIGANA LETTER TO-RA;Lo;0;L;;;;;N;;;;;
+1B07E;HENTAIGANA LETTER NA-1;Lo;0;L;;;;;N;;;;;
+1B07F;HENTAIGANA LETTER NA-2;Lo;0;L;;;;;N;;;;;
+1B080;HENTAIGANA LETTER NA-3;Lo;0;L;;;;;N;;;;;
+1B081;HENTAIGANA LETTER NA-4;Lo;0;L;;;;;N;;;;;
+1B082;HENTAIGANA LETTER NA-5;Lo;0;L;;;;;N;;;;;
+1B083;HENTAIGANA LETTER NA-6;Lo;0;L;;;;;N;;;;;
+1B084;HENTAIGANA LETTER NA-7;Lo;0;L;;;;;N;;;;;
+1B085;HENTAIGANA LETTER NA-8;Lo;0;L;;;;;N;;;;;
+1B086;HENTAIGANA LETTER NA-9;Lo;0;L;;;;;N;;;;;
+1B087;HENTAIGANA LETTER NI-1;Lo;0;L;;;;;N;;;;;
+1B088;HENTAIGANA LETTER NI-2;Lo;0;L;;;;;N;;;;;
+1B089;HENTAIGANA LETTER NI-3;Lo;0;L;;;;;N;;;;;
+1B08A;HENTAIGANA LETTER NI-4;Lo;0;L;;;;;N;;;;;
+1B08B;HENTAIGANA LETTER NI-5;Lo;0;L;;;;;N;;;;;
+1B08C;HENTAIGANA LETTER NI-6;Lo;0;L;;;;;N;;;;;
+1B08D;HENTAIGANA LETTER NI-7;Lo;0;L;;;;;N;;;;;
+1B08E;HENTAIGANA LETTER NI-TE;Lo;0;L;;;;;N;;;;;
+1B08F;HENTAIGANA LETTER NU-1;Lo;0;L;;;;;N;;;;;
+1B090;HENTAIGANA LETTER NU-2;Lo;0;L;;;;;N;;;;;
+1B091;HENTAIGANA LETTER NU-3;Lo;0;L;;;;;N;;;;;
+1B092;HENTAIGANA LETTER NE-1;Lo;0;L;;;;;N;;;;;
+1B093;HENTAIGANA LETTER NE-2;Lo;0;L;;;;;N;;;;;
+1B094;HENTAIGANA LETTER NE-3;Lo;0;L;;;;;N;;;;;
+1B095;HENTAIGANA LETTER NE-4;Lo;0;L;;;;;N;;;;;
+1B096;HENTAIGANA LETTER NE-5;Lo;0;L;;;;;N;;;;;
+1B097;HENTAIGANA LETTER NE-6;Lo;0;L;;;;;N;;;;;
+1B098;HENTAIGANA LETTER NE-KO;Lo;0;L;;;;;N;;;;;
+1B099;HENTAIGANA LETTER NO-1;Lo;0;L;;;;;N;;;;;
+1B09A;HENTAIGANA LETTER NO-2;Lo;0;L;;;;;N;;;;;
+1B09B;HENTAIGANA LETTER NO-3;Lo;0;L;;;;;N;;;;;
+1B09C;HENTAIGANA LETTER NO-4;Lo;0;L;;;;;N;;;;;
+1B09D;HENTAIGANA LETTER NO-5;Lo;0;L;;;;;N;;;;;
+1B09E;HENTAIGANA LETTER HA-1;Lo;0;L;;;;;N;;;;;
+1B09F;HENTAIGANA LETTER HA-2;Lo;0;L;;;;;N;;;;;
+1B0A0;HENTAIGANA LETTER HA-3;Lo;0;L;;;;;N;;;;;
+1B0A1;HENTAIGANA LETTER HA-4;Lo;0;L;;;;;N;;;;;
+1B0A2;HENTAIGANA LETTER HA-5;Lo;0;L;;;;;N;;;;;
+1B0A3;HENTAIGANA LETTER HA-6;Lo;0;L;;;;;N;;;;;
+1B0A4;HENTAIGANA LETTER HA-7;Lo;0;L;;;;;N;;;;;
+1B0A5;HENTAIGANA LETTER HA-8;Lo;0;L;;;;;N;;;;;
+1B0A6;HENTAIGANA LETTER HA-9;Lo;0;L;;;;;N;;;;;
+1B0A7;HENTAIGANA LETTER HA-10;Lo;0;L;;;;;N;;;;;
+1B0A8;HENTAIGANA LETTER HA-11;Lo;0;L;;;;;N;;;;;
+1B0A9;HENTAIGANA LETTER HI-1;Lo;0;L;;;;;N;;;;;
+1B0AA;HENTAIGANA LETTER HI-2;Lo;0;L;;;;;N;;;;;
+1B0AB;HENTAIGANA LETTER HI-3;Lo;0;L;;;;;N;;;;;
+1B0AC;HENTAIGANA LETTER HI-4;Lo;0;L;;;;;N;;;;;
+1B0AD;HENTAIGANA LETTER HI-5;Lo;0;L;;;;;N;;;;;
+1B0AE;HENTAIGANA LETTER HI-6;Lo;0;L;;;;;N;;;;;
+1B0AF;HENTAIGANA LETTER HI-7;Lo;0;L;;;;;N;;;;;
+1B0B0;HENTAIGANA LETTER HU-1;Lo;0;L;;;;;N;;;;;
+1B0B1;HENTAIGANA LETTER HU-2;Lo;0;L;;;;;N;;;;;
+1B0B2;HENTAIGANA LETTER HU-3;Lo;0;L;;;;;N;;;;;
+1B0B3;HENTAIGANA LETTER HE-1;Lo;0;L;;;;;N;;;;;
+1B0B4;HENTAIGANA LETTER HE-2;Lo;0;L;;;;;N;;;;;
+1B0B5;HENTAIGANA LETTER HE-3;Lo;0;L;;;;;N;;;;;
+1B0B6;HENTAIGANA LETTER HE-4;Lo;0;L;;;;;N;;;;;
+1B0B7;HENTAIGANA LETTER HE-5;Lo;0;L;;;;;N;;;;;
+1B0B8;HENTAIGANA LETTER HE-6;Lo;0;L;;;;;N;;;;;
+1B0B9;HENTAIGANA LETTER HE-7;Lo;0;L;;;;;N;;;;;
+1B0BA;HENTAIGANA LETTER HO-1;Lo;0;L;;;;;N;;;;;
+1B0BB;HENTAIGANA LETTER HO-2;Lo;0;L;;;;;N;;;;;
+1B0BC;HENTAIGANA LETTER HO-3;Lo;0;L;;;;;N;;;;;
+1B0BD;HENTAIGANA LETTER HO-4;Lo;0;L;;;;;N;;;;;
+1B0BE;HENTAIGANA LETTER HO-5;Lo;0;L;;;;;N;;;;;
+1B0BF;HENTAIGANA LETTER HO-6;Lo;0;L;;;;;N;;;;;
+1B0C0;HENTAIGANA LETTER HO-7;Lo;0;L;;;;;N;;;;;
+1B0C1;HENTAIGANA LETTER HO-8;Lo;0;L;;;;;N;;;;;
+1B0C2;HENTAIGANA LETTER MA-1;Lo;0;L;;;;;N;;;;;
+1B0C3;HENTAIGANA LETTER MA-2;Lo;0;L;;;;;N;;;;;
+1B0C4;HENTAIGANA LETTER MA-3;Lo;0;L;;;;;N;;;;;
+1B0C5;HENTAIGANA LETTER MA-4;Lo;0;L;;;;;N;;;;;
+1B0C6;HENTAIGANA LETTER MA-5;Lo;0;L;;;;;N;;;;;
+1B0C7;HENTAIGANA LETTER MA-6;Lo;0;L;;;;;N;;;;;
+1B0C8;HENTAIGANA LETTER MA-7;Lo;0;L;;;;;N;;;;;
+1B0C9;HENTAIGANA LETTER MI-1;Lo;0;L;;;;;N;;;;;
+1B0CA;HENTAIGANA LETTER MI-2;Lo;0;L;;;;;N;;;;;
+1B0CB;HENTAIGANA LETTER MI-3;Lo;0;L;;;;;N;;;;;
+1B0CC;HENTAIGANA LETTER MI-4;Lo;0;L;;;;;N;;;;;
+1B0CD;HENTAIGANA LETTER MI-5;Lo;0;L;;;;;N;;;;;
+1B0CE;HENTAIGANA LETTER MI-6;Lo;0;L;;;;;N;;;;;
+1B0CF;HENTAIGANA LETTER MI-7;Lo;0;L;;;;;N;;;;;
+1B0D0;HENTAIGANA LETTER MU-1;Lo;0;L;;;;;N;;;;;
+1B0D1;HENTAIGANA LETTER MU-2;Lo;0;L;;;;;N;;;;;
+1B0D2;HENTAIGANA LETTER MU-3;Lo;0;L;;;;;N;;;;;
+1B0D3;HENTAIGANA LETTER MU-4;Lo;0;L;;;;;N;;;;;
+1B0D4;HENTAIGANA LETTER ME-1;Lo;0;L;;;;;N;;;;;
+1B0D5;HENTAIGANA LETTER ME-2;Lo;0;L;;;;;N;;;;;
+1B0D6;HENTAIGANA LETTER ME-MA;Lo;0;L;;;;;N;;;;;
+1B0D7;HENTAIGANA LETTER MO-1;Lo;0;L;;;;;N;;;;;
+1B0D8;HENTAIGANA LETTER MO-2;Lo;0;L;;;;;N;;;;;
+1B0D9;HENTAIGANA LETTER MO-3;Lo;0;L;;;;;N;;;;;
+1B0DA;HENTAIGANA LETTER MO-4;Lo;0;L;;;;;N;;;;;
+1B0DB;HENTAIGANA LETTER MO-5;Lo;0;L;;;;;N;;;;;
+1B0DC;HENTAIGANA LETTER MO-6;Lo;0;L;;;;;N;;;;;
+1B0DD;HENTAIGANA LETTER YA-1;Lo;0;L;;;;;N;;;;;
+1B0DE;HENTAIGANA LETTER YA-2;Lo;0;L;;;;;N;;;;;
+1B0DF;HENTAIGANA LETTER YA-3;Lo;0;L;;;;;N;;;;;
+1B0E0;HENTAIGANA LETTER YA-4;Lo;0;L;;;;;N;;;;;
+1B0E1;HENTAIGANA LETTER YA-5;Lo;0;L;;;;;N;;;;;
+1B0E2;HENTAIGANA LETTER YA-YO;Lo;0;L;;;;;N;;;;;
+1B0E3;HENTAIGANA LETTER YU-1;Lo;0;L;;;;;N;;;;;
+1B0E4;HENTAIGANA LETTER YU-2;Lo;0;L;;;;;N;;;;;
+1B0E5;HENTAIGANA LETTER YU-3;Lo;0;L;;;;;N;;;;;
+1B0E6;HENTAIGANA LETTER YU-4;Lo;0;L;;;;;N;;;;;
+1B0E7;HENTAIGANA LETTER YO-1;Lo;0;L;;;;;N;;;;;
+1B0E8;HENTAIGANA LETTER YO-2;Lo;0;L;;;;;N;;;;;
+1B0E9;HENTAIGANA LETTER YO-3;Lo;0;L;;;;;N;;;;;
+1B0EA;HENTAIGANA LETTER YO-4;Lo;0;L;;;;;N;;;;;
+1B0EB;HENTAIGANA LETTER YO-5;Lo;0;L;;;;;N;;;;;
+1B0EC;HENTAIGANA LETTER YO-6;Lo;0;L;;;;;N;;;;;
+1B0ED;HENTAIGANA LETTER RA-1;Lo;0;L;;;;;N;;;;;
+1B0EE;HENTAIGANA LETTER RA-2;Lo;0;L;;;;;N;;;;;
+1B0EF;HENTAIGANA LETTER RA-3;Lo;0;L;;;;;N;;;;;
+1B0F0;HENTAIGANA LETTER RA-4;Lo;0;L;;;;;N;;;;;
+1B0F1;HENTAIGANA LETTER RI-1;Lo;0;L;;;;;N;;;;;
+1B0F2;HENTAIGANA LETTER RI-2;Lo;0;L;;;;;N;;;;;
+1B0F3;HENTAIGANA LETTER RI-3;Lo;0;L;;;;;N;;;;;
+1B0F4;HENTAIGANA LETTER RI-4;Lo;0;L;;;;;N;;;;;
+1B0F5;HENTAIGANA LETTER RI-5;Lo;0;L;;;;;N;;;;;
+1B0F6;HENTAIGANA LETTER RI-6;Lo;0;L;;;;;N;;;;;
+1B0F7;HENTAIGANA LETTER RI-7;Lo;0;L;;;;;N;;;;;
+1B0F8;HENTAIGANA LETTER RU-1;Lo;0;L;;;;;N;;;;;
+1B0F9;HENTAIGANA LETTER RU-2;Lo;0;L;;;;;N;;;;;
+1B0FA;HENTAIGANA LETTER RU-3;Lo;0;L;;;;;N;;;;;
+1B0FB;HENTAIGANA LETTER RU-4;Lo;0;L;;;;;N;;;;;
+1B0FC;HENTAIGANA LETTER RU-5;Lo;0;L;;;;;N;;;;;
+1B0FD;HENTAIGANA LETTER RU-6;Lo;0;L;;;;;N;;;;;
+1B0FE;HENTAIGANA LETTER RE-1;Lo;0;L;;;;;N;;;;;
+1B0FF;HENTAIGANA LETTER RE-2;Lo;0;L;;;;;N;;;;;
+1B100;HENTAIGANA LETTER RE-3;Lo;0;L;;;;;N;;;;;
+1B101;HENTAIGANA LETTER RE-4;Lo;0;L;;;;;N;;;;;
+1B102;HENTAIGANA LETTER RO-1;Lo;0;L;;;;;N;;;;;
+1B103;HENTAIGANA LETTER RO-2;Lo;0;L;;;;;N;;;;;
+1B104;HENTAIGANA LETTER RO-3;Lo;0;L;;;;;N;;;;;
+1B105;HENTAIGANA LETTER RO-4;Lo;0;L;;;;;N;;;;;
+1B106;HENTAIGANA LETTER RO-5;Lo;0;L;;;;;N;;;;;
+1B107;HENTAIGANA LETTER RO-6;Lo;0;L;;;;;N;;;;;
+1B108;HENTAIGANA LETTER WA-1;Lo;0;L;;;;;N;;;;;
+1B109;HENTAIGANA LETTER WA-2;Lo;0;L;;;;;N;;;;;
+1B10A;HENTAIGANA LETTER WA-3;Lo;0;L;;;;;N;;;;;
+1B10B;HENTAIGANA LETTER WA-4;Lo;0;L;;;;;N;;;;;
+1B10C;HENTAIGANA LETTER WA-5;Lo;0;L;;;;;N;;;;;
+1B10D;HENTAIGANA LETTER WI-1;Lo;0;L;;;;;N;;;;;
+1B10E;HENTAIGANA LETTER WI-2;Lo;0;L;;;;;N;;;;;
+1B10F;HENTAIGANA LETTER WI-3;Lo;0;L;;;;;N;;;;;
+1B110;HENTAIGANA LETTER WI-4;Lo;0;L;;;;;N;;;;;
+1B111;HENTAIGANA LETTER WI-5;Lo;0;L;;;;;N;;;;;
+1B112;HENTAIGANA LETTER WE-1;Lo;0;L;;;;;N;;;;;
+1B113;HENTAIGANA LETTER WE-2;Lo;0;L;;;;;N;;;;;
+1B114;HENTAIGANA LETTER WE-3;Lo;0;L;;;;;N;;;;;
+1B115;HENTAIGANA LETTER WE-4;Lo;0;L;;;;;N;;;;;
+1B116;HENTAIGANA LETTER WO-1;Lo;0;L;;;;;N;;;;;
+1B117;HENTAIGANA LETTER WO-2;Lo;0;L;;;;;N;;;;;
+1B118;HENTAIGANA LETTER WO-3;Lo;0;L;;;;;N;;;;;
+1B119;HENTAIGANA LETTER WO-4;Lo;0;L;;;;;N;;;;;
+1B11A;HENTAIGANA LETTER WO-5;Lo;0;L;;;;;N;;;;;
+1B11B;HENTAIGANA LETTER WO-6;Lo;0;L;;;;;N;;;;;
+1B11C;HENTAIGANA LETTER WO-7;Lo;0;L;;;;;N;;;;;
+1B11D;HENTAIGANA LETTER N-MU-MO-1;Lo;0;L;;;;;N;;;;;
+1B11E;HENTAIGANA LETTER N-MU-MO-2;Lo;0;L;;;;;N;;;;;
+1B170;NUSHU CHARACTER-1B170;Lo;0;L;;;;;N;;;;;
+1B171;NUSHU CHARACTER-1B171;Lo;0;L;;;;;N;;;;;
+1B172;NUSHU CHARACTER-1B172;Lo;0;L;;;;;N;;;;;
+1B173;NUSHU CHARACTER-1B173;Lo;0;L;;;;;N;;;;;
+1B174;NUSHU CHARACTER-1B174;Lo;0;L;;;;;N;;;;;
+1B175;NUSHU CHARACTER-1B175;Lo;0;L;;;;;N;;;;;
+1B176;NUSHU CHARACTER-1B176;Lo;0;L;;;;;N;;;;;
+1B177;NUSHU CHARACTER-1B177;Lo;0;L;;;;;N;;;;;
+1B178;NUSHU CHARACTER-1B178;Lo;0;L;;;;;N;;;;;
+1B179;NUSHU CHARACTER-1B179;Lo;0;L;;;;;N;;;;;
+1B17A;NUSHU CHARACTER-1B17A;Lo;0;L;;;;;N;;;;;
+1B17B;NUSHU CHARACTER-1B17B;Lo;0;L;;;;;N;;;;;
+1B17C;NUSHU CHARACTER-1B17C;Lo;0;L;;;;;N;;;;;
+1B17D;NUSHU CHARACTER-1B17D;Lo;0;L;;;;;N;;;;;
+1B17E;NUSHU CHARACTER-1B17E;Lo;0;L;;;;;N;;;;;
+1B17F;NUSHU CHARACTER-1B17F;Lo;0;L;;;;;N;;;;;
+1B180;NUSHU CHARACTER-1B180;Lo;0;L;;;;;N;;;;;
+1B181;NUSHU CHARACTER-1B181;Lo;0;L;;;;;N;;;;;
+1B182;NUSHU CHARACTER-1B182;Lo;0;L;;;;;N;;;;;
+1B183;NUSHU CHARACTER-1B183;Lo;0;L;;;;;N;;;;;
+1B184;NUSHU CHARACTER-1B184;Lo;0;L;;;;;N;;;;;
+1B185;NUSHU CHARACTER-1B185;Lo;0;L;;;;;N;;;;;
+1B186;NUSHU CHARACTER-1B186;Lo;0;L;;;;;N;;;;;
+1B187;NUSHU CHARACTER-1B187;Lo;0;L;;;;;N;;;;;
+1B188;NUSHU CHARACTER-1B188;Lo;0;L;;;;;N;;;;;
+1B189;NUSHU CHARACTER-1B189;Lo;0;L;;;;;N;;;;;
+1B18A;NUSHU CHARACTER-1B18A;Lo;0;L;;;;;N;;;;;
+1B18B;NUSHU CHARACTER-1B18B;Lo;0;L;;;;;N;;;;;
+1B18C;NUSHU CHARACTER-1B18C;Lo;0;L;;;;;N;;;;;
+1B18D;NUSHU CHARACTER-1B18D;Lo;0;L;;;;;N;;;;;
+1B18E;NUSHU CHARACTER-1B18E;Lo;0;L;;;;;N;;;;;
+1B18F;NUSHU CHARACTER-1B18F;Lo;0;L;;;;;N;;;;;
+1B190;NUSHU CHARACTER-1B190;Lo;0;L;;;;;N;;;;;
+1B191;NUSHU CHARACTER-1B191;Lo;0;L;;;;;N;;;;;
+1B192;NUSHU CHARACTER-1B192;Lo;0;L;;;;;N;;;;;
+1B193;NUSHU CHARACTER-1B193;Lo;0;L;;;;;N;;;;;
+1B194;NUSHU CHARACTER-1B194;Lo;0;L;;;;;N;;;;;
+1B195;NUSHU CHARACTER-1B195;Lo;0;L;;;;;N;;;;;
+1B196;NUSHU CHARACTER-1B196;Lo;0;L;;;;;N;;;;;
+1B197;NUSHU CHARACTER-1B197;Lo;0;L;;;;;N;;;;;
+1B198;NUSHU CHARACTER-1B198;Lo;0;L;;;;;N;;;;;
+1B199;NUSHU CHARACTER-1B199;Lo;0;L;;;;;N;;;;;
+1B19A;NUSHU CHARACTER-1B19A;Lo;0;L;;;;;N;;;;;
+1B19B;NUSHU CHARACTER-1B19B;Lo;0;L;;;;;N;;;;;
+1B19C;NUSHU CHARACTER-1B19C;Lo;0;L;;;;;N;;;;;
+1B19D;NUSHU CHARACTER-1B19D;Lo;0;L;;;;;N;;;;;
+1B19E;NUSHU CHARACTER-1B19E;Lo;0;L;;;;;N;;;;;
+1B19F;NUSHU CHARACTER-1B19F;Lo;0;L;;;;;N;;;;;
+1B1A0;NUSHU CHARACTER-1B1A0;Lo;0;L;;;;;N;;;;;
+1B1A1;NUSHU CHARACTER-1B1A1;Lo;0;L;;;;;N;;;;;
+1B1A2;NUSHU CHARACTER-1B1A2;Lo;0;L;;;;;N;;;;;
+1B1A3;NUSHU CHARACTER-1B1A3;Lo;0;L;;;;;N;;;;;
+1B1A4;NUSHU CHARACTER-1B1A4;Lo;0;L;;;;;N;;;;;
+1B1A5;NUSHU CHARACTER-1B1A5;Lo;0;L;;;;;N;;;;;
+1B1A6;NUSHU CHARACTER-1B1A6;Lo;0;L;;;;;N;;;;;
+1B1A7;NUSHU CHARACTER-1B1A7;Lo;0;L;;;;;N;;;;;
+1B1A8;NUSHU CHARACTER-1B1A8;Lo;0;L;;;;;N;;;;;
+1B1A9;NUSHU CHARACTER-1B1A9;Lo;0;L;;;;;N;;;;;
+1B1AA;NUSHU CHARACTER-1B1AA;Lo;0;L;;;;;N;;;;;
+1B1AB;NUSHU CHARACTER-1B1AB;Lo;0;L;;;;;N;;;;;
+1B1AC;NUSHU CHARACTER-1B1AC;Lo;0;L;;;;;N;;;;;
+1B1AD;NUSHU CHARACTER-1B1AD;Lo;0;L;;;;;N;;;;;
+1B1AE;NUSHU CHARACTER-1B1AE;Lo;0;L;;;;;N;;;;;
+1B1AF;NUSHU CHARACTER-1B1AF;Lo;0;L;;;;;N;;;;;
+1B1B0;NUSHU CHARACTER-1B1B0;Lo;0;L;;;;;N;;;;;
+1B1B1;NUSHU CHARACTER-1B1B1;Lo;0;L;;;;;N;;;;;
+1B1B2;NUSHU CHARACTER-1B1B2;Lo;0;L;;;;;N;;;;;
+1B1B3;NUSHU CHARACTER-1B1B3;Lo;0;L;;;;;N;;;;;
+1B1B4;NUSHU CHARACTER-1B1B4;Lo;0;L;;;;;N;;;;;
+1B1B5;NUSHU CHARACTER-1B1B5;Lo;0;L;;;;;N;;;;;
+1B1B6;NUSHU CHARACTER-1B1B6;Lo;0;L;;;;;N;;;;;
+1B1B7;NUSHU CHARACTER-1B1B7;Lo;0;L;;;;;N;;;;;
+1B1B8;NUSHU CHARACTER-1B1B8;Lo;0;L;;;;;N;;;;;
+1B1B9;NUSHU CHARACTER-1B1B9;Lo;0;L;;;;;N;;;;;
+1B1BA;NUSHU CHARACTER-1B1BA;Lo;0;L;;;;;N;;;;;
+1B1BB;NUSHU CHARACTER-1B1BB;Lo;0;L;;;;;N;;;;;
+1B1BC;NUSHU CHARACTER-1B1BC;Lo;0;L;;;;;N;;;;;
+1B1BD;NUSHU CHARACTER-1B1BD;Lo;0;L;;;;;N;;;;;
+1B1BE;NUSHU CHARACTER-1B1BE;Lo;0;L;;;;;N;;;;;
+1B1BF;NUSHU CHARACTER-1B1BF;Lo;0;L;;;;;N;;;;;
+1B1C0;NUSHU CHARACTER-1B1C0;Lo;0;L;;;;;N;;;;;
+1B1C1;NUSHU CHARACTER-1B1C1;Lo;0;L;;;;;N;;;;;
+1B1C2;NUSHU CHARACTER-1B1C2;Lo;0;L;;;;;N;;;;;
+1B1C3;NUSHU CHARACTER-1B1C3;Lo;0;L;;;;;N;;;;;
+1B1C4;NUSHU CHARACTER-1B1C4;Lo;0;L;;;;;N;;;;;
+1B1C5;NUSHU CHARACTER-1B1C5;Lo;0;L;;;;;N;;;;;
+1B1C6;NUSHU CHARACTER-1B1C6;Lo;0;L;;;;;N;;;;;
+1B1C7;NUSHU CHARACTER-1B1C7;Lo;0;L;;;;;N;;;;;
+1B1C8;NUSHU CHARACTER-1B1C8;Lo;0;L;;;;;N;;;;;
+1B1C9;NUSHU CHARACTER-1B1C9;Lo;0;L;;;;;N;;;;;
+1B1CA;NUSHU CHARACTER-1B1CA;Lo;0;L;;;;;N;;;;;
+1B1CB;NUSHU CHARACTER-1B1CB;Lo;0;L;;;;;N;;;;;
+1B1CC;NUSHU CHARACTER-1B1CC;Lo;0;L;;;;;N;;;;;
+1B1CD;NUSHU CHARACTER-1B1CD;Lo;0;L;;;;;N;;;;;
+1B1CE;NUSHU CHARACTER-1B1CE;Lo;0;L;;;;;N;;;;;
+1B1CF;NUSHU CHARACTER-1B1CF;Lo;0;L;;;;;N;;;;;
+1B1D0;NUSHU CHARACTER-1B1D0;Lo;0;L;;;;;N;;;;;
+1B1D1;NUSHU CHARACTER-1B1D1;Lo;0;L;;;;;N;;;;;
+1B1D2;NUSHU CHARACTER-1B1D2;Lo;0;L;;;;;N;;;;;
+1B1D3;NUSHU CHARACTER-1B1D3;Lo;0;L;;;;;N;;;;;
+1B1D4;NUSHU CHARACTER-1B1D4;Lo;0;L;;;;;N;;;;;
+1B1D5;NUSHU CHARACTER-1B1D5;Lo;0;L;;;;;N;;;;;
+1B1D6;NUSHU CHARACTER-1B1D6;Lo;0;L;;;;;N;;;;;
+1B1D7;NUSHU CHARACTER-1B1D7;Lo;0;L;;;;;N;;;;;
+1B1D8;NUSHU CHARACTER-1B1D8;Lo;0;L;;;;;N;;;;;
+1B1D9;NUSHU CHARACTER-1B1D9;Lo;0;L;;;;;N;;;;;
+1B1DA;NUSHU CHARACTER-1B1DA;Lo;0;L;;;;;N;;;;;
+1B1DB;NUSHU CHARACTER-1B1DB;Lo;0;L;;;;;N;;;;;
+1B1DC;NUSHU CHARACTER-1B1DC;Lo;0;L;;;;;N;;;;;
+1B1DD;NUSHU CHARACTER-1B1DD;Lo;0;L;;;;;N;;;;;
+1B1DE;NUSHU CHARACTER-1B1DE;Lo;0;L;;;;;N;;;;;
+1B1DF;NUSHU CHARACTER-1B1DF;Lo;0;L;;;;;N;;;;;
+1B1E0;NUSHU CHARACTER-1B1E0;Lo;0;L;;;;;N;;;;;
+1B1E1;NUSHU CHARACTER-1B1E1;Lo;0;L;;;;;N;;;;;
+1B1E2;NUSHU CHARACTER-1B1E2;Lo;0;L;;;;;N;;;;;
+1B1E3;NUSHU CHARACTER-1B1E3;Lo;0;L;;;;;N;;;;;
+1B1E4;NUSHU CHARACTER-1B1E4;Lo;0;L;;;;;N;;;;;
+1B1E5;NUSHU CHARACTER-1B1E5;Lo;0;L;;;;;N;;;;;
+1B1E6;NUSHU CHARACTER-1B1E6;Lo;0;L;;;;;N;;;;;
+1B1E7;NUSHU CHARACTER-1B1E7;Lo;0;L;;;;;N;;;;;
+1B1E8;NUSHU CHARACTER-1B1E8;Lo;0;L;;;;;N;;;;;
+1B1E9;NUSHU CHARACTER-1B1E9;Lo;0;L;;;;;N;;;;;
+1B1EA;NUSHU CHARACTER-1B1EA;Lo;0;L;;;;;N;;;;;
+1B1EB;NUSHU CHARACTER-1B1EB;Lo;0;L;;;;;N;;;;;
+1B1EC;NUSHU CHARACTER-1B1EC;Lo;0;L;;;;;N;;;;;
+1B1ED;NUSHU CHARACTER-1B1ED;Lo;0;L;;;;;N;;;;;
+1B1EE;NUSHU CHARACTER-1B1EE;Lo;0;L;;;;;N;;;;;
+1B1EF;NUSHU CHARACTER-1B1EF;Lo;0;L;;;;;N;;;;;
+1B1F0;NUSHU CHARACTER-1B1F0;Lo;0;L;;;;;N;;;;;
+1B1F1;NUSHU CHARACTER-1B1F1;Lo;0;L;;;;;N;;;;;
+1B1F2;NUSHU CHARACTER-1B1F2;Lo;0;L;;;;;N;;;;;
+1B1F3;NUSHU CHARACTER-1B1F3;Lo;0;L;;;;;N;;;;;
+1B1F4;NUSHU CHARACTER-1B1F4;Lo;0;L;;;;;N;;;;;
+1B1F5;NUSHU CHARACTER-1B1F5;Lo;0;L;;;;;N;;;;;
+1B1F6;NUSHU CHARACTER-1B1F6;Lo;0;L;;;;;N;;;;;
+1B1F7;NUSHU CHARACTER-1B1F7;Lo;0;L;;;;;N;;;;;
+1B1F8;NUSHU CHARACTER-1B1F8;Lo;0;L;;;;;N;;;;;
+1B1F9;NUSHU CHARACTER-1B1F9;Lo;0;L;;;;;N;;;;;
+1B1FA;NUSHU CHARACTER-1B1FA;Lo;0;L;;;;;N;;;;;
+1B1FB;NUSHU CHARACTER-1B1FB;Lo;0;L;;;;;N;;;;;
+1B1FC;NUSHU CHARACTER-1B1FC;Lo;0;L;;;;;N;;;;;
+1B1FD;NUSHU CHARACTER-1B1FD;Lo;0;L;;;;;N;;;;;
+1B1FE;NUSHU CHARACTER-1B1FE;Lo;0;L;;;;;N;;;;;
+1B1FF;NUSHU CHARACTER-1B1FF;Lo;0;L;;;;;N;;;;;
+1B200;NUSHU CHARACTER-1B200;Lo;0;L;;;;;N;;;;;
+1B201;NUSHU CHARACTER-1B201;Lo;0;L;;;;;N;;;;;
+1B202;NUSHU CHARACTER-1B202;Lo;0;L;;;;;N;;;;;
+1B203;NUSHU CHARACTER-1B203;Lo;0;L;;;;;N;;;;;
+1B204;NUSHU CHARACTER-1B204;Lo;0;L;;;;;N;;;;;
+1B205;NUSHU CHARACTER-1B205;Lo;0;L;;;;;N;;;;;
+1B206;NUSHU CHARACTER-1B206;Lo;0;L;;;;;N;;;;;
+1B207;NUSHU CHARACTER-1B207;Lo;0;L;;;;;N;;;;;
+1B208;NUSHU CHARACTER-1B208;Lo;0;L;;;;;N;;;;;
+1B209;NUSHU CHARACTER-1B209;Lo;0;L;;;;;N;;;;;
+1B20A;NUSHU CHARACTER-1B20A;Lo;0;L;;;;;N;;;;;
+1B20B;NUSHU CHARACTER-1B20B;Lo;0;L;;;;;N;;;;;
+1B20C;NUSHU CHARACTER-1B20C;Lo;0;L;;;;;N;;;;;
+1B20D;NUSHU CHARACTER-1B20D;Lo;0;L;;;;;N;;;;;
+1B20E;NUSHU CHARACTER-1B20E;Lo;0;L;;;;;N;;;;;
+1B20F;NUSHU CHARACTER-1B20F;Lo;0;L;;;;;N;;;;;
+1B210;NUSHU CHARACTER-1B210;Lo;0;L;;;;;N;;;;;
+1B211;NUSHU CHARACTER-1B211;Lo;0;L;;;;;N;;;;;
+1B212;NUSHU CHARACTER-1B212;Lo;0;L;;;;;N;;;;;
+1B213;NUSHU CHARACTER-1B213;Lo;0;L;;;;;N;;;;;
+1B214;NUSHU CHARACTER-1B214;Lo;0;L;;;;;N;;;;;
+1B215;NUSHU CHARACTER-1B215;Lo;0;L;;;;;N;;;;;
+1B216;NUSHU CHARACTER-1B216;Lo;0;L;;;;;N;;;;;
+1B217;NUSHU CHARACTER-1B217;Lo;0;L;;;;;N;;;;;
+1B218;NUSHU CHARACTER-1B218;Lo;0;L;;;;;N;;;;;
+1B219;NUSHU CHARACTER-1B219;Lo;0;L;;;;;N;;;;;
+1B21A;NUSHU CHARACTER-1B21A;Lo;0;L;;;;;N;;;;;
+1B21B;NUSHU CHARACTER-1B21B;Lo;0;L;;;;;N;;;;;
+1B21C;NUSHU CHARACTER-1B21C;Lo;0;L;;;;;N;;;;;
+1B21D;NUSHU CHARACTER-1B21D;Lo;0;L;;;;;N;;;;;
+1B21E;NUSHU CHARACTER-1B21E;Lo;0;L;;;;;N;;;;;
+1B21F;NUSHU CHARACTER-1B21F;Lo;0;L;;;;;N;;;;;
+1B220;NUSHU CHARACTER-1B220;Lo;0;L;;;;;N;;;;;
+1B221;NUSHU CHARACTER-1B221;Lo;0;L;;;;;N;;;;;
+1B222;NUSHU CHARACTER-1B222;Lo;0;L;;;;;N;;;;;
+1B223;NUSHU CHARACTER-1B223;Lo;0;L;;;;;N;;;;;
+1B224;NUSHU CHARACTER-1B224;Lo;0;L;;;;;N;;;;;
+1B225;NUSHU CHARACTER-1B225;Lo;0;L;;;;;N;;;;;
+1B226;NUSHU CHARACTER-1B226;Lo;0;L;;;;;N;;;;;
+1B227;NUSHU CHARACTER-1B227;Lo;0;L;;;;;N;;;;;
+1B228;NUSHU CHARACTER-1B228;Lo;0;L;;;;;N;;;;;
+1B229;NUSHU CHARACTER-1B229;Lo;0;L;;;;;N;;;;;
+1B22A;NUSHU CHARACTER-1B22A;Lo;0;L;;;;;N;;;;;
+1B22B;NUSHU CHARACTER-1B22B;Lo;0;L;;;;;N;;;;;
+1B22C;NUSHU CHARACTER-1B22C;Lo;0;L;;;;;N;;;;;
+1B22D;NUSHU CHARACTER-1B22D;Lo;0;L;;;;;N;;;;;
+1B22E;NUSHU CHARACTER-1B22E;Lo;0;L;;;;;N;;;;;
+1B22F;NUSHU CHARACTER-1B22F;Lo;0;L;;;;;N;;;;;
+1B230;NUSHU CHARACTER-1B230;Lo;0;L;;;;;N;;;;;
+1B231;NUSHU CHARACTER-1B231;Lo;0;L;;;;;N;;;;;
+1B232;NUSHU CHARACTER-1B232;Lo;0;L;;;;;N;;;;;
+1B233;NUSHU CHARACTER-1B233;Lo;0;L;;;;;N;;;;;
+1B234;NUSHU CHARACTER-1B234;Lo;0;L;;;;;N;;;;;
+1B235;NUSHU CHARACTER-1B235;Lo;0;L;;;;;N;;;;;
+1B236;NUSHU CHARACTER-1B236;Lo;0;L;;;;;N;;;;;
+1B237;NUSHU CHARACTER-1B237;Lo;0;L;;;;;N;;;;;
+1B238;NUSHU CHARACTER-1B238;Lo;0;L;;;;;N;;;;;
+1B239;NUSHU CHARACTER-1B239;Lo;0;L;;;;;N;;;;;
+1B23A;NUSHU CHARACTER-1B23A;Lo;0;L;;;;;N;;;;;
+1B23B;NUSHU CHARACTER-1B23B;Lo;0;L;;;;;N;;;;;
+1B23C;NUSHU CHARACTER-1B23C;Lo;0;L;;;;;N;;;;;
+1B23D;NUSHU CHARACTER-1B23D;Lo;0;L;;;;;N;;;;;
+1B23E;NUSHU CHARACTER-1B23E;Lo;0;L;;;;;N;;;;;
+1B23F;NUSHU CHARACTER-1B23F;Lo;0;L;;;;;N;;;;;
+1B240;NUSHU CHARACTER-1B240;Lo;0;L;;;;;N;;;;;
+1B241;NUSHU CHARACTER-1B241;Lo;0;L;;;;;N;;;;;
+1B242;NUSHU CHARACTER-1B242;Lo;0;L;;;;;N;;;;;
+1B243;NUSHU CHARACTER-1B243;Lo;0;L;;;;;N;;;;;
+1B244;NUSHU CHARACTER-1B244;Lo;0;L;;;;;N;;;;;
+1B245;NUSHU CHARACTER-1B245;Lo;0;L;;;;;N;;;;;
+1B246;NUSHU CHARACTER-1B246;Lo;0;L;;;;;N;;;;;
+1B247;NUSHU CHARACTER-1B247;Lo;0;L;;;;;N;;;;;
+1B248;NUSHU CHARACTER-1B248;Lo;0;L;;;;;N;;;;;
+1B249;NUSHU CHARACTER-1B249;Lo;0;L;;;;;N;;;;;
+1B24A;NUSHU CHARACTER-1B24A;Lo;0;L;;;;;N;;;;;
+1B24B;NUSHU CHARACTER-1B24B;Lo;0;L;;;;;N;;;;;
+1B24C;NUSHU CHARACTER-1B24C;Lo;0;L;;;;;N;;;;;
+1B24D;NUSHU CHARACTER-1B24D;Lo;0;L;;;;;N;;;;;
+1B24E;NUSHU CHARACTER-1B24E;Lo;0;L;;;;;N;;;;;
+1B24F;NUSHU CHARACTER-1B24F;Lo;0;L;;;;;N;;;;;
+1B250;NUSHU CHARACTER-1B250;Lo;0;L;;;;;N;;;;;
+1B251;NUSHU CHARACTER-1B251;Lo;0;L;;;;;N;;;;;
+1B252;NUSHU CHARACTER-1B252;Lo;0;L;;;;;N;;;;;
+1B253;NUSHU CHARACTER-1B253;Lo;0;L;;;;;N;;;;;
+1B254;NUSHU CHARACTER-1B254;Lo;0;L;;;;;N;;;;;
+1B255;NUSHU CHARACTER-1B255;Lo;0;L;;;;;N;;;;;
+1B256;NUSHU CHARACTER-1B256;Lo;0;L;;;;;N;;;;;
+1B257;NUSHU CHARACTER-1B257;Lo;0;L;;;;;N;;;;;
+1B258;NUSHU CHARACTER-1B258;Lo;0;L;;;;;N;;;;;
+1B259;NUSHU CHARACTER-1B259;Lo;0;L;;;;;N;;;;;
+1B25A;NUSHU CHARACTER-1B25A;Lo;0;L;;;;;N;;;;;
+1B25B;NUSHU CHARACTER-1B25B;Lo;0;L;;;;;N;;;;;
+1B25C;NUSHU CHARACTER-1B25C;Lo;0;L;;;;;N;;;;;
+1B25D;NUSHU CHARACTER-1B25D;Lo;0;L;;;;;N;;;;;
+1B25E;NUSHU CHARACTER-1B25E;Lo;0;L;;;;;N;;;;;
+1B25F;NUSHU CHARACTER-1B25F;Lo;0;L;;;;;N;;;;;
+1B260;NUSHU CHARACTER-1B260;Lo;0;L;;;;;N;;;;;
+1B261;NUSHU CHARACTER-1B261;Lo;0;L;;;;;N;;;;;
+1B262;NUSHU CHARACTER-1B262;Lo;0;L;;;;;N;;;;;
+1B263;NUSHU CHARACTER-1B263;Lo;0;L;;;;;N;;;;;
+1B264;NUSHU CHARACTER-1B264;Lo;0;L;;;;;N;;;;;
+1B265;NUSHU CHARACTER-1B265;Lo;0;L;;;;;N;;;;;
+1B266;NUSHU CHARACTER-1B266;Lo;0;L;;;;;N;;;;;
+1B267;NUSHU CHARACTER-1B267;Lo;0;L;;;;;N;;;;;
+1B268;NUSHU CHARACTER-1B268;Lo;0;L;;;;;N;;;;;
+1B269;NUSHU CHARACTER-1B269;Lo;0;L;;;;;N;;;;;
+1B26A;NUSHU CHARACTER-1B26A;Lo;0;L;;;;;N;;;;;
+1B26B;NUSHU CHARACTER-1B26B;Lo;0;L;;;;;N;;;;;
+1B26C;NUSHU CHARACTER-1B26C;Lo;0;L;;;;;N;;;;;
+1B26D;NUSHU CHARACTER-1B26D;Lo;0;L;;;;;N;;;;;
+1B26E;NUSHU CHARACTER-1B26E;Lo;0;L;;;;;N;;;;;
+1B26F;NUSHU CHARACTER-1B26F;Lo;0;L;;;;;N;;;;;
+1B270;NUSHU CHARACTER-1B270;Lo;0;L;;;;;N;;;;;
+1B271;NUSHU CHARACTER-1B271;Lo;0;L;;;;;N;;;;;
+1B272;NUSHU CHARACTER-1B272;Lo;0;L;;;;;N;;;;;
+1B273;NUSHU CHARACTER-1B273;Lo;0;L;;;;;N;;;;;
+1B274;NUSHU CHARACTER-1B274;Lo;0;L;;;;;N;;;;;
+1B275;NUSHU CHARACTER-1B275;Lo;0;L;;;;;N;;;;;
+1B276;NUSHU CHARACTER-1B276;Lo;0;L;;;;;N;;;;;
+1B277;NUSHU CHARACTER-1B277;Lo;0;L;;;;;N;;;;;
+1B278;NUSHU CHARACTER-1B278;Lo;0;L;;;;;N;;;;;
+1B279;NUSHU CHARACTER-1B279;Lo;0;L;;;;;N;;;;;
+1B27A;NUSHU CHARACTER-1B27A;Lo;0;L;;;;;N;;;;;
+1B27B;NUSHU CHARACTER-1B27B;Lo;0;L;;;;;N;;;;;
+1B27C;NUSHU CHARACTER-1B27C;Lo;0;L;;;;;N;;;;;
+1B27D;NUSHU CHARACTER-1B27D;Lo;0;L;;;;;N;;;;;
+1B27E;NUSHU CHARACTER-1B27E;Lo;0;L;;;;;N;;;;;
+1B27F;NUSHU CHARACTER-1B27F;Lo;0;L;;;;;N;;;;;
+1B280;NUSHU CHARACTER-1B280;Lo;0;L;;;;;N;;;;;
+1B281;NUSHU CHARACTER-1B281;Lo;0;L;;;;;N;;;;;
+1B282;NUSHU CHARACTER-1B282;Lo;0;L;;;;;N;;;;;
+1B283;NUSHU CHARACTER-1B283;Lo;0;L;;;;;N;;;;;
+1B284;NUSHU CHARACTER-1B284;Lo;0;L;;;;;N;;;;;
+1B285;NUSHU CHARACTER-1B285;Lo;0;L;;;;;N;;;;;
+1B286;NUSHU CHARACTER-1B286;Lo;0;L;;;;;N;;;;;
+1B287;NUSHU CHARACTER-1B287;Lo;0;L;;;;;N;;;;;
+1B288;NUSHU CHARACTER-1B288;Lo;0;L;;;;;N;;;;;
+1B289;NUSHU CHARACTER-1B289;Lo;0;L;;;;;N;;;;;
+1B28A;NUSHU CHARACTER-1B28A;Lo;0;L;;;;;N;;;;;
+1B28B;NUSHU CHARACTER-1B28B;Lo;0;L;;;;;N;;;;;
+1B28C;NUSHU CHARACTER-1B28C;Lo;0;L;;;;;N;;;;;
+1B28D;NUSHU CHARACTER-1B28D;Lo;0;L;;;;;N;;;;;
+1B28E;NUSHU CHARACTER-1B28E;Lo;0;L;;;;;N;;;;;
+1B28F;NUSHU CHARACTER-1B28F;Lo;0;L;;;;;N;;;;;
+1B290;NUSHU CHARACTER-1B290;Lo;0;L;;;;;N;;;;;
+1B291;NUSHU CHARACTER-1B291;Lo;0;L;;;;;N;;;;;
+1B292;NUSHU CHARACTER-1B292;Lo;0;L;;;;;N;;;;;
+1B293;NUSHU CHARACTER-1B293;Lo;0;L;;;;;N;;;;;
+1B294;NUSHU CHARACTER-1B294;Lo;0;L;;;;;N;;;;;
+1B295;NUSHU CHARACTER-1B295;Lo;0;L;;;;;N;;;;;
+1B296;NUSHU CHARACTER-1B296;Lo;0;L;;;;;N;;;;;
+1B297;NUSHU CHARACTER-1B297;Lo;0;L;;;;;N;;;;;
+1B298;NUSHU CHARACTER-1B298;Lo;0;L;;;;;N;;;;;
+1B299;NUSHU CHARACTER-1B299;Lo;0;L;;;;;N;;;;;
+1B29A;NUSHU CHARACTER-1B29A;Lo;0;L;;;;;N;;;;;
+1B29B;NUSHU CHARACTER-1B29B;Lo;0;L;;;;;N;;;;;
+1B29C;NUSHU CHARACTER-1B29C;Lo;0;L;;;;;N;;;;;
+1B29D;NUSHU CHARACTER-1B29D;Lo;0;L;;;;;N;;;;;
+1B29E;NUSHU CHARACTER-1B29E;Lo;0;L;;;;;N;;;;;
+1B29F;NUSHU CHARACTER-1B29F;Lo;0;L;;;;;N;;;;;
+1B2A0;NUSHU CHARACTER-1B2A0;Lo;0;L;;;;;N;;;;;
+1B2A1;NUSHU CHARACTER-1B2A1;Lo;0;L;;;;;N;;;;;
+1B2A2;NUSHU CHARACTER-1B2A2;Lo;0;L;;;;;N;;;;;
+1B2A3;NUSHU CHARACTER-1B2A3;Lo;0;L;;;;;N;;;;;
+1B2A4;NUSHU CHARACTER-1B2A4;Lo;0;L;;;;;N;;;;;
+1B2A5;NUSHU CHARACTER-1B2A5;Lo;0;L;;;;;N;;;;;
+1B2A6;NUSHU CHARACTER-1B2A6;Lo;0;L;;;;;N;;;;;
+1B2A7;NUSHU CHARACTER-1B2A7;Lo;0;L;;;;;N;;;;;
+1B2A8;NUSHU CHARACTER-1B2A8;Lo;0;L;;;;;N;;;;;
+1B2A9;NUSHU CHARACTER-1B2A9;Lo;0;L;;;;;N;;;;;
+1B2AA;NUSHU CHARACTER-1B2AA;Lo;0;L;;;;;N;;;;;
+1B2AB;NUSHU CHARACTER-1B2AB;Lo;0;L;;;;;N;;;;;
+1B2AC;NUSHU CHARACTER-1B2AC;Lo;0;L;;;;;N;;;;;
+1B2AD;NUSHU CHARACTER-1B2AD;Lo;0;L;;;;;N;;;;;
+1B2AE;NUSHU CHARACTER-1B2AE;Lo;0;L;;;;;N;;;;;
+1B2AF;NUSHU CHARACTER-1B2AF;Lo;0;L;;;;;N;;;;;
+1B2B0;NUSHU CHARACTER-1B2B0;Lo;0;L;;;;;N;;;;;
+1B2B1;NUSHU CHARACTER-1B2B1;Lo;0;L;;;;;N;;;;;
+1B2B2;NUSHU CHARACTER-1B2B2;Lo;0;L;;;;;N;;;;;
+1B2B3;NUSHU CHARACTER-1B2B3;Lo;0;L;;;;;N;;;;;
+1B2B4;NUSHU CHARACTER-1B2B4;Lo;0;L;;;;;N;;;;;
+1B2B5;NUSHU CHARACTER-1B2B5;Lo;0;L;;;;;N;;;;;
+1B2B6;NUSHU CHARACTER-1B2B6;Lo;0;L;;;;;N;;;;;
+1B2B7;NUSHU CHARACTER-1B2B7;Lo;0;L;;;;;N;;;;;
+1B2B8;NUSHU CHARACTER-1B2B8;Lo;0;L;;;;;N;;;;;
+1B2B9;NUSHU CHARACTER-1B2B9;Lo;0;L;;;;;N;;;;;
+1B2BA;NUSHU CHARACTER-1B2BA;Lo;0;L;;;;;N;;;;;
+1B2BB;NUSHU CHARACTER-1B2BB;Lo;0;L;;;;;N;;;;;
+1B2BC;NUSHU CHARACTER-1B2BC;Lo;0;L;;;;;N;;;;;
+1B2BD;NUSHU CHARACTER-1B2BD;Lo;0;L;;;;;N;;;;;
+1B2BE;NUSHU CHARACTER-1B2BE;Lo;0;L;;;;;N;;;;;
+1B2BF;NUSHU CHARACTER-1B2BF;Lo;0;L;;;;;N;;;;;
+1B2C0;NUSHU CHARACTER-1B2C0;Lo;0;L;;;;;N;;;;;
+1B2C1;NUSHU CHARACTER-1B2C1;Lo;0;L;;;;;N;;;;;
+1B2C2;NUSHU CHARACTER-1B2C2;Lo;0;L;;;;;N;;;;;
+1B2C3;NUSHU CHARACTER-1B2C3;Lo;0;L;;;;;N;;;;;
+1B2C4;NUSHU CHARACTER-1B2C4;Lo;0;L;;;;;N;;;;;
+1B2C5;NUSHU CHARACTER-1B2C5;Lo;0;L;;;;;N;;;;;
+1B2C6;NUSHU CHARACTER-1B2C6;Lo;0;L;;;;;N;;;;;
+1B2C7;NUSHU CHARACTER-1B2C7;Lo;0;L;;;;;N;;;;;
+1B2C8;NUSHU CHARACTER-1B2C8;Lo;0;L;;;;;N;;;;;
+1B2C9;NUSHU CHARACTER-1B2C9;Lo;0;L;;;;;N;;;;;
+1B2CA;NUSHU CHARACTER-1B2CA;Lo;0;L;;;;;N;;;;;
+1B2CB;NUSHU CHARACTER-1B2CB;Lo;0;L;;;;;N;;;;;
+1B2CC;NUSHU CHARACTER-1B2CC;Lo;0;L;;;;;N;;;;;
+1B2CD;NUSHU CHARACTER-1B2CD;Lo;0;L;;;;;N;;;;;
+1B2CE;NUSHU CHARACTER-1B2CE;Lo;0;L;;;;;N;;;;;
+1B2CF;NUSHU CHARACTER-1B2CF;Lo;0;L;;;;;N;;;;;
+1B2D0;NUSHU CHARACTER-1B2D0;Lo;0;L;;;;;N;;;;;
+1B2D1;NUSHU CHARACTER-1B2D1;Lo;0;L;;;;;N;;;;;
+1B2D2;NUSHU CHARACTER-1B2D2;Lo;0;L;;;;;N;;;;;
+1B2D3;NUSHU CHARACTER-1B2D3;Lo;0;L;;;;;N;;;;;
+1B2D4;NUSHU CHARACTER-1B2D4;Lo;0;L;;;;;N;;;;;
+1B2D5;NUSHU CHARACTER-1B2D5;Lo;0;L;;;;;N;;;;;
+1B2D6;NUSHU CHARACTER-1B2D6;Lo;0;L;;;;;N;;;;;
+1B2D7;NUSHU CHARACTER-1B2D7;Lo;0;L;;;;;N;;;;;
+1B2D8;NUSHU CHARACTER-1B2D8;Lo;0;L;;;;;N;;;;;
+1B2D9;NUSHU CHARACTER-1B2D9;Lo;0;L;;;;;N;;;;;
+1B2DA;NUSHU CHARACTER-1B2DA;Lo;0;L;;;;;N;;;;;
+1B2DB;NUSHU CHARACTER-1B2DB;Lo;0;L;;;;;N;;;;;
+1B2DC;NUSHU CHARACTER-1B2DC;Lo;0;L;;;;;N;;;;;
+1B2DD;NUSHU CHARACTER-1B2DD;Lo;0;L;;;;;N;;;;;
+1B2DE;NUSHU CHARACTER-1B2DE;Lo;0;L;;;;;N;;;;;
+1B2DF;NUSHU CHARACTER-1B2DF;Lo;0;L;;;;;N;;;;;
+1B2E0;NUSHU CHARACTER-1B2E0;Lo;0;L;;;;;N;;;;;
+1B2E1;NUSHU CHARACTER-1B2E1;Lo;0;L;;;;;N;;;;;
+1B2E2;NUSHU CHARACTER-1B2E2;Lo;0;L;;;;;N;;;;;
+1B2E3;NUSHU CHARACTER-1B2E3;Lo;0;L;;;;;N;;;;;
+1B2E4;NUSHU CHARACTER-1B2E4;Lo;0;L;;;;;N;;;;;
+1B2E5;NUSHU CHARACTER-1B2E5;Lo;0;L;;;;;N;;;;;
+1B2E6;NUSHU CHARACTER-1B2E6;Lo;0;L;;;;;N;;;;;
+1B2E7;NUSHU CHARACTER-1B2E7;Lo;0;L;;;;;N;;;;;
+1B2E8;NUSHU CHARACTER-1B2E8;Lo;0;L;;;;;N;;;;;
+1B2E9;NUSHU CHARACTER-1B2E9;Lo;0;L;;;;;N;;;;;
+1B2EA;NUSHU CHARACTER-1B2EA;Lo;0;L;;;;;N;;;;;
+1B2EB;NUSHU CHARACTER-1B2EB;Lo;0;L;;;;;N;;;;;
+1B2EC;NUSHU CHARACTER-1B2EC;Lo;0;L;;;;;N;;;;;
+1B2ED;NUSHU CHARACTER-1B2ED;Lo;0;L;;;;;N;;;;;
+1B2EE;NUSHU CHARACTER-1B2EE;Lo;0;L;;;;;N;;;;;
+1B2EF;NUSHU CHARACTER-1B2EF;Lo;0;L;;;;;N;;;;;
+1B2F0;NUSHU CHARACTER-1B2F0;Lo;0;L;;;;;N;;;;;
+1B2F1;NUSHU CHARACTER-1B2F1;Lo;0;L;;;;;N;;;;;
+1B2F2;NUSHU CHARACTER-1B2F2;Lo;0;L;;;;;N;;;;;
+1B2F3;NUSHU CHARACTER-1B2F3;Lo;0;L;;;;;N;;;;;
+1B2F4;NUSHU CHARACTER-1B2F4;Lo;0;L;;;;;N;;;;;
+1B2F5;NUSHU CHARACTER-1B2F5;Lo;0;L;;;;;N;;;;;
+1B2F6;NUSHU CHARACTER-1B2F6;Lo;0;L;;;;;N;;;;;
+1B2F7;NUSHU CHARACTER-1B2F7;Lo;0;L;;;;;N;;;;;
+1B2F8;NUSHU CHARACTER-1B2F8;Lo;0;L;;;;;N;;;;;
+1B2F9;NUSHU CHARACTER-1B2F9;Lo;0;L;;;;;N;;;;;
+1B2FA;NUSHU CHARACTER-1B2FA;Lo;0;L;;;;;N;;;;;
+1B2FB;NUSHU CHARACTER-1B2FB;Lo;0;L;;;;;N;;;;;
 1BC00;DUPLOYAN LETTER H;Lo;0;L;;;;;N;;;;;
 1BC01;DUPLOYAN LETTER X;Lo;0;L;;;;;N;;;;;
 1BC02;DUPLOYAN LETTER P;Lo;0;L;;;;;N;;;;;
@@ -28269,6 +29217,12 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F248;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557;So;0;L;<compat> 3014 
6557 3015;;;;N;;;;;
 1F250;CIRCLED IDEOGRAPH ADVANTAGE;So;0;L;<circle> 5F97;;;;N;;;;;
 1F251;CIRCLED IDEOGRAPH ACCEPT;So;0;L;<circle> 53EF;;;;N;;;;;
+1F260;ROUNDED SYMBOL FOR FU;So;0;ON;;;;;N;;;;;
+1F261;ROUNDED SYMBOL FOR LU;So;0;ON;;;;;N;;;;;
+1F262;ROUNDED SYMBOL FOR SHOU;So;0;ON;;;;;N;;;;;
+1F263;ROUNDED SYMBOL FOR XI;So;0;ON;;;;;N;;;;;
+1F264;ROUNDED SYMBOL FOR SHUANGXI;So;0;ON;;;;;N;;;;;
+1F265;ROUNDED SYMBOL FOR CAI;So;0;ON;;;;;N;;;;;
 1F300;CYCLONE;So;0;ON;;;;;N;;;;;
 1F301;FOGGY;So;0;ON;;;;;N;;;;;
 1F302;CLOSED UMBRELLA;So;0;ON;;;;;N;;;;;
@@ -29248,6 +30202,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F6D0;PLACE OF WORSHIP;So;0;ON;;;;;N;;;;;
 1F6D1;OCTAGONAL SIGN;So;0;ON;;;;;N;;;;;
 1F6D2;SHOPPING TROLLEY;So;0;ON;;;;;N;;;;;
+1F6D3;STUPA;So;0;ON;;;;;N;;;;;
+1F6D4;PAGODA;So;0;ON;;;;;N;;;;;
 1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;;
 1F6E1;SHIELD;So;0;ON;;;;;N;;;;;
 1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;;
@@ -29268,6 +30224,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F6F4;SCOOTER;So;0;ON;;;;;N;;;;;
 1F6F5;MOTOR SCOOTER;So;0;ON;;;;;N;;;;;
 1F6F6;CANOE;So;0;ON;;;;;N;;;;;
+1F6F7;SLED;So;0;ON;;;;;N;;;;;
+1F6F8;FLYING SAUCER;So;0;ON;;;;;N;;;;;
 1F700;ALCHEMICAL SYMBOL FOR QUINTESSENCE;So;0;ON;;;;;N;;;;;
 1F701;ALCHEMICAL SYMBOL FOR AIR;So;0;ON;;;;;N;;;;;
 1F702;ALCHEMICAL SYMBOL FOR FIRE;So;0;ON;;;;;N;;;;;
@@ -29617,6 +30575,18 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F8AB;RIGHTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;
 1F8AC;WHITE ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;;
 1F8AD;WHITE ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;;
+1F900;CIRCLED CROSS FORMEE WITH FOUR DOTS;So;0;ON;;;;;N;;;;;
+1F901;CIRCLED CROSS FORMEE WITH TWO DOTS;So;0;ON;;;;;N;;;;;
+1F902;CIRCLED CROSS FORMEE;So;0;ON;;;;;N;;;;;
+1F903;LEFT HALF CIRCLE WITH FOUR DOTS;So;0;ON;;;;;N;;;;;
+1F904;LEFT HALF CIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;;
+1F905;LEFT HALF CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;;
+1F906;LEFT HALF CIRCLE WITH DOT;So;0;ON;;;;;N;;;;;
+1F907;LEFT HALF CIRCLE;So;0;ON;;;;;N;;;;;
+1F908;DOWNWARD FACING HOOK;So;0;ON;;;;;N;;;;;
+1F909;DOWNWARD FACING NOTCHED HOOK;So;0;ON;;;;;N;;;;;
+1F90A;DOWNWARD FACING HOOK WITH DOT;So;0;ON;;;;;N;;;;;
+1F90B;DOWNWARD FACING NOTCHED HOOK WITH DOT;So;0;ON;;;;;N;;;;;
 1F910;ZIPPER-MOUTH FACE;So;0;ON;;;;;N;;;;;
 1F911;MONEY-MOUTH FACE;So;0;ON;;;;;N;;;;;
 1F912;FACE WITH THERMOMETER;So;0;ON;;;;;N;;;;;
@@ -29632,6 +30602,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F91C;RIGHT-FACING FIST;So;0;ON;;;;;N;;;;;
 1F91D;HANDSHAKE;So;0;ON;;;;;N;;;;;
 1F91E;HAND WITH INDEX AND MIDDLE FINGERS CROSSED;So;0;ON;;;;;N;;;;;
+1F91F;I LOVE YOU HAND SIGN;So;0;ON;;;;;N;;;;;
 1F920;FACE WITH COWBOY HAT;So;0;ON;;;;;N;;;;;
 1F921;CLOWN FACE;So;0;ON;;;;;N;;;;;
 1F922;NAUSEATED FACE;So;0;ON;;;;;N;;;;;
@@ -29640,7 +30611,17 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F925;LYING FACE;So;0;ON;;;;;N;;;;;
 1F926;FACE PALM;So;0;ON;;;;;N;;;;;
 1F927;SNEEZING FACE;So;0;ON;;;;;N;;;;;
+1F928;FACE WITH ONE EYEBROW RAISED;So;0;ON;;;;;N;;;;;
+1F929;GRINNING FACE WITH STAR EYES;So;0;ON;;;;;N;;;;;
+1F92A;GRINNING FACE WITH ONE LARGE AND ONE SMALL EYE;So;0;ON;;;;;N;;;;;
+1F92B;FACE WITH FINGER COVERING CLOSED LIPS;So;0;ON;;;;;N;;;;;
+1F92C;SERIOUS FACE WITH SYMBOLS COVERING MOUTH;So;0;ON;;;;;N;;;;;
+1F92D;SMILING FACE WITH SMILING EYES AND HAND COVERING MOUTH;So;0;ON;;;;;N;;;;;
+1F92E;FACE WITH OPEN MOUTH VOMITING;So;0;ON;;;;;N;;;;;
+1F92F;SHOCKED FACE WITH EXPLODING HEAD;So;0;ON;;;;;N;;;;;
 1F930;PREGNANT WOMAN;So;0;ON;;;;;N;;;;;
+1F931;BREAST-FEEDING;So;0;ON;;;;;N;;;;;
+1F932;PALMS UP TOGETHER;So;0;ON;;;;;N;;;;;
 1F933;SELFIE;So;0;ON;;;;;N;;;;;
 1F934;PRINCE;So;0;ON;;;;;N;;;;;
 1F935;MAN IN TUXEDO;So;0;ON;;;;;N;;;;;
@@ -29665,6 +30646,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F949;THIRD PLACE MEDAL;So;0;ON;;;;;N;;;;;
 1F94A;BOXING GLOVE;So;0;ON;;;;;N;;;;;
 1F94B;MARTIAL ARTS UNIFORM;So;0;ON;;;;;N;;;;;
+1F94C;CURLING STONE;So;0;ON;;;;;N;;;;;
 1F950;CROISSANT;So;0;ON;;;;;N;;;;;
 1F951;AVOCADO;So;0;ON;;;;;N;;;;;
 1F952;CUCUMBER;So;0;ON;;;;;N;;;;;
@@ -29680,6 +30662,19 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F95C;PEANUTS;So;0;ON;;;;;N;;;;;
 1F95D;KIWIFRUIT;So;0;ON;;;;;N;;;;;
 1F95E;PANCAKES;So;0;ON;;;;;N;;;;;
+1F95F;DUMPLING;So;0;ON;;;;;N;;;;;
+1F960;FORTUNE COOKIE;So;0;ON;;;;;N;;;;;
+1F961;TAKEOUT BOX;So;0;ON;;;;;N;;;;;
+1F962;CHOPSTICKS;So;0;ON;;;;;N;;;;;
+1F963;BOWL WITH SPOON;So;0;ON;;;;;N;;;;;
+1F964;CUP WITH STRAW;So;0;ON;;;;;N;;;;;
+1F965;COCONUT;So;0;ON;;;;;N;;;;;
+1F966;BROCCOLI;So;0;ON;;;;;N;;;;;
+1F967;PIE;So;0;ON;;;;;N;;;;;
+1F968;PRETZEL;So;0;ON;;;;;N;;;;;
+1F969;CUT OF MEAT;So;0;ON;;;;;N;;;;;
+1F96A;SANDWICH;So;0;ON;;;;;N;;;;;
+1F96B;CANNED FOOD;So;0;ON;;;;;N;;;;;
 1F980;CRAB;So;0;ON;;;;;N;;;;;
 1F981;LION FACE;So;0;ON;;;;;N;;;;;
 1F982;SCORPION;So;0;ON;;;;;N;;;;;
@@ -29698,7 +30693,36 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 1F98F;RHINOCEROS;So;0;ON;;;;;N;;;;;
 1F990;SHRIMP;So;0;ON;;;;;N;;;;;
 1F991;SQUID;So;0;ON;;;;;N;;;;;
+1F992;GIRAFFE FACE;So;0;ON;;;;;N;;;;;
+1F993;ZEBRA FACE;So;0;ON;;;;;N;;;;;
+1F994;HEDGEHOG;So;0;ON;;;;;N;;;;;
+1F995;SAUROPOD;So;0;ON;;;;;N;;;;;
+1F996;T-REX;So;0;ON;;;;;N;;;;;
+1F997;CRICKET;So;0;ON;;;;;N;;;;;
 1F9C0;CHEESE WEDGE;So;0;ON;;;;;N;;;;;
+1F9D0;FACE WITH MONOCLE;So;0;ON;;;;;N;;;;;
+1F9D1;ADULT;So;0;ON;;;;;N;;;;;
+1F9D2;CHILD;So;0;ON;;;;;N;;;;;
+1F9D3;OLDER ADULT;So;0;ON;;;;;N;;;;;
+1F9D4;BEARDED PERSON;So;0;ON;;;;;N;;;;;
+1F9D5;PERSON WITH HEADSCARF;So;0;ON;;;;;N;;;;;
+1F9D6;PERSON IN STEAMY ROOM;So;0;ON;;;;;N;;;;;
+1F9D7;PERSON CLIMBING;So;0;ON;;;;;N;;;;;
+1F9D8;PERSON IN LOTUS POSITION;So;0;ON;;;;;N;;;;;
+1F9D9;MAGE;So;0;ON;;;;;N;;;;;
+1F9DA;FAIRY;So;0;ON;;;;;N;;;;;
+1F9DB;VAMPIRE;So;0;ON;;;;;N;;;;;
+1F9DC;MERPERSON;So;0;ON;;;;;N;;;;;
+1F9DD;ELF;So;0;ON;;;;;N;;;;;
+1F9DE;GENIE;So;0;ON;;;;;N;;;;;
+1F9DF;ZOMBIE;So;0;ON;;;;;N;;;;;
+1F9E0;BRAIN;So;0;ON;;;;;N;;;;;
+1F9E1;ORANGE HEART;So;0;ON;;;;;N;;;;;
+1F9E2;BILLED CAP;So;0;ON;;;;;N;;;;;
+1F9E3;SCARF;So;0;ON;;;;;N;;;;;
+1F9E4;GLOVES;So;0;ON;;;;;N;;;;;
+1F9E5;COAT;So;0;ON;;;;;N;;;;;
+1F9E6;SOCKS;So;0;ON;;;;;N;;;;;
 20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;
 2A6D6;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
 2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;;
@@ -29707,6 +30731,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
 2B81D;<CJK Ideograph Extension D, Last>;Lo;0;L;;;;;N;;;;;
 2B820;<CJK Ideograph Extension E, First>;Lo;0;L;;;;;N;;;;;
 2CEA1;<CJK Ideograph Extension E, Last>;Lo;0;L;;;;;N;;;;;
+2CEB0;<CJK Ideograph Extension F, First>;Lo;0;L;;;;;N;;;;;
+2EBE0;<CJK Ideograph Extension F, Last>;Lo;0;L;;;;;N;;;;;
 2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;;
 2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;;
 2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;;
diff --git a/build-aux/config.guess b/build-aux/config.guess
index 2193702..07785f5 100755
--- a/build-aux/config.guess
+++ b/build-aux/config.guess
@@ -2,7 +2,7 @@
 # Attempt to guess a canonical system name.
 #   Copyright 1992-2017 Free Software Foundation, Inc.
 
-timestamp='2017-05-27'
+timestamp='2017-07-19'
 
 # 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
@@ -1429,8 +1429,8 @@ cat >&2 <<EOF
 $0: unable to guess system type
 
 This script (version $timestamp), has failed to recognize the
-operating system you are using. If your script is old, overwrite
-config.guess and config.sub with the latest versions from:
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
 
   http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 and
diff --git a/configure.ac b/configure.ac
index 980b4c6..e4647c6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -352,7 +352,8 @@ OPTION_DEFAULT_OFF([w32], [use native MS Windows GUI in a 
Cygwin build])
 
 OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux 
console])
 OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support])
-OPTION_DEFAULT_ON([gconf],[don't compile with GConf support])
+AC_ARG_WITH([gconf],[AS_HELP_STRING([--with-gconf],
+[compile with Gconf support (Gsettings replaces this)])],[],[with_gconf=maybe])
 OPTION_DEFAULT_ON([gsettings],[don't compile with GSettings support])
 OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support])
 OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support])
@@ -2506,7 +2507,8 @@ if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = 
"yes" || test "${HAVE_W32}"
   if test "${with_imagemagick}" != "no"; then
     ## 6.3.5 is the earliest version known to work; see Bug#17339.
     ## 6.8.2 makes Emacs crash; see Bug#13867.
-    IMAGEMAGICK_MODULE="Wand >= 6.3.5 Wand != 6.8.2"
+    ## 7 and later have not been ported to; See Bug#25967.
+    IMAGEMAGICK_MODULE="Wand >= 6.3.5 Wand != 6.8.2 Wand < 7"
     EMACS_CHECK_MODULES([IMAGEMAGICK], [$IMAGEMAGICK_MODULE])
 
     if test $HAVE_IMAGEMAGICK = yes; then
@@ -2775,6 +2777,7 @@ if test "${HAVE_X11}" = "yes" && test "${with_gsettings}" 
= "yes"; then
         AC_DEFINE(HAVE_GSETTINGS, 1, [Define to 1 if using GSettings.])
        SETTINGS_CFLAGS="$GSETTINGS_CFLAGS"
        SETTINGS_LIBS="$GSETTINGS_LIBS"
+       test "$with_gconf" = "yes" || with_gconf=no
       fi
       CFLAGS=$old_CFLAGS
       LIBS=$old_LIBS
@@ -2784,7 +2787,7 @@ fi
 dnl GConf has been tested under GNU/Linux only.
 dnl The version is really arbitrary, it is about the same age as Gtk+ 2.6.
 HAVE_GCONF=no
-if test "${HAVE_X11}" = "yes" && test "${with_gconf}" = "yes"; then
+if test "${HAVE_X11}" = "yes" && test "${with_gconf}" != "no"; then
    EMACS_CHECK_MODULES([GCONF], [gconf-2.0 >= 2.13])
    if test "$HAVE_GCONF" = yes; then
       AC_DEFINE(HAVE_GCONF, 1, [Define to 1 if using GConf.])
@@ -2831,6 +2834,87 @@ if test "${with_gnutls}" = "yes" ; then
     AC_DEFINE(HAVE_GNUTLS, 1, [Define if using GnuTLS.])
     EMACS_CHECK_MODULES([LIBGNUTLS3], [gnutls >= 3.0.0],
       [AC_DEFINE(HAVE_GNUTLS3, 1, [Define if using GnuTLS v3.])], [])
+
+    AC_CACHE_CHECK([for GnuTLS v3 with HMAC], [emacs_cv_gnutls3_hmac],
+      [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM([[
+             #include <gnutls/gnutls.h>
+             #include <gnutls/crypto.h>
+          ]], [[
+            int
+            main (void)
+            {
+              gnutls_hmac_hd_t handle;
+              gnutls_hmac_deinit (handle, NULL);
+            }
+          ]])],
+       [emacs_cv_gnutls3_hmac=yes],
+       [emacs_cv_gnutls3_hmac=no])])
+    if test "$emacs_cv_gnutls3_hmac" = yes; then
+      AC_DEFINE([HAVE_GNUTLS3_HMAC], [1],
+       [Define if using GnuTLS v3 with HMAC support.])
+    fi
+
+    AC_CACHE_CHECK([for GnuTLS v3 with AEAD], [emacs_cv_gnutls3_aead],
+      [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM([[
+             #include <gnutls/gnutls.h>
+             #include <gnutls/crypto.h>
+          ]], [[
+            int
+            main (void)
+            {
+              gnutls_aead_cipher_hd_t handle;
+              gnutls_aead_cipher_deinit (handle);
+            }
+          ]])],
+       [emacs_cv_gnutls3_aead=yes],
+       [emacs_cv_gnutls3_aead=no])])
+    if test "$emacs_cv_gnutls3_aead" = yes; then
+      AC_DEFINE([HAVE_GNUTLS3_AEAD], [1],
+       [Define if using GnuTLS v3 with AEAD support.])
+    fi
+
+    AC_CACHE_CHECK([for GnuTLS v3 with cipher], [emacs_cv_gnutls3_cipher],
+      [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM([[
+             #include <gnutls/gnutls.h>
+             #include <gnutls/crypto.h>
+          ]], [[
+            int
+            main (void)
+            {
+              gnutls_cipher_hd_t handle;
+              gnutls_cipher_encrypt2 (handle, NULL, 0, NULL, 0);
+              gnutls_cipher_deinit (handle);
+            }
+          ]])],
+       [emacs_cv_gnutls3_cipher=yes],
+       [emacs_cv_gnutls3_cipher=no])])
+    if test "$emacs_cv_gnutls3_cipher" = yes; then
+      AC_DEFINE([HAVE_GNUTLS3_CIPHER], [1],
+       [Define if using GnuTLS v3 with cipher support.])
+    fi
+
+    AC_CACHE_CHECK([for GnuTLS v3 with digest], [emacs_cv_gnutls3_digest],
+      [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM([[
+             #include <gnutls/gnutls.h>
+             #include <gnutls/crypto.h>
+          ]], [[
+            int
+            main (void)
+            {
+              gnutls_hash_hd_t handle;
+              gnutls_hash_deinit (handle, NULL);
+            }
+          ]])],
+       [emacs_cv_gnutls3_digest=yes],
+       [emacs_cv_gnutls3_digest=no])])
+    if test "$emacs_cv_gnutls3_digest" = yes; then
+      AC_DEFINE([HAVE_GNUTLS3_DIGEST], [1],
+       [Define if using GnuTLS v3 with digest support.])
+    fi
   fi
 
   # Windows loads GnuTLS dynamically
@@ -3476,27 +3560,22 @@ AC_SUBST(LIBZ)
 LIBMODULES=
 HAVE_MODULES=no
 MODULES_OBJ=
-MODULES_SUFFIX=
+case $opsys in
+  cygwin|mingw32) MODULES_SUFFIX=".dll" ;;
+  *) MODULES_SUFFIX=".so" ;;
+esac
 if test "${with_modules}" != "no"; then
   case $opsys in
     gnu|gnu-linux)
       LIBMODULES="-ldl"
-      MODULES_SUFFIX=".so"
-      HAVE_MODULES=yes
-      ;;
-    cygwin|mingw32)
-      MODULES_SUFFIX=".dll"
       HAVE_MODULES=yes
       ;;
-    darwin)
-      MODULES_SUFFIX=".so"
+    cygwin|mingw32|darwin)
       HAVE_MODULES=yes
       ;;
     *)
       # BSD systems have dlopen in libc.
-      AC_CHECK_FUNC([dlopen],
-        [MODULES_SUFFIX=".so"
-         HAVE_MODULES=yes])
+      AC_CHECK_FUNC([dlopen], [HAVE_MODULES=yes])
       ;;
   esac
 
@@ -5383,7 +5462,7 @@ AS_ECHO(["  Does Emacs use -lXaw3d?                       
          ${HAVE_XAW3D
   Does Emacs use a png library?                           ${HAVE_PNG} $LIBPNG
   Does Emacs use -lrsvg-2?                                ${HAVE_RSVG}
   Does Emacs use cairo?                                   ${HAVE_CAIRO}
-  Does Emacs use imagemagick?                             ${HAVE_IMAGEMAGICK}
+  Does Emacs use imagemagick (version 6)?                 ${HAVE_IMAGEMAGICK}
   Does Emacs support sound?                               ${HAVE_SOUND}
   Does Emacs use -lgpm?                                   ${HAVE_GPM}
   Does Emacs use -ldbus?                                  ${HAVE_DBUS}
diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi
index 6b66c18..5878e7d 100644
--- a/doc/emacs/basic.texi
+++ b/doc/emacs/basic.texi
@@ -630,7 +630,8 @@ Display the line number of point.
 @item M-x line-number-mode
 @itemx M-x column-number-mode
 Toggle automatic display of the current line number or column number.
address@hidden Mode Line}.
address@hidden Mode Line}.  If you want to have a line number
+displayed before each line, see @ref{Display Custom}.
 
 @item M-=
 Display the number of lines, words, and characters that are present in
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index c84f4a9..1c9c14a 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -1701,7 +1701,7 @@ and mouse events:
 (global-set-key (kbd "C-c y") 'clipboard-yank)
 (global-set-key (kbd "C-M-q") 'query-replace)
 (global-set-key (kbd "<f5>") 'flyspell-mode)
-(global-set-key (kbd "C-<f5>") 'linum-mode)
+(global-set-key (kbd "C-<f5>") 'display-line-numbers-mode)
 (global-set-key (kbd "C-<right>") 'forward-sentence)
 (global-set-key (kbd "<mouse-2>") 'mouse-save-then-kill)
 @end example
diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 28cb51d..ddd7229 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -1115,7 +1115,7 @@ parent directory.
 @findex dired-next-dirline
 @kindex > @r{(Dired)}
 @item >
-Move down to the next directory-file line (@code{dired-prev-dirline}).
+Move down to the next directory-file line (@code{dired-next-dirline}).
 @end table
 
 @node Hiding Subdirectories
diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index c4554eb..083fcdf 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -1333,7 +1333,7 @@ characters in the buffer, which means that @samp{k} for 
10^3, @samp{M}
 for 10^6, @samp{G} for 10^9, etc., are used to abbreviate.
 
 @cindex line number display
address@hidden display of line number
address@hidden display of current line number
 @findex line-number-mode
   The current line number of point appears in the mode line when Line
 Number mode is enabled.  Use the command @kbd{M-x line-number-mode} to
@@ -1710,6 +1710,66 @@ variable @code{visual-line-fringe-indicators}.
   This section describes variables that control miscellaneous aspects
 of the appearance of the Emacs screen.  Beginning users can skip it.
 
address@hidden display-line-numbers
address@hidden number lines in a buffer
address@hidden display line numbers
+  If you want to have Emacs display line numbers for every line in the
+buffer, customize the buffer-local variable
address@hidden; it is @code{nil} by default.  This
+variable can have several different values to support various modes of
+line-number display:
+
address@hidden @asis
address@hidden @code{t}
+Display (an absolute) line number before each non-continuation screen
+line that displays buffer text.  If the line is a continuation line,
+or if the entire screen line displays a display or an overlay string,
+that line will not be numbered.
+
address@hidden @code{relative}
+Display relative line numbers before non-continuation lines which show
+buffer text.  The line numbers are relative to the line showing point,
+so the numbers grow both up and down as lines become farther from the
+current line.
+
address@hidden @code{visual}
+This value causes Emacs to count lines visually: only lines actually
+shown on the display will be counted (disregarding any lines in
+invisible parts of text), and lines which wrap to consume more than
+one screen line will be numbered that many times.  The displayed
+numbers are relative, as with @code{relative} value above.  This is
+handy in modes that fold text, such as Outline mode (@pxref{Outline
+Mode}), and need to move by exact number of screen lines.
+
address@hidden anything else
+Any other address@hidden value is treated as @code{t}.
address@hidden table
+
address@hidden display-line-numbers-current-absolute
+When Emacs displays relative line numbers, you can control the number
+displayed before the current line, the line showing point.  By
+default, Emacs displays the absolute number of the current line there,
+even though all the other line numbers are relative.  If you customize
+the variable @code{display-line-numbers-current-absolute} to a
address@hidden value, the number displayed for the current line will be
+zero.  This is handy if you don't care about the number of the current
+line, and want to leave more horizontal space for text in large
+buffers.
+
address@hidden display-line-numbers-widen
+In a narrowed buffer (@pxref{Narrowing}) lines are normally numbered
+starting at the beginning of the narrowing.  However, if you customize
+the variable @code{display-line-numbers-widen} to a address@hidden
+value, line numbers will disregard any narrowing and will start at the
+first character of the buffer.
+
address@hidden line-number face
+The line numbers are displayed in a special face @code{line-number}.
+The current line number is displayed in a different face,
address@hidden, so you can make the current line's
+number have a distinct appearance, which will help locating the line
+showing point.
+
 @vindex visible-bell
   If the variable @code{visible-bell} is address@hidden, Emacs attempts
 to make the whole screen blink when it would normally make an audible bell
diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi
index 2ba3e26..f833f57 100644
--- a/doc/emacs/fixit.texi
+++ b/doc/emacs/fixit.texi
@@ -254,6 +254,7 @@ Restart the Aspell/Ispell/Hunspell process, using 
@var{dict} as the dictionary.
 Kill the Aspell/Ispell/Hunspell subprocess.
 @item address@hidden
 @itemx @key{ESC} @key{TAB}
address@hidden C-M-i
 Complete the word before point based on the spelling dictionary
 (@code{ispell-complete-word}).
 @item M-x flyspell-mode
diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi
index e3e59ad..ee33a68 100644
--- a/doc/emacs/frames.texi
+++ b/doc/emacs/frames.texi
@@ -575,7 +575,8 @@ font names in X resource files.
 If you are running Emacs on the GNOME desktop, you can tell Emacs to
 use the default system font by setting the variable
 @code{font-use-system-font} to @code{t} (the default is @code{nil}).
-For this to work, Emacs must have been compiled with Gconf support.
+For this to work, Emacs must have been compiled with support for
+Gsettings (or the older Gconf).
 
 @item
 Use the command line option @samp{-fn} (or @samp{--font}).  @xref{Font
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 80a4467..431ef35 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -56,6 +56,7 @@ versions of a source file, storing information such as the 
creation
 time of each version, who made it, and a description of what was
 changed.
 
address@hidden VC
   The Emacs version control interface is called @address@hidden  VC
 commands work with several different version control systems;
 currently, it supports Bazaar, CVS, Git, Mercurial, Monotone, RCS,
diff --git a/doc/emacs/modes.texi b/doc/emacs/modes.texi
index be89340..876431a 100644
--- a/doc/emacs/modes.texi
+++ b/doc/emacs/modes.texi
@@ -225,10 +225,12 @@ Font-Lock mode automatically highlights certain textual 
units found in
 programs.  It is enabled globally by default, but you can disable it
 in individual buffers.  @xref{Faces}.
 
address@hidden linum-mode
address@hidden Linum mode
address@hidden display-line-numbers-mode
address@hidden display-line-numbers-mode
 @item
-Linum mode displays each line's line number in the window's left margin.
+Display Line Numbers mode is a convenience wrapper around
address@hidden, setting it using the value of
address@hidden  @xref{Display Custom}.
 
 @item
 Outline minor mode provides similar facilities to the major mode
diff --git a/doc/emacs/mule.texi b/doc/emacs/mule.texi
index 8edf264..2f27b9a 100644
--- a/doc/emacs/mule.texi
+++ b/doc/emacs/mule.texi
@@ -1774,15 +1774,15 @@ Chars}).
 @cindex bidirectional editing
 @cindex right-to-left text
 
-  Emacs supports editing text written in scripts, such as Arabic and
-Hebrew, whose natural ordering of horizontal text for display is from
-right to left.  However, digits and Latin text embedded in these
-scripts are still displayed left to right.  It is also not uncommon to
-have small portions of text in Arabic or Hebrew embedded in an otherwise
-Latin document; e.g., as comments and strings in a program source
-file.  For these reasons, text that uses these scripts is actually
address@hidden: a mixture of runs of left-to-right and
-right-to-left characters.
+  Emacs supports editing text written in scripts, such as Arabic,
+Farsi, and Hebrew, whose natural ordering of horizontal text for
+display is from right to left.  However, digits and Latin text
+embedded in these scripts are still displayed left to right.  It is
+also not uncommon to have small portions of text in Arabic or Hebrew
+embedded in an otherwise Latin document; e.g., as comments and strings
+in a program source file.  For these reasons, text that uses these
+scripts is actually @dfn{bidirectional}: a mixture of runs of
+left-to-right and right-to-left characters.
 
   This section describes the facilities and options provided by Emacs
 for editing bidirectional text.
@@ -1811,15 +1811,21 @@ directionality when they are displayed.  The default 
value is
 
 @cindex base direction of paragraphs
 @cindex paragraph, base direction
address@hidden bidi-paragraph-start-re
address@hidden bidi-paragraph-separate-re
   Each paragraph of bidirectional text can have its own @dfn{base
-direction}, either right-to-left or left-to-right.  (Paragraph
address@hidden paragraph-separate etc have no influence on this?
-boundaries are empty lines, i.e., lines consisting entirely of
-whitespace characters.)  Text in left-to-right paragraphs begins on
-the screen at the left margin of the window and is truncated or
-continued when it reaches the right margin.  By contrast, text in
-right-to-left paragraphs is displayed starting at the right margin and
-is continued or truncated at the left margin.
+direction}, either right-to-left or left-to-right.  Text in
+left-to-right paragraphs begins on the screen at the left margin of
+the window and is truncated or continued when it reaches the right
+margin.  By contrast, text in right-to-left paragraphs is displayed
+starting at the right margin and is continued or truncated at the left
+margin.  By default, paragraph boundaries are empty lines, i.e., lines
+consisting entirely of whitespace characters.  To change that, you can
+customize the two variables @code{bidi-paragraph-start-re} and
address@hidden, whose values should be regular
+expressions (strings); e.g., to have a single newline start a new
+paragraph, set both of these variables to @code{"^"}.  These two
+variables are buffer-local (@pxref{Locals}).
 
 @vindex bidi-paragraph-direction
   Emacs determines the base direction of each paragraph dynamically,
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index 905df02..c9e83da 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -582,6 +582,8 @@ word search (@code{isearch-forward-word}).
 Search for @var{words}, using a forward nonincremental word search.
 @item M-s w C-r @key{RET} @var{words} @key{RET}
 Search backward for @var{words}, using a nonincremental word search.
address@hidden M-s M-w
+Search the Web for the text in region.
 @end table
 
 @kindex M-s w
@@ -617,12 +619,15 @@ toggling lax whitespace matching (@pxref{Lax Search, lax 
space
 matching}) has no effect on them.
 
 @kindex M-s M-w
address@hidden eww-search-word
address@hidden eww-search-words
 @vindex eww-search-prefix
-  Search the Web for the text in region.  This command performs an
-Internet search for the words in region using the search engine whose
address@hidden is specified by the variable @code{eww-search-prefix}.
address@hidden, EWW, , eww, The Emacs Web Wowser Manual}.
+  To search the Web for the text in region, type @kbd{M-s M-w}.  This
+command performs an Internet search for the words in region using the
+search engine whose @acronym{URL} is specified by the variable
address@hidden (@pxref{Basics, EWW, , eww, The Emacs Web
+Wowser Manual}).  If the region is not active, or doesn't contain any
+words, this command prompts the user for a URL or keywords to search.
+
 
 @node Symbol Search
 @section Symbol Search
diff --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi
index 7e27ddd..eaefcee 100644
--- a/doc/emacs/xresources.texi
+++ b/doc/emacs/xresources.texi
@@ -250,6 +250,11 @@ specified if @samp{off}.
 Gamma correction for colors, equivalent to the frame parameter
 @code{screen-gamma}.
 
address@hidden @code{scrollBar} (class @code{ScrollBar})
address@hidden tool bar
+If the value of this resource is @samp{off} or @samp{false} or
address@hidden, Emacs disables Scroll Bar mode at startup (@pxref{Scroll Bars}).
+
 @item @code{scrollBarWidth} (class @code{ScrollBarWidth})
 @cindex scrollbar width
 The scroll bar width in pixels, equivalent to the frame parameter
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 2ebe872..f5c73e5 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -2045,6 +2045,23 @@ selected window.  The value includes the line spacing of 
the line
 (@pxref{Line Height}).
 @end defun
 
+When a buffer is displayed with line numbers (@pxref{Display Custom,,,
+emacs, The GNU Emacs Manual}), it is sometimes useful to know the
+width taken for displaying the line numbers.  The following function
+is for Lisp programs which need this information for layout
+calculations.
+
address@hidden line-number-display-width &optional pixelwise
+This function returns the width used for displaying the line numbers
+in the selected window.  Optional argument @var{pixelwise}, if
address@hidden, means return the value in pixels; otherwise the value
+is returned in column units of the font defined for the
address@hidden face.  If line numbers are not displayed in the
+selected window, the value is zero.  Use @code{with-selected-window}
+(@pxref{Selecting Windows}) if you need this information about another
+window.
address@hidden defun
+
 
 @node Line Height
 @section Line Height
@@ -5288,6 +5305,17 @@ and if @code{:height} is set it will have precedence over
 wish.  @code{:max-width} and @code{:max-height} will always preserve
 the aspect ratio.
 
+If both @code{:width} and @code{:max-height} has been set (but
address@hidden:height} has not been set), then @code{:max-height} will have
+precedence.  The same is the case for the opposite combination: The
+``max'' keyword has precedence.  That is, if you have a 200x100 image
+and specify that @code{:width} should be 400 and @code{:max-height}
+should be 150, you'll end up with an image that is 300x150: Preserving
+the aspect ratio and not exceeding the ``max'' setting.  This
+combination of parameters is a useful way of saying ``display this
+image as large as possible, but no larger than the available display
+area''.
+
 @item :scale @var{scale}
 This should be a number, where values higher than 1 means to increase
 the size, and lower means to decrease the size.  For instance, a value
@@ -7428,6 +7456,35 @@ truncated or continued when the text reaches the right 
margin.
 Right-to-left paragraphs are displayed beginning at the right margin,
 and are continued or truncated at the left margin.
 
address@hidden paragraph-start, and bidirectional display
address@hidden paragraph-separate, and bidirectional display
+  Where exactly paragraphs start and end, for the purpose of the Emacs
address@hidden implementation, is determined by the following two
+buffer-local variables (note that that @code{paragraph-start} and
address@hidden have no influence on this).  By default both
+of these variables are @code{nil}, and paragraphs are bounded by empty
+lines, i.e., lines that consist entirely of zero or more whitespace
+characters followed by a newline.
+
address@hidden bidi-paragraph-start-re
+If address@hidden, this variable's value should be a regular
+expression matching a line that starts or separates two paragraphs.
+The regular expression is always matched after a newline, so it is
+best to anchor it, i.e., begin it with a @code{"^"}.
address@hidden defvar
+
address@hidden bidi-paragraph-separate-re
+If address@hidden, this variable's value should be a regular
+expression matching a line separates two paragraphs.  The regular
+expression is always matched after a newline, so it is best to anchor
+it, i.e., begin it with a @code{"^"}.
address@hidden defvar
+
+  If you modify any of these two variables, you should normally modify
+both, to make sure they describe paragraphs consistently.  For
+example, to have each new line start a new paragraph for
+bidi-reordering purposes, set both variables to @code{"^"}.
+
   By default, Emacs determines the base direction of each paragraph by
 looking at the text at its beginning.  The precise method of
 determining the base direction is specified by the @acronym{UBA}; in a
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 4bedea3..f30d9f9 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -1196,6 +1196,7 @@ Text
 * Decompression::           Dealing with compressed data.
 * Base 64::                 Conversion to or from base 64 encoding.
 * Checksum/Hash::           Computing cryptographic hashes.
+* GnuTLS Cryptography::     Cryptographic algorithms imported from GnuTLS.
 * Parsing HTML/XML::        Parsing HTML and XML.
 * Atomic Changes::          Installing several buffer changes atomically.
 * Change Hooks::            Supplying functions to be run when text is changed.
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index 8eab281..0c99380 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -1511,12 +1511,12 @@ respects.  A property list behaves like an association 
list in which
 each key can occur only once.  @xref{Property Lists}, for a comparison
 of property lists and association lists.
 
address@hidden assoc key alist
address@hidden assoc key alist &optional testfn
 This function returns the first association for @var{key} in
 @var{alist}, comparing @var{key} against the alist elements using
address@hidden (@pxref{Equality Predicates}).  It returns @code{nil} if no
-association in @var{alist} has a @sc{car} @code{equal} to @var{key}.
-For example:
address@hidden if non-nil, or @code{equal} if nil (@pxref{Equality
+Predicates}).  It returns @code{nil} if no association in @var{alist}
+has a @sc{car} equal to @var{key}.  For example:
 
 @smallexample
 (setq trees '((pine . cones) (oak . acorns) (maple . seeds)))
@@ -1561,11 +1561,11 @@ this as reverse @code{assoc}, finding the key for a 
given value.
 @defun assq key alist
 This function is like @code{assoc} in that it returns the first
 association for @var{key} in @var{alist}, but it makes the comparison
-using @code{eq} instead of @code{equal}.  @code{assq} returns @code{nil}
-if no association in @var{alist} has a @sc{car} @code{eq} to @var{key}.
-This function is used more often than @code{assoc}, since @code{eq} is
-faster than @code{equal} and most alists use symbols as keys.
address@hidden Predicates}.
+using @code{eq}.  @code{assq} returns @code{nil} if no association in
address@hidden has a @sc{car} @code{eq} to @var{key}.  This function is
+used more often than @code{assoc}, since @code{eq} is faster than
address@hidden and most alists use symbols as keys.  @xref{Equality
+Predicates}.
 
 @smallexample
 (setq trees '((pine . cones) (oak . acorns) (maple . seeds)))
@@ -1589,16 +1589,20 @@ keys may not be symbols:
 @end smallexample
 @end defun
 
address@hidden alist-get key alist &optional default remove
-This function is like @code{assq}, but instead of returning the entire
-association for @var{key} in @var{alist},
address@hidden@code{(@var{key} . @var{value})}}, it returns just the 
@var{value}.
-If @var{key} is not found in @var{alist}, it returns @var{default}.
-
-This is a generalized variable (@pxref{Generalized Variables}) that
-can be used to change a value with @code{setf}.  When using it to set
-a value, optional argument @var{remove} address@hidden means to remove
address@hidden from @var{alist} if the new value is @code{eql} to @var{default}.
address@hidden alist-get key alist &optional default remove testfn
+This function is similar to @code{assq}.  It finds the first
+association @address@hidden(@var{key} . @var{value})}} by comparing
address@hidden with @var{alist} elements, and, if found, returns the
address@hidden of that association.  If no association is found, the
+function returns @var{default}.  Comparison of @var{key} against
address@hidden elements uses the function specified by @var{testfn},
+defaulting to @code{eq}.
+
+This is a generalized variable (@pxref{Generalized Variables})
+that can be used to change a value with @code{setf}.  When
+using it to set a value, optional argument @var{remove} address@hidden
+means to remove @var{key}'s association from @var{alist} if the new
+value is @code{eql} to @var{default}.
 @end defun
 
 @defun rassq value alist
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index 9696c73..b825b1d 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -57,6 +57,7 @@ the character after point.
 * Decompression::    Dealing with compressed data.
 * Base 64::          Conversion to or from base 64 encoding.
 * Checksum/Hash::    Computing cryptographic hashes.
+* GnuTLS Cryptography:: Cryptographic algorithms imported from GnuTLS.
 * Parsing HTML/XML:: Parsing HTML and XML.
 * Atomic Changes::   Installing several buffer changes atomically.
 * Change Hooks::     Supplying functions to be run when text is changed.
@@ -4235,6 +4236,7 @@ A marker represents a buffer position to jump to.
 A string is text saved in the register.
 
 @item a rectangle
address@hidden rectangle, as contents of a register
 A rectangle is represented by a list of strings.
 
 @item @code{(@var{window-configuration} @var{position})}
@@ -4436,6 +4438,11 @@ similar theoretical weakness also exists in SHA-1.  
Therefore, for
 security-related applications you should use the other hash types,
 such as SHA-2.
 
address@hidden secure-hash-algorithms
+This function returns a list of symbols representing algorithms that
address@hidden can use.
address@hidden defun
+
 @defun secure-hash algorithm object &optional start end binary
 This function returns a hash for @var{object}.  The argument
 @var{algorithm} is a symbol stating which hash to compute: one of
@@ -4494,6 +4501,200 @@ It should be somewhat more efficient on larger buffers 
than
 @c according to what we find useful.
 @end defun
 
address@hidden GnuTLS Cryptography
address@hidden GnuTLS Cryptography
address@hidden MD5 checksum
address@hidden SHA hash
address@hidden hash, cryptographic
address@hidden cryptographic hash
address@hidden AEAD cipher
address@hidden cipher, AEAD
address@hidden symmetric cipher
address@hidden cipher, symmetric
+
+If compiled with GnuTLS, Emacs offers built-in cryptographic support.
+Following the GnuTLS API terminology, the available tools are digests,
+MACs, symmetric ciphers, and AEAD ciphers.
+
+The terms used herein, such as IV (Initialization Vector), require
+some familiarity with cryptography and will not be defined in detail.
+Please consult @uref{https://www.gnutls.org/} for specific
+documentation which may help you understand the terminology and
+structure of the GnuTLS library.
+
address@hidden
+* Format of GnuTLS Cryptography Inputs::
+* GnuTLS Cryptographic Functions::
address@hidden menu
+
address@hidden Format of GnuTLS Cryptography Inputs
address@hidden Format of GnuTLS Cryptography Inputs
address@hidden format of gnutls cryptography inputs
address@hidden gnutls cryptography inputs format
+
+The inputs to GnuTLS cryptographic functions can be specified in
+several ways, both as primitive Emacs Lisp types or as lists.
+
+The list form is currently similar to how @code{md5} and
address@hidden operate.
+
address@hidden @code
address@hidden @var{buffer}
+Simply passing a buffer as input means the whole buffer should be used.
+
address@hidden @var{string}
+A string as input will be used directly.  It may be modified by the
+function (unlike most other Emacs Lisp functions) to reduce the chance
+of exposing sensitive data after the function does its work.
+
address@hidden (@var{buffer-or-string} @var{start} @var{end} 
@var{coding-system} @var{noerror})
+This specifies a buffer or a string as described above, but an
+optional range can be specified with @var{start} and @var{end}.
+
+In addition an optional @var{coding-system} can be specified if needed.
+
+The last optional item, @var{noerror}, overrides the normal error when
+the text can't be encoded using the specified or chosen coding system.
+When @var{noerror} is address@hidden, this function silently uses
address@hidden coding instead.
+
address@hidden (@code{iv-auto} @var{length})
+This will generate an IV (Initialization Vector) of the specified
+length using the GnuTLS @code{GNUTLS_RND_NONCE} generator and pass it
+to the function.  This ensures that the IV is unpredictable and
+unlikely to be reused in the same session.  The actual value of the IV
+is returned by the function as described below.
+
address@hidden table
+
address@hidden GnuTLS Cryptographic Functions
address@hidden GnuTLS Cryptographic Functions
address@hidden gnutls cryptographic functions
+
address@hidden gnutls-digests
+This function returns the alist of the GnuTLS digest algorithms.
+
+Each entry has a key which represents the algorithm, followed by a
+plist with internal details about the algorithm.  The plist will have
address@hidden:type gnutls-digest-algorithm} and also will have the key
address@hidden:digest-algorithm-length 64} to indicate the size, in bytes, of
+the resulting digest.
+
+There is a name parallel between GnuTLS MAC and digest algorithms but
+they are separate things internally and should not be mixed.
address@hidden defun
+
address@hidden gnutls-hash-digest digest-method input
+The @var{digest-method} can be the whole plist from
address@hidden, or just the symbol key, or a string with the
+name of that symbol.
+
+The @var{input} can be specified as a buffer or string or in other
+ways (@pxref{Format of GnuTLS Cryptography Inputs}).
+
+This function returns @code{nil} on error, and signals a Lisp error if
+the @var{digest-method} or @var{input} are invalid.  On success, it
+returns a list of a binary string (the output) and the IV used.
address@hidden defun
+
address@hidden gnutls-macs
+This function returns the alist of the GnuTLS MAC algorithms.
+
+Each entry has a key which represents the algorithm, followed by a
+plist with internal details about the algorithm.  The plist will have
address@hidden:type gnutls-mac-algorithm} and also will have the keys
address@hidden:mac-algorithm-length} @code{:mac-algorithm-keysize}
address@hidden:mac-algorithm-noncesize} to indicate the size, in bytes, of the
+resulting hash, the key, and the nonce respectively.
+
+The nonce is currently unused and only some MACs support it.
+
+There is a name parallel between GnuTLS MAC and digest algorithms but
+they are separate things internally and should not be mixed.
address@hidden defun
+
address@hidden gnutls-hash-mac hash-method key input
+The @var{hash-method} can be the whole plist from
address@hidden, or just the symbol key, or a string with the
+name of that symbol.
+
+The @var{key} can be specified as a buffer or string or in other ways
+(@pxref{Format of GnuTLS Cryptography Inputs}).  The @var{key} will be
+wiped after use if it's a string.
+
+The @var{input} can be specified as a buffer or string or in other
+ways (@pxref{Format of GnuTLS Cryptography Inputs}).
+
+This function returns @code{nil} on error, and signals a Lisp error if
+the @var{hash-method} or @var{key} or @var{input} are invalid.
+
+On success, it returns a list of a binary string (the output) and the
+IV used.
address@hidden defun
+
address@hidden gnutls-ciphers
+This function returns the alist of the GnuTLS ciphers.
+
+Each entry has a key which represents the cipher, followed by a plist
+with internal details about the algorithm.  The plist will have
address@hidden:type gnutls-symmetric-cipher} and also will have the keys
address@hidden:cipher-aead-capable} set to @code{nil} or @code{t} to indicate
+AEAD capability; and @code{:cipher-tagsize} @code{:cipher-blocksize}
address@hidden:cipher-keysize} @code{:cipher-ivsize} to indicate the size, in
+bytes, of the tag, block size of the resulting data, the key, and the
+IV respectively.
address@hidden defun
+
address@hidden gnutls-symmetric-encrypt cipher key iv input &optional aead_auth
+The @var{cipher} can be the whole plist from
address@hidden, or just the symbol key, or a string with the
+name of that symbol.
+
+The @var{key} can be specified as a buffer or string or in other ways
+(@pxref{Format of GnuTLS Cryptography Inputs}).  The @var{key} will be
+wiped after use if it's a string.
+
+The @var{iv} and @var{input} and the optional @var{aead_auth} can be
+specified as a buffer or string or in other ways (@pxref{Format of
+GnuTLS Cryptography Inputs}).
+
address@hidden is only checked with AEAD ciphers, that is, ciphers whose
+plist has @code{:cipher-aead-capable t}.  Otherwise it's ignored.
+
+This function returns @code{nil} on error, and signals a Lisp error if
+the @var{cipher} or @var{key}, @var{iv}, or @var{input} are invalid,
+or if @var{aead_auth} was specified with an AEAD cipher and was
+invalid.
+
+On success, it returns a list of a binary string (the output) and the
+IV used.
address@hidden defun
+
address@hidden gnutls-symmetric-decrypt cipher key iv input &optional aead_auth
+The @var{cipher} can be the whole plist from
address@hidden, or just the symbol key, or a string with the
+name of that symbol.
+
+The @var{key} can be specified as a buffer or string or in other ways
+(@pxref{Format of GnuTLS Cryptography Inputs}).  The @var{key} will be
+wiped after use if it's a string.
+
+The @var{iv} and @var{input} and the optional @var{aead_auth} can be
+specified as a buffer or string or in other ways (@pxref{Format of
+GnuTLS Cryptography Inputs}).
+
address@hidden is only checked with AEAD ciphers, that is, ciphers whose
+plist has @code{:cipher-aead-capable t}.  Otherwise it's ignored.
+
+This function returns @code{nil} on decryption error, and signals a
+Lisp error if the @var{cipher} or @var{key}, @var{iv}, or @var{input}
+are invalid, or if @var{aead_auth} was specified with an AEAD cipher
+and was invalid.
+
+On success, it returns a list of a binary string (the output) and the
+IV used.
address@hidden defun
+
 @node Parsing HTML/XML
 @section Parsing HTML and XML
 @cindex parsing html
diff --git a/doc/misc/ses.texi b/doc/misc/ses.texi
index cac874d..fc79b02 100644
--- a/doc/misc/ses.texi
+++ b/doc/misc/ses.texi
@@ -292,7 +292,13 @@ Self-insert an expression.  The right-parenthesis is 
inserted for you
 (@code{ses-read-cell}).  To access another cell's value, just use its
 identifier in your expression.  Whenever the other cell is changed,
 this cell's formula will be reevaluated.  While typing in the
-expression, you can use @address@hidden to complete symbol names.
+expression, you can use the following keys:
address@hidden @kbd
address@hidden address@hidden
+to complete symbol names, and
address@hidden  C-h C-n
+to list the named cells symbols in a help buffer.
address@hidden table
 
 @item ' @r{(apostrophe)}
 Enter a symbol (ses-read-symbol).  @acronym{SES} remembers all symbols that 
have
@@ -458,11 +464,22 @@ Enter the default printer for the spreadsheet
 (@code{ses-read-default-printer}).
 @end table
 
-The @address@hidden commands have their own
-minibuffer history, which is preloaded with the set of all printers
-used in this spreadsheet, plus the standard printers (@pxref{Standard
-printer functions}) and the local printers (@pxref{Local printer
-functions}).
+The @address@hidden allows the following commands during editing:
+
address@hidden @kbd
address@hidden @key{arrow-up}
address@hidden @key{arrow-down}
+To browse history: the @address@hidden commands have
+their own minibuffer history, which is preloaded with the set of all
+printers used in this spreadsheet, plus the standard printers
+(@pxref{Standard printer functions}) and the local printers
+(@pxref{Local printer functions}).
address@hidden @key{TAB}
+To complete the local printer symbols, and
address@hidden C-h C-p
+To list the local printers in a help buffer.
address@hidden table
+
 
 @node Standard printer functions
 @subsection Standard printer functions
diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex
index b40a6e2..3844333 100644
--- a/doc/misc/texinfo.tex
+++ b/doc/misc/texinfo.tex
@@ -3,7 +3,7 @@
 % Load plain if necessary, i.e., if running under initex.
 \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
 %
-\def\texinfoversion{2017-06-04.19}
+\def\texinfoversion{2017-07-04.16}
 %
 % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
 % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
@@ -11009,7 +11009,6 @@ directory should work if nowhere else does.}
   \DeclareUnicodeCharacter{2113}{\ensuremath\ell}%
   \DeclareUnicodeCharacter{2118}{\ensuremath\wp}%
   \DeclareUnicodeCharacter{211C}{\ensuremath\Re}%
-  \DeclareUnicodeCharacter{2127}{\ensuremath\mho}%
   \DeclareUnicodeCharacter{2135}{\ensuremath\aleph}%
   \DeclareUnicodeCharacter{2190}{\ensuremath\leftarrow}%
   \DeclareUnicodeCharacter{2191}{\ensuremath\uparrow}%
@@ -11025,7 +11024,6 @@ directory should work if nowhere else does.}
   \DeclareUnicodeCharacter{21AA}{\ensuremath\hookrightarrow}%
   \DeclareUnicodeCharacter{21BC}{\ensuremath\leftharpoonup}%
   \DeclareUnicodeCharacter{21BD}{\ensuremath\leftharpoondown}%
-  \DeclareUnicodeCharacter{21BE}{\ensuremath\upharpoonright}%
   \DeclareUnicodeCharacter{21C0}{\ensuremath\rightharpoonup}%
   \DeclareUnicodeCharacter{21C1}{\ensuremath\rightharpoondown}%
   \DeclareUnicodeCharacter{21CC}{\ensuremath\rightleftharpoons}%
@@ -11034,8 +11032,6 @@ directory should work if nowhere else does.}
   \DeclareUnicodeCharacter{21D3}{\ensuremath\Downarrow}%
   \DeclareUnicodeCharacter{21D4}{\ensuremath\Leftrightarrow}%
   \DeclareUnicodeCharacter{21D5}{\ensuremath\Updownarrow}%
-  \DeclareUnicodeCharacter{21DD}{\ensuremath\leadsto}%
-  \DeclareUnicodeCharacter{2201}{\ensuremath\complement}%
   \DeclareUnicodeCharacter{2202}{\ensuremath\partial}%
   \DeclareUnicodeCharacter{2205}{\ensuremath\emptyset}%
   \DeclareUnicodeCharacter{2207}{\ensuremath\nabla}%
@@ -11069,8 +11065,6 @@ directory should work if nowhere else does.}
   \DeclareUnicodeCharacter{2283}{\ensuremath\supset}%
   \DeclareUnicodeCharacter{2286}{\ensuremath\subseteq}%
   \DeclareUnicodeCharacter{228E}{\ensuremath\uplus}%
-  \DeclareUnicodeCharacter{228F}{\ensuremath\sqsubset}%
-  \DeclareUnicodeCharacter{2290}{\ensuremath\sqsupset}%
   \DeclareUnicodeCharacter{2291}{\ensuremath\sqsubseteq}%
   \DeclareUnicodeCharacter{2292}{\ensuremath\sqsupseteq}%
   \DeclareUnicodeCharacter{2293}{\ensuremath\sqcap}%
@@ -11085,8 +11079,6 @@ directory should work if nowhere else does.}
   \DeclareUnicodeCharacter{22A4}{\ensuremath\ptextop}%
   \DeclareUnicodeCharacter{22A5}{\ensuremath\bot}%
   \DeclareUnicodeCharacter{22A8}{\ensuremath\models}%
-  \DeclareUnicodeCharacter{22B4}{\ensuremath\unlhd}%
-  \DeclareUnicodeCharacter{22B5}{\ensuremath\unrhd}%
   \DeclareUnicodeCharacter{22C0}{\ensuremath\bigwedge}%
   \DeclareUnicodeCharacter{22C1}{\ensuremath\bigvee}%
   \DeclareUnicodeCharacter{22C2}{\ensuremath\bigcap}%
@@ -11102,12 +11094,11 @@ directory should work if nowhere else does.}
   \DeclareUnicodeCharacter{2322}{\ensuremath\frown}%
   \DeclareUnicodeCharacter{2323}{\ensuremath\smile}%
   %
-  \DeclareUnicodeCharacter{25A1}{\ensuremath\Box}%
   \DeclareUnicodeCharacter{25B3}{\ensuremath\triangle}%
   \DeclareUnicodeCharacter{25B7}{\ensuremath\triangleright}%
   \DeclareUnicodeCharacter{25BD}{\ensuremath\bigtriangledown}%
   \DeclareUnicodeCharacter{25C1}{\ensuremath\triangleleft}%
-  \DeclareUnicodeCharacter{25C7}{\ensuremath\Diamond}%
+  \DeclareUnicodeCharacter{25C7}{\ensuremath\diamond}%
   \DeclareUnicodeCharacter{2660}{\ensuremath\spadesuit}%
   \DeclareUnicodeCharacter{2661}{\ensuremath\heartsuit}%
   \DeclareUnicodeCharacter{2662}{\ensuremath\diamondsuit}%
@@ -11129,7 +11120,6 @@ directory should work if nowhere else does.}
   \DeclareUnicodeCharacter{2A02}{\ensuremath\bigotimes}%
   \DeclareUnicodeCharacter{2A04}{\ensuremath\biguplus}%
   \DeclareUnicodeCharacter{2A06}{\ensuremath\bigsqcup}%
-  \DeclareUnicodeCharacter{2A1D}{\ensuremath\Join}%
   \DeclareUnicodeCharacter{2A3F}{\ensuremath\amalg}%
   \DeclareUnicodeCharacter{2AAF}{\ensuremath\preceq}%
   \DeclareUnicodeCharacter{2AB0}{\ensuremath\succeq}%
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index 6209e02..1b751a0 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -43,7 +43,7 @@ copy and modify this GNU manual.''
 @c Entries for @command{install-info} to use
 @dircategory Emacs network features
 @direntry
-* TRAMP: (tramp).               Transparent Remote Access, Multiple Protocol
+* @value{tramp}: (tramp).               Transparent Remote Access, Multiple 
Protocol
                                   Emacs remote file access via ssh and scp.
 @end direntry
 
@@ -77,8 +77,8 @@ You can find the latest version of this document on the web at
 @ifhtml
 The latest release of @value{tramp} is available for
 @uref{https://ftp.gnu.org/gnu/tramp/, download}, or you may see
address@hidden Tramp} for more details, including the Git server
-details.
address@hidden @value{tramp}} for more details, including the Git
+server details.
 
 @value{tramp} also has a @uref{https://savannah.gnu.org/projects/tramp/,
 Savannah Project Page}.
@@ -97,11 +97,12 @@ There is a mailing list for @value{tramp}, available at
 
 For the end user:
 
-* Obtaining Tramp::             How to obtain @value{tramp}.
+* Obtaining @value{tramp}::             How to obtain @value{tramp}.
 * History::                     History of @value{tramp}.
 @ifset installchapter
 * Installation::                Installing @value{tramp} with your Emacs.
 @end ifset
+* Quick Start Guide::           Short introduction how to use @value{tramp}.
 * Configuration::               Configuring @value{tramp} for use.
 * Usage::                       An overview of the operation of @value{tramp}.
 * Bug Reports::                 Reporting Bugs and Problems.
@@ -192,7 +193,7 @@ and related programs.  If these programs can successfully 
pass
 more secure alternative to @command{ftp} and other older access
 methods.
 
address@hidden on Windows operating systems is integrated with the
address@hidden on MS Windows operating systems is integrated with the
 PuTTY package, and uses the @command{plink} program.
 
 @value{tramp} mostly operates transparently in the background using
@@ -207,7 +208,7 @@ benefit of direct integration of @value{tramp} in Emacs.
 
 @value{tramp} can transfer files using any number of available host
 programs for remote files, such as @command{rcp}, @command{scp},
address@hidden or (under Windows) @command{pscp}.  @value{tramp}
address@hidden or (under MS Windows) @command{pscp}.  @value{tramp}
 provides easy ways to specify these programs and customize them to
 specific files, hosts, or access methods.
 
@@ -314,9 +315,9 @@ behind the scenes when you open a file with @value{tramp}.
 
 
 @c For the end user
address@hidden Obtaining Tramp
address@hidden Obtaining @value{tramp}
 @chapter Obtaining @value{tramp}
address@hidden obtaining Tramp
address@hidden obtaining @value{tramp}
 
 @value{tramp} is included as part of Emacs (since Emacs version 22.1).
 
@@ -354,7 +355,7 @@ From behind a firewall:
 @end example
 
 @noindent
-Tramp developers:
address@hidden developers:
 
 @example
 ] @strong{git clone login@@git.sv.gnu.org:/srv/git/tramp.git}
@@ -403,7 +404,7 @@ July 2002, @value{tramp} unified file names with Ange 
address@hidden  In July
 2004, proxy hosts replaced multi-hop methods.  Running commands on
 remote hosts was introduced in December 2005.  Support for gateways
 since April 2007 (and removed in December 2016).  GVFS integration
-started in February 2009.  Remote commands on Windows hosts since
+started in February 2009.  Remote commands on MS Windows hosts since
 September 2011.  Ad-hoc multi-hop methods (with a changed syntax)
 re-enabled in November 2011.  In November 2012, added Juergen
 Hoetzel's @file{tramp-adb.el}.
@@ -418,6 +419,147 @@ XEmacs support was stopped in January 2016.  Since March 
2017,
 @end ifset
 
 
address@hidden Quick Start Guide
address@hidden Short introduction how to use @value{tramp}
address@hidden quick start guide
+
address@hidden extends the Emacs file name syntax by a remote
+component.  A remote file name looks always like
address@hidden@trampfn{method,user@@host,/path/to/file}}.
+
+You can use remote files exactly like ordinary files, that means you
+could open a file or directory by @kbd{C-x C-f
address@hidden,user@@host,/path/to/file} @key{RET}}, edit the file,
+and save it.  You can also mix local files and remote files in file
+operations with two arguments, like @code{copy-file} or
address@hidden  And finally, you can run even processes on a
+remote host, when the buffer you call the process from has a remote
address@hidden
+
+
address@hidden Start Guide: File name syntax}
address@hidden File name syntax
address@hidden file name syntax
+
+Remote file names are prepended by the @code{method}, @code{user} and
address@hidden parts.  All of them, and also the local file name part,
+are optional, in case of a missing part a default value is assumed.
+The default value for an empty local file name part is the remote
+user's home directory.  The shortest remote file name is
address@hidden@trampfn{-,,}}, therefore.  The @samp{-} notation for the
+default host is used for syntactical reasons, @ref{Default Host}.
+
+The @code{method} part describes the connection method used to reach
+the remote host, see below.
+
+The @code{user} part is the user name for accessing the remote host.
+For the @option{smb} method, this could also require a domain name, in
+this case it is written as @code{user%domain}.
+
+The @code{host} part must be a host name which could be resolved on
+your local host.  It could be a short host name, a fully qualified
+domain name, an IPv4 or IPv6 address, @ref{File name syntax}.  Some
+connection methods support also a notation of the port to be used, in
+this case it is written as @code{host#port}.
+
+
address@hidden Start Guide: @option{ssh} and @option{plink} methods}
address@hidden Using @option{ssh} and @option{plink}
address@hidden method ssh
address@hidden ssh method
address@hidden method plink
address@hidden plink method
+
+If your local host runs an SSH client, and the remote host runs an SSH
+server, the most simple remote file name is
address@hidden@trampfn{ssh,user@@host,/path/to/file}}.  The remote file name
address@hidden@trampfn{ssh,,}} opens a remote connection to yourself on the
+local host, and is taken often for testing @value{tramp}.
+
+On MS Windows, PuTTY is often used as SSH client.  Its @command{plink}
+method can be used there to open a connection to a remote host running
+an @command{ssh} server:
address@hidden@trampfn{plink,user@@host,/path/to/file}}.
+
+
address@hidden Start Guide: @option{su}, @option{sudo} and @option{sg} methods}
address@hidden Using @option{su}, @option{sudo} and @option{sg}
address@hidden method su
address@hidden su method
address@hidden method sudo
address@hidden sudo method
address@hidden method sg
address@hidden sg method
+
+Sometimes, it is necessary to work on your local host under different
+permissions.  For this, you could use the @option{su} or @option{sudo}
+connection method.  Both methods use @samp{root} as default user name
+and the return value of @code{(system-name)} as default host name.
+Therefore, it is convenient to open a file as
address@hidden@trampfn{sudo,,/path/to/file}}.
+
+The method @option{sg} stands for ``switch group''; the changed group
+must be used here as user name.  The default host name is the same.
+
+
address@hidden Start Guide: @option{smb} method}
address@hidden Using @command{smbclient}
address@hidden method smb
address@hidden smb method
address@hidden ms windows (with smb method)
address@hidden smbclient
+
+In order to access a remote MS Windows host or Samba server, the
address@hidden client is used.  The remote file name syntax is
address@hidden@trampfn{smb,user%domain@@host,/path/to/file}}.  The first part
+of the local file name is the share exported by the remote host,
address@hidden in this example.
+
+
address@hidden Start Guide: GVFS-based methods}
address@hidden Using GVFS-based methods
address@hidden methods, gvfs
address@hidden gvfs based methods
address@hidden method sftp
address@hidden sftp method
address@hidden method afp
address@hidden afp method
address@hidden method dav
address@hidden method davs
address@hidden dav method
address@hidden davs method
+
+On systems, which have installed the virtual file system for the Gnome
+Desktop (GVFS), its offered methods could be used by @value{tramp}.
+Examples are @address@hidden,user@@host,/path/to/file}},
address@hidden@trampfn{afp,user@@host,/path/to/file}} (accessing Apple's AFP
+file system), @address@hidden,user@@host,/path/to/file}} and
address@hidden@trampfn{davs,user@@host,/path/to/file}} (for WebDAV shares).
+
+
address@hidden Start Guide: Google Drive}
address@hidden Using Google Drive
address@hidden method gdrive
address@hidden gdrive method
address@hidden google drive
+
+Another GVFS-based method allows to access a Google Drive file system.
+The file name syntax is here always
address@hidden@trampfn{gdrive,john.doe@@gmail.com,/path/to/file}}.
address@hidden@@gmail.com} stands here for your Google Drive account.
+
+
address@hidden Start Guide: Android}
address@hidden Using Android
address@hidden method adb
address@hidden adb method
address@hidden android
+
+An Android device, which is connected via USB to your local host, can
+be accessed via the @command{adb} command.  No user or host name is
+needed.  The file name syntax is @address@hidden,,/path/to/file}}.
+
+
 @node Configuration
 @chapter Configuring @value{tramp}
 @cindex configuration
@@ -610,16 +752,16 @@ continue connecting?''.  @value{tramp} cannot handle such 
questions.
 Connections will have to be setup where logins can proceed without
 such questions.
 
address@hidden is useful for Windows users when @command{ssh} triggers
-an error about allocating a pseudo tty.  This happens due to missing
-shell prompts that confuses @value{tramp}.
address@hidden is useful for MS Windows users when @command{ssh}
+triggers an error about allocating a pseudo tty.  This happens due to
+missing shell prompts that confuses @value{tramp}.
 
 @option{sshx} supports the @samp{-p} argument.
 
 @item @option{krlogin}
 @cindex method krlogin
 @cindex krlogin method
address@hidden Kerberos (with krlogin method)
address@hidden kerberos (with krlogin method)
 
 This method is also similar to @option{ssh}.  It uses the
 @command{krlogin -x} command only for remote host login.
@@ -627,7 +769,7 @@ This method is also similar to @option{ssh}.  It uses the
 @item @option{ksu}
 @cindex method ksu
 @cindex ksu method
address@hidden Kerberos (with ksu method)
address@hidden kerberos (with ksu method)
 
 This is another method from the Kerberos suite.  It behaves like @option{su}.
 
@@ -635,7 +777,7 @@ This is another method from the Kerberos suite.  It behaves 
like @option{su}.
 @cindex method plink
 @cindex plink method
 
address@hidden method is for Windows users with the PuTTY
address@hidden method is for MS Windows users with the PuTTY
 implementation of address@hidden  It uses @samp{plink -ssh} to log in to the
 remote host.
 
@@ -648,9 +790,9 @@ session.
 @cindex method plinkx
 @cindex plinkx method
 
-Another method using PuTTY on Windows with session names instead of
-host names.  @option{plinkx} calls @samp{plink -load @var{session} -t}.
-User names and port numbers must be defined in the session.
+Another method using PuTTY on MS Windows with session names instead of
+host names.  @option{plinkx} calls @samp{plink -load @var{session}
+-t}.  User names and port numbers must be defined in the session.
 
 Check the @samp{Share SSH connections if possible} control for that
 session.
@@ -730,9 +872,9 @@ This method supports the @samp{-p} argument.
 in performance to @option{scp}.  @option{scpx} uses @samp{ssh -t -t
 @var{host} -l @var{user} /bin/sh} to open a connection.
 
address@hidden is useful for Windows users when @command{ssh} triggers
-an error about allocating a pseudo tty.  This happens due to missing
-shell prompts that confuses @value{tramp}.
address@hidden is useful for MS Windows users when @command{ssh}
+triggers an error about allocating a pseudo tty.  This happens due to
+missing shell prompts that confuses @value{tramp}.
 
 This method supports the @samp{-p} argument.
 
@@ -742,17 +884,17 @@ This method supports the @samp{-p} argument.
 @cindex pscp method
 @cindex pscp (with pscp method)
 @cindex plink (with pscp method)
address@hidden PuTTY (with pscp method)
address@hidden putty (with pscp method)
 @cindex method psftp
 @cindex psftp method
 @cindex pscp (with psftp method)
 @cindex plink (with psftp method)
address@hidden PuTTY (with psftp method)
address@hidden putty (with psftp method)
 
 These methods are similar to @option{scp} or @option{sftp}, but they
 use the @command{plink} command to connect to the remote host, and
 they use @command{pscp} or @command{psftp} for transferring the files.
-These programs are part of PuTTY, an SSH implementation for Windows.
+These programs are part of PuTTY, an SSH implementation for MS Windows.
 
 Check the @samp{Share SSH connections if possible} control for that
 session.
@@ -805,6 +947,8 @@ capable of servicing requests from @value{tramp}.
 @item @option{smb}
 @cindex method smb
 @cindex smb method
address@hidden ms windows (with smb method)
address@hidden smbclient
 
 This non-native @value{tramp} method connects via the Server Message
 Block (SMB) networking protocol to hosts running file servers that are
@@ -831,15 +975,16 @@ handling}.
 
 To accommodate user name/domain name syntax required by MS Windows
 authorization, @value{tramp} provides for an extended syntax in
address@hidden format (where user is user name, @code{%} is the
-percent symbol, and domain is the windows domain name).  An example:
address@hidden format (where @code{user} is the user name,
address@hidden is the percent symbol, and @code{domain} is the MS Windows
+domain name).  An example:
 
 @example
 @trampfn{smb,daniel%BIZARRE@@melancholia,/daniel$$/.emacs}
 @end example
 
 where user @code{daniel} connects as a domain user to the SMB host
address@hidden in the windows domain @code{BIZARRE} to edit
address@hidden in the MS Windows domain @code{BIZARRE} to edit
 @file{.emacs} located in the home directory (share @code{daniel$}).
 
 Alternatively, for local WINS users (as opposed to domain users),
@@ -876,6 +1021,7 @@ can.
 @item @option{adb}
 @cindex method adb
 @cindex adb method
address@hidden android (with adb method)
 
 This method uses Android Debug Bridge program for accessing Android
 devices.  The Android Debug Bridge must be installed locally for
@@ -949,7 +1095,7 @@ but with SSL encryption.  Both methods support the port 
numbers.
 @item @option{gdrive}
 @cindex method gdrive
 @cindex gdrive method
address@hidden Google Drive
address@hidden google drive
 
 Via the @option{gdrive} method it is possible to access your Google
 Drive online storage.  User and host name of the remote file name are
@@ -981,8 +1127,8 @@ that for security reasons refuse @command{ssh} connections.
 @cindex method synce
 @cindex synce method
 
address@hidden method allows connecting to Windows Mobile devices.  It
-uses GVFS for mounting remote files and directories via FUSE and
address@hidden method allows connecting to MS Windows Mobile devices.
+It uses GVFS for mounting remote files and directories via FUSE and
 requires the SYNCE-GVFS plugin.
 
 @end table
@@ -1070,7 +1216,7 @@ access and it has the most reasonable security protocols, 
use
 @end example
 
 If @option{ssh} is unavailable for whatever reason, look for other
-obvious options.  For Windows, try the @option{plink} method.  For
+obvious options.  For MS Windows, try the @option{plink} method.  For
 Kerberos, try @option{krlogin}.
 
 For editing local files as @option{su} or @option{sudo} methods, try
@@ -1289,8 +1435,8 @@ restricted shell:
 
 @node Firewalls
 @section Passing firewalls
address@hidden HTTP tunnel
address@hidden proxy hosts, HTTP tunnel
address@hidden http tunnel
address@hidden proxy hosts, http tunnel
 
 Sometimes, it is not possible to reach a remote host directly.  A
 firewall might be in the way, which could be passed via a proxy
@@ -1746,8 +1892,8 @@ Similar localization may be necessary for handling wrong 
password
 prompts, for which @value{tramp} uses @option{tramp-wrong-passwd-regexp}.
 
 @item @command{tset} and other questions
address@hidden Unix command tset
address@hidden tset Unix command
address@hidden unix command tset
address@hidden tset unix command
 @vindex tramp-terminal-type
 
 To suppress inappropriate prompts for terminal type, @value{tramp}
@@ -1847,7 +1993,7 @@ Then re-set the prompt string in 
@file{~/.emacs_SHELLNAME} as follows:
 
 @example
 @group
-# Reset the prompt for remote Tramp shells.
+# Reset the prompt for remote @value{tramp} shells.
 if [ "address@hidden/*tramp*/address@hidden" == "tramp" ] ; then
    PS1="[\u@@\h \w]$ "
 fi
@@ -1859,8 +2005,8 @@ fi
 @end ifinfo
 
 @item @command{busybox} / @command{nc}
address@hidden Unix command nc
address@hidden nc Unix command
address@hidden unix command nc
address@hidden nc unix command
 
 @value{tramp}'s @option{nc} method uses the @command{nc} command to
 install and execute a listener as follows (see @code{tramp-methods}):
@@ -1891,7 +2037,7 @@ where @samp{192.168.0.1} is the remote host IP address
 
 @node Android shell setup
 @section Android shell setup hints
address@hidden android shell setup
address@hidden android shell setup for ssh
 
 @value{tramp} uses the @option{adb} method to access Android devices.
 Android devices provide a restricted shell access through an USB
@@ -2072,12 +2218,12 @@ to direct all auto saves to that location.
 
 @node Windows setup hints
 @section Issues with Cygwin ssh
address@hidden Cygwin, issues
address@hidden cygwin, issues
 
 This section is incomplete.  Please share your solutions.
 
address@hidden method sshx with Cygwin
address@hidden sshx method with Cygwin
address@hidden method sshx with cygwin
address@hidden sshx method with cygwin
 
 Cygwin's @command{ssh} works only with a Cygwin version of Emacs.  To
 check for compatibility: type @kbd{M-x eshell}, and start @kbd{ssh
@@ -2091,34 +2237,34 @@ Some older versions of Cygwin's @command{ssh} work with 
the
 @option{sshx} access method.  Consult Cygwin's FAQ at
 @uref{https://cygwin.com/faq/} for details.
 
address@hidden Cygwin and fakecygpty
address@hidden fakecygpty and Cygwin
address@hidden cygwin and fakecygpty
address@hidden fakecygpty and cygwin
 
 On @uref{https://www.emacswiki.org/emacs/SshWithNTEmacs, the Emacs
 Wiki} it is explained how to use the helper program @code{fakecygpty}
 to fix this problem.
 
address@hidden method scpx with Cygwin
address@hidden scpx method with Cygwin
address@hidden method scpx with cygwin
address@hidden scpx method with cygwin
 
 When using the @option{scpx} access method, Emacs may call
address@hidden with Windows file naming, such as @code{c:/foo}.  But
address@hidden with MS Windows file naming, such as @code{c:/foo}.  But
 the version of @command{scp} that is installed with Cygwin does not
-know about Windows file naming, which causes it to incorrectly look
+know about MS Windows file naming, which causes it to incorrectly look
 for a host named @code{c}.
 
 A workaround: write a wrapper script for @option{scp} to convert
 Windows file names to Cygwin file names.
 
address@hidden Cygwin and ssh-agent
address@hidden SSH_AUTH_SOCK and Emacs on Windows
address@hidden cygwin and ssh-agent
address@hidden SSH_AUTH_SOCK and emacs on ms windows
 
-When using the @command{ssh-agent} on Windows for password-less
+When using the @command{ssh-agent} on MS Windows for password-less
 interaction, @option{ssh} methods depend on the environment variable
 @env{SSH_AUTH_SOCK}.  But this variable is not set when Emacs is
 started from a Desktop shortcut and authentication fails.
 
-One workaround is to use a Windows based SSH Agent, such as
+One workaround is to use an MS Windows based SSH Agent, such as
 Pageant.  It is part of the Putty Suite of tools.
 
 The fallback is to start Emacs from a shell.
@@ -2716,11 +2862,11 @@ Arguments of the program to be debugged must be 
literal, can take
 relative or absolute paths, but not remote paths.
 
 
address@hidden Running remote processes on Windows hosts
address@hidden Running remote processes on MS Windows hosts
 @cindex winexe
 @cindex powershell
 
address@hidden runs processes on a remote Windows host, and
address@hidden runs processes on a remote MS Windows host, and
 @value{tramp} can use it for @code{process-file} and
 @code{start-file-process}.
 
@@ -2730,7 +2876,7 @@ processes triggered from @value{tramp}.
 
 @option{explicit-shell-file-name} and @option{explicit-*-args} have to
 be set properly so @kbd{M-x shell} can open a proper remote shell on a
-Windows host.  To open @command{cmd}, set it as follows:
+MS Windows host.  To open @command{cmd}, set it as follows:
 
 @lisp
 @group
@@ -3283,7 +3429,7 @@ Redefine another key sequence in Emacs for @kbd{C-x C-f}:
    (interactive)
    (find-file
     (read-file-name
-     "Find Tramp file: "
+     "Find @value{tramp} file: "
      "@trampfn{ssh,news@@news.my.domain,/opt/news/etc/}"))))
 @end group
 @end lisp
@@ -3353,7 +3499,7 @@ The minibuffer expands for further editing.
 
 @item Use bookmarks:
 
-Use bookmarks to save Tramp file names.
+Use bookmarks to save @value{tramp} file names.
 @ifinfo
 @pxref{Bookmarks, , , emacs}.
 @end ifinfo
@@ -3736,4 +3882,3 @@ strings from being written to @file{*trace-output*}.
 @c * Explain how tramp.el works in principle: open a shell on a remote
 @c   host and then send commands to it.
 @c * Consistent small or capitalized words especially in menus.
address@hidden * Make a unique declaration of @trampfn.
diff --git a/doc/misc/trampver.texi b/doc/misc/trampver.texi
index 05b577d..5d9dcc5 100644
--- a/doc/misc/trampver.texi
+++ b/doc/misc/trampver.texi
@@ -8,7 +8,7 @@
 @c In the Tramp GIT, the version number is auto-frobbed from
 @c configure.ac, so you should edit that file and run
 @c "autoconf && ./configure" to change the version number.
address@hidden trampver 2.3.2
address@hidden trampver 2.3.3-pre
 
 @c Other flags from configuration
 @set instprefix /usr/local
diff --git a/etc/NEWS b/etc/NEWS
index 13805ce..f43491b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -97,9 +97,28 @@ Terminal is automatically initialized to use 24-bit colors 
if the
 required capabilities are found in terminfo.  See the FAQ node
 "Colors on a TTY" for more information.
 
++++
+** Emacs now obeys the X resource "scrollBar" at startup.
+The effect is similar to that of "toolBar" resource on the tool bar.
+
 
 * Changes in Emacs 26.1
 
++++
+** The function 'assoc' now takes an optional third argument 'testfn'.
+This argument, when non-nil, is used for comparison instead of
+'equal'.
+
+---
+** New variable 'executable-prefix-env' for inserting magic signatures.
+This variable affects the format of the interpreter magic number
+inserted by 'executable-set-magic'.  If non-nil, the magic number now
+takes the form "#!/usr/bin/env interpreter", otherwise the value
+determined by 'executable-prefix', which is by default
+"#!/path/to/interpreter".  By default, 'executable-prefix-env' is nil,
+so the default behavior is not changed.
+
++++
 ** The variable 'emacs-version' no longer includes the build number.
 This is now stored separately in a new variable, 'emacs-build-number'.
 
@@ -353,6 +372,12 @@ variable of this kind to swap modifiers in Emacs.
 ---
 ** New input methods: 'cyrillic-tuvan', 'polish-prefix'.
 
+---
+** The 'dutch' input method no longer attempts to support Turkish too.
+Also, it no longer converts 'IJ' and 'ij' to the compatibility
+characters U+0132 LATIN CAPITAL LIGATURE IJ and U+0133 LATIN SMALL
+LIGATURE IJ.
+
 +++
 ** File name quoting by adding the prefix "/:" is now possible for the
 local part of a remote file name.  Thus, if you have a directory named
@@ -405,10 +430,74 @@ display of raw bytes from octal to hex.
 ** You can now provide explicit field numbers in format specifiers.
 For example, '(format "%2$s %1$s" "X" "Y")' produces "Y X".
 
-+++
 ** 'comment-indent-function' values may now return a cons to specify a
 range of indentation.
 
++++
+** Emacs now supports optional display of line numbers in the buffer.
+This is similar to what linum-mode provides, but much faster and
+doesn't usurp the display margin for the line numbers.  Customize the
+buffer-local variable 'display-line-numbers' to activate this optional
+display.  Alternatively, you can use the `display-line-numbers-mode'
+minor mode or the global `global-display-line-numbers-mode'.  When
+using these modes, customize `display-line-numbers-type' with the same
+value as you would use with `display-line-numbers'.
+
+If `display-line-numbers' is set to t, Emacs will display the number
+of each line before the line.  If set to 'relative', Emacs will
+display the line number relative to the line showing point, with that
+line's number displayed as absolute.  If set to 'visual', Emacs will
+display a relative number for every screen line, i.e. it will count
+screen lines rather than buffer lines.  The default is nil, which
+doesn't display the line numbers.
+
+In 'relative' and 'visual' modes, the variable
+'display-line-numbers-current-absolute' controls what number is
+displayed for the line showing point.  By default, this variable's
+value is t, which means display the absolute line number for the line
+showing point.  Customizing this variable to a nil value will cause
+Emacs to show zero instead, which preserves horizontal space of the
+window in large buffers.
+
+Line numbers are not displayed at all in minibuffer windows and in
+tooltips, as they are not useful there.
+
+The new face 'line-number' is used to display the line numbers.  The
+new face 'line-number-current-line' can be customized to display the
+current line's number differently from all the other line numbers; by
+default these two faces are identical.
+
+You can also customize the new buffer-local variable
+'display-line-numbers-width' to specify a fixed minimal with of the
+area allocated to line-number display.  The default is nil, meaning
+that Emacs will dynamically calculate the area width, enlarging or
+shrinking it as needed.  Setting it to a non-negative integer
+specifies that as the minimal width; selecting a value that is large
+enough to display all line numbers in a buffer will then keep the
+line-number display area of constant width at all times, if that is
+desired.
+
+When using `display-line-numbers-mode', you can customize the variable
+`display-line-numbers-grow-only' to a non-nil value; this means that
+Emacs may grow the above area width dynamically, but never shrink it.
+Under this mode, customizing the variable
+`display-line-numbers-width-start' to a non-nil value will cause Emacs
+to set `display-line-numbers-width' to the minimum width necessary to
+display all line numbers in the current buffer when first visiting it.
+
+Lisp programs can disable line-number display for a particular screen
+line by putting the 'display-line-numbers-disable' text property or
+overlay property on the first character of that screen line.  This is
+intended for add-on packages that need a finer control of the display.
+
+Lisp programs that need to know how much screen estate is used up for
+line-number display in a window can use the new function
+'line-number-display-width'.
+
+Linum mode and all similar packages are henceforth becoming obsolete.
+Users and developers are encouraged to switch to this new feature
+instead.
+
 
 * Editing Changes in Emacs 26.1
 
@@ -500,11 +589,19 @@ current buffer with the contents of the accessible 
portion of a
 different buffer while keeping point, mark, markers, and text
 properties as intact as possible.
 
++++
+** More user control of reordering bidirectional text for display.
+The two new variables, 'bidi-paragraph-start-re' and
+'bidi-paragraph-separate-re', allow customization of what exactly are
+paragraphs, for the purposes of bidirectional display.
+
 
 * Changes in Specialized Modes and Packages in Emacs 26.1
 
 ** Dired
-You can now use '`?`' in 'dired-do-shell-command'; as ' ? ', it gets replaced
+
++++
+*** You can now use '`?`' in 'dired-do-shell-command'; as ' ? ', it gets 
replaced
 by the current file name.
 
 *** html2text is now marked obsolete.
@@ -638,6 +735,18 @@ this is controlled by the 
'wdired-create-parent-directories' variable.
 *** 'W' is now bound to 'browse-url-of-dired-file', and is useful for
 viewing HTML files and the like.
 
+** Grep
+
+---
+*** Grep commands will now use GNU grep's '--null' option if
+available, which allows distinguishing the filename from contents if
+they contain colons.  This can be controlled by the new custom option
+'grep-use-null-filename-separator'.
+
+*** The grep/rgrep/lgrep functions will now ask about saving files
+before running.  This is controlled by the 'grep-save-buffers'
+variable.
+
 ** Edebug
 
 *** Edebug can be prevented from pausing 1 second after reaching a
@@ -702,6 +811,14 @@ Ido mode is active.
 in question).
 
 +++
+*** It's now possible to specify aspect-ratio preserving combinations
+of :width/:max-height and :height/:max-width keywords.  In either
+case, the "max" keywords win.  (Previously some combinations would,
+depending on the aspect ratio of the image, just be ignored and in
+other instances this would lead to the aspect ratio not being
+preserved.)
+
++++
 *** Images inserted with 'insert-image' and related functions get a
 keymap put into the text properties (or overlays) that span the
 image.  This keymap binds keystrokes for manipulating size and
@@ -978,10 +1095,6 @@ things like forward-word in readline work.
 ** hideshow mode got four key bindings that are analogous to outline
 mode bindings: 'C-c @ C-a', 'C-c @ C-t', 'C-c @ C-d', and 'C-c @ C-e.'
 
-** The grep/rgrep/lgrep functions will now ask about saving files
-before running.  This is controlled by the 'grep-save-buffers'
-variable.
-
 ---
 ** Customizable variable 'query-replace-from-to-separator'
 now doesn't propertize the string value of the separator.
@@ -1041,6 +1154,10 @@ instead of its first.
 renamed to 'lread--old-style-backquotes'.  No user code should use
 this variable.
 
+** To avoid confusion caused by "smart quotes", the reader no longer
+accepts Lisp symbols which begin with the following quotation
+characters: ‘’‛“”‟〞"', unless they are escaped with backslash.
+
 +++
 ** Module functions are now implemented slightly differently; in
 particular, the function 'internal--module-call' has been removed.
@@ -1050,9 +1167,26 @@ break.
 
 * Lisp Changes in Emacs 26.1
 
++++
+** New optional argument TESTFN in 'alist-get', 'map-elt' and 'map-put'.
+
 ** New function 'seq-set-equal-p' to check if SEQUENCE1 and SEQUENCE2
 contain the same elements, regardless of the order.
 
+** Checksum/Hash
+
++++
+** New function 'secure-hash-algorithms' to list the algorithms that
+'secure-hash' supports.
+See the node "(elisp) Checksum/Hash" in the ELisp manual for details.
+
++++
+** Emacs now exposes the GnuTLS cryptographic API with the functions
+'gnutls-macs' and 'gnutls-hash-mac'; 'gnutls-digests' and
+'gnutls-hash-digest'; 'gnutls-ciphers' and 'gnutls-symmetric-encrypt'
+and 'gnutls-symmetric-decrypt'.
+See the node "(elisp) GnuTLS Cryptography" in the ELisp manual for details.
+
 +++
 ** Emacs now supports records for user-defined types, via the new
 functions 'make-record', 'record', and 'recordp'.  Records are now
@@ -1418,9 +1552,12 @@ For details see the section "Mouse Window 
Auto-selection" in the Elisp
 manual.
 
 ---
-** 'tcl-auto-fill-mode' is now declared obsolete.  It's functionality
+** 'tcl-auto-fill-mode' is now declared obsolete.  Its functionality
 can be replicated simply by setting 'comment-auto-fill-only-comments'.
 
+** New pcase pattern 'rx' to match against a rx-style regular
+expression.
+
 
 * Changes in Emacs 26.1 on Non-Free Operating Systems
 
@@ -1466,6 +1603,9 @@ debugger has been attached to it.
 ** 'set-mouse-position' and 'set-mouse-absolute-pixel-position' work
 on macOS.
 
+** Emacs can now be run as a GUI application from the command line on
+macOS.
+
 
 ----------------------------------------------------------------------
 This file is part of GNU Emacs.
diff --git a/etc/NEWS.21 b/etc/NEWS.21
index 4a214cb..9574a5d 100644
--- a/etc/NEWS.21
+++ b/etc/NEWS.21
@@ -3367,7 +3367,7 @@ be strings that are compared case-insensitively.
     (sxhash (upcase a)))
 
   (define-hash-table-test 'case-fold 'case-fold-string=
-                          'case-fold-string-hash))
+                          'case-fold-string-hash)
 
   (make-hash-table :test 'case-fold)
 
diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el
index c15bd41..6ec0316 100644
--- a/etc/themes/leuven-theme.el
+++ b/etc/themes/leuven-theme.el
@@ -4,7 +4,7 @@
 
 ;; Author: Fabrice Niessen <(concat "fniessen" at-sign "pirilampo.org")>
 ;; URL: https://github.com/fniessen/emacs-leuven-theme
-;; Version: 20140929.1232
+;; Version: 20170715.0521
 ;; Keywords: color theme
 
 ;; This file is part of GNU Emacs.
@@ -600,6 +600,15 @@ Semantic, and Ansi-Color faces are included -- and much 
more...")
    `(rainbow-delimiters-depth-9-face ((,class (:foreground "#887070"))))
    `(rainbow-delimiters-mismatched-face ((,class ,paren-unmatched)))
    `(rainbow-delimiters-unmatched-face ((,class ,paren-unmatched)))
+   `(realgud-overlay-arrow1  ((,class (:foreground "#005522"))))
+   `(realgud-overlay-arrow2  ((,class (:foreground "#c18401"))))
+   `(realgud-overlay-arrow3  ((,class (:foreground "#909183"))))
+   `(realgud-bp-disabled-face      ((,class (:foreground "#909183"))))
+   `(realgud-bp-line-enabled-face  ((,class (:underline "red"))))
+   `(realgud-bp-line-disabled-face ((,class (:underline "#909183"))))
+   `(realgud-file-name             ((,class :foreground "#005522")))
+   `(realgud-line-number           ((,class :foreground "#A535AE")))
+   `(realgud-backtrace-number      ((,class :foreground "#A535AE" :weight 
bold)))
    `(recover-this-file ((,class (:weight bold :background "#FF3F3F"))))
    `(rng-error ((,class (:weight bold :foreground "red" :background 
"#FBE3E4"))))
    `(sh-heredoc ((,class (:foreground "blue" :background "#EEF5FE"))))
diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el
index bbfeb83..9b461cc 100644
--- a/etc/themes/manoj-dark-theme.el
+++ b/etc/themes/manoj-dark-theme.el
@@ -602,18 +602,16 @@ jarring angry fruit salad look to reduce eye fatigue.")
  '(paren-no-match-face ((t (:bold t :background "white" :foreground "red"))))
  '(query-replace ((t (:foreground "brown4" :background "palevioletred2"))))
  '(region ((t (:background "blue3"))))
-
- `(realgud-overlay-arrow1        ((t (:foreground "medium sea green"))))
- `(realgud-overlay-arrow2        ((t (:foreground "white"))))
- `(realgud-overlay-arrow3        ((t (:foreground "indian red"))))
- `(realgud-bp-enabled-face       ((t (:inherit error))))
- `(realgud-bp-disabled-face      ((t (:underline t))))
- `(realgud-bp-line-enabled-face  ((t (:foreground "orange"))))
- `(realgud-bp-line-disabled-face ((t (:underline t))))
- `(realgud-file-name             ((t (:foreground "cyan"))))
- `(realgud-line-number           ((t (:foreground "yellow"))))
- `(realgud-backtrace-number      ((t (:foreground "yellow" :weight bold))))))
-
+ '(realgud-overlay-arrow1        ((t (:foreground "medium sea green"))))
+ '(realgud-overlay-arrow2        ((t (:foreground "white"))))
+ '(realgud-overlay-arrow3        ((t (:foreground "indian red"))))
+ '(realgud-bp-enabled-face       ((t (:inherit error))))
+ '(realgud-bp-disabled-face      ((t (:underline t))))
+ '(realgud-bp-line-enabled-face  ((t (:foreground "orange"))))
+ '(realgud-bp-line-disabled-face ((t (:underline t))))
+ '(realgud-file-name             ((t (:foreground "cyan"))))
+ '(realgud-line-number           ((t (:foreground "yellow"))))
+ '(realgud-backtrace-number      ((t (:foreground "yellow" :weight bold))))
  '(scroll-bar ((t (:background "grey75" :foreground "WhiteSmoke"))))
  '(secondary-selection ((t (:background "SkyBlue4"))))
  '(semantic-dirty-token-face ((t (:background "lightyellow"))))
diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el
index ba7484c..91bda44 100644
--- a/etc/themes/tango-dark-theme.el
+++ b/etc/themes/tango-dark-theme.el
@@ -140,6 +140,16 @@ Semantic, and Ansi-Color faces are included.")
    ;; Flyspell faces
    `(flyspell-duplicate ((,class (:underline ,orange-1))))
    `(flyspell-incorrect ((,class (:underline ,red-1))))
+   ;; Realgud
+   `(realgud-overlay-arrow1  ((,class (:foreground "green"))))
+   `(realgud-overlay-arrow2  ((,class (:foreground ,orange-1))))
+   `(realgud-overlay-arrow3  ((,class (:foreground ,plum-0))))
+   `(realgud-bp-disabled-face      ((,class (:foreground ,blue-3))))
+   `(realgud-bp-line-enabled-face  ((,class (:underline "red"))))
+   `(realgud-bp-line-disabled-face ((,class (:underline ,blue-3))))
+   `(realgud-file-name             ((,class :foreground ,blue-1)))
+   `(realgud-line-number           ((,class :foreground ,plum-0)))
+   `(realgud-backtrace-number      ((,class :foreground ,plum-0 :weight bold)))
    ;; Semantic faces
    `(semantic-decoration-on-includes ((,class (:underline ,alum-4))))
    `(semantic-decoration-on-private-members-face
diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el
index 50b8a96..9f7c0c2 100644
--- a/etc/themes/tango-theme.el
+++ b/etc/themes/tango-theme.el
@@ -124,6 +124,16 @@ Semantic, and Ansi-Color faces are included.")
    ;; Flyspell
    `(flyspell-duplicate ((,class (:underline ,orange-1))))
    `(flyspell-incorrect ((,class (:underline ,red-1))))
+   ;; Realgud
+   `(realgud-overlay-arrow1  ((,class (:foreground "dark green"))))
+   `(realgud-overlay-arrow2  ((,class (:foreground "#7a4c02"))))
+   `(realgud-overlay-arrow3  ((,class (:foreground ,orange-1))))
+   `(realgud-bp-disabled-face      ((,class (:foreground ,plum-1))))
+   `(realgud-bp-line-enabled-face  ((,class (:underline "red"))))
+   `(realgud-bp-line-disabled-face ((,class (:underline ,plum-1))))
+   `(realgud-file-name             ((,class :foreground "dark green")))
+   `(realgud-line-number           ((,class :foreground ,blue-3)))
+   `(realgud-backtrace-number      ((,class :foreground ,blue-3 :weight bold)))
    ;; Semantic faces
    `(semantic-decoration-on-includes ((,class (:underline  ,cham-4))))
    `(semantic-decoration-on-private-members-face
diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el
index 4f48854..3890fe0 100644
--- a/etc/themes/tsdh-dark-theme.el
+++ b/etc/themes/tsdh-dark-theme.el
@@ -118,16 +118,16 @@
  '(outline-6 ((t (:foreground "light salmon" :weight bold))))
  '(outline-7 ((t (:foreground "pale goldenrod" :weight bold))))
  '(outline-8 ((t (:foreground "OliveDrab1" :weight bold))))
- `(realgud-overlay-arrow1        ((t (:foreground "medium spring green"))))
- `(realgud-overlay-arrow2        ((t (:foreground "OliveDrab1"))))
- `(realgud-overlay-arrow3        ((t (:foreground "light salmon"))))
- `(realgud-bp-enabled-face       ((t (:inherit error))))
- `(realgud-bp-disabled-face      ((t (:foreground "gray35"))))
- `(realgud-bp-line-enabled-face  ((t (:foreground "light salmon"))))
- `(realgud-bp-line-disabled-face ((t (:foreground "medium spring green"))))
- `(realgud-file-name             ((t (:foreground "dark khaki"))))
- `(realgud-line-number           ((t (:foreground "cyan3"))))
- `(realgud-backtrace-number      ((t (:foreground "cyan3" :weight bold))))))
+ '(realgud-overlay-arrow1        ((t (:foreground "medium spring green"))))
+ '(realgud-overlay-arrow2        ((t (:foreground "OliveDrab1"))))
+ '(realgud-overlay-arrow3        ((t (:foreground "light salmon"))))
+ '(realgud-bp-enabled-face       ((t (:inherit error))))
+ '(realgud-bp-disabled-face      ((t (:foreground "gray35"))))
+ '(realgud-bp-line-enabled-face  ((t (:foreground "light salmon"))))
+ '(realgud-bp-line-disabled-face ((t (:foreground "medium spring green"))))
+ '(realgud-file-name             ((t (:foreground "dark khaki"))))
+ '(realgud-line-number           ((t (:foreground "cyan3"))))
+ '(realgud-backtrace-number      ((t (:foreground "cyan3" :weight bold))))
  '(rcirc-my-nick ((t (:foreground "SpringGreen1" :weight bold))) t)
  '(rcirc-other-nick ((t (:foreground "dodger blue"))) t)
  '(rcirc-track-keyword ((t (:foreground "DodgerBlue" :weight bold))) t)
diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el
index e817480..8498fe2 100644
--- a/etc/themes/tsdh-light-theme.el
+++ b/etc/themes/tsdh-light-theme.el
@@ -90,6 +90,15 @@ Used and created by Tassilo Horn.")
  '(outline-7 ((t (:inherit font-lock-builtin-face :weight bold))))
  '(outline-8 ((t (:inherit font-lock-string-face :weight bold))))
  '(rcirc-my-nick ((t (:foreground "LightSkyBlue" :weight bold))))
+ '(realgud-overlay-arrow1  ((t (:foreground "dark green"))))
+ '(realgud-overlay-arrow2  ((t (:foreground "#c18401"))))
+ '(realgud-overlay-arrow3  ((t (:foreground "gray60"))))
+ '(realgud-bp-disabled-face      ((t (:foreground "gray60"))))
+ '(realgud-bp-line-enabled-face  ((t (:underline "red"))))
+ '(realgud-bp-line-disabled-face ((t (:underline "gray60"))))
+ '(realgud-file-name             ((t :foreground "dark green")))
+ '(realgud-line-number           ((t :foreground "#0184bc")))
+ '(realgud-backtrace-number      ((t :foreground "#0184bc" :weight bold)))
  '(region ((t (:background "lightgoldenrod1"))))
  '(show-paren-match ((t (:background "Cyan1" :weight bold))))
  '(show-paren-mismatch ((t (:background "deep pink" :weight bold))))
diff --git a/etc/themes/wheatgrass-theme.el b/etc/themes/wheatgrass-theme.el
index 269c33a..9ec532d 100644
--- a/etc/themes/wheatgrass-theme.el
+++ b/etc/themes/wheatgrass-theme.el
@@ -75,8 +75,8 @@ of green, brown, and blue.")
    `(realgud-overlay-arrow3        ((,class (:foreground "wheat"))))
    `(realgud-bp-enabled-face       ((,class (:inherit error))))
    `(realgud-bp-disabled-face      ((,class (:foreground "dark slate gray"))))
-   `(realgud-bp-line-enabled-face  ((,class (:foreground "salmon"))))
-   `(realgud-bp-line-disabled-face ((,class (:foreground "dark slate gray"))))
+   `(realgud-bp-line-enabled-face  ((,class (:underline "SpringGreen3"))))
+   `(realgud-bp-line-disabled-face ((,class (:underline "salmon"))))
    `(realgud-file-name             ((,class (:foreground "dark khaki"))))
    `(realgud-line-number           ((,class (:foreground "dark cyan"))))
    `(realgud-backtrace-number      ((,class (:foreground "dark cyan" :weight 
bold))))))
diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el
index 5e2f466..0192289 100644
--- a/etc/themes/whiteboard-theme.el
+++ b/etc/themes/whiteboard-theme.el
@@ -83,6 +83,16 @@
    `(outline-4 ((,class (:foreground "RoyalBlue"))))
    `(outline-5 ((,class (:foreground "DeepSkyBlue"))))
    `(primary-selection ((,class (:background "blue3"))))
+   `(realgud-overlay-arrow1  ((,class (:foreground "DarkGreen"))))
+   `(realgud-overlay-arrow2  ((,class (:foreground "DarkOliveGreen"))))
+   `(realgud-overlay-arrow3  ((,class (:foreground "gray60"))))
+   `(realgud-bp-disabled-face      ((,class (:foreground "gray60"))))
+   `(realgud-bp-line-enabled-face  ((,class (:underline "red"))))
+   `(realgud-bp-line-disabled-face ((,class (:underline "gray60"))))
+   `(realgud-file-name             ((,class :foreground "DarkGreen")))
+   `(realgud-line-number           ((,class :foreground "blue3")))
+   `(realgud-backtrace-number      ((,class :foreground "blue3" :weight bold)))
+
    `(region ((,class (:background "SkyBlue1"))))
    `(show-paren-match-face ((,class (:background "dodgerblue1" :foreground 
"white"))))
    `(show-paren-mismatch-face ((,class (:background "red1" :foreground 
"white"))))
diff --git a/lib-src/etags.c b/lib-src/etags.c
index e5ff7bd..7b1a7fc 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -373,6 +373,7 @@ static void readline (linebuffer *, FILE *);
 static long readline_internal (linebuffer *, FILE *, char const *);
 static bool nocase_tail (const char *);
 static void get_tag (char *, char **);
+static void get_lispy_tag (char *);
 
 static void analyze_regex (char *);
 static void free_regexps (void);
@@ -5347,7 +5348,7 @@ L_getit (void)
       /* Ok, then skip "(" before name in (defstruct (foo)) */
       dbp = skip_spaces (dbp);
   }
-  get_tag (dbp, NULL);
+  get_lispy_tag (dbp);
 }
 
 static void
@@ -5549,14 +5550,14 @@ Scheme_functions (FILE *inf)
       if (strneq (bp, "(def", 4) || strneq (bp, "(DEF", 4))
        {
          bp = skip_non_spaces (bp+4);
-         /* Skip over open parens and white space.  Don't continue past
-            '\0'. */
-         while (*bp && notinname (*bp))
+         /* Skip over open parens and white space.
+            Don't continue past '\0' or '='. */
+         while (*bp && notinname (*bp) && *bp != '=')
            bp++;
-         get_tag (bp, NULL);
+         get_lispy_tag (bp);
        }
       if (LOOKING_AT (bp, "(SET!") || LOOKING_AT (bp, "(set!"))
-       get_tag (bp, NULL);
+       get_lispy_tag (bp);
     }
 }
 
@@ -6591,6 +6592,22 @@ get_tag (register char *bp, char **namepp)
     *namepp = savenstr (bp, cp - bp);
 }
 
+/* Similar to get_tag, but include '=' as part of the tag. */
+static void
+get_lispy_tag (register char *bp)
+{
+  register char *cp = bp;
+
+  if (*bp != '\0')
+    {
+      /* Go till you get to white space or a syntactic break */
+      for (cp = bp + 1; !notinname (*cp) || *cp == '='; cp++)
+       continue;
+      make_tag (bp, cp - bp, true,
+               lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
+    }
+}
+
 /*
  * Read a line of text from `stream' into `lbp', excluding the
  * newline or CR-NL, if any.  Return the number of characters read from
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index 6b2cc11..ecd6447 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -667,7 +667,9 @@ close_emacs_globals (ptrdiff_t num_symbols)
           "#ifndef DEFINE_SYMBOLS\n"
           "extern\n"
           "#endif\n"
-          "struct Lisp_Symbol alignas (GCALIGNMENT) lispsym[%td];\n"),
+          "struct {\n"
+          "  struct Lisp_Symbol alignas (GCALIGNMENT) s;\n"
+          "} lispsym[%td];\n"),
          num_symbols);
 }
 
diff --git a/lib/explicit_bzero.c b/lib/explicit_bzero.c
new file mode 100644
index 0000000..262c68f
--- /dev/null
+++ b/lib/explicit_bzero.c
@@ -0,0 +1,48 @@
+/* Erasure of sensitive data, generic implementation.
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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.
+
+   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.
+
+   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/>.  */
+
+/* An assembler implementation of explicit_bzero can be created as an
+   assembler alias of an optimized bzero implementation.
+   Architecture-specific implementations also need to define
+   __explicit_bzero_chk.  */
+
+#if !_LIBC
+# include <config.h>
+#endif
+
+#include <string.h>
+
+/* glibc-internal users use __explicit_bzero_chk, and explicit_bzero
+   redirects to that.  */
+#undef explicit_bzero
+
+/* Set LEN bytes of S to 0.  The compiler will not delete a call to
+   this function, even if S is dead after the call.  */
+void
+explicit_bzero (void *s, size_t len)
+{
+#ifdef HAVE_EXPLICIT_MEMSET
+  explicit_memset (s, 0, len);
+#else
+  memset (s, '\0', len);
+# ifdef __GNUC__
+  /* Compiler barrier.  */
+  asm volatile ("" ::: "memory");
+# endif
+#endif
+}
diff --git a/lib/fpending.c b/lib/fpending.c
index c9b7786..02602a1 100644
--- a/lib/fpending.c
+++ b/lib/fpending.c
@@ -41,7 +41,7 @@ __fpending (FILE *fp)
   return fp->_ptr - fp->_buffer;
 #elif defined __minix                /* Minix */
   return fp_->_ptr - fp_->_buf;
-#elif defined _IOERR                 /* AIX, HP-UX, IRIX, OSF/1, Solaris, 
OpenServer, mingw, MSVC, NonStop Kernel */
+#elif defined _IOERR                 /* AIX, HP-UX, IRIX, OSF/1, Solaris, 
OpenServer, mingw, MSVC, NonStop Kernel, OpenVMS */
   return (fp_->_ptr ? fp_->_ptr - fp_->_base : 0);
 #elif defined __UCLIBC__             /* uClibc */
   return (fp->__modeflags & __FLAG_WRITING ? fp->__bufpos - fp->__bufstart : 
0);
@@ -51,8 +51,6 @@ __fpending (FILE *fp)
   return fp->__bufp - fp->__buffer;
 #elif defined EPLAN9                 /* Plan9 */
   return fp->wp - fp->buf;
-#elif defined __VMS                  /* VMS */
-  return (*fp)->_ptr - (*fp)->_base;
 #else
 # error "Please port gnulib fpending.c to your platform!"
   return 1;
diff --git a/lib/getdtablesize.c b/lib/getdtablesize.c
index c356cf4..a092863 100644
--- a/lib/getdtablesize.c
+++ b/lib/getdtablesize.c
@@ -1,4 +1,4 @@
-/* getdtablesize() function for platforms that don't have it.
+/* getdtablesize() function: Return maximum possible file descriptor value + 1.
    Copyright (C) 2008-2017 Free Software Foundation, Inc.
    Written by Bruno Haible <address@hidden>, 2008.
 
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index fd0f9e5..3e57391 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -21,7 +21,7 @@
 # the same distribution terms as the rest of that program.
 #
 # Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib 
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux 
--avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix 
--avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die 
--avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv 
--avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool 
--avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avo [...]
+# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib 
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux 
--avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix 
--avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die 
--avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv 
--avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool 
--avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avo [...]
 
 
 MOSTLYCLEANFILES += core *.stackdump
@@ -125,6 +125,7 @@ GNULIB_DUP2 = @GNULIB_DUP2@
 GNULIB_DUP3 = @GNULIB_DUP3@
 GNULIB_ENVIRON = @GNULIB_ENVIRON@
 GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_EXPLICIT_BZERO = @GNULIB_EXPLICIT_BZERO@
 GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
 GNULIB_FCHDIR = @GNULIB_FCHDIR@
 GNULIB_FCHMODAT = @GNULIB_FCHMODAT@
@@ -390,6 +391,7 @@ HAVE_DPRINTF = @HAVE_DPRINTF@
 HAVE_DUP2 = @HAVE_DUP2@
 HAVE_DUP3 = @HAVE_DUP3@
 HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_EXPLICIT_BZERO = @HAVE_EXPLICIT_BZERO@
 HAVE_FACCESSAT = @HAVE_FACCESSAT@
 HAVE_FCHDIR = @HAVE_FCHDIR@
 HAVE_FCHMODAT = @HAVE_FCHMODAT@
@@ -1356,6 +1358,17 @@ EXTRA_libgnu_a_SOURCES += execinfo.c
 endif
 ## end   gnulib module execinfo
 
+## begin gnulib module explicit_bzero
+ifeq (,$(OMIT_GNULIB_MODULE_explicit_bzero))
+
+
+EXTRA_DIST += explicit_bzero.c
+
+EXTRA_libgnu_a_SOURCES += explicit_bzero.c
+
+endif
+## end   gnulib module explicit_bzero
+
 ## begin gnulib module faccessat
 ifeq (,$(OMIT_GNULIB_MODULE_faccessat))
 
@@ -1798,6 +1811,16 @@ EXTRA_libgnu_a_SOURCES += mktime.c
 endif
 ## end   gnulib module mktime-internal
 
+## begin gnulib module nstrftime
+ifeq (,$(OMIT_GNULIB_MODULE_nstrftime))
+
+libgnu_a_SOURCES += nstrftime.c
+
+EXTRA_DIST += strftime.h
+
+endif
+## end   gnulib module nstrftime
+
 ## begin gnulib module openat-h
 ifeq (,$(OMIT_GNULIB_MODULE_openat-h))
 
@@ -2386,16 +2409,6 @@ EXTRA_libgnu_a_SOURCES += stpcpy.c
 endif
 ## end   gnulib module stpcpy
 
-## begin gnulib module strftime
-ifeq (,$(OMIT_GNULIB_MODULE_strftime))
-
-libgnu_a_SOURCES += strftime.c
-
-EXTRA_DIST += strftime.h
-
-endif
-## end   gnulib module strftime
-
 ## begin gnulib module string
 ifeq (,$(OMIT_GNULIB_MODULE_string))
 
@@ -2411,6 +2424,7 @@ string.h: string.in.h $(top_builddir)/config.status 
$(CXXDEFS_H) $(ARG_NONNULL_H
              -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
              -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
              -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \
+             -e 's/@''GNULIB_EXPLICIT_BZERO''@/$(GNULIB_EXPLICIT_BZERO)/g' \
              -e 's/@''GNULIB_FFSL''@/$(GNULIB_FFSL)/g' \
              -e 's/@''GNULIB_FFSLL''@/$(GNULIB_FFSLL)/g' \
              -e 's/@''GNULIB_MBSLEN''@/$(GNULIB_MBSLEN)/g' \
@@ -2449,7 +2463,8 @@ string.h: string.in.h $(top_builddir)/config.status 
$(CXXDEFS_H) $(ARG_NONNULL_H
              -e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \
              -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \
              < $(srcdir)/string.in.h | \
-         sed -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \
+         sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \
+             -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \
              -e 's|@''HAVE_FFSLL''@|$(HAVE_FFSLL)|g' \
              -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \
              -e 's|@''HAVE_MEMCHR''@|$(HAVE_MEMCHR)|g' \
diff --git a/lib/strftime.c b/lib/nstrftime.c
similarity index 100%
rename from lib/strftime.c
rename to lib/nstrftime.c
diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h
index 75a945e..d5b5943 100644
--- a/lib/stdio-impl.h
+++ b/lib/stdio-impl.h
@@ -99,6 +99,8 @@
                          int _file; \
                          unsigned int _flag; \
                        } *) fp)
+# elif defined __VMS                /* OpenVMS */
+#  define fp_ ((struct _iobuf *) fp)
 # else
 #  define fp_ fp
 # endif
diff --git a/lib/string.in.h b/lib/string.in.h
index 9a6b311..aaff563 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -74,6 +74,23 @@
 /* The definition of _GL_WARN_ON_USE is copied here.  */
 
 
+/* Clear a block of memory.  The compiler will not delete a call to
+   this function, even if the block is dead after the call.  */
+#if @GNULIB_EXPLICIT_BZERO@
+# if ! @HAVE_EXPLICIT_BZERO@
+_GL_FUNCDECL_SYS (explicit_bzero, void,
+                  (void *__dest, size_t __n) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (explicit_bzero, void, (void *__dest, size_t __n));
+_GL_CXXALIASWARN (explicit_bzero);
+#elif defined GNULIB_POSIXCHECK
+# undef explicit_bzero
+# if HAVE_RAW_DECL_EXPLICIT_BZERO
+_GL_WARN_ON_USE (explicit_bzero, "explicit_bzero is unportable - "
+                 "use gnulib module explicit_bzero for portability");
+# endif
+#endif
+
 /* Find the index of the least-significant set bit.  */
 #if @GNULIB_FFSL@
 # if address@hidden@
diff --git a/lib/xalloc-oversized.h b/lib/xalloc-oversized.h
index ff0efc6..2e09bab 100644
--- a/lib/xalloc-oversized.h
+++ b/lib/xalloc-oversized.h
@@ -44,7 +44,7 @@ typedef size_t __xalloc_count_type;
 #if 7 <= __GNUC__
 # define xalloc_oversized(n, s) \
    __builtin_mul_overflow_p (n, s, (__xalloc_count_type) 1)
-#elif 5 <= __GNUC__ && !__STRICT_ANSI__
+#elif 5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__
 # define xalloc_oversized(n, s) \
    (__builtin_constant_p (n) && __builtin_constant_p (s) \
     ? __xalloc_oversized (n, s) \
diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el
index 235eb83..b89c1c2 100644
--- a/lisp/calendar/todo-mode.el
+++ b/lisp/calendar/todo-mode.el
@@ -1,4 +1,4 @@
-;;; todo-mode.el --- facilities for making and maintaining todo lists
+;;; todo-mode.el --- facilities for making and maintaining todo lists  -*- 
lexical-binding:t -*-
 
 ;; Copyright (C) 1997, 1999, 2001-2017 Free Software Foundation, Inc.
 
@@ -72,14 +72,14 @@ file truenames in `todo-directory' with the extension
 \".todo\".  With non-nil ARCHIVES return the list of archive file
 truenames (those with the extension \".toda\")."
   (let ((files (if (file-exists-p todo-directory)
-                  (mapcar 'file-truename
+                  (mapcar #'file-truename
                    (directory-files todo-directory t
-                                    (if archives "\\.toda$" "\\.todo$") t)))))
+                                    (if archives "\\.toda\\'" "\\.todo\\'") 
t)))))
     (sort files (lambda (s1 s2) (let ((cis1 (upcase s1))
                                      (cis2 (upcase s2)))
                                  (string< cis1 cis2))))))
 
-(defcustom todo-files-function 'todo-files
+(defcustom todo-files-function #'todo-files
   "Function returning the value of the variable `todo-files'.
 This function should take an optional argument that, if non-nil,
 makes it return the value of the variable `todo-archives'."
@@ -188,6 +188,15 @@ The final element is \"*\", indicating an unspecified 
month.")
   "Array of abbreviated month names, in order.
 The final element is \"*\", indicating an unspecified month.")
 
+(with-no-warnings
+  ;; FIXME: These vars lack a prefix, but this is out of our control, because
+  ;; they're defined by Calendar, e.g. for calendar-date-display-form.
+  (defvar dayname)
+  (defvar monthname)
+  (defvar day)
+  (defvar month)
+  (defvar year))
+
 (defconst todo-date-pattern
   (let ((dayname (diary-name-pattern calendar-day-name-array nil t)))
     (concat "\\(?4:\\(?5:" dayname "\\)\\|"
@@ -198,7 +207,7 @@ The final element is \"*\", indicating an unspecified 
month.")
                  (month "\\(?7:[0-9]+\\|\\*\\)")
                  (day "\\(?8:[0-9]+\\|\\*\\)")
                  (year "-?\\(?9:[0-9]+\\|\\*\\)"))
-             (mapconcat 'eval calendar-date-display-form ""))
+             (mapconcat #'eval calendar-date-display-form ""))
            "\\)"))
   "Regular expression matching a todo item date header.")
 
@@ -260,7 +269,7 @@ This function is the value of the user variable
   (let ((file (todo-short-file-name todo-current-todo-file)))
     (format "%s category %d: %s" file todo-category-number cat)))
 
-(defcustom todo-mode-line-function 'todo-mode-line-control
+(defcustom todo-mode-line-function #'todo-mode-line-control
   "Function that returns a mode line control for Todo mode buffers.
 The function expects one argument holding the name of the current
 todo category.  The resulting control becomes the local value of
@@ -555,13 +564,15 @@ This lacks the extension and directory components."
   (when (stringp file)
     (file-name-sans-extension (file-name-nondirectory file))))
 
+(defun todo--files-type-list ()
+  (mapcar (lambda (f) (list 'const (todo-short-file-name f)))
+         (funcall todo-files-function)))
+
 (defcustom todo-default-todo-file (todo-short-file-name
                                   (car (funcall todo-files-function)))
   "Todo file visited by first session invocation of `todo-show'."
   :type (when todo-files
-         `(radio ,@(mapcar (lambda (f) (list 'const f))
-                           (mapcar 'todo-short-file-name
-                                   (funcall todo-files-function)))))
+         `(radio ,@(todo--files-type-list)))
   :group 'todo)
 
 (defcustom todo-show-current-file t
@@ -598,9 +609,7 @@ Otherwise, `todo-show' always visits 
`todo-default-todo-file'."
 
 (defcustom todo-category-completions-files nil
   "List of files for building `todo-read-category' completions."
-  :type `(set ,@(mapcar (lambda (f) (list 'const f))
-                       (mapcar 'todo-short-file-name
-                               (funcall todo-files-function))))
+  :type `(set ,@(todo--files-type-list))
   :group 'todo)
 
 (defcustom todo-completion-ignore-case nil
@@ -707,11 +716,12 @@ and done items are always shown on visiting a category."
                       (let ((rxfiles (directory-files todo-directory t
                                                       ".*\\.todr$" t)))
                         (when (and rxfiles (> (length rxfiles) 1))
-                          (let ((rxf (mapcar 'todo-short-file-name rxfiles)))
+                          (let ((rxf (mapcar #'todo-short-file-name rxfiles)))
                             (setq fi-file (todo-absolute-file-name
                                            (completing-read
                                             "Choose a regexp items file: "
-                                            rxf) 'regexp))))))
+                                            rxf)
+                                            'regexp))))))
                     (if (file-exists-p fi-file)
                         (progn
                           (set-window-buffer
@@ -823,7 +833,7 @@ buries it and restores state as needed."
           (when (buffer-live-p buf) (kill-buffer buf)))
          ((eq major-mode 'todo-mode)
           (todo-save)
-          (bury-buffer)))))
+           (quit-window)))))
 
 ;; 
-----------------------------------------------------------------------------
 ;;; Navigation between and within categories
@@ -857,7 +867,7 @@ category is the first)."
                (zerop (todo-get-count 'done))
                (not (zerop (todo-get-count 'archived))))
       (setq todo-category-number
-           (apply (if back '1- '1+) (list todo-category-number)))))
+           (funcall (if back #'1- #'1+) todo-category-number))))
   (todo-category-select)
   (goto-char (point-min)))
 
@@ -1117,7 +1127,8 @@ these files, also rename them accordingly."
         (snname (todo-short-file-name nname))
         (files (directory-files todo-directory t
                                 (concat ".*" (regexp-quote soname)
-                                        ".*\\.tod[aorty]$") t)))
+                                        ".*\\.tod[aorty]$")
+                                 t)))
     (dolist (f files)
       (let* ((sfname (todo-short-file-name f))
             (fext (file-name-extension f t))
@@ -1363,10 +1374,12 @@ todo or done items."
        (let ((buffer-read-only)
              (beg (re-search-backward
                    (concat "^" (regexp-quote (concat todo-category-beg cat))
-                           "\n") nil t))
+                           "\n")
+                    nil t))
              (end (if (re-search-forward
                        (concat "\n\\(" (regexp-quote todo-category-beg)
-                               ".*\n\\)") nil t)
+                               ".*\n\\)")
+                        nil t)
                       (match-beginning 1)
                     (point-max))))
          (remove-overlays beg end)
@@ -1475,7 +1488,8 @@ the archive of the file moved to, creating it if it does 
not exist."
                  (goto-char (point-max))
                  (re-search-backward
                   (concat "^" (regexp-quote todo-category-beg)
-                          "\\(" (regexp-quote cat) "\\)$") nil t)
+                          "\\(" (regexp-quote cat) "\\)$")
+                   nil t)
                  (replace-match new nil nil nil 1))
                 (setq todo-categories
                       (append todo-categories (list (cons (or new cat) 
counts))))
@@ -1746,7 +1760,7 @@ consist of the the last todo items and the first done 
items."
     (let ((cat (todo-current-category)))
       (unless (> n 1) (setq n 1))
       (catch 'end
-        (dotimes (i n)
+        (dotimes (_ n)
           (let* ((marks (assoc cat todo-categories-with-marks))
                  (ov (progn
                        (unless (looking-at todo-item-start)
@@ -2134,7 +2148,8 @@ the item at point."
                        (todo-item-start)
                        (re-search-forward
                         (concat " \\[" (regexp-quote todo-comment-string)
-                                ": \\([^]]+\\)\\]") end t)))
+                                ": \\([^]]+\\)\\]")
+                         end t)))
             (prompt (if comment "Edit comment: " "Enter a comment: "))
             (buffer-read-only nil))
        ;; When there are marked items, user can invoke todo-edit-item
@@ -2150,7 +2165,8 @@ the item at point."
              (todo-item-start)
              (if (re-search-forward (concat " \\["
                                             (regexp-quote todo-comment-string)
-                                            ": \\([^]]+\\)\\]") end t)
+                                            ": \\([^]]+\\)\\]")
+                                     end t)
                  (if comment-delete
                      (when (todo-y-or-n-p "Delete comment? ")
                        (delete-region (match-beginning 0) (match-end 0)))
@@ -2182,7 +2198,8 @@ the item at point."
                                                       (cons item 0))))))
              (when include-header
                (while (not (string-match (concat todo-date-string-start
-                                                 todo-date-pattern) new))
+                                                 todo-date-pattern)
+                                          new))
                  (setq new (read-from-minibuffer
                             "Item must start with a date: " new))))
              ;; Ensure lines following hard newlines are indented.
@@ -2211,7 +2228,8 @@ made in the number or names of categories."
            (regex "\\(\n\\)[^[:blank:]]")
            (buf (buffer-base-buffer)))
        (while (not (string-match (concat todo-date-string-start
-                                         todo-date-pattern) item))
+                                         todo-date-pattern)
+                                  item))
          (setq item (read-from-minibuffer
                     "Item must start with a date: " item)))
        ;; Ensure lines following hard newlines are indented.
@@ -2270,8 +2288,7 @@ made in the number or names of categories."
                                     "\\)\\(?2: " diary-time-regexp "\\)?"
                                     (regexp-quote todo-nondiary-end) "?")
                             (line-end-position) t)
-         (let* ((odate (match-string-no-properties 1))
-                (otime (match-string-no-properties 2))
+         (let* ((otime (match-string-no-properties 2))
                 (odayname (match-string-no-properties 5))
                 (omonthname (match-string-no-properties 6))
                 (omonth (match-string-no-properties 7))
@@ -2382,7 +2399,8 @@ made in the number or names of categories."
                                               (calendar-current-date))))
                                   (date (calendar-gregorian-from-absolute
                                          (+ (calendar-absolute-from-gregorian
-                                             (list mm dd yy)) inc)))
+                                             (list mm dd yy))
+                                             inc)))
                                   (adjmm (nth 0 date)))
                              ;; Set year and month(name) to adjusted values.
                              (unless (string= year "*")
@@ -2396,7 +2414,7 @@ made in the number or names of categories."
              ;; If year, month or day date string components were
              ;; changed, rebuild the date string.
              (when (memq what '(year month day))
-               (setq ndate (mapconcat 'eval calendar-date-display-form ""))))
+               (setq ndate (mapconcat #'eval calendar-date-display-form ""))))
            (when ndate (replace-match ndate nil nil nil 1))
            ;; Add new time string to the header, if it was supplied.
            (when ntime
@@ -2423,7 +2441,7 @@ made in the number or names of categories."
        (when marked (goto-char (point-min)))
        (while (not (eobp))
          (unless (and marked (not (todo-marked-item-p)))
-           (let* ((beg (todo-item-start))
+           (let* ((_beg (todo-item-start))
                   (lim (save-excursion (todo-item-end)))
                   (end (save-excursion
                          (or (todo-time-string-matcher lim)
@@ -2470,7 +2488,7 @@ items."
        (while (not (eobp))
          (if (todo-done-item-p)        ; We've gone too far.
              (throw 'stop nil)
-           (let* ((beg (todo-item-start))
+           (let* ((_beg (todo-item-start))
                   (lim (save-excursion (todo-item-end)))
                   (end (save-excursion
                          (or (todo-time-string-matcher lim)
@@ -2682,9 +2700,7 @@ section in the category moved to."
                 (not marked))
       (let* ((buffer-read-only)
             (file1 todo-current-todo-file)
-            (num todo-category-number)
             (item (todo-item-string))
-            (diary-item (todo-diary-item-p))
             (done-item (and (todo-done-item-p) item))
             (omark (save-excursion (todo-item-start) (point-marker)))
             (todo 0)
@@ -2956,7 +2972,8 @@ comments without asking."
                ;; affirmed, omit subsequent comments without asking.
                (when (re-search-forward
                       (concat " \\[" (regexp-quote todo-comment-string)
-                              ": [^]]+\\]") end t)
+                              ": [^]]+\\]")
+                       end t)
                  (unwind-protect
                      (if (eq first 'first)
                          (setq first
@@ -3216,7 +3233,8 @@ the only category in the archive, the archive file is 
deleted."
     (let* ((cat (todo-current-category))
           (tbuf (find-file-noselect
                  (concat (file-name-sans-extension todo-current-todo-file)
-                         ".todo") t))
+                         ".todo")
+                  t))
           (marked (assoc cat todo-categories-with-marks))
           (item (concat (todo-item-string) "\n"))
           (marked-count 0)
@@ -3241,7 +3259,8 @@ the only category in the archive, the archive file is 
deleted."
          ;; one, add it.
          (unless (re-search-forward
                   (concat "^" (regexp-quote (concat todo-category-beg cat))
-                          "$") nil t)
+                          "$")
+                   nil t)
            (todo-add-category nil cat)
            (setq newcat t))
          ;; Go to top of category's done section.
@@ -3449,9 +3468,9 @@ decreasing or increasing its number."
          (unless prompt (setq priority candidate)))
        (let* ((lower (< curnum priority)) ; Priority is being lowered.
               (head (butlast todo-categories
-                             (apply (if lower 'identity '1+)
-                                    (list (- maxnum priority)))))
-              (tail (nthcdr (apply (if lower 'identity '1-) (list priority))
+                             (funcall (if lower #'identity #'1+)
+                                       (- maxnum priority))))
+              (tail (nthcdr (funcall (if lower #'identity #'1-) priority)
                             todo-categories))
               ;; Category's name and items counts list.
               (catcons (nth (1- curnum) todo-categories))
@@ -3537,7 +3556,7 @@ decreasing or increasing its number."
   "Return adjusted length of category label button.
 The adjustment ensures proper tabular alignment in Todo
 Categories mode."
-  (let* ((categories (mapcar 'car todo-categories))
+  (let* ((categories (mapcar #'car todo-categories))
         (longest (todo-longest-category-name-length categories))
         (catlablen (length todo-categories-category-label))
         (lc-diff (- longest catlablen)))
@@ -3623,24 +3642,24 @@ LABEL determines which type of count is sorted."
         ov)
     (insert-button str 'face nil
                   'action
-                  `(lambda (button)
-                     (let ((key (todo-label-to-key ,label)))
-                       (if (and (member key todo-descending-counts)
-                                (eq key 'alpha))
-                           (progn
-                             ;; If display is alphabetical, switch back to
-                             ;; category priority order.
-                             (todo-display-sorted nil)
-                             (setq todo-descending-counts
-                                   (delete key todo-descending-counts)))
-                         (todo-display-sorted key)))))
+                  (lambda (_button)
+                    (let ((key (todo-label-to-key label)))
+                      (if (and (member key todo-descending-counts)
+                               (eq key 'alpha))
+                          (progn
+                            ;; If display is alphabetical, switch back to
+                            ;; category priority order.
+                            (todo-display-sorted nil)
+                            (setq todo-descending-counts
+                                  (delete key todo-descending-counts)))
+                        (todo-display-sorted key)))))
     (setq ov (make-overlay beg end))
     (overlay-put ov 'face 'todo-button)))
 
 (defun todo-total-item-counts ()
   "Return a list of total item counts for the current file."
-  (mapcar (lambda (i) (apply '+ (mapcar (lambda (l) (aref l i))
-                                       (mapcar 'cdr todo-categories))))
+  (mapcar (lambda (i) (apply #'+ (mapcar (lambda (x) (aref (cdr x) i))
+                                    todo-categories)))
          (list 0 1 2 3)))
 
 (defvar todo-categories-category-number 0
@@ -3685,9 +3704,10 @@ which is the value of the user option
                    (not (zerop (todo-get-count 'archived cat))))
               'todo-archived-only
             nil)
-     'action `(lambda (button) (let ((buf (current-buffer)))
-                                (todo-jump-to-category nil ,cat)
-                                (kill-buffer buf))))
+     'action (lambda (_button)
+               (let ((buf (current-buffer)))
+                (todo-jump-to-category nil cat)
+                (kill-buffer buf))))
     ;; Highlight the sorted count column.
     (let* ((beg (+ opoint 7 (length str)))
           end ovl)
@@ -3766,8 +3786,8 @@ which is the value of the user option
     (delete-region (point) (point-max))
     ;; Fill in the table with buttonized lines, each showing a category and
     ;; its item counts.
-    (mapc (lambda (cat) (todo-insert-category-line cat sortkey))
-         (mapcar 'car cats))
+    (dolist (cat cats)
+      (todo-insert-category-line (car cat) sortkey))
     (newline)
     ;; Add a line showing item count totals.
     (insert (make-string (+ 4 (length todo-categories-number-separator)) 32)
@@ -3823,7 +3843,8 @@ face."
            (when (looking-at todo-done-string-start)
              (setq in-done t))
            (re-search-backward (concat "^" (regexp-quote todo-category-beg)
-                                       "\\(.*\\)\n") nil t)
+                                       "\\(.*\\)\n")
+                                nil t)
            (setq cat (match-string-no-properties 1))
            (todo-category-number cat)
            (todo-category-select)
@@ -3885,9 +3906,7 @@ This variable should be set interactively by
 
 (defcustom todo-filter-files nil
   "List of default files for multifile item filtering."
-  :type `(set ,@(mapcar (lambda (f) (list 'const f))
-                       (mapcar 'todo-short-file-name
-                               (funcall todo-files-function))))
+  :type `(set ,@(todo--files-type-list))
   :group 'todo-filtered)
 
 (defcustom todo-filter-done-items nil
@@ -4067,19 +4086,17 @@ regexp items."
     (widget-insert "Select files for generating the top priorities list.\n\n")
     (setq todo-multiple-filter-files-widget
          (widget-create
-          `(set ,@(mapcar (lambda (x) (list 'const x))
-                          (mapcar 'todo-short-file-name
-                                  (funcall todo-files-function))))))
+          `(set ,@(todo--files-type-list))))
     (widget-insert "\n")
     (widget-create 'push-button
-                  :notify (lambda (widget &rest ignore)
+                  :notify (lambda (&rest _)
                             (setq todo-multiple-filter-files 'quit)
                             (quit-window t)
                             (exit-recursive-edit))
                   "Cancel")
     (widget-insert "   ")
     (widget-create 'push-button
-                  :notify (lambda (&rest ignore)
+                  :notify (lambda (&rest _)
                             (setq todo-multiple-filter-files
                                   (mapcar (lambda (f)
                                             (file-truename
@@ -4137,7 +4154,7 @@ multifile commands for further details."
                    ;; Pressed `cancel' in t-m-f-f file selection dialog.
                    (keyboard-quit)
                  (concat todo-directory
-                         (mapconcat 'todo-short-file-name flist "-")
+                         (mapconcat #'todo-short-file-name flist "-")
                          (cond (top ".todt")
                                (diary ".tody")
                                (regexp ".todr")))))
@@ -4150,10 +4167,11 @@ multifile commands for further details."
           (todo-filter-items-1 (cons 'top new) flist))
          ((and (not new) file-exists)
           (when (and rxfiles (> (length rxfiles) 1))
-            (let ((rxf (mapcar 'todo-short-file-name rxfiles)))
+            (let ((rxf (mapcar #'todo-short-file-name rxfiles)))
               (setq fname (todo-absolute-file-name
                            (completing-read "Choose a regexp items file: "
-                                            rxf) 'regexp))))
+                                            rxf)
+                            'regexp))))
           (find-file fname)
           (unless (derived-mode-p 'todo-filtered-items-mode)
             (todo-filtered-items-mode))
@@ -4164,12 +4182,13 @@ multifile commands for further details."
     (dolist (s (split-string (todo-short-file-name fname) "-"))
       (setq bufname (if bufname
                        (concat bufname (if (member s (mapcar
-                                                      'todo-short-file-name
+                                                      #'todo-short-file-name
                                                       todo-files))
-                                           ", " "-") s)
+                                           ", " "-")
+                                s)
                      s)))
-    (rename-buffer (format (concat "%s for file" (if multi "s" "")
-                                  " \"%s\"") buf bufname))))
+    (rename-buffer (format (concat "%s for file" (if multi "s" "") " \"%s\"")
+                           buf bufname))))
 
 (defun todo-filter-items-1 (filter file-list)
   "Build a list of items by applying FILTER to FILE-LIST.
@@ -4235,7 +4254,8 @@ the values of FILTER and FILE-LIST."
                               todo-top-priorities)))
              (while (re-search-forward
                      (concat "^" (regexp-quote todo-category-beg)
-                             "\\(.+\\)\n") nil t)
+                             "\\(.+\\)\n")
+                      nil t)
                (setq cat (match-string 1))
                (let (cnum)
                  ;; Unless the number of top priorities to show was
@@ -4389,7 +4409,8 @@ its priority has changed, and `same' otherwise."
                            "\\]"
                          (regexp-quote todo-nondiary-end)) "?"
                        "\\(?4: \\[\\(?3:(archive) \\)?\\(?2:.*:\\)?"
-                       "\\(?1:.*\\)\\]\\).*$") str)
+                       "\\(?1:.*\\)\\]\\).*$")
+                str)
   (let ((cat (match-string 1 str))
        (file (match-string 2 str))
        (archive (string= (match-string 3 str) "(archive) "))
@@ -4504,8 +4525,13 @@ If the file already exists, overwrite it only on 
confirmation."
 ;;; Printing Todo mode buffers
 ;; 
-----------------------------------------------------------------------------
 
-(defcustom todo-print-buffer-function 'ps-print-buffer-with-faces
-  "Function called by the command `todo-print-buffer'."
+(defcustom todo-print-buffer-function #'ps-print-buffer-with-faces
+  "Function called by `todo-print-buffer' to print Todo mode buffers.
+The function should take an optional argument whose non-nil value
+is a string naming a file to save the print image to; calling
+`todo-print-buffer-to-file' prompts for the file name, which is
+passed to this function.  Calling this function with no or a nil
+argument sends the image to the printer."
   :type 'symbol
   :group 'todo)
 
@@ -4531,8 +4557,7 @@ otherwise, send it to the default printer."
                            'face 'todo-prefix-string))
        (num 0)
        (fill-prefix (make-string todo-indent-to-here 32))
-       (content (buffer-string))
-       file)
+       (content (buffer-string)))
     (with-current-buffer (get-buffer-create buf)
       (insert content)
       (goto-char (point-min))
@@ -4556,10 +4581,9 @@ otherwise, send it to the default printer."
       (goto-char (point-min))
       (insert header)
       (newline 2)
-      (if to-file
-         (let ((file (read-file-name "Print to file: ")))
-           (funcall todo-print-buffer-function file))
-       (funcall todo-print-buffer-function)))
+      (funcall todo-print-buffer-function
+               (if to-file nil
+                 (read-file-name "Print to file: "))))
     (kill-buffer buf)))
 
 (defun todo-print-buffer-to-file ()
@@ -4596,7 +4620,7 @@ Helper function for `todo-convert-legacy-files'."
         (time (match-string 4))
         dayname)
     (replace-match "")
-    (insert (mapconcat 'eval calendar-date-display-form "")
+    (insert (mapconcat #'eval calendar-date-display-form "")
            (when time (concat " " time)))))
 
 (defun todo-convert-legacy-files ()
@@ -4720,7 +4744,8 @@ name in `todo-directory'.  See also the documentation 
string of
                    (unless (save-excursion
                              (re-search-backward
                               (concat "^" (regexp-quote todo-category-beg)
-                                      "\\(.*\\)$") nil t)
+                                      "\\(.*\\)$")
+                               nil t)
                              (string= (match-string 1) cat))
                      ;; Else move it to its category.
                      (setq item (buffer-substring-no-properties beg end))
@@ -4734,7 +4759,8 @@ name in `todo-directory'.  See also the documentation 
string of
                      (forward-line)
                      (if (re-search-forward
                           (concat "^" (regexp-quote todo-category-beg)
-                                  "\\(.*\\)$") nil t)
+                                  "\\(.*\\)$")
+                           nil t)
                          (progn (goto-char (match-beginning 0))
                                 (newline)
                                 (forward-line -1))
@@ -4828,10 +4854,7 @@ buffer, clean up the state and return nil."
            (setq todo-files (funcall todo-files-function))
            (setq todo-archives (funcall todo-files-function t))
            t)
-       (let* ((files (append todo-files todo-archives))
-              (tctf todo-current-todo-file)
-              (tgctf todo-global-current-todo-file)
-              (tdtf (todo-absolute-file-name todo-default-todo-file)))
+       (let* ((files (append todo-files todo-archives)))
          (unless (or (not todo-current-todo-file)
                      (member todo-current-todo-file files))
            (setq todo-current-todo-file nil))
@@ -4850,7 +4873,7 @@ buffer, clean up the state and return nil."
   "Return the number of category CAT in this todo file.
 The buffer-local variable `todo-category-number' holds this
 number as its value."
-  (let ((categories (mapcar 'car todo-categories)))
+  (let ((categories (mapcar #'car todo-categories)))
     (setq todo-category-number
          ;; Increment by one, so that the number of the first
          ;; category is one rather than zero.
@@ -4880,7 +4903,8 @@ number as its value."
     (todo-prefix-overlays)
     (goto-char (point-min))
     (if (re-search-forward (concat "\n\\(" (regexp-quote todo-category-done)
-                                  "\\)") nil t)
+                                   "\\)")
+                           nil t)
        (progn
          (setq done-start (match-beginning 0))
          (setq done-sep-start (match-beginning 1))
@@ -5264,7 +5288,8 @@ Overrides `diary-goto-entry'."
       (when (eq major-mode 'todo-mode)
        (let ((opoint (point)))
          (re-search-backward (concat "^" (regexp-quote todo-category-beg)
-                                     "\\(.*\\)\n") nil t)
+                                     "\\(.*\\)\n")
+                              nil t)
          (todo-category-number (match-string 1))
          (todo-category-select)
          (goto-char opoint))))))
@@ -5647,8 +5672,7 @@ already entered and those still available."
 (defvar        todo-edit-item--prompt "Press a key (so far `e'): ")
 
 (defun todo-edit-item--next-key (params &optional arg)
-  (let* ((map (make-sparse-keymap))
-        (p->k (mapconcat (lambda (elt)
+  (let* ((p->k (mapconcat (lambda (elt)
                            (format "%s=>%s"
                                    (propertize (cdr elt) 'face
                                                'todo-key-prompt)
@@ -5736,14 +5760,14 @@ have been removed."
                           todo-global-current-todo-file)
                      (todo-absolute-file-name todo-default-todo-file)))
         (files (or (unless archive
-                     (mapcar 'todo-absolute-file-name
+                     (mapcar #'todo-absolute-file-name
                              todo-category-completions-files))
                    (list curfile)))
         listall listf)
     ;; If file was just added, it has no category completions.
     (unless (zerop (buffer-size (find-buffer-visiting curfile)))
       (unless (member curfile todo-archives)
-       (add-to-list 'files curfile))
+       (cl-pushnew curfile files :test #'equal))
       (dolist (f files listall)
        (with-current-buffer (find-file-noselect f 'nowarn)
          (if archive
@@ -5783,7 +5807,7 @@ return the absolute truename of a todo archive file.  
With non-nil
 MUSTMATCH the name of an existing file must be chosen;
 otherwise, a new file name is allowed."
   (let* ((completion-ignore-case todo-completion-ignore-case)
-        (files (mapcar 'todo-short-file-name
+        (files (mapcar #'todo-short-file-name
                        ;; (funcall todo-files-function archive)))
                        (if archive todo-archives todo-files)))
         (file (completing-read prompt files nil mustmatch nil nil
@@ -5832,7 +5856,8 @@ categories from `todo-category-completions-files'."
                    (todo-read-file-name (concat "Choose a" (if archive
                                                                 "n archive"
                                                               " todo")
-                                                 " file: ") archive t)))
+                                                " file: ")
+                                         archive t)))
           (completions (unless file0 (todo-category-completions archive)))
           (categories (cond (file0
                              (with-current-buffer
@@ -5873,7 +5898,7 @@ categories from `todo-category-completions-files'."
                     (if (atom catfil)
                         catfil
                       (todo-absolute-file-name
-                       (let ((files (mapcar 'todo-short-file-name catfil)))
+                       (let ((files (mapcar #'todo-short-file-name catfil)))
                          (completing-read (format str cat) files)))))))
       ;; Default to the current file.
       (unless file0 (setq file0 todo-current-todo-file))
@@ -5907,7 +5932,7 @@ categories from `todo-category-completions-files'."
   "Prompt for new NAME for TYPE until it is valid, then return it.
 TYPE can be either of the symbols `file' or `category'."
   (let ((categories todo-categories)
-       (files (mapcar 'todo-short-file-name todo-files))
+       (files (mapcar #'todo-short-file-name todo-files))
        prompt)
     (while
        (and
@@ -5981,8 +6006,8 @@ number of the last the day of the month."
        (setq monthname (completing-read
                         "Month name (RET for current month, * for any month): "
                         mlist nil t nil nil
-                        (calendar-month-name (calendar-extract-month
-                                              (calendar-current-date)) t))
+                         (calendar-month-name
+                          (calendar-extract-month (calendar-current-date)) t))
              month (1+ (- (length mlist)
                           (length (or (member monthname mlist)
                                       (member monthname mablist))))))
@@ -6023,7 +6048,7 @@ number of the last the day of the month."
               (if (memq 'month calendar-date-display-form)
                   month
                 monthname)))
-      (mapconcat 'eval calendar-date-display-form ""))))
+      (mapconcat #'eval calendar-date-display-form ""))))
 
 (defun todo-read-dayname ()
   "Choose name of a day of the week with completion and return it."
@@ -6088,8 +6113,8 @@ the empty string (i.e., no time string)."
   "The :set function for user option `todo-show-current-file'."
   (custom-set-default symbol value)
   (if value
-      (add-hook 'pre-command-hook 'todo-show-current-file nil t)
-    (remove-hook 'pre-command-hook 'todo-show-current-file t)))
+      (add-hook 'pre-command-hook #'todo-show-current-file nil t)
+    (remove-hook 'pre-command-hook #'todo-show-current-file t)))
 
 (defun todo-reset-prefix (symbol value)
   "The :set function for `todo-prefix' and `todo-number-prefix'."
@@ -6228,6 +6253,8 @@ the empty string (i.e., no time string)."
 
 (defun todo-reevaluate-filelist-defcustoms ()
   "Reevaluate defcustoms that provide choice list of todo files."
+  ;; FIXME: This is hideous!  I don't know enough about Custom to
+  ;; offer something better, but please ask on emacs-devel!
   (custom-set-default 'todo-default-todo-file
                      (symbol-value 'todo-default-todo-file))
   (todo-reevaluate-default-file-defcustom)
@@ -6242,15 +6269,15 @@ the empty string (i.e., no time string)."
 Called after adding or deleting a todo file.  If the value of
 `todo-default-todo-file' before calling this function was
 associated with an existing file, keep that value."
+  ;; FIXME: This is hideous!  I don't know enough about Custom to
+  ;; offer something better, but please ask on emacs-devel!
   ;; (let ((curval todo-default-todo-file))
     (eval
      (defcustom todo-default-todo-file (todo-short-file-name
                                        (car (funcall todo-files-function)))
        "Todo file visited by first session invocation of `todo-show'."
        :type (when todo-files
-              `(radio ,@(mapcar (lambda (f) (list 'const f))
-                                (mapcar 'todo-short-file-name
-                                        (funcall todo-files-function)))))
+              `(radio ,@(todo--files-type-list)))
        :group 'todo))
     ;; (when (and curval (file-exists-p (todo-absolute-file-name curval)))
     ;;   (custom-set-default 'todo-default-todo-file curval)
@@ -6261,21 +6288,21 @@ associated with an existing file, keep that value."
 (defun todo-reevaluate-category-completions-files-defcustom ()
   "Reevaluate defcustom of `todo-category-completions-files'.
 Called after adding or deleting a todo file."
+  ;; FIXME: This is hideous!  I don't know enough about Custom to
+  ;; offer something better, but please ask on emacs-devel!
   (eval (defcustom todo-category-completions-files nil
   "List of files for building `todo-read-category' completions."
-         :type `(set ,@(mapcar (lambda (f) (list 'const f))
-                               (mapcar 'todo-short-file-name
-                                       (funcall todo-files-function))))
+         :type `(set ,@(todo--files-type-list))
          :group 'todo)))
 
 (defun todo-reevaluate-filter-files-defcustom ()
   "Reevaluate defcustom of `todo-filter-files'.
 Called after adding or deleting a todo file."
+  ;; FIXME: This is hideous!  I don't know enough about Custom to
+  ;; offer something better, but please ask on emacs-devel!
   (eval (defcustom todo-filter-files nil
          "List of files for multifile item filtering."
-         :type `(set ,@(mapcar (lambda (f) (list 'const f))
-                               (mapcar 'todo-short-file-name
-                                       (funcall todo-files-function))))
+         :type `(set ,@(todo--files-type-list))
          :group 'todo)))
 
 ;; 
-----------------------------------------------------------------------------
@@ -6292,7 +6319,8 @@ Called after adding or deleting a todo file."
 (defun todo-diary-nonmarking-matcher (lim)
   "Search for diary nonmarking symbol within LIM for font-locking."
   (re-search-forward (concat "^\\(?1:" (regexp-quote diary-nonmarking-symbol)
-                            "\\)" todo-date-pattern) lim t))
+                            "\\)" todo-date-pattern)
+                     lim t))
 
 (defun todo-date-string-matcher (lim)
   "Search for todo item date string within LIM for font-locking."
@@ -6302,14 +6330,16 @@ Called after adding or deleting a todo file."
 (defun todo-time-string-matcher (lim)
   "Search for todo item time string within LIM for font-locking."
   (re-search-forward (concat todo-date-string-start todo-date-pattern
-                            " \\(?1:" diary-time-regexp "\\)") lim t))
+                            " \\(?1:" diary-time-regexp "\\)")
+                     lim t))
 
 (defun todo-diary-expired-matcher (lim)
   "Search for expired diary item date within LIM for font-locking."
   (when (re-search-forward (concat "^\\(?:"
                                   (regexp-quote diary-nonmarking-symbol)
                                   "\\)?\\(?1:" todo-date-pattern "\\) \\(?2:"
-                                  diary-time-regexp "\\)?") lim t)
+                                  diary-time-regexp "\\)?")
+                           lim t)
     (let* ((date (match-string-no-properties 1))
           (time (match-string-no-properties 2))
           ;; Function days-between requires a non-empty time string.
@@ -6464,8 +6494,6 @@ Filtered Items mode following todo (not done) items."
 
 (defvar todo-mode-map
   (let ((map (make-keymap)))
-    ;; Don't suppress digit keys, so they can supply prefix arguments.
-    (suppress-keymap map)
     (dolist (kb todo-key-bindings-t)
       (define-key map (nth 0 kb) (nth 1 kb)))
     (dolist (kb todo-key-bindings-t+a+f)
@@ -6479,7 +6507,6 @@ Filtered Items mode following todo (not done) items."
 
 (defvar todo-archive-mode-map
   (let ((map (make-sparse-keymap)))
-    (suppress-keymap map)
     (dolist (kb todo-key-bindings-t+a+f)
       (define-key map (nth 0 kb) (nth 1 kb)))
     (dolist (kb todo-key-bindings-t+a)
@@ -6498,7 +6525,6 @@ Filtered Items mode following todo (not done) items."
 
 (defvar todo-categories-mode-map
   (let ((map (make-sparse-keymap)))
-    (suppress-keymap map)
     (define-key map "c" 'todo-sort-categories-alphabetically-or-numerically)
     (define-key map "t" 'todo-sort-categories-by-todo)
     (define-key map "y" 'todo-sort-categories-by-diary)
@@ -6517,7 +6543,6 @@ Filtered Items mode following todo (not done) items."
 
 (defvar todo-filtered-items-mode-map
   (let ((map (make-sparse-keymap)))
-    (suppress-keymap map)
     (dolist (kb todo-key-bindings-t+a+f)
       (define-key map (nth 0 kb) (nth 1 kb)))
     (dolist (kb todo-key-bindings-t+f)
@@ -6651,9 +6676,9 @@ Added to `window-configuration-change-hook' in Todo mode."
 (defun todo-modes-set-1 ()
   "Make some settings that apply to multiple Todo modes."
   (setq-local font-lock-defaults '(todo-font-lock-keywords t))
-  (setq-local revert-buffer-function 'todo-revert-buffer)
+  (setq-local revert-buffer-function #'todo-revert-buffer)
   (setq-local tab-width todo-indent-to-here)
-  (setq-local indent-line-function 'todo-indent)
+  (setq-local indent-line-function #'todo-indent)
   (when todo-wrap-lines
     (visual-line-mode)
     (setq wrap-prefix (make-string todo-indent-to-here 32))))
@@ -6671,13 +6696,13 @@ Added to `window-configuration-change-hook' in Todo 
mode."
   (setq buffer-read-only t)
   (setq-local todo--item-headers-hidden nil)
   (setq-local desktop-save-buffer 'todo-desktop-save-buffer)
-  (setq-local hl-line-range-function 'todo-hl-line-range))
+  (setq-local hl-line-range-function #'todo-hl-line-range))
 
 (defun todo-modes-set-3 ()
   "Make some settings that apply to multiple Todo modes."
   (setq-local todo-categories (todo-set-categories))
   (setq-local todo-category-number 1)
-  ;; (add-hook 'find-file-hook 'todo-display-as-todo-file nil t)
+  ;; (add-hook 'find-file-hook #'todo-display-as-todo-file nil t)
   )
 
 (put 'todo-mode 'mode-class 'special)
@@ -6700,13 +6725,13 @@ Added to `window-configuration-change-hook' in Todo 
mode."
       (setq-local todo-current-todo-file (file-truename (buffer-file-name))))
     (setq-local todo-show-done-only nil)
     (setq-local todo-categories-with-marks nil)
-    ;; (add-hook 'find-file-hook 'todo-add-to-buffer-list nil t)
-    (add-hook 'post-command-hook 'todo-update-buffer-list nil t)
+    ;; (add-hook 'find-file-hook #'todo-add-to-buffer-list nil t)
+    (add-hook 'post-command-hook #'todo-update-buffer-list nil t)
     (when todo-show-current-file
-      (add-hook 'pre-command-hook 'todo-show-current-file nil t))
+      (add-hook 'pre-command-hook #'todo-show-current-file nil t))
     (add-hook 'window-configuration-change-hook
-             'todo-reset-and-enable-done-separator nil t)
-    (add-hook 'kill-buffer-hook 'todo-reset-global-current-todo-file nil t)))
+             #'todo-reset-and-enable-done-separator nil t)
+    (add-hook 'kill-buffer-hook #'todo-reset-global-current-todo-file nil t)))
 
 (put 'todo-archive-mode 'mode-class 'special)
 
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 744fe7f..c28b8a1 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -584,6 +584,38 @@ since it could result in memory overflow and make Emacs 
crash."
                       (const :tag "Grow only" :value grow-only))
              "25.1")
             (display-raw-bytes-as-hex display boolean "26.1")
+             (display-line-numbers display-line-numbers
+                                   (choice
+                                    (const :tag "Off (nil)" :value nil)
+                                    (const :tag "Absolute line numbers"
+                                           :value t)
+                                    (const :tag "Relative line numbers"
+                                           :value relative)
+                                    (const :tag "Visually relative line 
numbers"
+                                           :value visual))
+                                   "26.1")
+             (display-line-numbers-width display-line-numbers
+                                 (choice
+                                  (const :tag "Dynamically computed"
+                                         :value nil)
+                                  (integer :menu-tag "Fixed number of columns"
+                                           :value 2
+                                           :format "%v"))
+                                 "26.1")
+             (display-line-numbers-current-absolute display-line-numbers
+                                 (choice
+                                  (const :tag "Display actual number of 
current line"
+                                         :value t)
+                                  (const :tag "Display zero as number of 
current line"
+                                         :value nil))
+                                 "26.1")
+             (display-line-numbers-widen display-line-numbers
+                                 (choice
+                                  (const :tag "Disregard narrowing when 
calculating line numbers"
+                                         :value t)
+                                  (const :tag "Count lines from beginning of 
narrowed region"
+                                         :value nil))
+                                 "26.1")
             ;; xfaces.c
             (scalable-fonts-allowed display boolean "22.1")
             ;; xfns.c
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 095ce8b..17dae60 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1623,10 +1623,14 @@ Special value `always' suppresses confirmation."
          (setq default-directory to
                dired-directory (expand-file-name;; this is correct
                                 ;; with and without wildcards
-                                (file-name-nondirectory dired-directory)
+                                (file-name-nondirectory (if (stringp 
dired-directory)
+                                                             dired-directory
+                                                           (car 
dired-directory)))
                                 to))
          (let ((new-name (file-name-nondirectory
-                          (directory-file-name dired-directory))))
+                          (directory-file-name (if (stringp dired-directory)
+                                                    dired-directory
+                                                  (car dired-directory))))))
            ;; try to rename buffer, but just leave old name if new
            ;; name would already exist (don't try appending "<%d>")
            (or (get-buffer new-name)
diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 7ceb672..9155509 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -546,7 +546,9 @@ Should never be used as marker by the user or other 
packages.")
   (interactive)
   (let ((dired-omit-mode nil)) (revert-buffer)) ;; Show omitted files
   (dired-mark-unmarked-files (dired-omit-regexp) nil nil dired-omit-localp
-                             (dired-omit-case-fold-p dired-directory)))
+                             (dired-omit-case-fold-p (if (stringp 
dired-directory)
+                                                         dired-directory
+                                                       (car 
dired-directory)))))
 
 (defcustom dired-omit-extensions
   (append completion-ignored-extensions
@@ -591,7 +593,9 @@ This functions works by temporarily binding 
`dired-marker-char' to
             (let ((dired-marker-char dired-omit-marker-char))
               (when dired-omit-verbose (message "Omitting..."))
               (if (dired-mark-unmarked-files omit-re nil nil dired-omit-localp
-                                             (dired-omit-case-fold-p 
dired-directory))
+                                             (dired-omit-case-fold-p (if 
(stringp dired-directory)
+                                                                         
dired-directory
+                                                                       (car 
dired-directory))))
                   (progn
                     (setq count (dired-do-kill-lines
                                 nil
diff --git a/lisp/dired.el b/lisp/dired.el
index 0c1f3e4..9d500a9 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -785,7 +785,7 @@ Type \\[describe-mode] after entering Dired for more info.
 If DIRNAME is already in a Dired buffer, that buffer is used without refresh."
   ;; Cannot use (interactive "D") because of wildcards.
   (interactive (dired-read-dir-and-switches ""))
-  (switch-to-buffer (dired-noselect dirname switches)))
+  (pop-to-buffer-same-window (dired-noselect dirname switches)))
 
 ;;;###autoload (define-key ctl-x-4-map "d" 'dired-other-window)
 ;;;###autoload
@@ -872,13 +872,15 @@ periodically reverts at specified time intervals."
   :version "23.2")
 
 (defun dired-internal-noselect (dir-or-list &optional switches mode)
-  ;; If there is an existing dired buffer for DIRNAME, just leave
-  ;; buffer as it is (don't even call dired-revert).
+  ;; If DIR-OR-LIST is a string and there is an existing dired buffer
+  ;; for it, just leave buffer as it is (don't even call dired-revert).
   ;; This saves time especially for deep trees or with ange-ftp.
   ;; The user can type `g' easily, and it is more consistent with find-file.
   ;; But if SWITCHES are given they are probably different from the
   ;; buffer's old value, so call dired-sort-other, which does
   ;; revert the buffer.
+  ;; Revert the buffer if DIR-OR-LIST is a cons or `dired-directory'
+  ;; is a cons and DIR-OR-LIST is a string.
   ;; A pity we can't possibly do "Directory has changed - refresh? "
   ;; like find-file does.
   ;; Optional argument MODE is passed to dired-find-buffer-nocreate,
@@ -898,6 +900,11 @@ periodically reverts at specified time intervals."
               (setq dired-directory dir-or-list)
               ;; this calls dired-revert
               (dired-sort-other switches))
+             ;; Always revert when `dir-or-list' is a cons.  Also revert
+             ;; if `dired-directory' is a cons but `dir-or-list' is not.
+             ((or (consp dir-or-list) (consp dired-directory))
+              (setq dired-directory dir-or-list)
+              (revert-buffer))
              ;; Always revert regardless of whether it has changed or not.
              ((eq dired-auto-revert-buffer t)
               (revert-buffer))
diff --git a/lisp/display-line-numbers.el b/lisp/display-line-numbers.el
new file mode 100644
index 0000000..a994745
--- /dev/null
+++ b/lisp/display-line-numbers.el
@@ -0,0 +1,106 @@
+;;; display-line-numbers.el --- interface for display-line-numbers -*- 
lexical-binding: t -*-
+
+;; Copyright (C) 2017 Free Software Foundation, Inc.
+
+;; Maintainer: address@hidden
+;; Keywords: convenience
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Provides a minor mode interface for `display-line-numbers'.
+;;
+;; Toggle display of line numbers with M-x display-line-numbers-mode.
+;; To enable line numbering in all buffers, use M-x
+;; global-display-line-numbers-mode.  To change the default type of
+;; line numbers displayed, customize display-line-numbers-type.
+
+;; NOTE: Customization variables for `display-line-numbers' itself are
+;; defined in cus-start.el.
+
+;;; Code:
+
+(defgroup display-line-numbers nil
+  "Display line numbers in the buffer."
+  :group 'display)
+
+;;;###autoload
+(defcustom display-line-numbers-type t
+  "The default type of line numbers to use in `display-line-numbers-mode'.
+See `display-line-numbers' for value options."
+  :group 'display-line-numbers
+  :type '(choice (const :tag "Relative line numbers" relative)
+                 (const :tag "Relative visual line numbers" visual)
+                 (other :tag "Absolute line numbers" t))
+  :version "26.1")
+
+(defcustom display-line-numbers-grow-only nil
+  "If non-nil, do not shrink line number width."
+  :group 'display-line-numbers
+  :type 'boolean
+  :version "26.1")
+
+(defcustom display-line-numbers-width-start nil
+  "If non-nil, count number of lines to use for line number width.
+When `display-line-numbers-mode' is turned on,
+`display-line-numbers-width' is set to the minimum width necessary
+to display all line numbers in the buffer."
+  :group 'display-line-numbers
+  :type 'boolean
+  :version "26.1")
+
+(defun display-line-numbers-update-width ()
+  "Prevent the line number width from shrinking."
+  (let ((width (line-number-display-width)))
+    (when (> width (or display-line-numbers-width 1))
+      (setq display-line-numbers-width width))))
+
+;;;###autoload
+(define-minor-mode display-line-numbers-mode
+  "Toggle display of line numbers in the buffer.
+This uses `display-line-numbers' internally.
+
+To change the type of line numbers displayed by default,
+customize `display-line-numbers-type'.  To change the type while
+the mode is on, set `display-line-numbers' directly."
+  :lighter nil
+  (if display-line-numbers-mode
+      (progn
+        (when display-line-numbers-width-start
+          (setq display-line-numbers-width
+                (length (number-to-string
+                         (count-lines (point-min) (point-max))))))
+        (when display-line-numbers-grow-only
+          (add-hook 'pre-command-hook #'display-line-numbers-update-width nil 
t))
+        (setq display-line-numbers display-line-numbers-type))
+    (remove-hook 'pre-command-hook #'display-line-numbers-update-width t)
+    (setq display-line-numbers nil)))
+
+(defun display-line-numbers--turn-on ()
+  "Turn on `display-line-numbers-mode'."
+  (unless (or (minibufferp)
+              ;; taken from linum.el
+              (and (daemonp) (null (frame-parameter nil 'client))))
+    (display-line-numbers-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode global-display-line-numbers-mode
+  display-line-numbers-mode display-line-numbers--turn-on)
+
+(provide 'display-line-numbers)
+
+;;; display-line-numbers.el ends here
diff --git a/lisp/electric.el b/lisp/electric.el
index 4c1d9039..a71e79f 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -469,56 +469,50 @@ This requotes when a quoting key is typed."
                  (and (not electric-quote-context-sensitive)
                       (eq last-command-event ?\`)))
              (not (run-hook-with-args-until-success
-                   'electric-quote-inhibit-functions)))
-    (let ((start
-           (if (and comment-start comment-use-syntax)
-               (when (or electric-quote-comment electric-quote-string)
-                 (let* ((syntax (syntax-ppss))
-                        (beg (nth 8 syntax)))
-                   (and beg
-                        (or (and electric-quote-comment (nth 4 syntax))
-                            (and electric-quote-string (nth 3 syntax)))
-                        ;; Do not requote a quote that starts or ends
-                        ;; a comment or string.
-                        (eq beg (nth 8 (save-excursion
-                                         (syntax-ppss (1- (point)))))))))
-             (and electric-quote-paragraph
-                  (derived-mode-p 'text-mode)
-                  ;; FIXME: Why is the next form there?  It’s never
-                  ;; nil.
-                  (or (eq last-command-event ?\`)
-                      (save-excursion (backward-paragraph) (point)))))))
-      (pcase electric-quote-chars
-        (`(,q< ,q> ,q<< ,q>>)
-         (when start
-           (save-excursion
-             (let ((backtick ?\`))
-               (if (or (eq last-command-event ?\`)
-                       (and electric-quote-context-sensitive
-                            (save-excursion
-                              (backward-char)
-                              (or (bobp) (bolp)
-                                  (memq (char-before) (list q< q<<))
-                                  (memq (char-syntax (char-before))
-                                        '(?\s ?\())))
-                            (setq backtick ?\')))
-                   (cond ((search-backward (string q< backtick) (- (point) 2) 
t)
-                          (replace-match (string q<<))
-                          (when (and electric-pair-mode
-                                     (eq (cdr-safe
-                                          (assq q< electric-pair-text-pairs))
-                                         (char-after)))
-                            (delete-char 1))
-                          (setq last-command-event q<<))
-                         ((search-backward (string backtick) (1- (point)) t)
-                          (replace-match (string q<))
-                          (setq last-command-event q<)))
-                 (cond ((search-backward (string q> ?') (- (point) 2) t)
-                        (replace-match (string q>>))
-                        (setq last-command-event q>>))
-                       ((search-backward "'" (1- (point)) t)
-                        (replace-match (string q>))
-                        (setq last-command-event q>))))))))))))
+                   'electric-quote-inhibit-functions))
+             (if (derived-mode-p 'text-mode)
+                 electric-quote-paragraph
+               (and comment-start comment-use-syntax
+                    (or electric-quote-comment electric-quote-string)
+                    (let* ((syntax (syntax-ppss))
+                           (beg (nth 8 syntax)))
+                      (and beg
+                           (or (and electric-quote-comment (nth 4 syntax))
+                               (and electric-quote-string (nth 3 syntax)))
+                           ;; Do not requote a quote that starts or ends
+                           ;; a comment or string.
+                           (eq beg (nth 8 (save-excursion
+                                            (syntax-ppss (1- (point)))))))))))
+    (pcase electric-quote-chars
+      (`(,q< ,q> ,q<< ,q>>)
+       (save-excursion
+         (let ((backtick ?\`))
+           (if (or (eq last-command-event ?\`)
+                   (and electric-quote-context-sensitive
+                        (save-excursion
+                          (backward-char)
+                          (or (bobp) (bolp)
+                              (memq (char-before) (list q< q<<))
+                              (memq (char-syntax (char-before))
+                                    '(?\s ?\())))
+                        (setq backtick ?\')))
+               (cond ((search-backward (string q< backtick) (- (point) 2) t)
+                      (replace-match (string q<<))
+                      (when (and electric-pair-mode
+                                 (eq (cdr-safe
+                                      (assq q< electric-pair-text-pairs))
+                                     (char-after)))
+                        (delete-char 1))
+                      (setq last-command-event q<<))
+                     ((search-backward (string backtick) (1- (point)) t)
+                      (replace-match (string q<))
+                      (setq last-command-event q<)))
+             (cond ((search-backward (string q> ?') (- (point) 2) t)
+                    (replace-match (string q>>))
+                    (setq last-command-event q>>))
+                   ((search-backward "'" (1- (point)) t)
+                    (replace-match (string q>))
+                    (setq last-command-event q>))))))))))
 
 (put 'electric-quote-post-self-insert-function 'priority 10)
 
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index e5b9b47..fdd4276 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -1263,12 +1263,6 @@ when printing the error message."
 
 (defun byte-compile-arglist-signature (arglist)
   (cond
-   ;; New style byte-code arglist.
-   ((integerp arglist)
-    (cons (logand arglist 127)             ;Mandatory.
-          (if (zerop (logand arglist 128)) ;No &rest.
-              (lsh arglist -8))))          ;Nonrest.
-   ;; Old style byte-code, or interpreted function.
    ((listp arglist)
     (let ((args 0)
           opts
@@ -1289,6 +1283,19 @@ when printing the error message."
    ;; Unknown arglist.
    (t '(0))))
 
+(defun byte-compile--function-signature (f)
+  ;; Similar to help-function-arglist, except that it returns the info
+  ;; in a different format.
+  (and (eq 'macro (car-safe f)) (setq f (cdr f)))
+  ;; Advice wrappers have "catch all" args, so fetch the actual underlying
+  ;; function to find the real arguments.
+  (while (advice--p f) (setq f (advice--cdr f)))
+  (if (eq (car-safe f) 'declared)
+      (byte-compile-arglist-signature (nth 1 f))
+    (condition-case nil
+        (let ((sig (func-arity f)))
+          (if (numberp (cdr sig)) sig (list (car sig))))
+      (error '(0)))))
 
 (defun byte-compile-arglist-signatures-congruent-p (old new)
   (not (or
@@ -1330,19 +1337,7 @@ when printing the error message."
 (defun byte-compile-callargs-warn (form)
   (let* ((def (or (byte-compile-fdefinition (car form) nil)
                  (byte-compile-fdefinition (car form) t)))
-        (sig (if (and def (not (eq def t)))
-                 (progn
-                   (and (eq (car-safe def) 'macro)
-                        (eq (car-safe (cdr-safe def)) 'lambda)
-                        (setq def (cdr def)))
-                   (byte-compile-arglist-signature
-                    (if (memq (car-safe def) '(declared lambda))
-                        (nth 1 def)
-                      (if (byte-code-function-p def)
-                          (aref def 0)
-                        '(&rest def)))))
-               (if (subrp (symbol-function (car form)))
-                   (subr-arity (symbol-function (car form))))))
+        (sig (byte-compile--function-signature def))
         (ncall (length (cdr form))))
     ;; Check many or unevalled from subr-arity.
     (if (and (cdr-safe sig)
@@ -1461,15 +1456,7 @@ extra args."
     (and initial (symbolp initial)
          (setq old (byte-compile-fdefinition initial nil)))
     (when (and old (not (eq old t)))
-      (and (eq 'macro (car-safe old))
-           (eq 'lambda (car-safe (cdr-safe old)))
-           (setq old (cdr old)))
-      (let ((sig1 (byte-compile-arglist-signature
-                   (pcase old
-                     (`(lambda ,args . ,_) args)
-                     (`(closure ,_ ,args . ,_) args)
-                     ((pred byte-code-function-p) (aref old 0))
-                     (_ '(&rest def)))))
+      (let ((sig1 (byte-compile--function-signature old))
             (sig2 (byte-compile-arglist-signature arglist)))
         (unless (byte-compile-arglist-signatures-congruent-p sig1 sig2)
           (byte-compile-set-symbol-position name)
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index c64376b..6a4ee47 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -182,8 +182,7 @@ SPECIALIZERS-FUNCTION takes as first argument a tag value 
TAG
              origname))
     (if generic
         (cl-assert (eq name (cl--generic-name generic)))
-      (setf (cl--generic name) (setq generic (cl--generic-make name)))
-      (defalias name (cl--generic-make-function generic)))
+      (setf (cl--generic name) (setq generic (cl--generic-make name))))
     generic))
 
 ;;;###autoload
@@ -1210,5 +1209,18 @@ Used internally for the (major-mode MODE) context 
specializers."
                     (progn (cl-assert (null modes)) mode)
                   `(derived-mode ,mode . ,modes))))
 
+;;; Support for unloading.
+
+(cl-defmethod loadhist-unload-element ((x (head cl-defmethod)))
+  (pcase-let*
+      ((`(,name ,qualifiers . ,specializers) (cdr x))
+       (generic (cl-generic-ensure-function name 'noerror)))
+    (when generic
+      (let* ((mt (cl--generic-method-table generic))
+             (me (cl--generic-member-method specializers qualifiers mt)))
+        (when me
+          (setf (cl--generic-method-table generic) (delq (car me) mt)))))))
+
+
 (provide 'cl-generic)
 ;;; cl-generic.el ends here
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el
index 936c852..6ac08d8 100644
--- a/lisp/emacs-lisp/cl-lib.el
+++ b/lisp/emacs-lisp/cl-lib.el
@@ -288,14 +288,6 @@ If true return the decimal value of digit CHAR in RADIX."
   (let ((n (aref cl-digit-char-table char)))
     (and n (< n (or radix 10)) n)))
 
-(defun cl--random-time ()
-  (let* ((time (copy-sequence (current-time-string))) (i (length time)) (v 0))
-    (while (>= (cl-decf i) 0) (setq v (+ (* v 3) (aref time i))))
-    v))
-
-(defvar cl--random-state
-  (vector 'cl--random-state-tag -1 30 (cl--random-time)))
-
 (defconst cl-most-positive-float nil
   "The largest value that a Lisp float can hold.
 If your system supports infinities, this is the largest finite value.
@@ -639,7 +631,7 @@ If ALIST is non-nil, the new pairs are prepended to it."
   (require 'cl-seq))
 
 (defun cl--old-struct-type-of (orig-fun object)
-  (or (and (vectorp object)
+  (or (and (vectorp object) (> (length object) 0)
            (let ((tag (aref object 0)))
              (when (and (symbolp tag)
                         (string-prefix-p "cl-struct-" (symbol-name tag)))
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 65e30f8..1494ed1 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -906,7 +906,7 @@ circular objects.  Let `read' read everything else."
                 ;; with the object itself, wherever it occurs.
                 (forward-char 1)
                 (let ((obj (edebug-read-storing-offsets stream)))
-                  (substitute-object-in-subtree obj placeholder)
+                  (lread--substitute-object-in-subtree obj placeholder t)
                   (throw 'return (setf (cdr elem) obj)))))
              ((eq ?# (following-char))
               ;; #n# returns a previously read object.
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index a05bd7c..bca40ab 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -160,6 +160,10 @@ This is used to determine if `eldoc-idle-delay' is changed 
by the user.")
 It should receive the same arguments as `message'.")
 
 (defun eldoc-edit-message-commands ()
+  "Return an obarray containing common editing commands.
+
+When `eldoc-print-after-edit' is non-nil, ElDoc messages are only
+printed after commands contained in this obarray."
   (let ((cmds (make-vector 31 0))
        (re (regexp-opt '("delete" "insert" "edit" "electric" "newline"))))
     (mapatoms (lambda (s)
@@ -211,16 +215,21 @@ expression point is on."
 
 ;;;###autoload
 (defun turn-on-eldoc-mode ()
-  "Turn on `eldoc-mode' if the buffer has eldoc support enabled.
+  "Turn on `eldoc-mode' if the buffer has ElDoc support enabled.
 See `eldoc-documentation-function' for more detail."
   (when (eldoc--supported-p)
     (eldoc-mode 1)))
 
 (defun eldoc--supported-p ()
+  "Non-nil if an ElDoc function is set for this buffer."
   (not (memq eldoc-documentation-function '(nil ignore))))
 
 
 (defun eldoc-schedule-timer ()
+  "Ensure `eldoc-timer' is running.
+
+If the user has changed `eldoc-idle-delay', update the timer to
+reflect the change."
   (or (and eldoc-timer
            (memq eldoc-timer timer-idle-list)) ;FIXME: Why?
       (setq eldoc-timer
@@ -229,8 +238,7 @@ See `eldoc-documentation-function' for more detail."
             (lambda ()
                (when (or eldoc-mode
                          (and global-eldoc-mode
-                              (not (memq eldoc-documentation-function
-                                         '(nil ignore)))))
+                              (eldoc--supported-p)))
                  (eldoc-print-current-symbol-info))))))
 
   ;; If user has changed the idle delay, update the timer.
@@ -268,16 +276,19 @@ Otherwise work like `message'."
           (force-mode-line-update)))
     (apply 'message format-string args)))
 
-(defun eldoc-message (&rest args)
+(defun eldoc-message (&optional format-string &rest args)
+  "Display FORMAT-STRING formatted with ARGS as an ElDoc message.
+
+Store the message (if any) in `eldoc-last-message', and return it."
   (let ((omessage eldoc-last-message))
     (setq eldoc-last-message
-         (cond ((eq (car args) eldoc-last-message) eldoc-last-message)
-               ((null (car args)) nil)
+         (cond ((eq format-string eldoc-last-message) eldoc-last-message)
+               ((null format-string) nil)
                ;; If only one arg, no formatting to do, so put it in
                ;; eldoc-last-message so eq test above might succeed on
                ;; subsequent calls.
-               ((null (cdr args)) (car args))
-               (t (apply #'format-message args))))
+               ((null args) format-string)
+               (t (apply #'format-message format-string args))))
     ;; In emacs 19.29 and later, and XEmacs 19.13 and later, all messages
     ;; are recorded in a log.  Do not put eldoc messages in that log since
     ;; they are Legion.
@@ -289,6 +300,7 @@ Otherwise work like `message'."
   eldoc-last-message)
 
 (defun eldoc--message-command-p (command)
+  "Return non-nil if COMMAND is in `eldoc-message-commands'."
   (and (symbolp command)
        (intern-soft (symbol-name command) eldoc-message-commands)))
 
@@ -299,6 +311,7 @@ Otherwise work like `message'."
 ;; before the next command executes, which does away with the flicker.
 ;; This doesn't seem to be required for Emacs 19.28 and earlier.
 (defun eldoc-pre-command-refresh-echo-area ()
+  "Reprint `eldoc-last-message' in the echo area."
   (and eldoc-last-message
        (not (minibufferp))      ;We don't use the echo area when in minibuffer.
        (if (and (eldoc-display-message-no-interference-p)
@@ -310,6 +323,7 @@ Otherwise work like `message'."
 
 ;; Decide whether now is a good time to display a message.
 (defun eldoc-display-message-p ()
+  "Return non-nil when it is appropriate to display an ElDoc message."
   (and (eldoc-display-message-no-interference-p)
        ;; If this-command is non-nil while running via an idle
        ;; timer, we're still in the middle of executing a command,
@@ -322,6 +336,7 @@ Otherwise work like `message'."
 ;; Check various conditions about the current environment that might make
 ;; it undesirable to print eldoc messages right this instant.
 (defun eldoc-display-message-no-interference-p ()
+  "Return nil if displaying a message would cause interference."
   (not (or executing-kbd-macro (bound-and-true-p edebug-active))))
 
 
@@ -347,6 +362,7 @@ variable) is taken into account if the major mode specific 
function does not
 return any documentation.")
 
 (defun eldoc-print-current-symbol-info ()
+  "Print the text produced by `eldoc-documentation-function'."
   ;; This is run from post-command-hook or some idle timer thing,
   ;; so we need to be careful that errors aren't ignored.
   (with-demoted-errors "eldoc error: %s"
@@ -361,6 +377,13 @@ return any documentation.")
 ;; truncated or eliminated entirely from the output to make room for the
 ;; description.
 (defun eldoc-docstring-format-sym-doc (prefix doc &optional face)
+  "Combine PREFIX and DOC, and shorten the result to fit in the echo area.
+
+When PREFIX is a symbol, propertize its symbol name with FACE
+before combining it with DOC.  If FACE is not provided, just
+apply the nil face.
+
+See also: `eldoc-echo-area-use-multiline-p'."
   (when (symbolp prefix)
     (setq prefix (concat (propertize (symbol-name prefix) 'face face) ": ")))
   (let* ((ea-multi eldoc-echo-area-use-multiline-p)
@@ -390,22 +413,26 @@ return any documentation.")
 ;; These functions do display-command table management.
 
 (defun eldoc-add-command (&rest cmds)
+  "Add each of CMDS to the obarray `eldoc-message-commands'."
   (dolist (name cmds)
     (and (symbolp name)
          (setq name (symbol-name name)))
     (set (intern name eldoc-message-commands) t)))
 
 (defun eldoc-add-command-completions (&rest names)
+  "Pass every prefix completion of NAMES to `eldoc-add-command'."
   (dolist (name names)
     (apply #'eldoc-add-command (all-completions name obarray 'commandp))))
 
 (defun eldoc-remove-command (&rest cmds)
+  "Remove each of CMDS from the obarray `eldoc-message-commands'."
   (dolist (name cmds)
     (and (symbolp name)
          (setq name (symbol-name name)))
     (unintern name eldoc-message-commands)))
 
 (defun eldoc-remove-command-completions (&rest names)
+  "Pass every prefix completion of NAMES to `eldoc-remove-command'."
   (dolist (name names)
     (apply #'eldoc-remove-command
            (all-completions name eldoc-message-commands))))
@@ -418,9 +445,9 @@ return any documentation.")
  "down-list" "end-of-" "exchange-point-and-mark" "forward-" "goto-"
  "handle-select-window" "indent-for-tab-command" "left-" "mark-page"
  "mark-paragraph" "mouse-set-point" "move-" "move-beginning-of-"
- "move-end-of-" "newline" "next-" "other-window" "pop-global-mark" "previous-"
- "recenter" "right-" "scroll-" "self-insert-command" "split-window-"
- "up-list")
+ "move-end-of-" "newline" "next-" "other-window" "pop-global-mark"
+ "previous-" "recenter" "right-" "scroll-" "self-insert-command"
+ "split-window-" "up-list")
 
 (provide 'eldoc)
 
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index eb2b2e3..5c88b07 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -136,8 +136,15 @@ Emacs bug 6581 at URL 
`http://debbugs.gnu.org/cgi/bugreport.cgi?bug=6581'."
     ;; ert-test objects.  It designates an anonymous test.
     (error "Attempt to define a test named nil"))
   (put symbol 'ert--test definition)
+  ;; Register in load-history, so `symbol-file' can find us, and so
+  ;; unload-feature can unload our tests.
+  (cl-pushnew `(ert-deftest . ,symbol) current-load-list :test #'equal)
   definition)
 
+(cl-defmethod loadhist-unload-element ((x (head ert-deftest)))
+  (let ((name (cdr x)))
+    (put name 'ert--test nil)))
+
 (defun ert-make-test-unbound (symbol)
   "Make SYMBOL name no test.  Return SYMBOL."
   (cl-remprop symbol 'ert--test)
@@ -214,12 +221,6 @@ description of valid values for RESULT-TYPE.
                         ,@(when tags-supplied-p
                             `(:tags ,tags))
                         :body (lambda () ,@body)))
-         ;; This hack allows `symbol-file' to associate `ert-deftest'
-         ;; forms with files, and therefore enables `find-function' to
-         ;; work with tests.  However, it leads to warnings in
-         ;; `unload-feature', which doesn't know how to undefine tests
-         ;; and has no mechanism for extension.
-         (push '(ert-deftest . ,name) current-load-list)
          ',name))))
 
 ;; We use these `put' forms in addition to the (declare (indent)) in
@@ -1512,7 +1513,7 @@ Ran \\([0-9]+\\) tests, \\([0-9]+\\) results as expected\
       (message "%d files contained unexpected results:" (length unexpected))
       (mapc (lambda (l) (message "  %s" l)) unexpected))
     ;; More details on hydra, where the logs are harder to get to.
-    (when (and (getenv "NIX_STORE")
+    (when (and (getenv "EMACS_HYDRA_CI")
                (not (zerop (+ nunexpected nskipped))))
       (message "\nDETAILS")
       (message "-------")
diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el
index c5c12a6..27376fc 100644
--- a/lisp/emacs-lisp/gv.el
+++ b/lisp/emacs-lisp/gv.el
@@ -377,10 +377,12 @@ The return value is the last VAL in the list.
     `(with-current-buffer ,buf (set (make-local-variable ,var) ,v))))
 
 (gv-define-expander alist-get
-  (lambda (do key alist &optional default remove)
+  (lambda (do key alist &optional default remove testfn)
     (macroexp-let2 macroexp-copyable-p k key
       (gv-letplace (getter setter) alist
-        (macroexp-let2 nil p `(assq ,k ,getter)
+        (macroexp-let2 nil p `(if (and ,testfn (not (eq ,testfn 'eq)))
+                                  (assoc ,k ,getter ,testfn)
+                                (assq ,k ,getter))
           (funcall do (if (null default) `(cdr ,p)
                         `(if ,p (cdr ,p) ,default))
                    (lambda (v)
diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index a89457e..e098eef 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -4,7 +4,7 @@
 
 ;; Author: Nicolas Petton <address@hidden>
 ;; Keywords: convenience, map, hash-table, alist, array
-;; Version: 1.1
+;; Version: 1.2
 ;; Package: map
 
 ;; Maintainer: address@hidden
@@ -93,11 +93,13 @@ Returns the result of evaluating the form associated with 
MAP-VAR's type."
            ((arrayp ,map-var) ,(plist-get args :array))
            (t (error "Unsupported map: %s" ,map-var)))))
 
-(defun map-elt (map key &optional default)
+(defun map-elt (map key &optional default testfn)
   "Lookup KEY in MAP and return its associated value.
 If KEY is not found, return DEFAULT which defaults to nil.
 
-If MAP is a list, `eql' is used to lookup KEY.
+If MAP is a list, `eql' is used to lookup KEY.  Optional argument
+TESTFN, if non-nil, means use its function definition instead of
+`eql'.
 
 MAP can be a list, hash-table or array."
   (declare
@@ -106,30 +108,31 @@ MAP can be a list, hash-table or array."
       (gv-letplace (mgetter msetter) `(gv-delay-error ,map)
         (macroexp-let2* nil
             ;; Eval them once and for all in the right order.
-            ((key key) (default default))
+            ((key key) (default default) (testfn testfn))
           `(if (listp ,mgetter)
                ;; Special case the alist case, since it can't be handled by the
                ;; map--put function.
                ,(gv-get `(alist-get ,key (gv-synthetic-place
                                           ,mgetter ,msetter)
-                                    ,default)
+                                    ,default nil ,testfn)
                         do)
              ,(funcall do `(map-elt ,mgetter ,key ,default)
                        (lambda (v) `(map--put ,mgetter ,key ,v)))))))))
   (map--dispatch map
-    :list (alist-get key map default)
+    :list (alist-get key map default nil testfn)
     :hash-table (gethash key map default)
     :array (if (and (>= key 0) (< key (seq-length map)))
                (seq-elt map key)
              default)))
 
-(defmacro map-put (map key value)
+(defmacro map-put (map key value &optional testfn)
   "Associate KEY with VALUE in MAP and return VALUE.
 If KEY is already present in MAP, replace the associated value
 with VALUE.
+When MAP is a list, test equality with TESTFN if non-nil, otherwise use `eql'.
 
 MAP can be a list, hash-table or array."
-  `(setf (map-elt ,map ,key) ,value))
+  `(setf (map-elt ,map ,key nil ,testfn) ,value))
 
 (defun map-delete (map key)
   "Delete KEY from MAP and return MAP.
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el
index fd1cd2c..c68ecbc 100644
--- a/lisp/emacs-lisp/nadvice.el
+++ b/lisp/emacs-lisp/nadvice.el
@@ -385,6 +385,18 @@ of the piece of advice."
 
 (defun advice--defalias-fset (fsetfun symbol newdef)
   (unless fsetfun (setq fsetfun #'fset))
+  ;; `newdef' shouldn't include advice wrappers, since that's what *we* manage!
+  ;; So if `newdef' includes advice wrappers, it's usually because someone
+  ;; naively took (symbol-function F) and then passed that back to `defalias':
+  ;; let's strip them away.
+  (cond
+   ((advice--p newdef) (setq newdef (advice--cd*r newdef)))
+   ((and (eq 'macro (car-safe newdef))
+         (advice--p (cdr newdef)))
+    (setq newdef `(macro . ,(advice--cd*r (cdr newdef))))))
+  ;; The saved-rewrite is specific to the current value, so since we are about
+  ;; to overwrite that current value with new value, the old saved-rewrite is
+  ;; not relevant any more.
   (when (get symbol 'advice--saved-rewrite)
     (put symbol 'advice--saved-rewrite nil))
   (setq newdef (advice--normalize symbol newdef))
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 4a06ab2..b401611 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -930,6 +930,5 @@ QPAT can take the following forms:
    ((or (stringp qpat) (integerp qpat) (symbolp qpat)) `',qpat)
    (t (error "Unknown QPAT: %S" qpat))))
 
-
 (provide 'pcase)
 ;;; pcase.el ends here
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index 386232c..b66f2c6 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -1169,6 +1169,62 @@ enclosed in `(and ...)'.
         (rx-to-string `(and ,@regexps) t))
        (t
         (rx-to-string (car regexps) t))))
+
+
+(pcase-defmacro rx (&rest regexps)
+  "Build a `pcase' pattern matching `rx' regexps.
+The REGEXPS are interpreted as by `rx'.  The pattern matches if
+the regular expression so constructed matches the object, as if
+by `string-match'.
+
+In addition to the usual `rx' constructs, REGEXPS can contain the
+following constructs:
+
+  (let VAR FORM...)  creates a new explicitly numbered submatch
+                     that matches FORM and binds the match to
+                     VAR.
+  (backref VAR)      creates a backreference to the submatch
+                     introduced by a previous (let VAR ...)
+                     construct.
+
+The VARs are associated with explicitly numbered submatches
+starting from 1.  Multiple occurrences of the same VAR refer to
+the same submatch.
+
+If a case matches, the match data is modified as usual so you can
+use it in the case body, but you still have to pass the correct
+string as argument to `match-string'."
+  (let* ((vars ())
+         (rx-constituents
+          `((let
+             ,(lambda (form)
+                (rx-check form)
+                (let ((var (cadr form)))
+                  (cl-check-type var symbol)
+                  (let ((i (or (cl-position var vars :test #'eq)
+                               (prog1 (length vars)
+                                 (setq vars `(,@vars ,var))))))
+                    (rx-form `(submatch-n ,(1+ i) ,@(cddr form))))))
+             1 nil)
+            (backref
+             ,(lambda (form)
+                (rx-check form)
+                (rx-backref
+                 `(backref ,(let ((var (cadr form)))
+                              (if (integerp var) var
+                                (1+ (cl-position var vars :test #'eq)))))))
+             1 1
+             ,(lambda (var)
+                (cond ((integerp var) (rx-check-backref var))
+                      ((memq var vars) t)
+                      (t (error "rx `backref' variable must be one of %s: %s"
+                                vars var)))))
+            ,@rx-constituents))
+         (regexp (rx-to-string `(seq ,@regexps) :no-group)))
+    `(and (pred (string-match ,regexp))
+          ,@(cl-loop for i from 1
+                     for var in vars
+                     collect `(app (match-string ,i) ,var)))))
 
 ;; ;; sregex.el replacement
 
diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el
index 8c81b43..2fd1db2 100644
--- a/lisp/eshell/em-prompt.el
+++ b/lisp/eshell/em-prompt.el
@@ -161,14 +161,25 @@ If N is negative, find the previous or Nth previous 
match."
   "Move to end of Nth next prompt in the buffer.
 See `eshell-prompt-regexp'."
   (interactive "p")
-  (forward-paragraph n)
+  (if eshell-highlight-prompt
+      (progn
+        (while (< n 0)
+          (while (and (re-search-backward eshell-prompt-regexp nil t)
+                      (not (get-text-property (match-beginning 0) 
'read-only))))
+          (setq n (1+ n)))
+        (while (> n 0)
+          (while (and (re-search-forward eshell-prompt-regexp nil t)
+                      (not (get-text-property (match-beginning 0) 
'read-only))))
+          (setq n (1- n))))
+    (re-search-forward eshell-prompt-regexp nil t n))
   (eshell-skip-prompt))
 
 (defun eshell-previous-prompt (n)
   "Move to end of Nth previous prompt in the buffer.
 See `eshell-prompt-regexp'."
   (interactive "p")
-  (eshell-next-prompt (- (1+ n))))
+  (beginning-of-line)            ; Don't count prompt on current line.
+  (eshell-next-prompt (- n)))
 
 (defun eshell-skip-prompt ()
   "Skip past the text matching regexp `eshell-prompt-regexp'.
diff --git a/lisp/faces.el b/lisp/faces.el
index 9a8a134..97c3216 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -102,11 +102,16 @@ a font height that isn't optimal."
     ;; Monospace Serif is an Emacs invention, intended to work around
     ;; portability problems when using Courier.  It should work well
     ;; when combined with Monospaced and with other standard fonts.
+    ;; One of its uses is for 'tex-verbatim' and 'Info-quoted' faces,
+    ;; so the result must be different from the default face's font,
+    ;; and must be monospaced.
     ("Monospace Serif"
 
      ;; This looks good on GNU/Linux.
      "Courier 10 Pitch"
-     ;; This looks good on MS-Windows and OS X.
+     ;; This looks good on MS-Windows and OS X.  Note that this is
+     ;; actually a sans-serif font, but it's here for lack of a better
+     ;; alternative.
      "Consolas"
      ;; This looks good on macOS.  "Courier" looks good too, but is
      ;; jagged on GNU/Linux and so is listed later as "courier".
@@ -2465,6 +2470,33 @@ If you set `term-file-prefix' to nil, this function does 
nothing."
   :version "21.1"
   :group 'basic-faces)
 
+;; Definition stolen from linum.el.
+(defface line-number
+  '((t :inherit (shadow default)))
+  "Face for displaying line numbers.
+This face is used when `display-line-numbers' is non-nil.
+
+If you customize the font of this face, make sure it is a
+monospaced font, otherwise line numbers will not line up,
+and text lines might move horizontally as you move through
+the buffer."
+  :version "26.1"
+  :group 'basic-faces)
+
+(defface line-number-current-line
+  '((t :inherit line-number))
+  "Face for displaying the current line number.
+This face is used when `display-line-numbers' is non-nil.
+
+If you customize the font of this face, make sure it is a
+monospaced font, otherwise line numbers will not line up,
+and text lines might move horizontally as you move through
+the buffer.  Similarly, making this face's font different
+from that of the `line-number' face could produce such
+unwanted effects."
+  :version "26.1"
+  :group 'basic-faces)
+
 (defface escape-glyph
   '((((background dark)) :foreground "cyan")
     ;; See the comment in minibuffer-prompt for
diff --git a/lisp/files.el b/lisp/files.el
index 06f49bb..321a35b 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -434,8 +434,11 @@ and toggle it if ARG is `toggle'."
              (not (and buffer-auto-save-file-name
                        auto-save-visited-file-name)))))))
 
+;; The 'set' part is so we don't get a warning for using this variable
+;; above, while still catching code that _sets_ the variable to get
+;; the same effect as the new auto-save-visited-mode.
 (make-obsolete-variable 'auto-save-visited-file-name 'auto-save-visited-mode
-                        "Emacs 26.1")
+                        "Emacs 26.1" 'set)
 
 (defcustom save-abbrevs t
   "Non-nil means save word abbrevs too when files are saved.
@@ -2540,7 +2543,7 @@ since only a single case-insensitive search through the 
alist is made."
      ("\\.[ckz]?sh\\'\\|\\.shar\\'\\|/\\.z?profile\\'" . sh-mode)
      ("\\.bash\\'" . sh-mode)
      
("\\(/\\|\\`\\)\\.\\(bash_\\(profile\\|history\\|log\\(in\\|out\\)\\)\\|z?log\\(in\\|out\\)\\)\\'"
 . sh-mode)
-     ("\\(/\\|\\`\\)\\.\\(shrc\\|[kz]shrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . 
sh-mode)
+     
("\\(/\\|\\`\\)\\.\\(shrc\\|zshrc\\|m?kshrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . 
sh-mode)
      ("\\(/\\|\\`\\)\\.\\([kz]shenv\\|xinitrc\\|startxrc\\|xsession\\)\\'" . 
sh-mode)
      ("\\.m?spec\\'" . sh-mode)
      ("\\.m[mes]\\'" . nroff-mode)
diff --git a/lisp/frame.el b/lisp/frame.el
index b54df6f..634367e 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -1482,6 +1482,7 @@ FRAME."
 
 (declare-function w32-mouse-absolute-pixel-position "w32fns.c")
 (declare-function x-mouse-absolute-pixel-position "xfns.c")
+(declare-function ns-mouse-absolute-pixel-position "nsfns.c")
 
 (defun mouse-absolute-pixel-position ()
   "Return absolute position of mouse cursor in pixels.
@@ -1494,6 +1495,8 @@ position (0, 0) of the selected frame's terminal."
       (x-mouse-absolute-pixel-position))
      ((eq frame-type 'w32)
       (w32-mouse-absolute-pixel-position))
+     ((eq frame-type 'ns)
+      (ns-mouse-absolute-pixel-position))
      (t
       (cons 0 0)))))
 
@@ -2458,7 +2461,13 @@ See also `toggle-frame-maximized'."
 (make-obsolete-variable
  'window-system-version "it does not give useful information." "24.3")
 
-;; Variables which should trigger redisplay of the current buffer.
+;; Variables whose change of value should trigger redisplay of the
+;; current buffer.
+;; To test whether a given variable needs to be added to this list,
+;; write a simple interactive function that changes the variable's
+;; value and bind that function to a simple key, like F5.  If typing
+;; F5 then produces the correct effect, the variable doesn't need
+;; to be in this list; otherwise, it does.
 (mapc (lambda (var)
         (add-variable-watcher var (symbol-function 'set-buffer-redisplay)))
       '(line-spacing
@@ -2466,6 +2475,10 @@ See also `toggle-frame-maximized'."
         line-prefix
         wrap-prefix
         truncate-lines
+        display-line-numbers
+        display-line-numbers-width
+        display-line-numbers-current-absolute
+        display-line-numbers-widen
         bidi-paragraph-direction
         bidi-display-reordering))
 
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 9bdd0c6..f2e51fb 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -9780,8 +9780,11 @@ If ARG is a negative number, hide the unwanted header 
lines."
             (inhibit-point-motion-hooks t)
             (hidden (if (numberp arg)
                         (>= arg 0)
-                      (or (not (looking-at "[^ \t\n]+:"))
-                          (gnus-article-hidden-text-p 'headers))))
+                      (or
+                       ;; The case where there's no visible header
+                       ;; that matches `gnus-visible-headers'.
+                       (looking-at "\n?\\'")
+                       (gnus-article-hidden-text-p 'headers))))
             s e)
        (delete-region (point-min) (point-max))
        (with-current-buffer gnus-original-article-buffer
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index f5d94d8..cb0b2d7 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -564,7 +564,6 @@ FILE is the file where FUNCTION was probably defined."
   "Return information about FUNCTION.
 Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)."
   (let* ((advised (and (symbolp function)
-                      (featurep 'nadvice)
                       (advice--p (advice--symbol-function function))))
         ;; If the function is advised, use the symbol that has the
         ;; real definition, if that symbol is already set up.
diff --git a/lisp/help.el b/lisp/help.el
index 0fb1c2d..bc7ee2c 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -1384,6 +1384,9 @@ If PRESERVE-NAMES is non-nil, return a formal arglist 
that uses
 the same names as used in the original source code, when possible."
   ;; Handle symbols aliased to other symbols.
   (if (and (symbolp def) (fboundp def)) (setq def (indirect-function def)))
+  ;; Advice wrappers have "catch all" args, so fetch the actual underlying
+  ;; function to find the real arguments.
+  (while (advice--p def) (setq def (advice--cdr def)))
   ;; If definition is a macro, find the function inside it.
   (if (eq (car-safe def) 'macro) (setq def (cdr def)))
   (cond
diff --git a/lisp/international/characters.el b/lisp/international/characters.el
index 33cb3d8..e48fc83 100644
--- a/lisp/international/characters.el
+++ b/lisp/international/characters.el
@@ -148,6 +148,7 @@ with L, LRE, or LRO Unicode bidi character type.")
 (modify-category-entry '(#xF900 . #xFAFF) ?C)
 (modify-category-entry '(#xF900 . #xFAFF) ?c)
 (modify-category-entry '(#xF900 . #xFAFF) ?|)
+(modify-category-entry '(#x1B170 . #x1B2FF) ?c)
 (modify-category-entry '(#x20000 . #x2FFFF) ?|)
 (modify-category-entry '(#x20000 . #x2FFFF) ?C)
 (modify-category-entry '(#x20000 . #x2FFFF) ?c)
@@ -221,6 +222,8 @@ with L, LRE, or LRO Unicode bidi character type.")
 (modify-category-entry #x30A0 ?H)
 (modify-category-entry #x30FC ?H)
 
+(modify-category-entry '(#x1B000 . #x1B1FF) ?j)
+
 
 ;; JISX0208
 (map-charset-chars #'modify-syntax-entry 'japanese-jisx0208 "_" #x2121 #x227E)
@@ -1196,10 +1199,11 @@ with L, LRE, or LRO Unicode bidi character type.")
           (#xFE30 . #xFE6F)
           (#xFF01 . #xFF60)
           (#xFFE0 . #xFFE6)
-          (#x16FE0 . #x16FE0)
+          (#x16FE0 . #x16FE1)
           (#x17000 . #x187EC)
           (#x18800 . #x18AF2)
-          (#x1B000 . #x1B001)
+          (#x1B000 . #x1B11E)
+           (#x1B170 . #x1B2FB)
           (#x1F004 . #x1F004)
           (#x1F0CF . #x1F0CF)
           (#x1F18E . #x1F18E)
@@ -1229,15 +1233,13 @@ with L, LRE, or LRO Unicode bidi character type.")
           (#x1F6CC . #x1F6CC)
           (#x1F6D0 . #x1F6D2)
           (#x1F6EB . #x1F6EC)
-          (#x1F6F4 . #x1F6F6)
-          (#x1F910 . #x1F91E)
-          (#x1F920 . #x1F927)
-          (#x1F930 . #x1F930)
-          (#x1F933 . #x1F93E)
-          (#x1F940 . #x1F94B)
-          (#x1F950 . #x1F95E)
-          (#x1F980 . #x1F991)
+          (#x1F6F4 . #x1F6F8)
+          (#x1F910 . #x1F93E)
+          (#x1F940 . #x1F94C)
+          (#x1F950 . #x1F96B)
+          (#x1F980 . #x1F997)
           (#x1F9C0 . #x1F9C0)
+           (#x1F9D0 . #x1F9E6)
           (#x20000 . #x2FFFF)
           (#x30000 . #x3FFFF))))
   (dolist (elt l)
diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el
index e023d25..8a1a9cf 100644
--- a/lisp/international/fontset.el
+++ b/lisp/international/fontset.el
@@ -227,9 +227,12 @@
        (modi #x11600)
        (takri #x11680)
        (warang-citi #x118A1)
+        (zanabazar-square #x11A00)
+        (soyombo #x11A50)
        (pau-cin-hau #x11AC0)
         (bhaiksuki #x11C00)
         (marchen #x11C72)
+        (masaram-gondi #x11D00)
        (cuneiform #x12000)
        (cuneiform-numbers-and-punctuation #x12400)
        (mro #x16A40)
@@ -237,6 +240,7 @@
        (pahawh-hmong #x16B11)
         (tangut #x17000)
         (tangut-components #x18800)
+        (nushu #x1B170)
        (duployan-shorthand #x1BC20)
        (byzantine-musical-symbol #x1D000)
        (musical-symbol #x1D100)
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index bdba8ee..bcbc928 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -2945,8 +2945,10 @@ on encoding."
                ;; (#x17000 . #x187FF) Tangut Ideographs
                ;; (#x18800 . #x18AFF) Tangut Components
               ;; (#x18B00 . #x1AFFF) unused
-              (#x1B000 . #x1B0FF)
-              ;; (#x1B100 . #x1BBFF) unused
+              (#x1B000 . #x1B12F)
+               ;; (#x1B130 . #x1B16F) unused
+               (#x1B170 . #x1B2FF)
+              ;; (#x1B300 . #x1BBFF) unused
                (#x1BC00 . #x1BCAF)
               ;; (#x1BCB0 . #x1CFFF) unused
               (#x1D000 . #x1FFFF)
diff --git a/lisp/kmacro.el b/lisp/kmacro.el
index 838a492..472972e 100644
--- a/lisp/kmacro.el
+++ b/lisp/kmacro.el
@@ -565,7 +565,8 @@ Use \\[kmacro-insert-counter] to insert (and increment) the 
macro counter.
 The counter value can be set or modified via \\[kmacro-set-counter] and 
\\[kmacro-add-counter].
 The format of the counter can be modified via \\[kmacro-set-format].
 
-Use \\[kmacro-name-last-macro] to give it a permanent name.
+Use \\[kmacro-name-last-macro] to give it a name that will remain valid even
+after another macro is defined.
 Use \\[kmacro-bind-to-key] to bind it to a key sequence."
   (interactive "P")
   (if (or defining-kbd-macro executing-kbd-macro)
@@ -628,8 +629,8 @@ just the last key in the key sequence that you used to call 
this
 command.  See `kmacro-call-repeat-key' and `kmacro-call-repeat-with-arg'
 for details on how to adjust or disable this behavior.
 
-To make a macro permanent so you can call it even after defining
-others, use \\[kmacro-name-last-macro]."
+To give a macro a name so you can call it even after defining others,
+use \\[kmacro-name-last-macro]."
   (interactive "p")
   (let ((repeat-key (and (or (and (null no-repeat)
                                   (> (length (this-single-command-keys)) 1))
@@ -730,8 +731,8 @@ With \\[universal-argument], call second macro in macro 
ring."
 With numeric prefix ARG, repeat macro that many times.
 Zero argument means repeat until there is an error.
 
-To give a macro a permanent name, so you can call it
-even after defining other macros, use \\[kmacro-name-last-macro]."
+To give a macro a name, so you can call it even after defining other
+macros, use \\[kmacro-name-last-macro]."
   (interactive "P")
   (if defining-kbd-macro
       (kmacro-end-macro nil))
diff --git a/lisp/leim/quail/latin-alt.el b/lisp/leim/quail/latin-alt.el
index 6c0dab2..cc72134 100644
--- a/lisp/leim/quail/latin-alt.el
+++ b/lisp/leim/quail/latin-alt.el
@@ -1152,7 +1152,7 @@ Doubling the postfix separates the letter and postfix: 
e.g. a^^ -> a^
 (quail-define-package
  "dutch" "Dutch" "NL" t
  "Dutch character mixfix input method.
-Caters for French and Turkish as well as Dutch.
+Caters for French and Dutch.
 
              |         | examples
  ------------+---------+----------
@@ -1163,8 +1163,6 @@ Caters for French and Turkish as well as Dutch.
   acute      |    \\='    | a\\=' -> á
   grave      |    \\=`    | a\\=` -> à
   circumflex |    ^    | a^ -> â
-  Turkish    | various | i/ -> ı  s, -> ş  g^ -> ğ   I/ -> İ
-             |         |  S, -> Ş  G^ -> Ğ
  ------------+---------+----------
              | prefix  |
  ------------+---------+----------
@@ -1176,9 +1174,6 @@ Doubling the postfix separates the letter and postfix: 
e.g. a\\='\\=' -> a\\='
 (quail-define-rules
  ("fl." ?ƒ) ;; LATIN SMALL LETTER F WITH HOOK (florin currency symbol)
  ("eur." ?€) ;; EURO SIGN
- ;; “The 25th letter of the Dutch alphabet.”
- ("ij" ?ij) ;; LATIN SMALL LIGATURE IJ
- ("IJ" ?IJ) ;; LATIN CAPITAL LIGATURE IJ
  ;; “Trema on the second letter of vowel pair.”  Yudit uses `:', not `"'.
  ("\"a" ?ä) ;; LATIN SMALL LETTER A WITH DIAERESIS
  ("\"e" ?ë) ;; LATIN SMALL LETTER E WITH DIAERESIS
@@ -1226,15 +1221,6 @@ Doubling the postfix separates the letter and postfix: 
e.g. a\\='\\=' -> a\\='
  ("I^" ?Î) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX
  ("O^" ?Ô) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX
  ("U^" ?Û) ;; LATIN CAPITAL LETTER U WITH CIRCUMFLEX
- ;; “Follow the example of the Dutch POSIX locale, using ISO-8859-9 to
- ;; cater to the many Turks in Dutch society.”  Perhaps German methods
- ;; should do so too.  Follow turkish-alt-postfix here.
- ("i/" ?ı) ;; LATIN SMALL LETTER I WITH NO DOT
- ("s," ?ş) ;; LATIN SMALL LETTER S WITH CEDILLA
- ("g^" ?ğ) ;; LATIN SMALL LETTER G WITH BREVE
- ("I/" ?İ) ;; LATIN CAPITAL LETTER I WITH DOT ABOVE
- ("S," ?Ş) ;; LATIN CAPITAL LETTER S WITH CEDILLA
- ("G^" ?Ğ) ;; LATIN CAPITAL LETTER G WITH BREVE
  )
 
 ;; Originally from Yudit, discussed with Albertas Agejevas
diff --git a/lisp/loadhist.el b/lisp/loadhist.el
index 28d0b18..24c3acd 100644
--- a/lisp/loadhist.el
+++ b/lisp/loadhist.el
@@ -162,6 +162,65 @@ documentation of `unload-feature' for details.")
           ;; mode, or proposed is not nil and not major-mode, and so we use it.
           (funcall (or proposed 'fundamental-mode)))))))
 
+(cl-defgeneric loadhist-unload-element (x)
+  "Unload an element from the `load-history'."
+  (message "Unexpected element %S in load-history" x))
+
+;; In `load-history', the definition of a previously autoloaded
+;; function is represented by 2 entries: (t . SYMBOL) comes before
+;; (defun . SYMBOL) and says we should restore SYMBOL's autoload when
+;; we undefine it.
+;; So we use this auxiliary variable to keep track of the last (t . SYMBOL)
+;; that occurred.
+(defvar loadhist--restore-autoload
+  "If non-nil, this is a symbol for which we should
+restore a previous autoload if possible.")
+
+(cl-defmethod loadhist-unload-element ((x (head t)))
+  (setq loadhist--restore-autoload (cdr x)))
+
+(defun loadhist--unload-function (x)
+  (let ((fun (cdr x)))
+    (when (fboundp fun)
+      (when (fboundp 'ad-unadvise)
+       (ad-unadvise fun))
+      (let ((aload (get fun 'autoload)))
+       (defalias fun
+          (if (and aload (eq fun loadhist--restore-autoload))
+             (cons 'autoload aload)
+            nil)))))
+  (setq loadhist--restore-autoload nil))
+
+(cl-defmethod loadhist-unload-element ((x (head defun)))
+  (loadhist--unload-function x))
+(cl-defmethod loadhist-unload-element ((x (head autoload)))
+  (loadhist--unload-function x))
+
+(cl-defmethod loadhist-unload-element ((_ (head require))) nil)
+(cl-defmethod loadhist-unload-element ((_ (head defface))) nil)
+
+(cl-defmethod loadhist-unload-element ((x (head provide)))
+  ;; Remove any feature names that this file provided.
+  (setq features (delq (cdr x) features)))
+
+(cl-defmethod loadhist-unload-element ((x symbol))
+  ;; Kill local values as much as possible.
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (if (and (boundp x) (timerp (symbol-value x)))
+         (cancel-timer (symbol-value x)))
+      (kill-local-variable x)))
+  (if (and (boundp x) (timerp (symbol-value x)))
+      (cancel-timer (symbol-value x)))
+  ;; Get rid of the default binding if we can.
+  (unless (local-variable-if-set-p x)
+    (makunbound x)))
+
+(cl-defmethod loadhist-unload-element ((x (head define-type)))
+  (let* ((name (cdr x)))
+    ;; Remove the struct.
+    (setf (cl--find-class name) nil)))
+
 ;;;###autoload
 (defun unload-feature (feature &optional force)
   "Unload the library that provided FEATURE.
@@ -200,9 +259,6 @@ something strange, such as redefining an Emacs function."
               (prin1-to-string dependents) file))))
   (let* ((unload-function-defs-list (feature-symbols feature))
          (file (pop unload-function-defs-list))
-        ;; If non-nil, this is a symbol for which we should
-        ;; restore a previous autoload if possible.
-        restore-autoload
         (name (symbol-name feature))
          (unload-hook (intern-soft (concat name "-unload-hook")))
         (unload-func (intern-soft (concat name "-unload-function"))))
@@ -250,38 +306,7 @@ something strange, such as redefining an Emacs function."
          (when (symbolp elt)
            (elp-restore-function elt))))
 
-      (dolist (x unload-function-defs-list)
-       (if (consp x)
-           (pcase (car x)
-             ;; Remove any feature names that this file provided.
-             (`provide
-              (setq features (delq (cdr x) features)))
-             ((or `defun `autoload)
-              (let ((fun (cdr x)))
-                (when (fboundp fun)
-                  (when (fboundp 'ad-unadvise)
-                    (ad-unadvise fun))
-                  (let ((aload (get fun 'autoload)))
-                    (if (and aload (eq fun restore-autoload))
-                        (fset fun (cons 'autoload aload))
-                      (fmakunbound fun))))))
-             ;; (t . SYMBOL) comes before (defun . SYMBOL)
-             ;; and says we should restore SYMBOL's autoload
-             ;; when we undefine it.
-             (`t (setq restore-autoload (cdr x)))
-             ((or `require `defface) nil)
-             (_ (message "Unexpected element %s in load-history" x)))
-         ;; Kill local values as much as possible.
-         (dolist (buf (buffer-list))
-           (with-current-buffer buf
-             (if (and (boundp x) (timerp (symbol-value x)))
-                 (cancel-timer (symbol-value x)))
-             (kill-local-variable x)))
-         (if (and (boundp x) (timerp (symbol-value x)))
-             (cancel-timer (symbol-value x)))
-         ;; Get rid of the default binding if we can.
-         (unless (local-variable-if-set-p x)
-           (makunbound x))))
+      (mapc #'loadhist-unload-element unload-function-defs-list)
       ;; Delete the load-history element for this file.
       (setq load-history (delq (assoc file load-history) load-history))))
   ;; Don't return load-history, it is not useful.
diff --git a/lisp/ls-lisp.el b/lisp/ls-lisp.el
index 7ae2343..b368efb 100644
--- a/lisp/ls-lisp.el
+++ b/lisp/ls-lisp.el
@@ -245,11 +245,11 @@ to fail to line up, e.g. if month names are not all of 
the same length."
   "Format to display integer GIDs.")
 (defvar ls-lisp-gid-s-fmt " %s"
   "Format to display user group names.")
-(defvar ls-lisp-filesize-d-fmt "%d"
+(defvar ls-lisp-filesize-d-fmt " %d"
   "Format to display integer file sizes.")
-(defvar ls-lisp-filesize-f-fmt "%.0f"
+(defvar ls-lisp-filesize-f-fmt " %.0f"
   "Format to display float file sizes.")
-(defvar ls-lisp-filesize-b-fmt "%.0f"
+(defvar ls-lisp-filesize-b-fmt " %.0f"
   "Format to display file sizes in blocks (for the -s switch).")
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index df07140..b240588 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -2828,8 +2828,6 @@ The current mail message becomes the message displayed."
                 (re-search-forward "mime-version: 1.0" nil t))
            (let ((rmail-buffer mbox-buf)
                  (rmail-view-buffer view-buf))
-             (setq showing-message t)
-             (message "Showing message %d..." msg)
              (set (make-local-variable 'rmail-mime-decoded) t)
              (funcall rmail-show-mime-function))
          (setq body-start (search-forward "\n\n" nil t))
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index 9c7bcff..05a336b 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -1101,17 +1101,77 @@ The selected font will be the default on both the 
existing and future frames."
                     :button (:radio . (eq tool-bar-mode nil))))
       menu)))
 
+(defun menu-bar-display-line-numbers-mode (type)
+  (setq display-line-numbers-type type)
+  (if global-display-line-numbers-mode
+      (global-display-line-numbers-mode)
+    (display-line-numbers-mode)))
+
+(defvar menu-bar-showhide-line-numbers-menu
+  (let ((menu (make-sparse-keymap "Line Numbers")))
+
+    (bindings--define-key menu [visual]
+      `(menu-item "Visual Line Numbers"
+                  ,(lambda ()
+                     (interactive)
+                     (menu-bar-display-line-numbers-mode 'visual)
+                     (message "Visual line numbers enabled"))
+                  :help "Enable visual line numbers"
+                  :button (:radio . (eq display-line-numbers 'visual))
+                  :visible (menu-bar-menu-frame-live-and-visible-p)))
+
+    (bindings--define-key menu [relative]
+      `(menu-item "Relative Line Numbers"
+                  ,(lambda ()
+                     (interactive)
+                     (menu-bar-display-line-numbers-mode 'relative)
+                     (message "Relative line numbers enabled"))
+                  :help "Enable relative line numbers"
+                  :button (:radio . (eq display-line-numbers 'relative))
+                  :visible (menu-bar-menu-frame-live-and-visible-p)))
+
+    (bindings--define-key menu [absolute]
+      `(menu-item "Absolute Line Numbers"
+                  ,(lambda ()
+                     (interactive)
+                     (menu-bar-display-line-numbers-mode t)
+                     (setq display-line-numbers t)
+                     (message "Absolute line numbers enabled"))
+                  :help "Enable absolute line numbers"
+                  :button (:radio . (eq display-line-numbers t))
+                  :visible (menu-bar-menu-frame-live-and-visible-p)))
+
+    (bindings--define-key menu [none]
+      `(menu-item "No Line Numbers"
+                  ,(lambda ()
+                     (interactive)
+                     (menu-bar-display-line-numbers-mode nil)
+                     (message "Line numbers disabled"))
+                  :help "Disable line numbers"
+                  :button (:radio . (null display-line-numbers))
+                  :visible (menu-bar-menu-frame-live-and-visible-p)))
+
+    (bindings--define-key menu [global]
+      (menu-bar-make-mm-toggle global-display-line-numbers-mode
+                               "Global Line Numbers Mode"
+                               "Set line numbers globally"))
+    menu))
+
 (defvar menu-bar-showhide-menu
   (let ((menu (make-sparse-keymap "Show/Hide")))
 
+    (bindings--define-key menu [display-line-numbers]
+      `(menu-item "Line Numbers for All Lines"
+                 ,menu-bar-showhide-line-numbers-menu))
+
     (bindings--define-key menu [column-number-mode]
       (menu-bar-make-mm-toggle column-number-mode
-                               "Column Numbers"
+                               "Column Numbers in Mode Line"
                                "Show the current column number in the mode 
line"))
 
     (bindings--define-key menu [line-number-mode]
       (menu-bar-make-mm-toggle line-number-mode
-                               "Line Numbers"
+                               "Line Numbers in Mode Line"
                                "Show the current line number in the mode 
line"))
 
     (bindings--define-key menu [size-indication-mode]
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 4d4e8a8..fe93fc3 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -945,6 +945,7 @@ If EXTERNAL, browse the URL using `shr-external-browser'."
     (when (and (buffer-name buffer)
               (not (plist-get status :error)))
       (url-store-in-cache image-buffer)
+      (goto-char (point-min))
       (when (or (search-forward "\n\n" nil t)
                (search-forward "\r\n\r\n" nil t))
        (let ((data (shr-parse-image-data)))
@@ -998,7 +999,7 @@ element is the data blob and the second element is the 
content-type."
                      (create-image data nil t :ascent 100
                                    :format content-type))
                     ((eq content-type 'image/svg+xml)
-                     (create-image data 'imagemagick t :ascent 100))
+                     (create-image data 'svg t :ascent 100))
                     ((eq size 'full)
                      (ignore-errors
                        (shr-rescale-image data content-type
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el
index ac5a9c4..a162ab0 100644
--- a/lisp/net/tramp-cache.el
+++ b/lisp/net/tramp-cache.el
@@ -136,7 +136,11 @@ Returns DEFAULT if not set."
     (tramp-message key 8 "%s %s %s" file property value)
     (when (>= tramp-verbose 10)
       (let* ((var (intern (concat "tramp-cache-get-count-" property)))
-            (val (or (and (boundp var) (symbol-value var)) 0)))
+            (val (or (bound-and-true-p var)
+                     (progn
+                       (add-hook 'tramp-cache-unload-hook
+                                 (lambda () (makunbound var)))
+                       0))))
        (set var (1+ val))))
     value))
 
@@ -156,7 +160,11 @@ Returns VALUE."
     (tramp-message key 8 "%s %s %s" file property value)
     (when (>= tramp-verbose 10)
       (let* ((var (intern (concat "tramp-cache-set-count-" property)))
-            (val (or (and (boundp var) (symbol-value var)) 0)))
+            (val (or (bound-and-true-p var)
+                     (progn
+                       (add-hook 'tramp-cache-unload-hook
+                                 (lambda () (makunbound var)))
+                       0))))
        (set var (1+ val))))
     value))
 
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 94518d0..4beb6fe 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -3432,7 +3432,9 @@ the result will be a local, non-Tramp, file name."
               `((,(tramp-file-name-regexp) . tramp-vc-file-name-handler))))
 
          ;; Here we collect only file names, which need an operation.
-         (ignore-errors (tramp-run-real-handler 'vc-registered (list file)))
+         (tramp-with-demoted-errors
+             v "Error in 1st pass of `vc-registered': %s"
+           (tramp-run-real-handler 'vc-registered (list file)))
          (tramp-message v 10 "\n%s" tramp-vc-registered-file-names)
 
          ;; Send just one command, in order to fill the cache.
@@ -3493,7 +3495,8 @@ the result will be a local, non-Tramp, file name."
                             v vc-hg-program (tramp-get-remote-path v)))))
            (setq vc-handled-backends (remq 'Hg vc-handled-backends)))
          ;; Run.
-         (ignore-errors
+         (tramp-with-demoted-errors
+             v "Error in 2nd pass of `vc-registered': %s"
            (tramp-run-real-handler 'vc-registered (list file))))))))
 
 ;;;###tramp-autoload
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 945f811..8d7fbc0 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1641,6 +1641,18 @@ an input event arrives.  The other arguments are passed 
to `tramp-error'."
        (when (tramp-file-name-equal-p vec (car tramp-current-connection))
          (setcdr tramp-current-connection (current-time)))))))
 
+(defmacro tramp-with-demoted-errors (vec-or-proc format &rest body)
+  "Execute BODY while redirecting the error message to `tramp-message'.
+BODY is executed like wrapped by `with-demoted-errors'.  FORMAT
+is a format-string containing a %-sequence meaning to substitute
+the resulting error message."
+  (declare (debug (symbolp body))
+           (indent 2))
+  (let ((err (make-symbol "err")))
+    `(condition-case-unless-debug ,err
+         (progn ,@body)
+       (error (tramp-message ,vec-or-proc 3 ,format ,err) nil))))
+
 (defmacro with-parsed-tramp-file-name (filename var &rest body)
   "Parse a Tramp filename and make components available in the body.
 
diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el
index 4be487e..527630d 100644
--- a/lisp/net/trampver.el
+++ b/lisp/net/trampver.el
@@ -7,7 +7,7 @@
 ;; Maintainer: Michael Albinus <address@hidden>
 ;; Keywords: comm, processes
 ;; Package: tramp
-;; Version: 2.3.2
+;; Version: 2.3.3-pre
 
 ;; This file is part of GNU Emacs.
 
@@ -33,7 +33,7 @@
 ;; should be changed only there.
 
 ;;;###tramp-autoload
-(defconst tramp-version "2.3.2"
+(defconst tramp-version "2.3.3-pre"
   "This version of Tramp.")
 
 ;;;###tramp-autoload
@@ -55,7 +55,7 @@
 ;; Check for Emacs version.
 (let ((x (if (>= emacs-major-version 24)
     "ok"
-  (format "Tramp 2.3.2 is not fit for %s"
+  (format "Tramp 2.3.3-pre is not fit for %s"
          (when (string-match "^.*$" (emacs-version))
            (match-string 0 (emacs-version)))))))
   (unless (string-match "\\`ok\\'" x) (error "%s" x)))
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 121ba24..dec59c5 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1843,19 +1843,25 @@ with a brace block."
          (unless (eq where 'at-header)
            (c-backward-to-nth-BOF-{ 1 where)
            (c-beginning-of-decl-1))
+         (when (looking-at c-typedef-key)
+           (goto-char (match-end 0))
+           (c-forward-syntactic-ws))
 
          ;; Pick out the defun name, according to the type of defun.
          (cond
           ;; struct, union, enum, or similar:
-          ((and (looking-at c-type-prefix-key)
-                (progn (c-forward-token-2 2) ; over "struct foo "
-                       (or (eq (char-after) ?\{)
-                           (looking-at c-symbol-key)))) ; "struct foo bar ..."
-           (save-match-data (c-forward-token-2))
-           (when (eq (char-after) ?\{)
-             (c-backward-token-2)
-             (looking-at c-symbol-key))
-           (match-string-no-properties 0))
+          ((looking-at c-type-prefix-key)
+           (let ((key-pos (point)))
+             (c-forward-token-2 1)     ; over "struct ".
+             (cond
+              ((looking-at c-symbol-key)       ; "struct foo { ..."
+               (buffer-substring-no-properties key-pos (match-end 0)))
+              ((eq (char-after) ?{)    ; "struct { ... } foo"
+               (when (c-go-list-forward)
+                 (c-forward-syntactic-ws)
+                 (when (looking-at c-symbol-key) ; a bit bogus - there might
+                                                 ; be several identifiers.
+                   (match-string-no-properties 0)))))))
 
           ((looking-at "DEFUN\\s-*(") ;"DEFUN\\_>") think of XEmacs!
            ;; DEFUN ("file-name-directory", Ffile_name_directory, 
Sfile_name_directory, ...) ==> Ffile_name_directory
@@ -1900,7 +1906,8 @@ with a brace block."
                (c-backward-syntactic-ws))
              (setq name-end (point))
              (c-back-over-compound-identifier)
-             (buffer-substring-no-properties (point) name-end)))))))))
+             (and (looking-at c-symbol-start)
+                  (buffer-substring-no-properties (point) name-end))))))))))
 
 (defun c-declaration-limits (near)
   ;; Return a cons of the beginning and end positions of the current
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index eb7bde0..ab910ab 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -417,6 +417,17 @@ to it is returned.  This function does not modify the 
point or the mark."
     ;; Emacs.
     `(setq mark-active ,activate)))
 
+(defmacro c-set-keymap-parent (map parent)
+  (cond
+   ;; XEmacs
+   ((cc-bytecomp-fboundp 'set-keymap-parents)
+    `(set-keymap-parents ,map ,parent))
+   ;; Emacs
+   ((cc-bytecomp-fboundp 'set-keymap-parent)
+    `(set-keymap-parent ,map ,parent))
+   ;; incompatible
+   (t (error "CC Mode is incompatible with this version of Emacs"))))
+
 (defmacro c-delete-and-extract-region (start end)
   "Delete the text between START and END and return it."
   (if (cc-bytecomp-fboundp 'delete-and-extract-region)
@@ -1266,6 +1277,7 @@ with value CHAR in the region [FROM to)."
 (def-edebug-spec cc-eval-when-compile (&rest def-form))
 (def-edebug-spec c-point t)
 (def-edebug-spec c-set-region-active t)
+(def-edebug-spec c-set-keymap-parent t)
 (def-edebug-spec c-safe t)
 (def-edebug-spec c-save-buffer-state let*)
 (def-edebug-spec c-tentative-buffer-changes t)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index e880bd3..59dc96a 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -6089,7 +6089,8 @@ comment at the start of cc-engine.el for more info."
 
 (defsubst c-clear-found-types ()
   ;; Clears `c-found-types'.
-  (setq c-found-types (make-vector 53 0)))
+  (setq c-found-types
+       (make-hash-table :test #'equal :weakness nil)))
 
 (defun c-add-type (from to)
   ;; Add the given region as a type in `c-found-types'.  If the region
@@ -6103,29 +6104,27 @@ comment at the start of cc-engine.el for more info."
   ;;
   ;; This function might do hidden buffer changes.
   (let ((type (c-syntactic-content from to c-recognize-<>-arglists)))
-    (unless (intern-soft type c-found-types)
-      (unintern (substring type 0 -1) c-found-types)
-      (intern type c-found-types))))
+    (unless (gethash type c-found-types)
+      (remhash (substring type 0 -1) c-found-types)
+      (puthash type t c-found-types))))
 
 (defun c-unfind-type (name)
   ;; Remove the "NAME" from c-found-types, if present.
-  (unintern name c-found-types))
+  (remhash name c-found-types))
 
 (defsubst c-check-type (from to)
   ;; Return non-nil if the given region contains a type in
   ;; `c-found-types'.
   ;;
   ;; This function might do hidden buffer changes.
-  (intern-soft (c-syntactic-content from to c-recognize-<>-arglists)
-              c-found-types))
+  (gethash (c-syntactic-content from to c-recognize-<>-arglists) 
c-found-types))
 
 (defun c-list-found-types ()
   ;; Return all the types in `c-found-types' as a sorted list of
   ;; strings.
   (let (type-list)
-    (mapatoms (lambda (type)
-               (setq type-list (cons (symbol-name type)
-                                     type-list)))
+    (maphash (lambda (type _)
+              (setq type-list (cons type type-list)))
              c-found-types)
     (sort type-list 'string-lessp)))
 
@@ -7059,6 +7058,7 @@ comment at the start of cc-engine.el for more info."
   ;; This function might do hidden buffer changes.
 
   (let ((start (point))
+       (old-found-types (copy-hash-table c-found-types))
        ;; If `c-record-type-identifiers' is set then activate
        ;; recording of any found types that constitute an argument in
        ;; the arglist.
@@ -7074,6 +7074,7 @@ comment at the start of cc-engine.el for more info."
                  (nconc c-record-found-types c-record-type-identifiers)))
          t)
 
+      (setq c-found-types old-found-types)
       (goto-char start)
       nil)))
 
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 9b89681..bf0439f 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -225,18 +225,7 @@ control).  See \"cc-mode.el\" for more info."
 
 (defun c-make-inherited-keymap ()
   (let ((map (make-sparse-keymap)))
-    ;; Necessary to use `cc-bytecomp-fboundp' below since this
-    ;; function is called from top-level forms that are evaluated
-    ;; while cc-bytecomp is active when one does M-x eval-buffer.
-    (cond
-     ;; Emacs
-     ((cc-bytecomp-fboundp 'set-keymap-parent)
-      (set-keymap-parent map c-mode-base-map))
-     ;; XEmacs
-     ((fboundp 'set-keymap-parents)
-      (set-keymap-parents map c-mode-base-map))
-     ;; incompatible
-     (t (error "CC Mode is incompatible with this version of Emacs")))
+    (c-set-keymap-parent map c-mode-base-map)
     map))
 
 (defun c-define-abbrev-table (name defs &optional doc)
@@ -276,6 +265,8 @@ control).  See \"cc-mode.el\" for more info."
     nil
 
   (setq c-mode-base-map (make-sparse-keymap))
+  (when (boundp 'prog-mode-map)
+    (c-set-keymap-parent c-mode-base-map prog-mode-map))
 
   ;; Separate M-BS from C-M-h.  The former should remain
   ;; backward-kill-word.
@@ -446,27 +437,36 @@ preferably use the `c-mode-menu' language constant 
directly."
        t))))
 
 (defun c-unfind-coalesced-tokens (beg end)
-  ;; unless the non-empty region (beg end) is entirely WS and there's at
-  ;; least one character of WS just before or after this region, remove
-  ;; the tokens which touch the region from `c-found-types' should they
-  ;; be present.
-  (or (c-partial-ws-p beg end)
-      (save-excursion
-       (progn
-         (goto-char beg)
-         (or (eq beg (point-min))
-             (c-skip-ws-backward (1- beg))
-             (/= (point) beg)
-             (= (c-backward-token-2) 1)
-             (c-unfind-type (buffer-substring-no-properties
-                             (point) beg)))
-         (goto-char end)
-         (or (eq end (point-max))
-             (c-skip-ws-forward (1+ end))
-             (/= (point) end)
-             (progn (forward-char) (c-end-of-current-token) nil)
-             (c-unfind-type (buffer-substring-no-properties
-                             end (point))))))))
+  ;; If removing the region (beg end) would coalesce an identifier ending at
+  ;; beg with an identifier (fragment) beginning at end, or an identifier
+  ;; fragment ending at beg with an identifier beginning at end, remove the
+  ;; pertinent identifier(s) from `c-found-types'.
+  (save-excursion
+    (when (< beg end)
+      (goto-char beg)
+      (when
+         (and (not (bobp))
+              (progn (c-backward-syntactic-ws) (eq (point) beg))
+              (/= (skip-chars-backward c-symbol-chars (1- (point))) 0)
+              (progn (goto-char beg) (c-forward-syntactic-ws) (<= (point) end))
+              (> (point) beg)
+              (goto-char end)
+              (looking-at c-symbol-char-key))
+       (goto-char beg)
+       (c-simple-skip-symbol-backward)
+       (c-unfind-type (buffer-substring-no-properties (point) beg)))
+
+      (goto-char end)
+      (when
+         (and (not (eobp))
+              (progn (c-forward-syntactic-ws) (eq (point) end))
+              (looking-at c-symbol-char-key)
+              (progn (c-backward-syntactic-ws) (>= (point) beg))
+              (< (point) end)
+              (/= (skip-chars-backward c-symbol-chars (1- (point))) 0))
+       (goto-char (1+ end))
+       (c-end-of-current-token)
+       (c-unfind-type (buffer-substring-no-properties end (point)))))))
 
 ;; c-maybe-stale-found-type records a place near the region being
 ;; changed where an element of `found-types' might become stale.  It
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index c0f1aaf..c69eca2 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -3734,7 +3734,7 @@ the sections using `cperl-pod-head-face', 
`cperl-pod-face',
           "\\(\\`\n?\\|^\n\\)="        ; POD
           "\\|"
           ;; One extra () before this:
-          "<<"                         ; HERE-DOC
+          "<<~?"                       ; HERE-DOC
           "\\("                        ; 1 + 1
           ;; First variant "BLAH" or just ``.
           "[ \t]*"                     ; Yes, whitespace is allowed!
@@ -4000,7 +4000,7 @@ the sections using `cperl-pod-head-face', 
`cperl-pod-face',
                  (setq b (point))
                  ;; We do not search to max, since we may be called from
                  ;; some hook of fontification, and max is random
-                 (or (and (re-search-forward (concat "^" qtag "$")
+                 (or (and (re-search-forward (concat "^[ \t]*" qtag "$")
                                              stop-point 'toend)
                           ;;;(eq (following-char) ?\n) ; XXXX WHY???
                           )
diff --git a/lisp/progmodes/executable.el b/lisp/progmodes/executable.el
index da148bd..7c040e7 100644
--- a/lisp/progmodes/executable.el
+++ b/lisp/progmodes/executable.el
@@ -83,13 +83,21 @@ When this is `function', only ask when called 
non-interactively."
   :type 'regexp
   :group 'executable)
 
-
 (defcustom executable-prefix "#!"
-  "Interpreter magic number prefix inserted when there was no magic number."
-  :version "24.3"                       ; "#! " -> "#!"
+  "Interpreter magic number prefix inserted when there was no magic number.
+Use of `executable-prefix-env' is preferable to this option."
+  :version "26.1"                       ; deprecated
   :type 'string
   :group 'executable)
 
+(defcustom executable-prefix-env nil
+  "If non-nil, use \"/usr/bin/env\" in interpreter magic number.
+If this variable is non-nil, the interpreter magic number inserted
+by `executable-set-magic' will be \"#!/usr/bin/env INTERPRETER\",
+otherwise it will be \"#!/path/to/INTERPRETER\"."
+  :version "26.1"
+  :type 'boolean
+  :group 'executable)
 
 (defcustom executable-chmod 73
   "After saving, if the file is not executable, set this mode.
@@ -199,7 +207,7 @@ command to find the next error.  The buffer is also in 
`comint-mode' and
 (defun executable-set-magic (interpreter &optional argument
                                         no-query-flag insert-flag)
   "Set this buffer's interpreter to INTERPRETER with optional ARGUMENT.
-The variables `executable-magicless-file-regexp', `executable-prefix',
+The variables `executable-magicless-file-regexp', `executable-prefix-env',
 `executable-insert', `executable-query' and `executable-chmod' control
 when and how magic numbers are inserted or replaced and scripts made
 executable."
@@ -220,6 +228,14 @@ executable."
                         (and argument (string< "" argument) " ")
                         argument))
 
+  ;; For backward compatibilty, allow `executable-prefix-env' to be
+  ;; overriden by custom `executable-prefix'.
+  (if (string-match "#!\\([ \t]*/usr/bin/env[ \t]*\\)?$" executable-prefix)
+      (if executable-prefix-env
+          (setq argument (concat "/usr/bin/env "
+                                 (file-name-nondirectory argument))))
+    (setq argument (concat (substring executable-prefix 2) argument)))
+
   (or buffer-read-only
       (if buffer-file-name
          (string-match executable-magicless-file-regexp
@@ -241,15 +257,13 @@ executable."
                           ;; Make buffer visible before question.
                           (switch-to-buffer (current-buffer))
                           (y-or-n-p (format-message
-                                     "Replace magic number by `%s%s'? "
-                                     executable-prefix argument))))
+                                     "Replace magic number by `#!%s'? "
+                                     argument))))
                     (progn
                       (replace-match argument t t nil 1)
-                      (message "Magic number changed to `%s'"
-                               (concat executable-prefix argument)))))
-         (insert executable-prefix argument ?\n)
-         (message "Magic number changed to `%s'"
-                  (concat executable-prefix argument)))))
+                      (message "Magic number changed to `#!%s'" argument))))
+         (insert "#!" argument ?\n)
+         (message "Magic number changed to `#!%s'" argument))))
     interpreter)
 
 
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index b3d8a51..2ddaf88 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -47,8 +47,8 @@ to avoid computing them again.")
 (defun grep-apply-setting (symbol value)
   "Set SYMBOL to VALUE, and update `grep-host-defaults-alist'.
 SYMBOL should be one of `grep-command', `grep-template',
-`grep-use-null-device', `grep-find-command',
-`grep-find-template', `grep-find-use-xargs', or
+`grep-use-null-device', `grep-find-command' `grep-find-template',
+`grep-find-use-xargs', `grep-use-null-filename-separator', or
 `grep-highlight-matches'."
   (when grep-host-defaults-alist
     (let* ((host-id
@@ -160,6 +160,15 @@ Customize or call the function `grep-apply-setting'."
   :set 'grep-apply-setting
   :group 'grep)
 
+(defcustom grep-use-null-filename-separator 'auto-detect
+  "If non-nil, use `grep's `--null' option.
+This is done to disambiguate file names in `grep's output."
+  :type '(choice (const :tag "Do Not Use `--null'" nil)
+                 (const :tag "Use `--null'" t)
+                 (other :tag "Not Set" auto-detect))
+  :set 'grep-apply-setting
+  :group 'grep)
+
 ;;;###autoload
 (defcustom grep-find-command nil
   "The default find command for \\[grep-find].
@@ -357,33 +366,53 @@ A grep buffer becomes most recent when you select Grep 
mode in it.
 Notice that using \\[next-error] or \\[compile-goto-error] modifies
 `compilation-last-buffer' rather than `grep-last-buffer'.")
 
-;;;###autoload
-(defconst grep-regexp-alist
-  '(
-    ;; Use a tight regexp to handle weird file names (with colons
+(defconst grep--regexp-alist-column
+  ;; Calculate column positions (col . end-col) of first grep match on a line
+  (cons
+   (lambda ()
+     (when grep-highlight-matches
+       (let* ((beg (match-end 0))
+              (end (save-excursion (goto-char beg) (line-end-position)))
+              (mbeg (text-property-any beg end 'font-lock-face 
'grep-match-face)))
+         (when mbeg
+           (- mbeg beg)))))
+   (lambda ()
+     (when grep-highlight-matches
+       (let* ((beg (match-end 0))
+              (end (save-excursion (goto-char beg) (line-end-position)))
+              (mbeg (text-property-any beg end 'font-lock-face 
'grep-match-face))
+              (mend (and mbeg (next-single-property-change mbeg 
'font-lock-face nil end))))
+         (when mend
+           (- mend beg)))))))
+(defconst grep--regexp-alist-bin-matcher
+  '("^Binary file \\(.+\\) matches$" 1 nil nil 0 1))
+(defconst grep-with-null-regexp-alist
+  `(("^\\([^\0]+\\)\\(\0\\)\\([0-9]+\\):" 1 3 ,grep--regexp-alist-column nil 
nil
+     (2 '(face unspecified display ":")))
+    ,grep--regexp-alist-bin-matcher)
+  "Regexp used to match grep hits.
+See `compilation-error-regexp-alist'.")
+(defconst grep-fallback-regexp-alist
+  `(;; Use a tight regexp to handle weird file names (with colons
     ;; in them) as well as possible.  E.g., use [1-9][0-9]* rather
     ;; than [0-9]+ so as to accept ":034:" in file names.
     ("^\\(.*?[^/\n]\\):[ \t]*\\([1-9][0-9]*\\)[ \t]*:"
-     1 2
-     ;; Calculate column positions (col . end-col) of first grep match on a 
line
-     ((lambda ()
-       (when grep-highlight-matches
-         (let* ((beg (match-end 0))
-                (end (save-excursion (goto-char beg) (line-end-position)))
-                (mbeg (text-property-any beg end 'font-lock-face 
grep-match-face)))
-           (when mbeg
-             (- mbeg beg)))))
-      .
-      (lambda ()
-       (when grep-highlight-matches
-         (let* ((beg (match-end 0))
-                (end (save-excursion (goto-char beg) (line-end-position)))
-                (mbeg (text-property-any beg end 'font-lock-face 
grep-match-face))
-                (mend (and mbeg (next-single-property-change mbeg 
'font-lock-face nil end))))
-           (when mend
-             (- mend beg)))))))
-    ("^Binary file \\(.+\\) matches$" 1 nil nil 0 1))
-  "Regexp used to match grep hits.  See `compilation-error-regexp-alist'.")
+     1 2 ,grep--regexp-alist-column)
+    ,grep--regexp-alist-bin-matcher)
+  "Regexp used to match grep hits when `--null' is not supported.
+See `compilation-error-regexp-alist'.")
+
+(defvaralias 'grep-regex-alist 'grep-with-null-regexp-alist)
+(make-obsolete-variable
+ 'grep-regex-alist "Call `grep-regexp-alist' instead." "26.1")
+
+;;;###autoload
+(defun grep-regexp-alist ()
+  "Return a regexp alist to match grep hits.
+The regexp used depends on `grep-use-null-filename-separator'.
+See `compilation-error-regexp-alist' for format details."
+  (if grep-use-null-filename-separator
+      grep-with-null-regexp-alist grep-fallback-regexp-alist))
 
 (defvar grep-first-column 0            ; bug#10594
   "Value to use for `compilation-first-column' in grep buffers.")
@@ -538,6 +567,8 @@ This function is called from `compilation-filter-hook'."
             (grep-use-null-device ,grep-use-null-device)
             (grep-find-command ,grep-find-command)
             (grep-find-template ,grep-find-template)
+             (grep-use-null-filename-separator
+              ,grep-use-null-filename-separator)
             (grep-find-use-xargs ,grep-find-use-xargs)
             (grep-highlight-matches ,grep-highlight-matches)))))
   (let* ((host-id
@@ -550,7 +581,8 @@ This function is called from `compilation-filter-hook'."
     ;; computed for every host once.
     (dolist (setting '(grep-command grep-template
                       grep-use-null-device grep-find-command
-                      grep-find-template grep-find-use-xargs
+                       grep-use-null-filename-separator
+                       grep-find-template grep-find-use-xargs
                       grep-highlight-matches))
       (set setting
           (cadr (or (assq setting host-defaults)
@@ -576,6 +608,21 @@ This function is called from `compilation-filter-hook'."
                         (concat (regexp-quote hello-file)
                                 ":[0-9]+:English")))))))))
 
+    (when (eq grep-use-null-filename-separator 'auto-detect)
+      (setq grep-use-null-filename-separator
+            (with-temp-buffer
+              (let* ((hello-file (expand-file-name "HELLO" data-directory))
+                     (args `("--null" "-ne" "^English" ,hello-file)))
+                (if grep-use-null-device
+                    (setq args (append args (list null-device)))
+                  (push "-H" args))
+                (and (grep-probe grep-program `(nil t nil ,@args))
+                     (progn
+                       (goto-char (point-min))
+                       (looking-at
+                        (concat (regexp-quote hello-file)
+                                "\0[0-9]+:English"))))))))
+
     (when (eq grep-highlight-matches 'auto-detect)
       (setq grep-highlight-matches
            (with-temp-buffer
@@ -591,6 +638,7 @@ This function is called from `compilation-filter-hook'."
                 grep-template grep-find-template)
       (let ((grep-options
             (concat (if grep-use-null-device "-n" "-nH")
+                     (if grep-use-null-filename-separator " --null")
                     (if (grep-probe grep-program
                                     `(nil nil nil "-e" "foo" ,null-device)
                                     nil 1)
@@ -733,7 +781,7 @@ This function is called from `compilation-filter-hook'."
   (set (make-local-variable 'compilation-error-face)
        grep-hit-face)
   (set (make-local-variable 'compilation-error-regexp-alist)
-       grep-regexp-alist)
+       (grep-regexp-alist))
   ;; compilation-directory-matcher can't be nil, so we set it to a regexp that
   ;; can never match.
   (set (make-local-variable 'compilation-directory-matcher) '("\\`a\\`"))
diff --git a/lisp/progmodes/ld-script.el b/lisp/progmodes/ld-script.el
index 389ddfc..7a666e9 100644
--- a/lisp/progmodes/ld-script.el
+++ b/lisp/progmodes/ld-script.el
@@ -85,10 +85,12 @@
     ;; 3.4.5 Other Linker Script Commands
     "ASSERT" "EXTERN" "FORCE_COMMON_ALLOCATION"
     "INHIBIT_COMMON_ALLOCATION" "INSERT" "AFTER" "BEFORE"
-    "NOCROSSREFS" "OUTPUT_ARCH" "LD_FEATURE"
-    ;; 3.5.2 PROVIDE
+    "NOCROSSREFS" "NOCROSSREFS_TO" "OUTPUT_ARCH" "LD_FEATURE"
+    ;; 3.5.2 HIDDEN
+    "HIDDEN"
+    ;; 3.5.3 PROVIDE
     "PROVIDE"
-    ;; 3.5.3 PROVIDE_HIDDEN
+    ;; 3.5.4 PROVIDE_HIDDEN
     "PROVIDE_HIDDEN"
     ;; 3.6 SECTIONS Command
     "SECTIONS"
@@ -142,6 +144,7 @@
     "DEFINED"
     "LENGTH" "len" "l"
     "LOADADDR"
+    "LOG2CEIL"
     "MAX"
     "MIN"
     "NEXT"
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index 3def37a..6197a53 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -213,25 +213,6 @@
             (regexp-opt perl--syntax-exp-intro-keywords)
             "\\|[-?:.,;|&+*=!~({[]\\|\\(^\\)\\)[ \t\n]*")))
 
-;; FIXME: handle here-docs and regexps.
-;; <<EOF <<"EOF" <<'EOF' (no space)
-;; see `man perlop'
-;; ?...?
-;; /.../
-;; m [...]
-;; m /.../
-;; q /.../ = '...'
-;; qq /.../ = "..."
-;; qx /.../ = `...`
-;; qr /.../ = precompiled regexp =~=~ m/.../
-;; qw /.../
-;; s /.../.../
-;; s <...> /.../
-;; s '...'...'
-;; tr /.../.../
-;; y /.../.../
-;;
-;; <file*glob>
 (defun perl-syntax-propertize-function (start end)
   (let ((case-fold-search nil))
     (goto-char start)
@@ -324,23 +305,25 @@
       ((concat
         "\\(?:"
         ;; << "EOF", << 'EOF', or << \EOF
-        "<<[ \t]*\\('[^'\n]*'\\|\"[^\"\n]*\"\\|\\\\[[:alpha:]][[:alnum:]]*\\)"
+        "<<\\(~\\)?[ 
\t]*\\('[^'\n]*'\\|\"[^\"\n]*\"\\|\\\\[[:alpha:]][[:alnum:]]*\\)"
         ;; The <<EOF case which needs perl--syntax-exp-intro-regexp, to
         ;; disambiguate with the left-bitshift operator.
-        "\\|" perl--syntax-exp-intro-regexp "<<\\(?1:\\sw+\\)\\)"
+        "\\|" perl--syntax-exp-intro-regexp "<<\\(?2:\\sw+\\)\\)"
         ".*\\(\n\\)")
-       (3 (let* ((st (get-text-property (match-beginning 3) 'syntax-table))
-                 (name (match-string 1)))
-            (goto-char (match-end 1))
+       (4 (let* ((st (get-text-property (match-beginning 4) 'syntax-table))
+                 (name (match-string 2))
+                 (indented (match-beginning 1)))
+            (goto-char (match-end 2))
             (if (save-excursion (nth 8 (syntax-ppss (match-beginning 0))))
                 ;; Leave the property of the newline unchanged.
                 st
               (cons (car (string-to-syntax "< c"))
                     ;; Remember the names of heredocs found on this line.
-                    (cons (pcase (aref name 0)
-                            (`?\\ (substring name 1))
-                            ((or `?\" `?\' `?\`) (substring name 1 -1))
-                            (_ name))
+                    (cons (cons (pcase (aref name 0)
+                                  (`?\\ (substring name 1))
+                                  ((or `?\" `?\' `?\`) (substring name 1 -1))
+                                  (_ name))
+                                indented)
                           (cdr st)))))))
       ;; We don't call perl-syntax-propertize-special-constructs directly
       ;; from the << rule, because there might be other elements (between
@@ -383,7 +366,9 @@
           (goto-char (nth 8 state)))
         (while (and names
                     (re-search-forward
-                     (concat "^" (regexp-quote (pop names)) "\n")
+                     (pcase-let ((`(,name . ,indented) (pop names)))
+                       (concat "^" (if indented "[ \t]*")
+                               (regexp-quote name) "\n"))
                      limit 'move))
           (unless names
             (put-text-property (1- (point)) (point) 'syntax-table
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index b8ec50f..cc9b794 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -917,20 +917,21 @@ IGNORES is a list of glob patterns."
   (grep-compute-defaults)
   (defvar grep-find-template)
   (defvar grep-highlight-matches)
-  (let* ((grep-find-template (replace-regexp-in-string "<C>" "<C> -E"
-                                                       grep-find-template t t))
-         (grep-highlight-matches nil)
-         ;; TODO: Sanitize the regexp to remove Emacs-specific terms,
-         ;; so that Grep can search for the "relaxed" version.  Can we
-         ;; do that reliably enough, without creating false negatives?
-         (command (xref--rgrep-command (xref--regexp-to-extended regexp)
-                                       files
-                                       (expand-file-name dir)
-                                       ignores))
-         (buf (get-buffer-create " *xref-grep*"))
-         (grep-re (caar grep-regexp-alist))
-         status
-         hits)
+  (pcase-let*
+      ((grep-find-template (replace-regexp-in-string "<C>" "<C> -E"
+                                                     grep-find-template t t))
+       (grep-highlight-matches nil)
+       ;; TODO: Sanitize the regexp to remove Emacs-specific terms,
+       ;; so that Grep can search for the "relaxed" version.  Can we
+       ;; do that reliably enough, without creating false negatives?
+       (command (xref--rgrep-command (xref--regexp-to-extended regexp)
+                                     files
+                                     (expand-file-name dir)
+                                     ignores))
+       (buf (get-buffer-create " *xref-grep*"))
+       (`(,grep-re ,file-group ,line-group . ,_) (car (grep-regexp-alist)))
+       (status nil)
+       (hits nil))
     (with-current-buffer buf
       (erase-buffer)
       (setq status
@@ -944,8 +945,8 @@ IGNORES is a list of glob patterns."
                  (not (looking-at grep-re)))
         (user-error "Search failed with status %d: %s" status (buffer-string)))
       (while (re-search-forward grep-re nil t)
-        (push (list (string-to-number (match-string 2))
-                    (match-string 1)
+        (push (list (string-to-number (match-string line-group))
+                    (match-string file-group)
                     (buffer-substring-no-properties (point) 
(line-end-position)))
               hits)))
     (xref--convert-hits (nreverse hits) regexp)))
diff --git a/lisp/ses.el b/lisp/ses.el
index 741d588..8c5ff21 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -167,12 +167,32 @@ Each function is called with ARG=1."
     ["Export values" ses-export-tsv t]
     ["Export formulas" ses-export-tsf t]))
 
+(defconst ses-completion-keys '("\M-\C-i" "\C-i")
+  "List for keys that can be used for completion while editing.")
+
+(defvar ses--completion-table nil
+  "Set globally to what completion table to use depending on type
+  of completion (local printers, cells, etc.). We need to go
+  through a local variable to pass the SES buffer local variable
+  to completing function while the current buffer is the
+  minibuffer.")
+
+(defvar ses--list-orig-buffer nil
+  "Calling buffer for SES listing help. Used for listing local
+  printers or renamed cells.")
+
+
 (defconst ses-mode-edit-map
   (let ((keys '("\C-c\C-r"    ses-insert-range
                "\C-c\C-s"    ses-insert-ses-range
                [S-mouse-3]   ses-insert-range-click
                [C-S-mouse-3] ses-insert-ses-range-click
-               "\M-\C-i"     lisp-complete-symbol)) ; FIXME obsolete
+                "\C-h\C-p"    ses-list-local-printers
+                "\C-h\C-n"    ses-list-named-cells
+               "\M-\C-i"     lisp-complete-symbol)) ; redefined
+                                                     ; dynamically in
+                                                     ; editing
+                                                     ; functions
        (newmap (make-sparse-keymap)))
     (set-keymap-parent newmap minibuffer-local-map)
     (while keys
@@ -1715,7 +1735,7 @@ to each symbol."
                     (set (make-local-variable sym) nil)
                     (put sym 'ses-cell (cons row col)))))) )))
     ;; Relocate the cell values.
-    (let (oldval myrow mycol xrow xcol)
+    (let (oldval myrow mycol xrow xcol sym)
       (cond
        ((and (<= rowincr 0) (<= colincr 0))
        ;; Deletion of rows and/or columns.
@@ -1725,16 +1745,16 @@ to each symbol."
          (dotimes (col (- ses--numcols mincol))
            (setq mycol  (+ col mincol)
                  xrow   (- myrow rowincr)
-                 xcol   (- mycol colincr))
-           (let ((sym (ses-cell-symbol myrow mycol)))
-             ;; We don't need to relocate value for renamed cells, as they 
keep the same
-             ;; symbol.
-             (unless (eq (get sym 'ses-cell) :ses-named)
-               (ses-set-cell myrow mycol 'value
-                             (if (and (< xrow ses--numrows) (< xcol 
ses--numcols))
-                                 (ses-cell-value xrow xcol)
-                               ;; Cell is off the end of the array.
-                               (symbol-value (ses-create-cell-symbol xrow 
xcol))))))))
+                 xcol   (- mycol colincr)
+                  sym (ses-cell-symbol myrow mycol))
+           ;; We don't need to relocate value for renamed cells, as they keep 
the same
+           ;; symbol.
+           (unless (eq (get sym 'ses-cell) :ses-named)
+             (ses-set-cell myrow mycol 'value
+                           (if (and (< xrow ses--numrows) (< xcol 
ses--numcols))
+                               (ses-cell-value xrow xcol)
+                             ;; Cell is off the end of the array.
+                             (symbol-value (ses-create-cell-symbol xrow 
xcol)))))))
        (when ses--in-killing-named-cell-list
          (message "Unbinding killed named cell symbols...")
          (setq ses-start-time (float-time))
@@ -1754,13 +1774,17 @@ to each symbol."
            (dotimes (col (- ses--numcols mincol))
              (setq mycol (- distx col)
                    xrow  (- myrow rowincr)
-                   xcol  (- mycol colincr))
-             (if (or (< xrow minrow) (< xcol mincol))
-                 ;; Newly-inserted value.
-                 (setq oldval nil)
-               ;; Transfer old value.
-               (setq oldval (ses-cell-value xrow xcol)))
-             (ses-set-cell myrow mycol 'value oldval)))
+                   xcol  (- mycol colincr)
+                    sym (ses-cell-symbol myrow mycol))
+             ;; We don't need to relocate value for renamed cells, as they 
keep the same
+             ;; symbol.
+             (unless (eq (get sym 'ses-cell) :ses-named)
+               (if (or (< xrow minrow) (< xcol mincol))
+                   ;; Newly-inserted value.
+                   (setq oldval nil)
+                 ;; Transfer old value.
+                 (setq oldval (ses-cell-value xrow xcol)))
+               (ses-set-cell myrow mycol 'value oldval))))
          t))  ; Make testcover happy by returning non-nil here.
        (t
        (error "ROWINCR and COLINCR must have the same sign"))))
@@ -2443,6 +2467,42 @@ to are recalculated first."
 ;;----------------------------------------------------------------------------
 ;; Input of cell formulas
 ;;----------------------------------------------------------------------------
+(defun ses-edit-cell-complete-symbol ()
+  (interactive)
+  (let ((completion-at-point-functions (cons 
'ses--edit-cell-completion-at-point-function
+                                             completion-at-point-functions)))
+    (completion-at-point)))
+
+(defun ses--edit-cell-completion-at-point-function ()
+  (and
+   ses--completion-table
+   (let* ((bol (save-excursion (move-beginning-of-line nil) (point)))
+         start end collection
+         (prefix
+          (save-excursion
+            (setq end (point))
+            (backward-sexp)
+            (if (< (point) bol)
+                (progn
+                  (setq start bol)
+                  (buffer-substring start end))
+              (setq start (point))
+              (forward-sexp)
+              (if (>= (point) end)
+                  (progn
+                    (setq end (point))
+                    (buffer-substring start end))
+                nil))))
+         prefix-length)
+    (when (and prefix (null (string= prefix "")))
+      (setq prefix-length (length prefix))
+      (maphash (lambda (key val)
+                 (let ((key-name (symbol-name key)))
+                   (when (and (>= (length key-name) prefix-length)
+                              (string= prefix (substring key-name 0 
prefix-length)))
+                     (push key-name collection))))
+               ses--completion-table)
+      (and collection (list start end collection))))))
 
 (defun ses-edit-cell (row col newval)
   "Display current cell contents in minibuffer, for editing.  Returns nil if
@@ -2464,6 +2524,10 @@ cell formula was unsafe and user declined confirmation."
        (if (stringp formula)
           ;; Position cursor inside close-quote.
           (setq initial (cons initial (length initial))))
+       (dolist (key ses-completion-keys)
+         (define-key ses-mode-edit-map key 'ses-edit-cell-complete-symbol))
+       ;; make it globally visible, so that it can be visible from the 
minibuffer.
+       (setq ses--completion-table ses--named-cell-hashmap)
        (list row col
             (read-from-minibuffer (format "Cell %s: " ses--curcell)
                                   initial
@@ -2558,6 +2622,40 @@ cells."
 ;;----------------------------------------------------------------------------
 ;; Input of cell-printer functions
 ;;----------------------------------------------------------------------------
+(defun ses-read-printer-complete-symbol ()
+  (interactive)
+  (let ((completion-at-point-functions (cons 
'ses--read-printer-completion-at-point-function
+                                             completion-at-point-functions)))
+    (completion-at-point)))
+
+(defun ses--read-printer-completion-at-point-function ()
+  (let* ((bol (save-excursion (move-beginning-of-line nil) (point)))
+         start end collection
+         (prefix
+          (save-excursion
+            (setq end (point))
+            (backward-sexp)
+            (if (< (point) bol)
+                (progn
+                  (setq start bol)
+                  (buffer-substring start end))
+              (setq start (point))
+              (forward-sexp)
+              (if (>= (point) end)
+                  (progn
+                    (setq end (point))
+                    (buffer-substring start end))
+                nil))))
+         prefix-length)
+    (when prefix
+      (setq prefix-length (length prefix))
+      (maphash (lambda (key val)
+                 (let ((key-name (symbol-name key)))
+                   (when (and (>= (length key-name) prefix-length)
+                              (string= prefix (substring key-name 0 
prefix-length)))
+                     (push key-name collection))))
+               ses--completion-table)
+      (and collection (list start end collection)))))
 
 (defun ses-read-printer (prompt default)
   "Common code for functions `ses-read-cell-printer', 
`ses-read-column-printer',
@@ -2570,6 +2668,10 @@ canceled."
     (setq prompt (format "%s (default %S): "
                         (substring prompt 0 -2)
                         default)))
+  (dolist (key ses-completion-keys)
+    (define-key ses-mode-edit-map key 'ses-read-printer-complete-symbol))
+  ;; make it globally visible, so that it can be visible from the minibuffer.
+  (setq ses--completion-table ses--local-printer-hashmap)
   (let ((new (read-from-minibuffer prompt
                                   nil ; Initial contents.
                                   ses-mode-edit-map
@@ -3278,6 +3380,78 @@ is non-nil.  Newlines and tabs in the export text are 
escaped."
     (setq result (apply #'concat (nreverse result)))
     (kill-new result)))
 
+;;----------------------------------------------------------------------------
+;; Interactive help on symbols
+;;----------------------------------------------------------------------------
+
+(defun ses-list-local-printers (&optional local-printer-hashmap)
+  "List local printers in a help buffer. Can be called either
+during editing a printer or a formula, or while in the SES
+buffer."
+  (interactive
+   (list (cond
+          ((derived-mode-p 'ses-mode) ses--local-printer-hashmap)
+          ((minibufferp) ses--completion-table)
+          ((derived-mode-p 'help-mode) nil)
+          (t (error "Not in a SES buffer")))))
+  (when local-printer-hashmap
+    (let ((ses--list-orig-buffer (or ses--list-orig-buffer (current-buffer))))
+      (help-setup-xref
+       (list (lambda (local-printer-hashmap buffer)
+               (let ((ses--list-orig-buffer
+                      (if (buffer-live-p buffer) buffer)))
+                 (ses-list-local-printers local-printer-hashmap)))
+             local-printer-hashmap ses--list-orig-buffer)
+       (called-interactively-p 'interactive))
+
+      (save-excursion
+        (with-help-window (help-buffer)
+          (if (= 0 (hash-table-count local-printer-hashmap))
+              (princ "No local printers defined.")
+            (princ "List of local printers definitions:\n")
+            (maphash (lambda (key val)
+                       (princ key)
+                       (princ " as ")
+                       (prin1 (ses--locprn-def val))
+                       (princ "\n"))
+                     local-printer-hashmap))
+          (with-current-buffer standard-output
+            (buffer-string)))))))
+
+(defun ses-list-named-cells (&optional named-cell-hashmap)
+  "List named cells in a help buffer. Can be called either
+during editing a printer or a formula, or while in the SES
+buffer."
+  (interactive
+   (list (cond
+          ((derived-mode-p 'ses-mode) ses--named-cell-hashmap)
+          ((minibufferp) ses--completion-table)
+          ((derived-mode-p 'help-mode) nil)
+          (t (error "Not in a SES buffer")))))
+  (when named-cell-hashmap
+    (let ((ses--list-orig-buffer (or ses--list-orig-buffer (current-buffer))))
+      (help-setup-xref
+       (list (lambda (named-cell-hashmap buffer)
+               (let ((ses--list-orig-buffer
+                      (if (buffer-live-p buffer) buffer)))
+                 (ses-list-named-cells named-cell-hashmap)))
+             named-cell-hashmap ses--list-orig-buffer)
+       (called-interactively-p 'interactive))
+
+      (save-excursion
+        (with-help-window (help-buffer)
+          (if (= 0 (hash-table-count named-cell-hashmap))
+              (princ "No cell was renamed.")
+            (princ "List of named cells definitions:\n")
+            (maphash (lambda (key val)
+                       (princ key)
+                       (princ " for ")
+                       (prin1 (ses-create-cell-symbol (car val) (cdr val)))
+                       (princ "\n"))
+                     named-cell-hashmap))
+          (with-current-buffer standard-output
+            (buffer-string)))))))
+
 
 ;;----------------------------------------------------------------------------
 ;; Other user commands
@@ -3460,8 +3634,12 @@ highlighted range in the spreadsheet."
 
 (defun ses-replace-name-in-formula (formula old-name new-name)
   (let ((new-formula formula))
-    (unless (and (consp formula)
-                (eq (car-safe formula) 'quote))
+    (cond
+     ((eq (car-safe formula) 'quote))
+     ((symbolp formula)
+      (if (eq formula old-name)
+          (setq new-formula new-name)))
+     ((consp formula)
       (while formula
        (let ((elt (car-safe formula)))
          (cond
@@ -3470,8 +3648,8 @@ highlighted range in the spreadsheet."
           ((and (symbolp elt)
                 (eq (car-safe formula) old-name))
            (setcar formula new-name))))
-       (setq formula (cdr formula))))
-    new-formula))
+       (setq formula (cdr formula)))))
+  new-formula))
 
 (defun ses-rename-cell (new-name &optional cell)
   "Rename current cell."
@@ -3496,9 +3674,10 @@ highlighted range in the spreadsheet."
         (rowcol (ses-sym-rowcol sym))
         (row (car rowcol))
         (col (cdr rowcol))
-        new-rowcol old-name)
+        new-rowcol old-name old-value)
     (setq cell (or cell (ses-get-cell row col))
          old-name (ses-cell-symbol cell)
+          old-value (symbol-value old-name)
          new-rowcol (ses-decode-cell-symbol (symbol-name new-name)))
     ;; when ses-rename-cell is called interactively, then 'sym' is the
     ;; 'cursor-intangible' property of text at cursor position, while
@@ -3518,10 +3697,12 @@ highlighted range in the spreadsheet."
       (put new-name 'ses-cell :ses-named)
       (puthash new-name rowcol ses--named-cell-hashmap))
     (push `(ses-rename-cell ,old-name ,cell) buffer-undo-list)
+    (cl-pushnew rowcol ses--deferred-write :test #'equal)
     ;; Replace name by new name in formula of cells refering to renamed cell.
     (dolist (ref (ses-cell-references cell))
       (let* ((x (ses-sym-rowcol ref))
             (xcell  (ses-get-cell (car x) (cdr x))))
+        (cl-pushnew x ses--deferred-write :test #'equal)
        (setf (ses-cell-formula xcell)
               (ses-replace-name-in-formula
                (ses-cell-formula xcell)
@@ -3532,11 +3713,14 @@ highlighted range in the spreadsheet."
     (dolist (ref (ses-formula-references (ses-cell-formula cell)))
       (let* ((x (ses-sym-rowcol ref))
             (xcell (ses-get-cell (car x) (cdr x))))
+        (cl-pushnew x ses--deferred-write :test #'equal)
        (setf (ses-cell-references xcell)
               (cons new-name (delq old-name
                                    (ses-cell-references xcell))))))
     (set (make-local-variable new-name) (symbol-value sym))
     (setf (ses-cell--symbol cell) new-name)
+    ;; set new name to value
+    (set new-name old-value)
     ;; Unbind old name
     (if (eq (get old-name 'ses-cell) :ses-named)
         (ses--unbind-cell-name old-name)
diff --git a/lisp/simple.el b/lisp/simple.el
index 1db14a8..3d23fc3 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5942,6 +5942,10 @@ columns by which window is scrolled from left margin.
 When the `track-eol' feature is doing its job, the value is
 `most-positive-fixnum'.")
 
+(defvar last--line-number-width 0
+  "Last value of width used for displaying line numbers.
+Used internally by `line-move-visual'.")
+
 (defcustom line-move-ignore-invisible t
   "Non-nil means commands that move by lines ignore invisible newlines.
 When this option is non-nil, \\[next-line], \\[previous-line], 
\\[move-end-of-line], and \\[move-beginning-of-line] behave
@@ -6212,6 +6216,7 @@ not vscroll."
 If NOERROR, don't signal an error if we can't move that many lines."
   (let ((opoint (point))
        (hscroll (window-hscroll))
+        (lnum-width (line-number-display-width t))
        target-hscroll)
     ;; Check if the previous command was a line-motion command, or if
     ;; we were called from some other command.
@@ -6219,9 +6224,19 @@ If NOERROR, don't signal an error if we can't move that 
many lines."
             (memq last-command `(next-line previous-line ,this-command)))
        ;; If so, there's no need to reset `temporary-goal-column',
        ;; but we may need to hscroll.
-       (if (or (/= (cdr temporary-goal-column) hscroll)
-               (>  (cdr temporary-goal-column) 0))
-           (setq target-hscroll (cdr temporary-goal-column)))
+        (progn
+          (if (or (/= (cdr temporary-goal-column) hscroll)
+                  (>  (cdr temporary-goal-column) 0))
+              (setq target-hscroll (cdr temporary-goal-column)))
+          ;; Update the COLUMN part of temporary-goal-column if the
+          ;; line-number display changed its width since the last
+          ;; time.
+          (setq temporary-goal-column
+                (cons (+ (car temporary-goal-column)
+                         (/ (float (- lnum-width last--line-number-width))
+                            (frame-char-width)))
+                      (cdr temporary-goal-column)))
+          (setq last--line-number-width lnum-width))
       ;; Otherwise, we should reset `temporary-goal-column'.
       (let ((posn (posn-at-point))
            x-pos)
diff --git a/lisp/startup.el b/lisp/startup.el
index bc60bbd..0fbba1b 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -1432,6 +1432,7 @@ settings will be marked as \"CHANGED outside of 
Customize\"."
   (let ((no-vals  '("no" "off" "false" "0"))
        (settings '(("menuBar" "MenuBar" menu-bar-mode nil)
                    ("toolBar" "ToolBar" tool-bar-mode nil)
+                   ("scrollBar" "ScrollBar" scroll-bar-mode nil)
                    ("cursorBlink" "CursorBlink" no-blinking-cursor t))))
     (dolist (x settings)
       (if (member (x-get-resource (nth 0 x) (nth 1 x)) no-vals)
diff --git a/lisp/subr.el b/lisp/subr.el
index a9edff6..79a28d3 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -725,15 +725,18 @@ Elements of ALIST that are not conses are ignored."
        (setq tail tail-cdr))))
   alist)
 
-(defun alist-get (key alist &optional default remove)
-  "Return the value associated with KEY in ALIST, using `assq'.
+(defun alist-get (key alist &optional default remove testfn)
+  "Return the value associated with KEY in ALIST.
 If KEY is not found in ALIST, return DEFAULT.
+Use TESTFN to lookup in the alist if non-nil.  Otherwise, use `assq'.
 
 This is a generalized variable suitable for use with `setf'.
 When using it to set a value, optional argument REMOVE non-nil
 means to remove KEY from ALIST if the new value is `eql' to DEFAULT."
   (ignore remove) ;;Silence byte-compiler.
-  (let ((x (assq key alist)))
+  (let ((x (if (not testfn)
+               (assq key alist)
+             (assoc key alist testfn))))
     (if x (cdr x) default)))
 
 (defun remove (elt seq)
@@ -1786,7 +1789,8 @@ Return the new history list.
 If MAXELT is non-nil, it specifies the maximum length of the history.
 Otherwise, the maximum history length is the value of the `history-length'
 property on symbol HISTORY-VAR, if set, or the value of the `history-length'
-variable.
+variable.  The possible values of maximum length have the same meaning as
+the values of `history-length'.
 Remove duplicates of NEWELT if `history-delete-duplicates' is non-nil.
 If optional fourth arg KEEP-ALL is non-nil, add NEWELT to history even
 if it is empty or a duplicate."
diff --git a/lisp/vc/vc-src.el b/lisp/vc/vc-src.el
index 5c8b3da..0e47cc1 100644
--- a/lisp/vc/vc-src.el
+++ b/lisp/vc/vc-src.el
@@ -180,7 +180,7 @@ For a description of possible values, see 
`vc-check-master-templates'."
 
 (defun vc-src-dir-status-files (dir files update-function)
   ;; FIXME: Use one src status -a call for this
-  (if (not files) (setq files (vc-expand-dirs (list dir) 'RCS)))
+  (if (not files) (setq files (vc-expand-dirs (list dir) 'SRC)))
   (let ((result nil))
     (dolist (file files)
       (let ((state (vc-state file))
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index ca402c1..6687bec 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -3694,15 +3694,17 @@ example:
 (defun widget-color--choose-action (widget &optional _event)
   (list-colors-display
    nil nil
-   `(lambda (color)
-      (when (buffer-live-p ,(current-buffer))
-       (widget-value-set ',(widget-get widget :parent) color)
-       (let* ((buf (get-buffer "*Colors*"))
-              (win (get-buffer-window buf 0)))
-         (if win
-             (quit-window nil win)
-           (bury-buffer buf)))
-       (pop-to-buffer ,(current-buffer))))))
+   (let ((cbuf (current-buffer))
+         (wp (widget-get widget :parent)))
+     (lambda (color)
+       (when (buffer-live-p cbuf)
+        (widget-value-set wp color)
+        (let* ((buf (get-buffer "*Colors*"))
+               (win (get-buffer-window buf 0)))
+          (if win
+              (quit-window nil win)
+            (bury-buffer buf)))
+        (pop-to-buffer cbuf))))))
 
 (defun widget-color-sample-face-get (widget)
   (let* ((value (condition-case nil
diff --git a/lisp/window.el b/lisp/window.el
index 43e9e99..2b979f4 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7192,9 +7192,9 @@ See `display-buffer' for the format of display actions."
        (let ((pars (special-display-p (buffer-name buffer))))
         (when pars
            (list (list #'display-buffer-reuse-window
-                       `(lambda (buffer _alist)
-                          (funcall special-display-function
-                                   buffer ',(if (listp pars) pars)))))))))
+                       (lambda (buffer _alist)
+                         (funcall special-display-function
+                                  buffer (if (listp pars) pars)))))))))
 
 (defun display-buffer-pop-up-frame (buffer alist)
   "Display BUFFER in a new frame.
diff --git a/m4/dirfd.m4 b/m4/dirfd.m4
index b4ec3d1..d472c38 100644
--- a/m4/dirfd.m4
+++ b/m4/dirfd.m4
@@ -1,4 +1,4 @@
-# serial 24   -*- Autoconf -*-
+# serial 26   -*- Autoconf -*-
 
 dnl Find out how to get the file descriptor associated with an open DIR*.
 
@@ -12,6 +12,7 @@ dnl From Jim Meyering
 AC_DEFUN([gl_FUNC_DIRFD],
 [
   AC_REQUIRE([gl_DIRENT_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
 
   dnl Persuade glibc <dirent.h> to declare dirfd().
   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
@@ -25,15 +26,15 @@ AC_DEFUN([gl_FUNC_DIRFD],
   fi
 
   AC_CACHE_CHECK([whether dirfd is a macro],
-    gl_cv_func_dirfd_macro,
+    [gl_cv_func_dirfd_macro],
     [AC_EGREP_CPP([dirent_header_defines_dirfd], [
 #include <sys/types.h>
 #include <dirent.h>
 #ifdef dirfd
  dirent_header_defines_dirfd
 #endif],
-       gl_cv_func_dirfd_macro=yes,
-       gl_cv_func_dirfd_macro=no)])
+       [gl_cv_func_dirfd_macro=yes],
+       [gl_cv_func_dirfd_macro=no])])
 
   # Use the replacement if we have no function or macro with that name,
   # or if OS/2 kLIBC whose dirfd() does not work.
diff --git a/m4/explicit_bzero.m4 b/m4/explicit_bzero.m4
new file mode 100644
index 0000000..f9dc678
--- /dev/null
+++ b/m4/explicit_bzero.m4
@@ -0,0 +1,22 @@
+dnl Copyright 2017 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_EXPLICIT_BZERO],
+[
+  AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+
+  dnl Persuade glibc <string.h> to declare explicit_bzero.
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_CHECK_FUNCS_ONCE([explicit_bzero])
+  if test $ac_cv_func_explicit_bzero = no; then
+    HAVE_EXPLICIT_BZERO=0
+  fi
+])
+
+AC_DEFUN([gl_PREREQ_EXPLICIT_BZERO],
+[
+  AC_CHECK_FUNCS([explicit_memset])
+])
diff --git a/m4/getdtablesize.m4 b/m4/getdtablesize.m4
index 1af2a24..f1e4f5f 100644
--- a/m4/getdtablesize.m4
+++ b/m4/getdtablesize.m4
@@ -1,4 +1,4 @@
-# getdtablesize.m4 serial 6
+# getdtablesize.m4 serial 7
 dnl Copyright (C) 2008-2017 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -12,29 +12,43 @@ AC_DEFUN([gl_FUNC_GETDTABLESIZE],
   AC_CHECK_DECLS_ONCE([getdtablesize])
   if test $ac_cv_func_getdtablesize = yes &&
      test $ac_cv_have_decl_getdtablesize = yes; then
-    # Cygwin 1.7.25 automatically increases the RLIMIT_NOFILE soft limit
-    # up to an unchangeable hard limit; all other platforms correctly
-    # require setrlimit before getdtablesize() can report a larger value.
     AC_CACHE_CHECK([whether getdtablesize works],
       [gl_cv_func_getdtablesize_works],
-      [AC_RUN_IFELSE([
-        AC_LANG_PROGRAM([[#include <unistd.h>]],
-          [int size = getdtablesize();
-           if (dup2 (0, getdtablesize()) != -1)
-             return 1;
-           if (size != getdtablesize())
-             return 2;
-          ])],
-        [gl_cv_func_getdtablesize_works=yes],
-        [gl_cv_func_getdtablesize_works=no],
-        [case "$host_os" in
-          cygwin*) # on cygwin 1.5.25, getdtablesize() automatically grows
-            gl_cv_func_getdtablesize_works="guessing no" ;;
-          *) gl_cv_func_getdtablesize_works="guessing yes" ;;
-         esac])
+      [dnl There are two concepts: the "maximum possible file descriptor value 
+ 1"
+       dnl and the "maximum number of open file descriptors in a process".
+       dnl Per SUSv2 and POSIX, getdtablesize() should return the first one.
+       dnl On most platforms, the first and the second concept are the same.
+       dnl On OpenVMS, however, they are different and getdtablesize() returns
+       dnl the second one; thus the test below fails. But we don't care
+       dnl because there's no good way to write a replacement getdtablesize().
+       case "$host_os" in
+         vms*) gl_cv_func_getdtablesize_works="no (limitation)" ;;
+         *)
+           dnl Cygwin 1.7.25 automatically increases the RLIMIT_NOFILE soft
+           dnl limit up to an unchangeable hard limit; all other platforms
+           dnl correctly require setrlimit before getdtablesize() can report
+           dnl a larger value.
+           AC_RUN_IFELSE([
+             AC_LANG_PROGRAM([[#include <unistd.h>]],
+               [int size = getdtablesize();
+                if (dup2 (0, getdtablesize()) != -1)
+                  return 1;
+                if (size != getdtablesize())
+                  return 2;
+               ])],
+             [gl_cv_func_getdtablesize_works=yes],
+             [gl_cv_func_getdtablesize_works=no],
+             [case "$host_os" in
+                cygwin*) # on cygwin 1.5.25, getdtablesize() automatically 
grows
+                  gl_cv_func_getdtablesize_works="guessing no" ;;
+                *) gl_cv_func_getdtablesize_works="guessing yes" ;;
+              esac
+             ])
+           ;;
+       esac
       ])
     case "$gl_cv_func_getdtablesize_works" in
-      *yes) ;;
+      *yes | "no (limitation)") ;;
       *) REPLACE_GETDTABLESIZE=1 ;;
     esac
   else
diff --git a/m4/gettimeofday.m4 b/m4/gettimeofday.m4
index 8ee206e..efa114d 100644
--- a/m4/gettimeofday.m4
+++ b/m4/gettimeofday.m4
@@ -1,4 +1,4 @@
-# serial 23
+# serial 24
 
 # Copyright (C) 2001-2003, 2005, 2007, 2009-2017 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -105,6 +105,8 @@ AC_DEFUN([gl_FUNC_GETTIMEOFDAY_CLOBBER],
       case "$host_os" in
                 # Guess all is fine on glibc systems.
         *-gnu*) gl_cv_func_gettimeofday_clobber="guessing no" ;;
+                # Guess no on native Windows.
+        mingw*) gl_cv_func_gettimeofday_clobber="guessing no" ;;
                 # If we don't know, assume the worst.
         *)      gl_cv_func_gettimeofday_clobber="guessing yes" ;;
       esac
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 107645d..2f13577 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -72,6 +72,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module errno:
   # Code from module euidaccess:
   # Code from module execinfo:
+  # Code from module explicit_bzero:
   # Code from module extensions:
   # Code from module extern-inline:
   # Code from module faccessat:
@@ -112,6 +113,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module mktime-internal:
   # Code from module multiarch:
   # Code from module nocrash:
+  # Code from module nstrftime:
   # Code from module openat-h:
   # Code from module pipe2:
   # Code from module pselect:
@@ -138,7 +140,6 @@ AC_DEFUN([gl_EARLY],
   # Code from module stdio:
   # Code from module stdlib:
   # Code from module stpcpy:
-  # Code from module strftime:
   # Code from module string:
   # Code from module strtoimax:
   # Code from module strtoll:
@@ -210,6 +211,12 @@ AC_DEFUN([gl_INIT],
   gl_UNISTD_MODULE_INDICATOR([environ])
   gl_HEADER_ERRNO_H
   gl_EXECINFO_H
+  gl_FUNC_EXPLICIT_BZERO
+  if test $HAVE_EXPLICIT_BZERO = 0; then
+    AC_LIBOBJ([explicit_bzero])
+    gl_PREREQ_EXPLICIT_BZERO
+  fi
+  gl_STRING_MODULE_INDICATOR([explicit_bzero])
   AC_REQUIRE([gl_EXTERN_INLINE])
   gl_FUNC_FACCESSAT
   if test $HAVE_FACCESSAT = 0; then
@@ -307,6 +314,7 @@ AC_DEFUN([gl_INIT],
   fi
   gl_TIME_MODULE_INDICATOR([mktime])
   gl_MULTIARCH
+  gl_FUNC_GNU_STRFTIME
   gl_FUNC_PIPE2
   gl_UNISTD_MODULE_INDICATOR([pipe2])
   gl_FUNC_PSELECT
@@ -358,7 +366,6 @@ AC_DEFUN([gl_INIT],
     gl_PREREQ_STPCPY
   fi
   gl_STRING_MODULE_INDICATOR([stpcpy])
-  gl_FUNC_GNU_STRFTIME
   gl_HEADER_STRING_H
   gl_FUNC_STRTOIMAX
   if test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; then
@@ -837,6 +844,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/euidaccess.c
   lib/execinfo.c
   lib/execinfo.in.h
+  lib/explicit_bzero.c
   lib/faccessat.c
   lib/fcntl.c
   lib/fcntl.in.h
@@ -885,6 +893,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/mkostemp.c
   lib/mktime-internal.h
   lib/mktime.c
+  lib/nstrftime.c
   lib/openat-priv.h
   lib/openat-proc.c
   lib/openat.h
@@ -916,7 +925,6 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/stdio.in.h
   lib/stdlib.in.h
   lib/stpcpy.c
-  lib/strftime.c
   lib/strftime.h
   lib/string.in.h
   lib/strtoimax.c
@@ -967,6 +975,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/errno_h.m4
   m4/euidaccess.m4
   m4/execinfo.m4
+  m4/explicit_bzero.m4
   m4/extensions.m4
   m4/extern-inline.m4
   m4/faccessat.m4
@@ -1004,6 +1013,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/mktime.m4
   m4/multiarch.m4
   m4/nocrash.m4
+  m4/nstrftime.m4
   m4/off_t.m4
   m4/pipe2.m4
   m4/pselect.m4
@@ -1028,7 +1038,6 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/stdio_h.m4
   m4/stdlib_h.m4
   m4/stpcpy.m4
-  m4/strftime.m4
   m4/string_h.m4
   m4/strtoimax.m4
   m4/strtoll.m4
diff --git a/m4/lstat.m4 b/m4/lstat.m4
index 953c117..0b6e5d7 100644
--- a/m4/lstat.m4
+++ b/m4/lstat.m4
@@ -1,4 +1,4 @@
-# serial 27
+# serial 29
 
 # Copyright (C) 1997-2001, 2003-2017 Free Software Foundation, Inc.
 #
@@ -33,6 +33,7 @@ AC_DEFUN([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK],
 [
   dnl We don't use AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK any more, because it
   dnl is no longer maintained in Autoconf and because it invokes AC_LIBOBJ.
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
   AC_CACHE_CHECK([whether lstat correctly handles trailing slash],
     [gl_cv_func_lstat_dereferences_slashed_symlink],
     [rm -f conftest.sym conftest.file
@@ -54,6 +55,9 @@ AC_DEFUN([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK],
           *-gnu*)
             # Guess yes on glibc systems.
             gl_cv_func_lstat_dereferences_slashed_symlink="guessing yes" ;;
+          mingw*)
+            # Guess no on native Windows.
+            gl_cv_func_lstat_dereferences_slashed_symlink="guessing no" ;;
           *)
             # If we don't know, assume the worst.
             gl_cv_func_lstat_dereferences_slashed_symlink="guessing no" ;;
diff --git a/m4/mktime.m4 b/m4/mktime.m4
index 31da65e..8566684 100644
--- a/m4/mktime.m4
+++ b/m4/mktime.m4
@@ -1,4 +1,4 @@
-# serial 28
+# serial 29
 dnl Copyright (C) 2002-2003, 2005-2007, 2009-2017 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
@@ -25,6 +25,7 @@ dnl Test whether mktime works. Set gl_cv_func_working_mktime.
 AC_DEFUN([gl_FUNC_MKTIME_WORKS],
 [
   AC_REQUIRE([gl_TIME_T_IS_SIGNED])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
 
   dnl We don't use AC_FUNC_MKTIME any more, because it is no longer maintained
   dnl in Autoconf and because it invokes AC_LIBOBJ.
@@ -239,7 +240,12 @@ main ()
 }]])],
        [gl_cv_func_working_mktime=yes],
        [gl_cv_func_working_mktime=no],
-       [gl_cv_func_working_mktime="guessing no"])
+       [case "$host_os" in
+                  # Guess no on native Windows.
+          mingw*) gl_cv_func_working_mktime="guessing no" ;;
+          *)      gl_cv_func_working_mktime="guessing no" ;;
+        esac
+       ])
     ])
 ])
 
diff --git a/m4/strftime.m4 b/m4/nstrftime.m4
similarity index 100%
rename from m4/strftime.m4
rename to m4/nstrftime.m4
diff --git a/m4/pselect.m4 b/m4/pselect.m4
index 3f1c43f..eb1ad11 100644
--- a/m4/pselect.m4
+++ b/m4/pselect.m4
@@ -1,4 +1,4 @@
-# pselect.m4 serial 2
+# pselect.m4 serial 4
 dnl Copyright (C) 2011-2017 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,11 +8,12 @@ AC_DEFUN([gl_FUNC_PSELECT],
 [
   AC_REQUIRE([gl_HEADER_SYS_SELECT])
   AC_REQUIRE([AC_C_RESTRICT])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
   AC_CHECK_FUNCS_ONCE([pselect])
 
   if test $ac_cv_func_pselect = yes; then
     AC_CACHE_CHECK([whether signature of pselect conforms to POSIX],
-      gl_cv_sig_pselect,
+      [gl_cv_sig_pselect],
       [AC_LINK_IFELSE(
          [AC_LANG_PROGRAM(
               [[#include <sys/select.h>
diff --git a/m4/putenv.m4 b/m4/putenv.m4
index a8e3ab3..08ae416 100644
--- a/m4/putenv.m4
+++ b/m4/putenv.m4
@@ -1,4 +1,4 @@
-# putenv.m4 serial 20
+# putenv.m4 serial 21
 dnl Copyright (C) 2002-2017 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -36,6 +36,8 @@ AC_DEFUN([gl_FUNC_PUTENV],
              [case "$host_os" in
                         # Guess yes on glibc systems.
                 *-gnu*) gl_cv_func_svid_putenv="guessing yes" ;;
+                        # Guess no on native Windows.
+                mingw*) gl_cv_func_svid_putenv="guessing no" ;;
                         # If we don't know, assume the worst.
                 *)      gl_cv_func_svid_putenv="guessing no" ;;
               esac
diff --git a/m4/stdint.m4 b/m4/stdint.m4
index 4ac854d..4bf3e47 100644
--- a/m4/stdint.m4
+++ b/m4/stdint.m4
@@ -1,4 +1,4 @@
-# stdint.m4 serial 50
+# stdint.m4 serial 51
 dnl Copyright (C) 2001-2017 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,6 +10,7 @@ dnl Test whether <stdint.h> is supported or must be 
substituted.
 AC_DEFUN_ONCE([gl_STDINT_H],
 [
   AC_PREREQ([2.59])dnl
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
 
   AC_REQUIRE([gl_LIMITS_H])
   AC_REQUIRE([gt_TYPE_WINT_T])
@@ -288,8 +289,12 @@ static const char *macro_values[] =
 ]])],
               [gl_cv_header_working_stdint_h=yes],
               [],
-              [dnl When cross-compiling, assume it works.
-               gl_cv_header_working_stdint_h=yes
+              [case "$host_os" in
+                         # Guess yes on native Windows.
+                 mingw*) gl_cv_header_working_stdint_h="guessing yes" ;;
+                         # In general, assume it works.
+                 *)      gl_cv_header_working_stdint_h="guessing yes" ;;
+               esac
               ])
          ])
       ])
@@ -299,15 +304,16 @@ static const char *macro_values[] =
   HAVE_SYS_BITYPES_H=0
   HAVE_SYS_INTTYPES_H=0
   STDINT_H=stdint.h
-  if test "$gl_cv_header_working_stdint_h" = yes; then
-    HAVE_C99_STDINT_H=1
-    dnl Now see whether the system <stdint.h> works without
-    dnl __STDC_CONSTANT_MACROS/__STDC_LIMIT_MACROS defined.
-    AC_CACHE_CHECK([whether stdint.h predates C++11],
-      [gl_cv_header_stdint_predates_cxx11_h],
-      [gl_cv_header_stdint_predates_cxx11_h=yes
-       AC_COMPILE_IFELSE([
-         AC_LANG_PROGRAM([[
+  case "$gl_cv_header_working_stdint_h" in
+    *yes)
+      HAVE_C99_STDINT_H=1
+      dnl Now see whether the system <stdint.h> works without
+      dnl __STDC_CONSTANT_MACROS/__STDC_LIMIT_MACROS defined.
+      AC_CACHE_CHECK([whether stdint.h predates C++11],
+        [gl_cv_header_stdint_predates_cxx11_h],
+        [gl_cv_header_stdint_predates_cxx11_h=yes
+         AC_COMPILE_IFELSE([
+           AC_LANG_PROGRAM([[
 #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
 #include <stdint.h>
 ]
@@ -315,45 +321,47 @@ gl_STDINT_INCLUDES
 [
 intmax_t im = INTMAX_MAX;
 int32_t i32 = INT32_C (0x7fffffff);
-         ]])],
-         [gl_cv_header_stdint_predates_cxx11_h=no])])
+           ]])],
+           [gl_cv_header_stdint_predates_cxx11_h=no])])
 
-    if test "$gl_cv_header_stdint_predates_cxx11_h" = yes; then
-      AC_DEFINE([__STDC_CONSTANT_MACROS], [1],
-                [Define to 1 if the system <stdint.h> predates C++11.])
-      AC_DEFINE([__STDC_LIMIT_MACROS], [1],
-                [Define to 1 if the system <stdint.h> predates C++11.])
-    fi
-    AC_CACHE_CHECK([whether stdint.h has UINTMAX_WIDTH etc.],
-      [gl_cv_header_stdint_width],
-      [gl_cv_header_stdint_width=no
-       AC_COMPILE_IFELSE(
-         [AC_LANG_PROGRAM([[
-            /* Work if build is not clean.  */
-            #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1
-            #ifndef __STDC_WANT_IEC_60559_BFP_EXT__
-             #define __STDC_WANT_IEC_60559_BFP_EXT__ 1
-            #endif
-            #include <stdint.h>
-            ]gl_STDINT_INCLUDES[
-            int iw = UINTMAX_WIDTH;
-            ]])],
-         [gl_cv_header_stdint_width=yes])])
-    if test "$gl_cv_header_stdint_width" = yes; then
-      STDINT_H=
-    fi
-  else
-    dnl Check for <sys/inttypes.h>, and for
-    dnl <sys/bitypes.h> (used in Linux libc4 >= 4.6.7 and libc5).
-    AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h])
-    if test $ac_cv_header_sys_inttypes_h = yes; then
-      HAVE_SYS_INTTYPES_H=1
-    fi
-    if test $ac_cv_header_sys_bitypes_h = yes; then
-      HAVE_SYS_BITYPES_H=1
-    fi
-    gl_STDINT_TYPE_PROPERTIES
-  fi
+      if test "$gl_cv_header_stdint_predates_cxx11_h" = yes; then
+        AC_DEFINE([__STDC_CONSTANT_MACROS], [1],
+                  [Define to 1 if the system <stdint.h> predates C++11.])
+        AC_DEFINE([__STDC_LIMIT_MACROS], [1],
+                  [Define to 1 if the system <stdint.h> predates C++11.])
+      fi
+      AC_CACHE_CHECK([whether stdint.h has UINTMAX_WIDTH etc.],
+        [gl_cv_header_stdint_width],
+        [gl_cv_header_stdint_width=no
+         AC_COMPILE_IFELSE(
+           [AC_LANG_PROGRAM([[
+              /* Work if build is not clean.  */
+              #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1
+              #ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+               #define __STDC_WANT_IEC_60559_BFP_EXT__ 1
+              #endif
+              #include <stdint.h>
+              ]gl_STDINT_INCLUDES[
+              int iw = UINTMAX_WIDTH;
+              ]])],
+           [gl_cv_header_stdint_width=yes])])
+      if test "$gl_cv_header_stdint_width" = yes; then
+        STDINT_H=
+      fi
+      ;;
+    *)
+      dnl Check for <sys/inttypes.h>, and for
+      dnl <sys/bitypes.h> (used in Linux libc4 >= 4.6.7 and libc5).
+      AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h])
+      if test $ac_cv_header_sys_inttypes_h = yes; then
+        HAVE_SYS_INTTYPES_H=1
+      fi
+      if test $ac_cv_header_sys_bitypes_h = yes; then
+        HAVE_SYS_BITYPES_H=1
+      fi
+      gl_STDINT_TYPE_PROPERTIES
+      ;;
+  esac
 
   dnl The substitute stdint.h needs the substitute limit.h's _GL_INTEGER_WIDTH.
   LIMITS_H=limits.h
diff --git a/m4/string_h.m4 b/m4/string_h.m4
index 3d2ad22..ac6311f 100644
--- a/m4/string_h.m4
+++ b/m4/string_h.m4
@@ -43,6 +43,7 @@ AC_DEFUN([gl_STRING_MODULE_INDICATOR],
 
 AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
 [
+  GNULIB_EXPLICIT_BZERO=0; AC_SUBST([GNULIB_EXPLICIT_BZERO])
   GNULIB_FFSL=0;        AC_SUBST([GNULIB_FFSL])
   GNULIB_FFSLL=0;       AC_SUBST([GNULIB_FFSLL])
   GNULIB_MEMCHR=0;      AC_SUBST([GNULIB_MEMCHR])
@@ -82,6 +83,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
   GNULIB_STRVERSCMP=0;  AC_SUBST([GNULIB_STRVERSCMP])
   HAVE_MBSLEN=0;        AC_SUBST([HAVE_MBSLEN])
   dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE_EXPLICIT_BZERO=1;        AC_SUBST([HAVE_EXPLICIT_BZERO])
   HAVE_FFSL=1;                  AC_SUBST([HAVE_FFSL])
   HAVE_FFSLL=1;                 AC_SUBST([HAVE_FFSLL])
   HAVE_MEMCHR=1;                AC_SUBST([HAVE_MEMCHR])
diff --git a/m4/strtoimax.m4 b/m4/strtoimax.m4
index f0586f1..61809c8 100644
--- a/m4/strtoimax.m4
+++ b/m4/strtoimax.m4
@@ -1,4 +1,4 @@
-# strtoimax.m4 serial 14
+# strtoimax.m4 serial 15
 dnl Copyright (C) 2002-2004, 2006, 2009-2017 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -61,10 +61,12 @@ int main ()
          [gl_cv_func_strtoimax=yes],
          [gl_cv_func_strtoimax=no],
          [case "$host_os" in
-                   # Guess no on AIX 5.
-            aix5*) gl_cv_func_strtoimax="guessing no" ;;
-                   # Guess yes otherwise.
-            *)     gl_cv_func_strtoimax="guessing yes" ;;
+                    # Guess no on AIX 5.
+            aix5*)  gl_cv_func_strtoimax="guessing no" ;;
+                    # Guess yes on native Windows.
+            mingw*) gl_cv_func_strtoimax="guessing yes" ;;
+                    # Guess yes otherwise.
+            *)      gl_cv_func_strtoimax="guessing yes" ;;
           esac
          ])
       ])
diff --git a/m4/utimes.m4 b/m4/utimes.m4
index 518824f..847b2eb 100644
--- a/m4/utimes.m4
+++ b/m4/utimes.m4
@@ -1,5 +1,5 @@
 # Detect some bugs in glibc's implementation of utimes.
-# serial 4
+# serial 5
 
 dnl Copyright (C) 2003-2005, 2009-2017 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
@@ -20,10 +20,10 @@ dnl with or without modifications, as long as this notice 
is preserved.
 
 AC_DEFUN([gl_FUNC_UTIMES],
 [
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
   AC_CACHE_CHECK([whether the utimes function works],
                  [gl_cv_func_working_utimes],
-  [
-  AC_RUN_IFELSE([AC_LANG_SOURCE([[
+    [AC_RUN_IFELSE([AC_LANG_SOURCE([[
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -142,9 +142,17 @@ main ()
   ]])],
        [gl_cv_func_working_utimes=yes],
        [gl_cv_func_working_utimes=no],
-       [gl_cv_func_working_utimes=no])])
+       [case "$host_os" in
+                  # Guess no on native Windows.
+          mingw*) gl_cv_func_working_utimes="guessing no" ;;
+          *)      gl_cv_func_working_utimes="guessing no" ;;
+        esac
+       ])
+    ])
 
-  if test $gl_cv_func_working_utimes = yes; then
-    AC_DEFINE([HAVE_WORKING_UTIMES], [1], [Define if utimes works properly.])
-  fi
+  case "$gl_cv_func_working_utimes" in
+    *yes)
+      AC_DEFINE([HAVE_WORKING_UTIMES], [1], [Define if utimes works properly.])
+      ;;
+  esac
 ])
diff --git a/nextstep/INSTALL b/nextstep/INSTALL
index 799cd4d..b7e84e0 100644
--- a/nextstep/INSTALL
+++ b/nextstep/INSTALL
@@ -21,15 +21,23 @@ In the top-level directory, use:
 
 (On macOS, --with-ns is enabled by default.)
 
-This will compile all the files, but emacs will not be able to be run except
-in -nw (terminal) mode.
+Then run:
 
-In order to run Emacs.app, you must run:
+  make
+
+This will compile all the files.
+
+In order to run Emacs, you must run:
+
+  src/emacs
+
+In order to install Emacs, you must run:
 
   make install
 
 This will assemble the app in nextstep/Emacs.app (i.e., the --prefix
-argument has no effect in this case).
+argument has no effect in this case).  You can then move the Emacs.app
+bundle to a location of your choice.
 
 If you pass the --disable-ns-self-contained option to configure, the lisp
 files will be installed under whatever 'prefix' is set to (defaults to
diff --git a/src/alloc.c b/src/alloc.c
index ac3de83..2cee646 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1553,7 +1553,7 @@ make_interval (void)
 /* Mark Lisp objects in interval I.  */
 
 static void
-mark_interval (register INTERVAL i, Lisp_Object dummy)
+mark_interval (INTERVAL i, void *dummy)
 {
   /* Intervals should never be shared.  So, if extra internal checking is
      enabled, GC aborts if it seems to have visited an interval twice.  */
@@ -1567,7 +1567,7 @@ mark_interval (register INTERVAL i, Lisp_Object dummy)
 #define MARK_INTERVAL_TREE(i)                                  \
   do {                                                         \
     if (i && !i->gcmarkbit)                                    \
-      traverse_intervals_noorder (i, mark_interval, Qnil);     \
+      traverse_intervals_noorder (i, mark_interval, NULL);     \
   } while (0)
 
 /***********************************************************************
@@ -6943,7 +6943,7 @@ sweep_symbols (void)
   symbol_free_list = NULL;
 
   for (int i = 0; i < ARRAYELTS (lispsym); i++)
-    lispsym[i].gcmarkbit = 0;
+    lispsym[i].s.gcmarkbit = 0;
 
   for (sblk = symbol_block; sblk; sblk = *sprev)
     {
diff --git a/src/bidi.c b/src/bidi.c
index e34da77..7637974 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -1448,8 +1448,14 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t 
bytepos)
   Lisp_Object start_re;
   ptrdiff_t val;
 
-  sep_re = paragraph_separate_re;
-  start_re = paragraph_start_re;
+  if (STRINGP (BVAR (current_buffer, bidi_paragraph_separate_re)))
+    sep_re = BVAR (current_buffer, bidi_paragraph_separate_re);
+  else
+    sep_re = paragraph_separate_re;
+  if (STRINGP (BVAR (current_buffer, bidi_paragraph_start_re)))
+    start_re = BVAR (current_buffer, bidi_paragraph_start_re);
+  else
+    start_re = paragraph_start_re;
 
   val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil);
   if (val < 0)
@@ -1523,7 +1529,10 @@ bidi_paragraph_cache_on_off (void)
 static ptrdiff_t
 bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
 {
-  Lisp_Object re = paragraph_start_re;
+  Lisp_Object re =
+    STRINGP (BVAR (current_buffer, bidi_paragraph_start_re))
+    ? BVAR (current_buffer, bidi_paragraph_start_re)
+    : paragraph_start_re;
   ptrdiff_t limit = ZV, limit_byte = ZV_BYTE;
   struct region_cache *bpc = bidi_paragraph_cache_on_off ();
   ptrdiff_t n = 0, oldpos = pos, next;
@@ -3498,10 +3507,16 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
          if (sep_len >= 0)
            {
              bidi_it->new_paragraph = 1;
-             /* Record the buffer position of the last character of the
-                paragraph separator.  */
-             bidi_it->separator_limit
-               = bidi_it->charpos + bidi_it->nchars + sep_len;
+             /* Record the buffer position of the last character of
+                the paragraph separator.  If the paragraph separator
+                is an empty string (e.g., the regex is "^"), the
+                newline that precedes the end of the paragraph is
+                that last character.  */
+             if (sep_len > 0)
+               bidi_it->separator_limit
+                 = bidi_it->charpos + bidi_it->nchars + sep_len;
+             else
+               bidi_it->separator_limit = bidi_it->charpos;
            }
        }
     }
diff --git a/src/buffer.c b/src/buffer.c
index 80dbd33..649ddbe 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -173,6 +173,16 @@ bset_bidi_display_reordering (struct buffer *b, 
Lisp_Object val)
   b->bidi_display_reordering_ = val;
 }
 static void
+bset_bidi_paragraph_start_re (struct buffer *b, Lisp_Object val)
+{
+  b->bidi_paragraph_start_re_ = val;
+}
+static void
+bset_bidi_paragraph_separate_re (struct buffer *b, Lisp_Object val)
+{
+  b->bidi_paragraph_separate_re_ = val;
+}
+static void
 bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val)
 {
   b->buffer_file_coding_system_ = val;
@@ -1164,7 +1174,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object 
buffer)
       { /* Look in local_var_alist.  */
        struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
        XSETSYMBOL (variable, sym); /* Update In case of aliasing.  */
-       result = Fassoc (variable, BVAR (buf, local_var_alist));
+       result = Fassoc (variable, BVAR (buf, local_var_alist), Qnil);
        if (!NILP (result))
          {
            if (blv->fwd)
@@ -2322,6 +2332,8 @@ results, see Info node `(elisp)Swapping Text'.  */)
   swapfield_ (enable_multibyte_characters, Lisp_Object);
   swapfield_ (bidi_display_reordering, Lisp_Object);
   swapfield_ (bidi_paragraph_direction, Lisp_Object);
+  swapfield_ (bidi_paragraph_separate_re, Lisp_Object);
+  swapfield_ (bidi_paragraph_start_re, Lisp_Object);
   /* FIXME: Not sure what we should do with these *_marker fields.
      Hopefully they're just nil anyway.  */
   swapfield_ (pt_marker, Lisp_Object);
@@ -3054,6 +3066,33 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
   return i < n;
 }
 
+/* Return the value of the 'display-line-numbers-disable' property at
+   EOB, if there's an overlay at ZV with a non-nil value of that property.  */
+Lisp_Object
+disable_line_numbers_overlay_at_eob (void)
+{
+  ptrdiff_t n, i, size;
+  Lisp_Object *v, tem = Qnil;
+  Lisp_Object vbuf[10];
+  USE_SAFE_ALLOCA;
+
+  size = ARRAYELTS (vbuf);
+  v = vbuf;
+  n = overlays_in (ZV, ZV, 0, &v, &size, NULL, NULL);
+  if (n > size)
+    {
+      SAFE_NALLOCA (v, 1, n);
+      overlays_in (ZV, ZV, 0, &v, &n, NULL, NULL);
+    }
+
+  for (i = 0; i < n; ++i)
+    if ((tem = Foverlay_get (v[i], Qdisplay_line_numbers_disable),
+        !NILP (tem)))
+      break;
+
+  SAFE_FREE ();
+  return tem;
+}
 
 
 /* Fast function to just test if we're at an overlay boundary.  */
@@ -5094,6 +5133,8 @@ init_buffer_once (void)
   XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); 
++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); 
++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_separate_re), idx); 
++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_start_re), idx); 
++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, buffer_file_coding_system), idx);
   /* Make this one a permanent local.  */
   buffer_permanent_local_flags[idx++] = 1;
@@ -5175,6 +5216,8 @@ init_buffer_once (void)
   bset_ctl_arrow (&buffer_defaults, Qt);
   bset_bidi_display_reordering (&buffer_defaults, Qt);
   bset_bidi_paragraph_direction (&buffer_defaults, Qnil);
+  bset_bidi_paragraph_start_re (&buffer_defaults, Qnil);
+  bset_bidi_paragraph_separate_re (&buffer_defaults, Qnil);
   bset_cursor_type (&buffer_defaults, Qt);
   bset_extra_line_spacing (&buffer_defaults, Qnil);
   bset_cursor_in_non_selected_windows (&buffer_defaults, Qt);
@@ -5589,6 +5632,49 @@ This variable is never applied to a way of decoding a 
file while reading it.  */
                     &BVAR (current_buffer, bidi_display_reordering), Qnil,
                     doc: /* Non-nil means reorder bidirectional text for 
display in the visual order.  */);
 
+  DEFVAR_PER_BUFFER ("bidi-paragraph-start-re",
+                    &BVAR (current_buffer, bidi_paragraph_start_re), Qnil,
+                    doc: /* If non-nil, a regexp matching a line that starts 
OR separates paragraphs.
+
+The value of nil means to use empty lines as lines that start and
+separate paragraphs.
+
+When Emacs displays bidirectional text, it by default computes
+the base paragraph direction separately for each paragraph.
+Setting this variable changes the places where paragraph base
+direction is recomputed.
+
+The regexp is always matched after a newline, so it is best to
+anchor it by beginning it with a "^".
+
+If you change the value of this variable, be sure to change
+the value of `bidi-paragraph-separate-re' accordingly.  For
+example, to have a single newline behave as a paragraph separator,
+set both these variables to "^".
+
+See also `bidi-paragraph-direction'.  */);
+
+  DEFVAR_PER_BUFFER ("bidi-paragraph-separate-re",
+                    &BVAR (current_buffer, bidi_paragraph_separate_re), Qnil,
+                    doc: /* If non-nil, a regexp matching a line that 
separates paragraphs.
+
+The value of nil means to use empty lines as paragraph separators.
+
+When Emacs displays bidirectional text, it by default computes
+the base paragraph direction separately for each paragraph.
+Setting this variable changes the places where paragraph base
+direction is recomputed.
+
+The regexp is always matched after a newline, so it is best to
+anchor it by beginning it with a "^".
+
+If you change the value of this variable, be sure to change
+the value of `bidi-paragraph-start-re' accordingly.  For
+example, to have a single newline behave as a paragraph separator,
+set both these variables to "^".
+
+See also `bidi-paragraph-direction'.  */);
+
   DEFVAR_PER_BUFFER ("bidi-paragraph-direction",
                     &BVAR (current_buffer, bidi_paragraph_direction), Qnil,
                     doc: /* If non-nil, forces directionality of text 
paragraphs in the buffer.
diff --git a/src/buffer.h b/src/buffer.h
index be270fe..46ca6aa 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -611,6 +611,12 @@ struct buffer
      direction dynamically for each paragraph.  */
   Lisp_Object bidi_paragraph_direction_;
 
+  /* If non-nil, a regular expression for bidi paragraph separator.  */
+  Lisp_Object bidi_paragraph_separate_re_;
+
+  /* If non-nil, a regular expression for bidi paragraph start.  */
+  Lisp_Object bidi_paragraph_start_re_;
+
   /* Non-nil means do selective display;
      see doc string in syms_of_buffer (buffer.c) for details.  */
   Lisp_Object selective_display_;
diff --git a/src/charset.c b/src/charset.c
index 9c3b8db..6ce2f90 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -407,44 +407,49 @@ load_charset_map (struct charset *charset, struct 
charset_map_entries *entries,
 
 
 /* Read a hexadecimal number (preceded by "0x") from the file FP while
-   paying attention to comment character '#'.  */
+   paying attention to comment character '#'.  LOOKAHEAD is the
+   lookahead byte if it is nonnegative.  Store into *TERMINATOR the
+   input byte after the number, or EOF if an end-of-file or input
+   error occurred.  Set *OVERFLOW if the number overflows.  */
 
 static unsigned
-read_hex (FILE *fp, bool *eof, bool *overflow)
+read_hex (FILE *fp, int lookahead, int *terminator, bool *overflow)
 {
-  int c;
-  unsigned n;
+  int c = lookahead < 0 ? getc_unlocked (fp) : lookahead;
 
-  while ((c = getc_unlocked (fp)) != EOF)
+  while (true)
     {
       if (c == '#')
-       {
-         while ((c = getc_unlocked (fp)) != EOF && c != '\n');
-       }
+       do
+         c = getc_unlocked (fp);
+       while (0 <= c && c != '\n');
       else if (c == '0')
        {
-         if ((c = getc_unlocked (fp)) == EOF || c == 'x')
+         c = getc_unlocked (fp);
+         if (c < 0 || c == 'x')
            break;
        }
-    }
-  if (c == EOF)
-    {
-      *eof = 1;
-      return 0;
-    }
-  n = 0;
-  while (true)
-    {
-      c = getc_unlocked (fp);
-      int digit = char_hexdigit (c);
-      if (digit < 0)
+      if (c < 0)
        break;
-      if (INT_LEFT_SHIFT_OVERFLOW (n, 4))
-       *overflow = 1;
-      n = (n << 4) + digit;
+      c = getc_unlocked (fp);
     }
-  if (c != EOF)
-    ungetc (c, fp);
+
+  unsigned n = 0;
+  bool v = false;
+
+  if (0 <= c)
+    while (true)
+      {
+       c = getc_unlocked (fp);
+       int digit = char_hexdigit (c);
+       if (digit < 0)
+         break;
+       v |= INT_LEFT_SHIFT_OVERFLOW (n, 4);
+       n = (n << 4) + digit;
+      }
+
+  *terminator = c;
+  *overflow |= v;
   return n;
 }
 
@@ -499,23 +504,26 @@ load_charset_map_from_file (struct charset *charset, 
Lisp_Object mapfile,
   memset (entries, 0, sizeof (struct charset_map_entries));
 
   n_entries = 0;
-  while (1)
+  int ch = -1;
+  while (true)
     {
-      unsigned from, to, c;
-      int idx;
-      bool eof = 0, overflow = 0;
-
-      from = read_hex (fp, &eof, &overflow);
-      if (eof)
+      bool overflow = false;
+      unsigned from = read_hex (fp, ch, &ch, &overflow), to;
+      if (ch < 0)
        break;
-      if (getc_unlocked (fp) == '-')
-       to = read_hex (fp, &eof, &overflow);
+      if (ch == '-')
+       {
+         to = read_hex (fp, -1, &ch, &overflow);
+         if (ch < 0)
+           break;
+       }
       else
-       to = from;
-      if (eof)
-       break;
-      c = read_hex (fp, &eof, &overflow);
-      if (eof)
+       {
+         to = from;
+         ch = -1;
+       }
+      unsigned c = read_hex (fp, ch, &ch, &overflow);
+      if (ch < 0)
        break;
 
       if (overflow)
@@ -530,7 +538,7 @@ load_charset_map_from_file (struct charset *charset, 
Lisp_Object mapfile,
          memset (entries, 0, sizeof (struct charset_map_entries));
          n_entries = 0;
        }
-      idx = n_entries;
+      int idx = n_entries;
       entries->entry[idx].from = from;
       entries->entry[idx].to = to;
       entries->entry[idx].c = c;
diff --git a/src/coding.c b/src/coding.c
index 5682fc0..50ad206 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -10539,7 +10539,7 @@ usage: (define-coding-system-internal ...)  */)
          ASET (this_spec, 2, this_eol_type);
          Fputhash (this_name, this_spec, Vcoding_system_hash_table);
          Vcoding_system_list = Fcons (this_name, Vcoding_system_list);
-         val = Fassoc (Fsymbol_name (this_name), Vcoding_system_alist);
+         val = Fassoc (Fsymbol_name (this_name), Vcoding_system_alist, Qnil);
          if (NILP (val))
            Vcoding_system_alist
              = Fcons (Fcons (Fsymbol_name (this_name), Qnil),
@@ -10554,7 +10554,7 @@ usage: (define-coding-system-internal ...)  */)
 
   Fputhash (name, spec_vec, Vcoding_system_hash_table);
   Vcoding_system_list = Fcons (name, Vcoding_system_list);
-  val = Fassoc (Fsymbol_name (name), Vcoding_system_alist);
+  val = Fassoc (Fsymbol_name (name), Vcoding_system_alist, Qnil);
   if (NILP (val))
     Vcoding_system_alist = Fcons (Fcons (Fsymbol_name (name), Qnil),
                                  Vcoding_system_alist);
@@ -10662,7 +10662,7 @@ DEFUN ("define-coding-system-alias", 
Fdefine_coding_system_alias,
 
   Fputhash (alias, spec, Vcoding_system_hash_table);
   Vcoding_system_list = Fcons (alias, Vcoding_system_list);
-  val = Fassoc (Fsymbol_name (alias), Vcoding_system_alist);
+  val = Fassoc (Fsymbol_name (alias), Vcoding_system_alist, Qnil);
   if (NILP (val))
     Vcoding_system_alist = Fcons (Fcons (Fsymbol_name (alias), Qnil),
                                  Vcoding_system_alist);
diff --git a/src/dbusbind.c b/src/dbusbind.c
index d2460fd..0d9d3e5 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -955,7 +955,7 @@ xd_get_connection_address (Lisp_Object bus)
   DBusConnection *connection;
   Lisp_Object val;
 
-  val = CDR_SAFE (Fassoc (bus, xd_registered_buses));
+  val = CDR_SAFE (Fassoc (bus, xd_registered_buses, Qnil));
   if (NILP (val))
     XD_SIGNAL2 (build_string ("No connection to bus"), bus);
   else
@@ -1057,7 +1057,7 @@ xd_close_bus (Lisp_Object bus)
   Lisp_Object busobj;
 
   /* Check whether we are connected.  */
-  val = Fassoc (bus, xd_registered_buses);
+  val = Fassoc (bus, xd_registered_buses, Qnil);
   if (NILP (val))
     return;
 
@@ -1127,7 +1127,7 @@ this connection to those buses.  */)
   xd_close_bus (bus);
 
   /* Check, whether we are still connected.  */
-  val = Fassoc (bus, xd_registered_buses);
+  val = Fassoc (bus, xd_registered_buses, Qnil);
   if (!NILP (val))
     {
       connection = xd_get_connection_address (bus);
diff --git a/src/dispextern.h b/src/dispextern.h
index 8644ce2..1df769a 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -384,6 +384,7 @@ struct glyph
       glyph standing for newline at end of line    0
       empty space after the end of the line       -1
       overlay arrow on a TTY                      -1
+      glyph displaying line number                -1
       glyph at EOB that ends in a newline         -1
       left truncation glyphs:                     -1
       right truncation/continuation glyphs        next buffer position
@@ -2537,7 +2538,12 @@ struct it
      Do NOT use !BUFFERP (it.object) as a test whether we are
      iterating over a string; use STRINGP (it.string) instead.
 
-     Position is the current iterator position in object.  */
+     Position is the current iterator position in object.
+
+     The 'position's CHARPOS is copied to glyph->charpos of the glyph
+     produced by PRODUCE_GLYPHS, so any artificial value documented
+     under 'struct glyph's 'charpos' member can also be found in the
+     'position' member here.  */
   Lisp_Object object;
   struct text_pos position;
 
@@ -2621,6 +2627,20 @@ struct it
      coordinate is past first_visible_x.  */
   int hpos;
 
+  /* Current line number, zero-based.  */
+  ptrdiff_t lnum;
+
+  /* The byte position corresponding to lnum.  */
+  ptrdiff_t lnum_bytepos;
+
+  /* The width, in columns and in pixels, needed for display of the
+     line numbers, or zero if not computed.  */
+  int lnum_width;
+  int lnum_pixel_width;
+
+  /* The line number of point's line, or zero if not computed yet.  */
+  ptrdiff_t pt_lnum;
+
   /* Left fringe bitmap number (enum fringe_bitmap_type).  */
   unsigned left_user_fringe_bitmap : FRINGE_ID_BITS;
 
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 7b1a402..ad6c8fb 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -315,20 +315,18 @@ module_free_global_ref (emacs_env *env, emacs_value ref)
   MODULE_FUNCTION_BEGIN ();
   struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash);
   Lisp_Object obj = value_to_lisp (ref);
-  EMACS_UINT hashcode;
-  ptrdiff_t i = hash_lookup (h, obj, &hashcode);
+  ptrdiff_t i = hash_lookup (h, obj, NULL);
 
   if (i >= 0)
     {
-      Lisp_Object value = HASH_VALUE (h, i);
-      EMACS_INT refcount = XFASTINT (value) - 1;
+      EMACS_INT refcount = XFASTINT (HASH_VALUE (h, i)) - 1;
       if (refcount > 0)
+        set_hash_value_slot (h, i, make_natnum (refcount));
+      else
         {
-          value = make_natnum (refcount);
-          set_hash_value_slot (h, i, value);
+          eassert (refcount == 0);
+          hash_remove_from_table (h, obj);
         }
-      else
-       hash_remove_from_table (h, value);
     }
 
   if (module_assertions)
@@ -817,9 +815,13 @@ in_current_thread (void)
 static void
 module_assert_thread (void)
 {
-  if (! module_assertions || in_current_thread ())
+  if (!module_assertions)
     return;
-  module_abort ("Module function called from outside the current Lisp thread");
+  if (!in_current_thread ())
+    module_abort ("Module function called from outside "
+                  "the current Lisp thread");
+  if (gc_in_progress)
+    module_abort ("Module function called during garbage collection");
 }
 
 static void
diff --git a/src/eval.c b/src/eval.c
index 8f293c9..e590038 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -213,13 +213,6 @@ backtrace_next (union specbinding *pdl)
   return pdl;
 }
 
-/* Return a pointer to somewhere near the top of the C stack.  */
-void *
-near_C_stack_top (void)
-{
-  return backtrace_args (backtrace_top ());
-}
-
 void
 init_eval_once (void)
 {
@@ -2090,7 +2083,7 @@ record_in_backtrace (Lisp_Object function, Lisp_Object 
*args, ptrdiff_t nargs)
   specpdl_ptr->bt.kind = SPECPDL_BACKTRACE;
   specpdl_ptr->bt.debug_on_exit = false;
   specpdl_ptr->bt.function = function;
-  specpdl_ptr->bt.args = args;
+  current_thread->stack_top = specpdl_ptr->bt.args = args;
   specpdl_ptr->bt.nargs = nargs;
   grow_specpdl ();
 
diff --git a/src/fns.c b/src/fns.c
index 6610d2a..d849618 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -35,6 +35,11 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "intervals.h"
 #include "window.h"
 #include "puresize.h"
+#include "gnutls.h"
+
+#ifdef WINDOWSNT
+# define gnutls_rnd w32_gnutls_rnd
+#endif
 
 static void sort_vector_copy (Lisp_Object, ptrdiff_t,
                              Lisp_Object *restrict, Lisp_Object *restrict);
@@ -1417,17 +1422,22 @@ assq_no_quit (Lisp_Object key, Lisp_Object list)
   return Qnil;
 }
 
-DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
-       doc: /* Return non-nil if KEY is `equal' to the car of an element of 
LIST.
-The value is actually the first element of LIST whose car equals KEY.  */)
-  (Lisp_Object key, Lisp_Object list)
+DEFUN ("assoc", Fassoc, Sassoc, 2, 3, 0,
+       doc: /* Return non-nil if KEY is equal to the car of an element of LIST.
+The value is actually the first element of LIST whose car equals KEY.
+
+Equality is defined by TESTFN if non-nil or by `equal' if nil.  */)
+     (Lisp_Object key, Lisp_Object list, Lisp_Object testfn)
 {
   Lisp_Object tail = list;
   FOR_EACH_TAIL (tail)
     {
       Lisp_Object car = XCAR (tail);
       if (CONSP (car)
-         && (EQ (XCAR (car), key) || !NILP (Fequal (XCAR (car), key))))
+         && (NILP (testfn)
+             ? (EQ (XCAR (car), key) || !NILP (Fequal
+                                               (XCAR (car), key)))
+             : !NILP (call2 (testfn, XCAR (car), key))))
        return car;
     }
   CHECK_LIST_END (tail, list);
@@ -4735,22 +4745,42 @@ make_digest_string (Lisp_Object digest, int digest_size)
   return digest;
 }
 
-/* ALGORITHM is a symbol: md5, sha1, sha224 and so on. */
+DEFUN ("secure-hash-algorithms", Fsecure_hash_algorithms,
+       Ssecure_hash_algorithms, 0, 0, 0,
+       doc: /* Return a list of all the supported `secure_hash' algorithms. */)
+  (void)
+{
+  return listn (CONSTYPE_HEAP, 6,
+                Qmd5,
+                Qsha1,
+                Qsha224,
+                Qsha256,
+                Qsha384,
+                Qsha512);
+}
 
-static Lisp_Object
-secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start,
-            Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror,
-            Lisp_Object binary)
+/* Extract data from a string or a buffer. SPEC is a list of
+(BUFFER-OR-STRING-OR-SYMBOL START END CODING-SYSTEM NOERROR) which behave as
+specified with `secure-hash' and in Info node
+`(elisp)Format of GnuTLS Cryptography Inputs'.  */
+char *
+extract_data_from_object (Lisp_Object spec,
+                          ptrdiff_t *start_byte,
+                          ptrdiff_t *end_byte)
 {
-  ptrdiff_t size, start_char = 0, start_byte, end_char = 0, end_byte;
-  register EMACS_INT b, e;
-  register struct buffer *bp;
-  EMACS_INT temp;
-  int digest_size;
-  void *(*hash_func) (const char *, size_t, void *);
-  Lisp_Object digest;
+  Lisp_Object object = XCAR (spec);
 
-  CHECK_SYMBOL (algorithm);
+  if (CONSP (spec)) spec = XCDR (spec);
+  Lisp_Object start = CAR_SAFE (spec);
+
+  if (CONSP (spec)) spec = XCDR (spec);
+  Lisp_Object end = CAR_SAFE (spec);
+
+  if (CONSP (spec)) spec = XCDR (spec);
+  Lisp_Object coding_system = CAR_SAFE (spec);
+
+  if (CONSP (spec)) spec = XCDR (spec);
+  Lisp_Object noerror = CAR_SAFE (spec);
 
   if (STRINGP (object))
     {
@@ -4778,23 +4808,24 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, 
Lisp_Object start,
       if (STRING_MULTIBYTE (object))
        object = code_convert_string (object, coding_system, Qnil, 1, 0, 1);
 
-      size = SCHARS (object);
+      ptrdiff_t size = SCHARS (object), start_char, end_char;
       validate_subarray (object, start, end, size, &start_char, &end_char);
 
-      start_byte = !start_char ? 0 : string_char_to_byte (object, start_char);
-      end_byte = (end_char == size
-                 ? SBYTES (object)
-                 : string_char_to_byte (object, end_char));
+      *start_byte = !start_char ? 0 : string_char_to_byte (object, start_char);
+      *end_byte = (end_char == size
+                   ? SBYTES (object)
+                   : string_char_to_byte (object, end_char));
     }
-  else
+  else if (BUFFERP (object))
     {
       struct buffer *prev = current_buffer;
+      EMACS_INT b, e;
 
       record_unwind_current_buffer ();
 
       CHECK_BUFFER (object);
 
-      bp = XBUFFER (object);
+      struct buffer *bp = XBUFFER (object);
       set_buffer_internal (bp);
 
       if (NILP (start))
@@ -4814,7 +4845,11 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, 
Lisp_Object start,
        }
 
       if (b > e)
-       temp = b, b = e, e = temp;
+       {
+         EMACS_INT temp = b;
+         b = e;
+         e = temp;
+       }
 
       if (!(BEGV <= b && e <= ZV))
        args_out_of_range (start, end);
@@ -4887,10 +4922,55 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, 
Lisp_Object start,
 
       if (STRING_MULTIBYTE (object))
        object = code_convert_string (object, coding_system, Qnil, 1, 0, 0);
-      start_byte = 0;
-      end_byte = SBYTES (object);
+      *start_byte = 0;
+      *end_byte = SBYTES (object);
+    }
+  else if (EQ (object, Qiv_auto))
+    {
+#ifdef HAVE_GNUTLS3
+      /* Format: (iv-auto REQUIRED-LENGTH).  */
+
+      if (! NATNUMP (start))
+        error ("Without a length, `iv-auto' can't be used; see ELisp manual");
+      else
+        {
+         EMACS_INT start_hold = XFASTINT (start);
+          object = make_uninit_string (start_hold);
+          gnutls_rnd (GNUTLS_RND_NONCE, SSDATA (object), start_hold);
+
+          *start_byte = 0;
+          *end_byte = start_hold;
+        }
+#else
+      error ("GnuTLS is not available, so `iv-auto' can't be used");
+#endif
     }
 
+  return SSDATA (object);
+}
+
+
+/* ALGORITHM is a symbol: md5, sha1, sha224 and so on. */
+
+static Lisp_Object
+secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start,
+            Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror,
+            Lisp_Object binary)
+{
+  ptrdiff_t start_byte, end_byte;
+  int digest_size;
+  void *(*hash_func) (const char *, size_t, void *);
+  Lisp_Object digest;
+
+  CHECK_SYMBOL (algorithm);
+
+  Lisp_Object spec = list5 (object, start, end, coding_system, noerror);
+
+  const char *input = extract_data_from_object (spec, &start_byte, &end_byte);
+
+  if (input == NULL)
+    error ("secure_hash: failed to extract data from object, aborting!");
+
   if (EQ (algorithm, Qmd5))
     {
       digest_size = MD5_DIGEST_SIZE;
@@ -4928,7 +5008,7 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, 
Lisp_Object start,
      hexified value */
   digest = make_uninit_string (digest_size * 2);
 
-  hash_func (SSDATA (object) + start_byte,
+  hash_func (input + start_byte,
             end_byte - start_byte,
             SSDATA (digest));
 
@@ -4979,6 +5059,8 @@ The two optional arguments START and END are positions 
specifying for
 which part of OBJECT to compute the hash.  If nil or omitted, uses the
 whole OBJECT.
 
+The full list of algorithms can be obtained with `secure-hash-algorithms'.
+
 If BINARY is non-nil, returns a string in binary form.  */)
   (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object 
end, Lisp_Object binary)
 {
@@ -5026,13 +5108,6 @@ disregarding any coding systems.  If nil, use the 
current buffer.  */ )
 void
 syms_of_fns (void)
 {
-  DEFSYM (Qmd5,    "md5");
-  DEFSYM (Qsha1,   "sha1");
-  DEFSYM (Qsha224, "sha224");
-  DEFSYM (Qsha256, "sha256");
-  DEFSYM (Qsha384, "sha384");
-  DEFSYM (Qsha512, "sha512");
-
   /* Hash table stuff.  */
   DEFSYM (Qhash_table_p, "hash-table-p");
   DEFSYM (Qeq, "eq");
@@ -5069,6 +5144,18 @@ syms_of_fns (void)
   defsubr (&Smaphash);
   defsubr (&Sdefine_hash_table_test);
 
+  /* Crypto and hashing stuff.  */
+  DEFSYM (Qiv_auto, "iv-auto");
+
+  DEFSYM (Qmd5,    "md5");
+  DEFSYM (Qsha1,   "sha1");
+  DEFSYM (Qsha224, "sha224");
+  DEFSYM (Qsha256, "sha256");
+  DEFSYM (Qsha384, "sha384");
+  DEFSYM (Qsha512, "sha512");
+
+  /* Miscellaneous stuff.  */
+
   DEFSYM (Qstring_lessp, "string-lessp");
   DEFSYM (Qprovide, "provide");
   DEFSYM (Qrequire, "require");
@@ -5187,6 +5274,7 @@ this variable.  */);
   defsubr (&Sbase64_encode_string);
   defsubr (&Sbase64_decode_string);
   defsubr (&Smd5);
+  defsubr (&Ssecure_hash_algorithms);
   defsubr (&Ssecure_hash);
   defsubr (&Sbuffer_hash);
   defsubr (&Slocale_info);
diff --git a/src/font.c b/src/font.c
index 5a3f271..a5e5b6a 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1893,7 +1893,7 @@ otf_tag_symbol (OTF_Tag tag)
 static OTF *
 otf_open (Lisp_Object file)
 {
-  Lisp_Object val = Fassoc (file, otf_list);
+  Lisp_Object val = Fassoc (file, otf_list, Qnil);
   OTF *otf;
 
   if (! NILP (val))
diff --git a/src/fontset.c b/src/fontset.c
index 850558b..7401806 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -1186,7 +1186,7 @@ fs_query_fontset (Lisp_Object name, int name_pattern)
     {
       tem = Frassoc (name, Vfontset_alias_alist);
       if (NILP (tem))
-       tem = Fassoc (name, Vfontset_alias_alist);
+       tem = Fassoc (name, Vfontset_alias_alist, Qnil);
       if (CONSP (tem) && STRINGP (XCAR (tem)))
        name = XCAR (tem);
       else if (name_pattern == 0)
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index d720057..9b592e6 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -81,9 +81,9 @@ ftcrfont_glyph_extents (struct font *font,
       ftcrfont_info->metrics =
        xrealloc (ftcrfont_info->metrics,
                  sizeof (struct font_metrics *) * (row + 1));
-      bzero (ftcrfont_info->metrics + ftcrfont_info->metrics_nrows,
-            (sizeof (struct font_metrics *)
-             * (row + 1 - ftcrfont_info->metrics_nrows)));
+      memset (ftcrfont_info->metrics + ftcrfont_info->metrics_nrows, 0,
+             (sizeof (struct font_metrics *)
+              * (row + 1 - ftcrfont_info->metrics_nrows)));
       ftcrfont_info->metrics_nrows = row + 1;
     }
   if (ftcrfont_info->metrics[row] == NULL)
diff --git a/src/gfilenotify.c b/src/gfilenotify.c
index 285a253..fa4854c 100644
--- a/src/gfilenotify.c
+++ b/src/gfilenotify.c
@@ -266,7 +266,7 @@ reason.  Removing the watch by calling `gfile-rm-watch' 
also makes it
 invalid.  */)
      (Lisp_Object watch_descriptor)
 {
-  Lisp_Object watch_object = Fassoc (watch_descriptor, watch_list);
+  Lisp_Object watch_object = Fassoc (watch_descriptor, watch_list, Qnil);
   if (NILP (watch_object))
     return Qnil;
   else
diff --git a/src/gnutls.c b/src/gnutls.c
index 2078ad8..5969407 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -24,6 +24,7 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "process.h"
 #include "gnutls.h"
 #include "coding.h"
+#include "buffer.h"
 
 #ifdef HAVE_GNUTLS
 
@@ -171,6 +172,59 @@ DEF_DLL_FN (const char *, gnutls_cipher_get_name,
 DEF_DLL_FN (gnutls_mac_algorithm_t, gnutls_mac_get, (gnutls_session_t));
 DEF_DLL_FN (const char *, gnutls_mac_get_name, (gnutls_mac_algorithm_t));
 
+# ifdef HAVE_GNUTLS3
+DEF_DLL_FN (int, gnutls_rnd, (gnutls_rnd_level_t, void *, size_t));
+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));
+DEF_DLL_FN (size_t, gnutls_mac_get_key_size, (gnutls_mac_algorithm_t));
+DEF_DLL_FN (const gnutls_digest_algorithm_t *, gnutls_digest_list, (void));
+DEF_DLL_FN (const char *, gnutls_digest_get_name, (gnutls_digest_algorithm_t));
+#  ifdef HAVE_GNUTLS3_CIPHER
+DEF_DLL_FN (gnutls_cipher_algorithm_t *, gnutls_cipher_list, (void));
+DEF_DLL_FN (int, gnutls_cipher_get_iv_size, (gnutls_cipher_algorithm_t));
+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));
+DEF_DLL_FN (int, gnutls_cipher_get_tag_size, (gnutls_cipher_algorithm_t));
+DEF_DLL_FN (int, gnutls_cipher_init,
+           (gnutls_cipher_hd_t *, gnutls_cipher_algorithm_t,
+            const gnutls_datum_t *, const gnutls_datum_t *));
+DEF_DLL_FN (void, gnutls_cipher_set_iv, (gnutls_cipher_hd_t, void *, size_t));
+DEF_DLL_FN (int, gnutls_cipher_encrypt2,
+           (gnutls_cipher_hd_t, const void *, size_t, void *, size_t));
+DEF_DLL_FN (void, gnutls_cipher_deinit, (gnutls_cipher_hd_t));
+DEF_DLL_FN (int, gnutls_cipher_decrypt2,
+           (gnutls_cipher_hd_t, const void *, size_t, void *, size_t));
+#   ifdef HAVE_GNUTLS3_AEAD
+DEF_DLL_FN (int, gnutls_aead_cipher_init,
+           (gnutls_aead_cipher_hd_t *, gnutls_cipher_algorithm_t,
+            const gnutls_datum_t *));
+DEF_DLL_FN (void, gnutls_aead_cipher_deinit, (gnutls_aead_cipher_hd_t));
+DEF_DLL_FN (int, gnutls_aead_cipher_encrypt,
+           (gnutls_aead_cipher_hd_t, const void *, size_t, const void *,
+            size_t, size_t, const void *, size_t, void *, size_t *));
+DEF_DLL_FN (int, gnutls_aead_cipher_decrypt,
+           (gnutls_aead_cipher_hd_t, const void *, size_t, const void *,
+            size_t, size_t, const void *, size_t, void *, size_t *));
+#   endif /* HAVE_GNUTLS3_AEAD */
+#   ifdef HAVE_GNUTLS3_HMAC
+DEF_DLL_FN (int, gnutls_hmac_init,
+           (gnutls_hmac_hd_t *, gnutls_mac_algorithm_t, const void *, size_t));
+DEF_DLL_FN (int, gnutls_hmac_get_len, (gnutls_mac_algorithm_t));
+DEF_DLL_FN (int, gnutls_hmac, (gnutls_hmac_hd_t, const void *, size_t));
+DEF_DLL_FN (void, gnutls_hmac_deinit, (gnutls_hmac_hd_t, void *));
+DEF_DLL_FN (void, gnutls_hmac_output, (gnutls_hmac_hd_t, void *));
+#   endif  /* HAVE_GNUTLS3_HMAC */
+#  endif  /* HAVE_GNUTLS3_CIPHER */
+#  ifdef HAVE_GNUTLS3_DIGEST
+  DEF_DLL_FN (int, gnutls_hash_init,
+           (gnutls_hash_hd_t *, gnutls_digest_algorithm_t));
+DEF_DLL_FN (int, gnutls_hash_get_len, (gnutls_digest_algorithm_t));
+DEF_DLL_FN (int, gnutls_hash, (gnutls_hash_hd_t, const void *, size_t));
+DEF_DLL_FN (void, gnutls_hash_deinit, (gnutls_hash_hd_t, void *));
+DEF_DLL_FN (void, gnutls_hash_output, (gnutls_hash_hd_t, void *));
+#  endif  /* HAVE_GNUTLS3_DIGEST */
+# endif         /* HAVE_GNUTLS3 */
+
 
 static bool
 init_gnutls_functions (void)
@@ -255,6 +309,46 @@ init_gnutls_functions (void)
   LOAD_DLL_FN (library, gnutls_cipher_get_name);
   LOAD_DLL_FN (library, gnutls_mac_get);
   LOAD_DLL_FN (library, gnutls_mac_get_name);
+# ifdef HAVE_GNUTLS3
+  LOAD_DLL_FN (library, gnutls_rnd);
+  LOAD_DLL_FN (library, gnutls_mac_list);
+  LOAD_DLL_FN (library, gnutls_mac_get_nonce_size);
+  LOAD_DLL_FN (library, gnutls_mac_get_key_size);
+  LOAD_DLL_FN (library, gnutls_digest_list);
+  LOAD_DLL_FN (library, gnutls_digest_get_name);
+#  ifdef HAVE_GNUTLS3_CIPHER
+  LOAD_DLL_FN (library, gnutls_cipher_list);
+  LOAD_DLL_FN (library, gnutls_cipher_get_iv_size);
+  LOAD_DLL_FN (library, gnutls_cipher_get_key_size);
+  LOAD_DLL_FN (library, gnutls_cipher_get_block_size);
+  LOAD_DLL_FN (library, gnutls_cipher_get_tag_size);
+  LOAD_DLL_FN (library, gnutls_cipher_init);
+  LOAD_DLL_FN (library, gnutls_cipher_set_iv);
+  LOAD_DLL_FN (library, gnutls_cipher_encrypt2);
+  LOAD_DLL_FN (library, gnutls_cipher_deinit);
+  LOAD_DLL_FN (library, gnutls_cipher_decrypt2);
+#   ifdef HAVE_GNUTLS3_AEAD
+  LOAD_DLL_FN (library, gnutls_aead_cipher_init);
+  LOAD_DLL_FN (library, gnutls_aead_cipher_deinit);
+  LOAD_DLL_FN (library, gnutls_aead_cipher_encrypt);
+  LOAD_DLL_FN (library, gnutls_aead_cipher_decrypt);
+#   endif
+#   ifdef HAVE_GNUTLS3_HMAC
+  LOAD_DLL_FN (library, gnutls_hmac_init);
+  LOAD_DLL_FN (library, gnutls_hmac_get_len);
+  LOAD_DLL_FN (library, gnutls_hmac);
+  LOAD_DLL_FN (library, gnutls_hmac_deinit);
+  LOAD_DLL_FN (library, gnutls_hmac_output);
+#   endif  /* HAVE_GNUTLS3_HMAC */
+#  endif  /* HAVE_GNUTLS3_CIPHER */
+#  ifdef HAVE_GNUTLS3_DIGEST
+  LOAD_DLL_FN (library, gnutls_hash_init);
+  LOAD_DLL_FN (library, gnutls_hash_get_len);
+  LOAD_DLL_FN (library, gnutls_hash);
+  LOAD_DLL_FN (library, gnutls_hash_deinit);
+  LOAD_DLL_FN (library, gnutls_hash_output);
+#  endif
+# endif         /* HAVE_GNUTLS3 */
 
   max_log_level = global_gnutls_log_level;
 
@@ -332,8 +426,56 @@ init_gnutls_functions (void)
 # define gnutls_x509_crt_get_version fn_gnutls_x509_crt_get_version
 # define gnutls_x509_crt_import fn_gnutls_x509_crt_import
 # define gnutls_x509_crt_init fn_gnutls_x509_crt_init
+# ifdef HAVE_GNUTLS3
+# define gnutls_rnd fn_gnutls_rnd
+# define gnutls_mac_list fn_gnutls_mac_list
+# define gnutls_mac_get_nonce_size fn_gnutls_mac_get_nonce_size
+# 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
+#  ifdef HAVE_GNUTLS3_CIPHER
+# define gnutls_cipher_list fn_gnutls_cipher_list
+# define gnutls_cipher_get_iv_size fn_gnutls_cipher_get_iv_size
+# 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
+# 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
+# define gnutls_cipher_decrypt2 fn_gnutls_cipher_decrypt2
+# define gnutls_cipher_deinit fn_gnutls_cipher_deinit
+#   ifdef HAVE_GNUTLS3_AEAD
+# define gnutls_aead_cipher_encrypt fn_gnutls_aead_cipher_encrypt
+# define gnutls_aead_cipher_decrypt fn_gnutls_aead_cipher_decrypt
+# define gnutls_aead_cipher_init fn_gnutls_aead_cipher_init
+# define gnutls_aead_cipher_deinit fn_gnutls_aead_cipher_deinit
+#   endif /* HAVE_GNUTLS3_AEAD */
+#   ifdef HAVE_GNUTLS3_HMAC
+# define gnutls_hmac_init fn_gnutls_hmac_init
+# define gnutls_hmac_get_len fn_gnutls_hmac_get_len
+# define gnutls_hmac fn_gnutls_hmac
+# define gnutls_hmac_deinit fn_gnutls_hmac_deinit
+# define gnutls_hmac_output fn_gnutls_hmac_output
+#   endif  /* HAVE_GNUTLS3_HMAC */
+#  endif  /* HAVE_GNUTLS3_CIPHER */
+#  ifdef HAVE_GNUTLS3_DIGEST
+# define gnutls_hash_init fn_gnutls_hash_init
+# define gnutls_hash_get_len fn_gnutls_hash_get_len
+# define gnutls_hash fn_gnutls_hash
+# define gnutls_hash_deinit fn_gnutls_hash_deinit
+# define gnutls_hash_output fn_gnutls_hash_output
+#  endif
+# endif         /* HAVE_GNUTLS3 */
+
+/* This wrapper is called from fns.c, which doesn't know about the
+   LOAD_DLL_FN stuff above.  */
+int
+w32_gnutls_rnd (gnutls_rnd_level_t level, void *data, size_t len)
+{
+  return gnutls_rnd (level, data, len);
+}
 
-#endif
+#endif /* WINDOWSNT */
 
 
 /* Report memory exhaustion if ERR is an out-of-memory indication.  */
@@ -433,7 +575,7 @@ emacs_gnutls_nonblock_errno (gnutls_transport_ptr_t ptr)
       return err;
     }
 }
-#endif
+#endif /* !WINDOWSNT */
 
 static int
 emacs_gnutls_handshake (struct Lisp_Process *proc)
@@ -556,6 +698,13 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, 
ptrdiff_t nbyte)
   }
 }
 
+static char const *
+emacs_gnutls_strerror (int err)
+{
+  char const *str = gnutls_strerror (err);
+  return str ? str : "unknown";
+}
+
 /* Report a GnuTLS error to the user.
    Return true if the error code was successfully handled.  */
 static bool
@@ -564,7 +713,6 @@ emacs_gnutls_handle_error (gnutls_session_t session, int 
err)
   int max_log_level = 0;
 
   bool ret;
-  const char *str;
 
   /* TODO: use a Lisp_Object generated by gnutls_make_error?  */
   if (err >= 0)
@@ -576,9 +724,7 @@ emacs_gnutls_handle_error (gnutls_session_t session, int 
err)
 
   /* TODO: use gnutls-error-fatalp and gnutls-error-string.  */
 
-  str = gnutls_strerror (err);
-  if (!str)
-    str = "unknown";
+  char const *str = emacs_gnutls_strerror (err);
 
   if (gnutls_error_is_fatal (err))
     {
@@ -592,11 +738,11 @@ emacs_gnutls_handle_error (gnutls_session_t session, int 
err)
 #endif
 
       GNUTLS_LOG2 (level, max_log_level, "fatal error:", str);
-      ret = 0;
+      ret = false;
     }
   else
     {
-      ret = 1;
+      ret = true;
 
       switch (err)
         {
@@ -784,7 +930,7 @@ usage: (gnutls-error-string ERROR)  */)
   if (! TYPE_RANGED_INTEGERP (int, err))
     return build_string ("Not an error symbol or code");
 
-  return build_string (gnutls_strerror (XINT (err)));
+  return build_string (emacs_gnutls_strerror (XINT (err)));
 }
 
 DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0,
@@ -1476,9 +1622,9 @@ one trustfile (usually a CA bundle).  */)
       XPROCESS (proc)->gnutls_x509_cred = x509_cred;
 
       verify_flags = Fplist_get (proplist, QCverify_flags);
-      if (NUMBERP (verify_flags))
+      if (TYPE_RANGED_INTEGERP (unsigned int, verify_flags))
        {
-         gnutls_verify_flags = XINT (verify_flags);
+         gnutls_verify_flags = XFASTINT (verify_flags);
          GNUTLS_LOG (2, max_log_level, "setting verification flags");
        }
       else if (NILP (verify_flags))
@@ -1697,28 +1843,624 @@ This function may also return `gnutls-e-again', or
 
 #endif /* HAVE_GNUTLS */
 
+#ifdef HAVE_GNUTLS3
+
+DEFUN ("gnutls-ciphers", Fgnutls_ciphers, Sgnutls_ciphers, 0, 0, 0,
+       doc: /* Return alist of GnuTLS symmetric cipher descriptions as plists.
+The alist key is the cipher name. */)
+  (void)
+{
+  Lisp_Object ciphers = Qnil;
+
+#ifdef HAVE_GNUTLS3_CIPHER
+  const gnutls_cipher_algorithm_t *gciphers = gnutls_cipher_list ();
+  for (ptrdiff_t pos = 0; gciphers[pos] != 0; pos++)
+    {
+      gnutls_cipher_algorithm_t gca = gciphers[pos];
+      if (gca == GNUTLS_CIPHER_NULL)
+       continue;
+      char const *cipher_name = gnutls_cipher_get_name (gca);
+      if (!cipher_name)
+       continue;
+
+      /* A symbol representing the GnuTLS cipher.  */
+      Lisp_Object cipher_symbol = intern (cipher_name);
+
+      ptrdiff_t cipher_tag_size = gnutls_cipher_get_tag_size (gca);
+
+      Lisp_Object cp
+       = listn (CONSTYPE_HEAP, 15, cipher_symbol,
+                QCcipher_id, make_number (gca),
+                QCtype, Qgnutls_type_cipher,
+                QCcipher_aead_capable, cipher_tag_size == 0 ? Qnil : Qt,
+                QCcipher_tagsize, make_number (cipher_tag_size),
+
+                QCcipher_blocksize,
+                make_number (gnutls_cipher_get_block_size (gca)),
+
+                QCcipher_keysize,
+                make_number (gnutls_cipher_get_key_size (gca)),
+
+                QCcipher_ivsize,
+                make_number (gnutls_cipher_get_iv_size (gca)));
+
+      ciphers = Fcons (cp, ciphers);
+    }
+#endif
+
+  return ciphers;
+}
+
+static Lisp_Object
+gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca,
+                       Lisp_Object cipher,
+                      const char *kdata, ptrdiff_t ksize,
+                      const char *vdata, ptrdiff_t vsize,
+                      const char *idata, ptrdiff_t isize,
+                       Lisp_Object aead_auth)
+{
+#ifdef HAVE_GNUTLS3_AEAD
+
+  const char *desc = encrypting ? "encrypt" : "decrypt";
+  Lisp_Object actual_iv = make_unibyte_string (vdata, vsize);
+
+  gnutls_aead_cipher_hd_t acipher;
+  gnutls_datum_t key_datum = { (unsigned char *) kdata, ksize };
+  int ret = gnutls_aead_cipher_init (&acipher, gca, &key_datum);
+
+  if (ret < GNUTLS_E_SUCCESS)
+    error ("GnuTLS AEAD cipher %s/%s initialization failed: %s",
+          gnutls_cipher_get_name (gca), desc, emacs_gnutls_strerror (ret));
+
+  ptrdiff_t cipher_tag_size = gnutls_cipher_get_tag_size (gca);
+  ptrdiff_t tagged_size;
+  if (INT_ADD_WRAPV (isize, cipher_tag_size, &tagged_size)
+      || SIZE_MAX < tagged_size)
+    memory_full (SIZE_MAX);
+  size_t storage_length = tagged_size;
+  USE_SAFE_ALLOCA;
+  char *storage = SAFE_ALLOCA (storage_length);
+
+  const char *aead_auth_data = NULL;
+  ptrdiff_t aead_auth_size = 0;
+
+  if (!NILP (aead_auth))
+    {
+      if (BUFFERP (aead_auth) || STRINGP (aead_auth))
+        aead_auth = list1 (aead_auth);
+
+      CHECK_CONS (aead_auth);
+
+      ptrdiff_t astart_byte, aend_byte;
+      const char *adata
+       = extract_data_from_object (aead_auth, &astart_byte, &aend_byte);
+      if (adata == NULL)
+        error ("GnuTLS AEAD cipher auth extraction failed");
+
+      aead_auth_data = adata;
+      aead_auth_size = aend_byte - astart_byte;
+    }
+
+  ptrdiff_t expected_remainder = encrypting ? 0 : cipher_tag_size;
+  ptrdiff_t cipher_block_size = gnutls_cipher_get_block_size (gca);
+
+  if (isize < expected_remainder
+      || (isize - expected_remainder) % cipher_block_size != 0)
+    error (("GnuTLS AEAD cipher %s/%s input block length %"pD"d "
+           "is not %"pD"d greater than a multiple of the required %"pD"d"),
+           gnutls_cipher_get_name (gca), desc,
+          isize, expected_remainder, cipher_block_size);
+
+  ret = ((encrypting ? gnutls_aead_cipher_encrypt : gnutls_aead_cipher_decrypt)
+        (acipher, vdata, vsize, aead_auth_data, aead_auth_size,
+         cipher_tag_size, idata, isize, storage, &storage_length));
+
+  Lisp_Object output;
+  if (GNUTLS_E_SUCCESS <= ret)
+    output = make_unibyte_string (storage, storage_length);
+  explicit_bzero (storage, storage_length);
+  gnutls_aead_cipher_deinit (acipher);
+
+  if (ret < GNUTLS_E_SUCCESS)
+    error ((encrypting
+           ? "GnuTLS AEAD cipher %s encryption failed: %s"
+           : "GnuTLS AEAD cipher %s decryption failed: %s"),
+          gnutls_cipher_get_name (gca), emacs_gnutls_strerror (ret));
+
+  SAFE_FREE ();
+  return list2 (output, actual_iv);
+#else
+  printmax_t print_gca = gca;
+  error ("GnuTLS AEAD cipher %"pMd" is invalid or not found", print_gca);
+#endif
+}
+
+static Lisp_Object
+gnutls_symmetric (bool encrypting, Lisp_Object cipher,
+                  Lisp_Object key, Lisp_Object iv,
+                  Lisp_Object input, Lisp_Object aead_auth)
+{
+  if (BUFFERP (key) || STRINGP (key))
+    key = list1 (key);
+
+  CHECK_CONS (key);
+
+  if (BUFFERP (input) || STRINGP (input))
+    input = list1 (input);
+
+  CHECK_CONS (input);
+
+  if (BUFFERP (iv) || STRINGP (iv))
+    iv = list1 (iv);
+
+  CHECK_CONS (iv);
+
+
+  const char *desc = encrypting ? "encrypt" : "decrypt";
+
+  gnutls_cipher_algorithm_t gca = GNUTLS_CIPHER_UNKNOWN;
+
+  Lisp_Object info = Qnil;
+  if (STRINGP (cipher))
+    cipher = intern (SSDATA (cipher));
+
+  if (SYMBOLP (cipher))
+    info = XCDR (Fassq (cipher, Fgnutls_ciphers ()));
+  else if (TYPE_RANGED_INTEGERP (gnutls_cipher_algorithm_t, cipher))
+    gca = XINT (cipher);
+  else
+    info = cipher;
+
+  if (!NILP (info) && CONSP (info))
+    {
+      Lisp_Object v = Fplist_get (info, QCcipher_id);
+      if (TYPE_RANGED_INTEGERP (gnutls_cipher_algorithm_t, v))
+        gca = XINT (v);
+    }
+
+  ptrdiff_t key_size = gnutls_cipher_get_key_size (gca);
+  if (key_size == 0)
+    error ("GnuTLS cipher is invalid or not found");
+
+  ptrdiff_t kstart_byte, kend_byte;
+  const char *kdata = extract_data_from_object (key, &kstart_byte, &kend_byte);
+
+  if (kdata == NULL)
+    error ("GnuTLS cipher key extraction failed");
+
+  if (kend_byte - kstart_byte != key_size)
+    error (("GnuTLS cipher %s/%s key length %"pD"d is not equal to "
+           "the required %"pD"d"),
+           gnutls_cipher_get_name (gca), desc,
+          kend_byte - kstart_byte, key_size);
+
+  ptrdiff_t vstart_byte, vend_byte;
+  char *vdata = extract_data_from_object (iv, &vstart_byte, &vend_byte);
+
+  if (vdata == NULL)
+    error ("GnuTLS cipher IV extraction failed");
+
+  ptrdiff_t iv_size = gnutls_cipher_get_iv_size (gca);
+  if (vend_byte - vstart_byte != iv_size)
+    error (("GnuTLS cipher %s/%s IV length %"pD"d is not equal to "
+           "the required %"pD"d"),
+           gnutls_cipher_get_name (gca), desc,
+          vend_byte - vstart_byte, iv_size);
+
+  Lisp_Object actual_iv = make_unibyte_string (vdata, vend_byte - vstart_byte);
+
+  ptrdiff_t istart_byte, iend_byte;
+  const char *idata
+    = extract_data_from_object (input, &istart_byte, &iend_byte);
+
+  if (idata == NULL)
+    error ("GnuTLS cipher input extraction failed");
+
+  /* Is this an AEAD cipher? */
+  if (gnutls_cipher_get_tag_size (gca) > 0)
+    {
+      Lisp_Object aead_output =
+        gnutls_symmetric_aead (encrypting, gca, cipher,
+                               kdata, kend_byte - kstart_byte,
+                               vdata, vend_byte - vstart_byte,
+                               idata, iend_byte - istart_byte,
+                               aead_auth);
+      if (STRINGP (XCAR (key)))
+        Fclear_string (XCAR (key));
+      return aead_output;
+    }
+
+  ptrdiff_t cipher_block_size = gnutls_cipher_get_block_size (gca);
+  if ((iend_byte - istart_byte) % cipher_block_size != 0)
+    error (("GnuTLS cipher %s/%s input block length %"pD"d is not a multiple "
+           "of the required %"pD"d"),
+           gnutls_cipher_get_name (gca), desc,
+          iend_byte - istart_byte, cipher_block_size);
+
+  gnutls_cipher_hd_t hcipher;
+  gnutls_datum_t key_datum
+    = { (unsigned char *) kdata, kend_byte - kstart_byte };
+
+  int ret = gnutls_cipher_init (&hcipher, gca, &key_datum, NULL);
+
+  if (ret < GNUTLS_E_SUCCESS)
+    error ("GnuTLS cipher %s/%s initialization failed: %s",
+          gnutls_cipher_get_name (gca), desc, emacs_gnutls_strerror (ret));
+
+  /* Note that this will not support streaming block mode. */
+  gnutls_cipher_set_iv (hcipher, vdata, vend_byte - vstart_byte);
+
+  /* GnuTLS docs: "For the supported ciphers the encrypted data length
+     will equal the plaintext size."  */
+  ptrdiff_t storage_length = iend_byte - istart_byte;
+  Lisp_Object storage = make_uninit_string (storage_length);
+
+  ret = ((encrypting ? gnutls_cipher_encrypt2 : gnutls_cipher_decrypt2)
+        (hcipher, idata, iend_byte - istart_byte,
+         SSDATA (storage), storage_length));
+
+  if (STRINGP (XCAR (key)))
+    Fclear_string (XCAR (key));
+
+  if (ret < GNUTLS_E_SUCCESS)
+    {
+      gnutls_cipher_deinit (hcipher);
+      if (encrypting)
+       error ("GnuTLS cipher %s encryption failed: %s",
+              gnutls_cipher_get_name (gca), emacs_gnutls_strerror (ret));
+      else
+       error ("GnuTLS cipher %s decryption failed: %s",
+              gnutls_cipher_get_name (gca), emacs_gnutls_strerror (ret));
+    }
+
+  gnutls_cipher_deinit (hcipher);
+
+  return list2 (storage, actual_iv);
+}
+
+DEFUN ("gnutls-symmetric-encrypt", Fgnutls_symmetric_encrypt,
+       Sgnutls_symmetric_encrypt, 4, 5, 0,
+       doc: /* Encrypt INPUT with symmetric CIPHER, KEY+AEAD_AUTH, and IV to a 
unibyte string.
+
+Return nil on error.
+
+The KEY can be specified as a buffer or string or in other ways (see
+Info node `(elisp)Format of GnuTLS Cryptography Inputs').  The KEY
+will be wiped after use if it's a string.
+
+The IV and INPUT and the optional AEAD_AUTH can be specified as a
+buffer or string or in other ways (see Info node `(elisp)Format of
+GnuTLS Cryptography Inputs').
+
+The alist of symmetric ciphers can be obtained with `gnutls-ciphers`.
+The CIPHER may be a string or symbol matching a key in that alist, or
+a plist with the :cipher-id numeric property, or the number itself.
+
+AEAD ciphers: these ciphers will have a `gnutls-ciphers' entry with
+:cipher-aead-capable set to t.  AEAD_AUTH can be supplied for
+these AEAD ciphers, but it may still be omitted (nil) as well. */)
+  (Lisp_Object cipher, Lisp_Object key, Lisp_Object iv,
+   Lisp_Object input, Lisp_Object aead_auth)
+{
+  return gnutls_symmetric (true, cipher, key, iv, input, aead_auth);
+}
+
+DEFUN ("gnutls-symmetric-decrypt", Fgnutls_symmetric_decrypt,
+       Sgnutls_symmetric_decrypt, 4, 5, 0,
+       doc: /* Decrypt INPUT with symmetric CIPHER, KEY+AEAD_AUTH, and IV to a 
unibyte string.
+
+Return nil on error.
+
+The KEY can be specified as a buffer or string or in other ways (see
+Info node `(elisp)Format of GnuTLS Cryptography Inputs').  The KEY
+will be wiped after use if it's a string.
+
+The IV and INPUT and the optional AEAD_AUTH can be specified as a
+buffer or string or in other ways (see Info node `(elisp)Format of
+GnuTLS Cryptography Inputs').
+
+The alist of symmetric ciphers can be obtained with `gnutls-ciphers`.
+The CIPHER may be a string or symbol matching a key in that alist, or
+a plist with the `:cipher-id' numeric property, or the number itself.
+
+AEAD ciphers: these ciphers will have a `gnutls-ciphers' entry with
+:cipher-aead-capable set to t.  AEAD_AUTH can be supplied for
+these AEAD ciphers, but it may still be omitted (nil) as well. */)
+  (Lisp_Object cipher, Lisp_Object key, Lisp_Object iv,
+   Lisp_Object input, Lisp_Object aead_auth)
+{
+  return gnutls_symmetric (false, cipher, key, iv, input, aead_auth);
+}
+
+DEFUN ("gnutls-macs", Fgnutls_macs, Sgnutls_macs, 0, 0, 0,
+       doc: /* Return alist of GnuTLS mac-algorithm method descriptions as 
plists.
+
+Use the value of the alist (extract it with `alist-get' for instance)
+with `gnutls-hash-mac'.  The alist key is the mac-algorithm method
+name. */)
+  (void)
+{
+  Lisp_Object mac_algorithms = Qnil;
+#ifdef HAVE_GNUTLS3_HMAC
+  const gnutls_mac_algorithm_t *macs = gnutls_mac_list ();
+  for (ptrdiff_t pos = 0; macs[pos] != 0; pos++)
+    {
+      const gnutls_mac_algorithm_t gma = macs[pos];
+
+      /* A symbol representing the GnuTLS MAC algorithm.  */
+      Lisp_Object gma_symbol = intern (gnutls_mac_get_name (gma));
+
+      Lisp_Object mp = listn (CONSTYPE_HEAP, 11, gma_symbol,
+                             QCmac_algorithm_id, make_number (gma),
+                             QCtype, Qgnutls_type_mac_algorithm,
+
+                              QCmac_algorithm_length,
+                              make_number (gnutls_hmac_get_len (gma)),
+
+                              QCmac_algorithm_keysize,
+                              make_number (gnutls_mac_get_key_size (gma)),
+
+                              QCmac_algorithm_noncesize,
+                              make_number (gnutls_mac_get_nonce_size (gma)));
+      mac_algorithms = Fcons (mp, mac_algorithms);
+    }
+#endif
+
+  return mac_algorithms;
+}
+
+DEFUN ("gnutls-digests", Fgnutls_digests, Sgnutls_digests, 0, 0, 0,
+       doc: /* Return alist of GnuTLS digest-algorithm method descriptions as 
plists.
+
+Use the value of the alist (extract it with `alist-get' for instance)
+with `gnutls-hash-digest'.  The alist key is the digest-algorithm
+method name. */)
+  (void)
+{
+  Lisp_Object digest_algorithms = Qnil;
+#ifdef HAVE_GNUTLS3_DIGEST
+  const gnutls_digest_algorithm_t *digests = gnutls_digest_list ();
+  for (ptrdiff_t pos = 0; digests[pos] != 0; pos++)
+    {
+      const gnutls_digest_algorithm_t gda = digests[pos];
+
+      /* A symbol representing the GnuTLS digest algorithm.  */
+      Lisp_Object gda_symbol = intern (gnutls_digest_get_name (gda));
+
+      Lisp_Object mp = listn (CONSTYPE_HEAP, 7, gda_symbol,
+                             QCdigest_algorithm_id, make_number (gda),
+                             QCtype, Qgnutls_type_digest_algorithm,
+
+                              QCdigest_algorithm_length,
+                              make_number (gnutls_hash_get_len (gda)));
+
+      digest_algorithms = Fcons (mp, digest_algorithms);
+    }
+#endif
+
+  return digest_algorithms;
+}
+
+DEFUN ("gnutls-hash-mac", Fgnutls_hash_mac, Sgnutls_hash_mac, 3, 3, 0,
+       doc: /* Hash INPUT with HASH-METHOD and KEY into a unibyte string.
+
+Return nil on error.
+
+The KEY can be specified as a buffer or string or in other ways (see
+Info node `(elisp)Format of GnuTLS Cryptography Inputs').  The KEY
+will be wiped after use if it's a string.
+
+The INPUT can be specified as a buffer or string or in other
+ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs').
+
+The alist of MAC algorithms can be obtained with `gnutls-macs`.  The
+HASH-METHOD may be a string or symbol matching a key in that alist, or
+a plist with the `:mac-algorithm-id' numeric property, or the number
+itself. */)
+  (Lisp_Object hash_method, Lisp_Object key, Lisp_Object input)
+{
+  if (BUFFERP (input) || STRINGP (input))
+    input = list1 (input);
+
+  CHECK_CONS (input);
+
+  if (BUFFERP (key) || STRINGP (key))
+    key = list1 (key);
+
+  CHECK_CONS (key);
+
+  gnutls_mac_algorithm_t gma = GNUTLS_MAC_UNKNOWN;
+
+  Lisp_Object info = Qnil;
+  if (STRINGP (hash_method))
+    hash_method = intern (SSDATA (hash_method));
+
+  if (SYMBOLP (hash_method))
+    info = XCDR (Fassq (hash_method, Fgnutls_macs ()));
+  else if (TYPE_RANGED_INTEGERP (gnutls_mac_algorithm_t, hash_method))
+    gma = XINT (hash_method);
+  else
+    info = hash_method;
+
+  if (!NILP (info) && CONSP (info))
+    {
+      Lisp_Object v = Fplist_get (info, QCmac_algorithm_id);
+      if (TYPE_RANGED_INTEGERP (gnutls_mac_algorithm_t, v))
+        gma = XINT (v);
+    }
+
+  ptrdiff_t digest_length = gnutls_hmac_get_len (gma);
+  if (digest_length == 0)
+    error ("GnuTLS MAC-method is invalid or not found");
+
+  ptrdiff_t kstart_byte, kend_byte;
+  const char *kdata = extract_data_from_object (key, &kstart_byte, &kend_byte);
+  if (kdata == NULL)
+    error ("GnuTLS MAC key extraction failed");
+
+  gnutls_hmac_hd_t hmac;
+  int ret = gnutls_hmac_init (&hmac, gma,
+                             kdata + kstart_byte, kend_byte - kstart_byte);
+  if (ret < GNUTLS_E_SUCCESS)
+    error ("GnuTLS MAC %s initialization failed: %s",
+          gnutls_mac_get_name (gma), emacs_gnutls_strerror (ret));
+
+  ptrdiff_t istart_byte, iend_byte;
+  const char *idata
+    = extract_data_from_object (input, &istart_byte, &iend_byte);
+  if (idata == NULL)
+    error ("GnuTLS MAC input extraction failed");
+
+  Lisp_Object digest = make_uninit_string (digest_length);
+
+  ret = gnutls_hmac (hmac, idata + istart_byte, iend_byte - istart_byte);
+
+  if (STRINGP (XCAR (key)))
+    Fclear_string (XCAR (key));
+
+  if (ret < GNUTLS_E_SUCCESS)
+    {
+      gnutls_hmac_deinit (hmac, NULL);
+      error ("GnuTLS MAC %s application failed: %s",
+            gnutls_mac_get_name (gma), emacs_gnutls_strerror (ret));
+    }
+
+  gnutls_hmac_output (hmac, SSDATA (digest));
+  gnutls_hmac_deinit (hmac, NULL);
+
+  return digest;
+}
+
+DEFUN ("gnutls-hash-digest", Fgnutls_hash_digest, Sgnutls_hash_digest, 2, 2, 0,
+       doc: /* Digest INPUT with DIGEST-METHOD into a unibyte string.
+
+Return nil on error.
+
+The INPUT can be specified as a buffer or string or in other
+ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs').
+
+The alist of digest algorithms can be obtained with `gnutls-digests`.
+The DIGEST-METHOD may be a string or symbol matching a key in that
+alist, or a plist with the `:digest-algorithm-id' numeric property, or
+the number itself. */)
+  (Lisp_Object digest_method, Lisp_Object input)
+{
+  if (BUFFERP (input) || STRINGP (input))
+    input = list1 (input);
+
+  CHECK_CONS (input);
+
+  gnutls_digest_algorithm_t gda = GNUTLS_DIG_UNKNOWN;
+
+  Lisp_Object info = Qnil;
+  if (STRINGP (digest_method))
+    digest_method = intern (SSDATA (digest_method));
+
+  if (SYMBOLP (digest_method))
+    info = XCDR (Fassq (digest_method, Fgnutls_digests ()));
+  else if (TYPE_RANGED_INTEGERP (gnutls_digest_algorithm_t, digest_method))
+    gda = XINT (digest_method);
+  else
+    info = digest_method;
+
+  if (!NILP (info) && CONSP (info))
+    {
+      Lisp_Object v = Fplist_get (info, QCdigest_algorithm_id);
+      if (TYPE_RANGED_INTEGERP (gnutls_digest_algorithm_t, v))
+        gda = XINT (v);
+    }
+
+  ptrdiff_t digest_length = gnutls_hash_get_len (gda);
+  if (digest_length == 0)
+    error ("GnuTLS digest-method is invalid or not found");
+
+  gnutls_hash_hd_t hash;
+  int ret = gnutls_hash_init (&hash, gda);
+
+  if (ret < GNUTLS_E_SUCCESS)
+    error ("GnuTLS digest initialization failed: %s",
+          emacs_gnutls_strerror (ret));
+
+  Lisp_Object digest = make_uninit_string (digest_length);
+
+  ptrdiff_t istart_byte, iend_byte;
+  const char *idata
+    = extract_data_from_object (input, &istart_byte, &iend_byte);
+  if (idata == NULL)
+    error ("GnuTLS digest input extraction failed");
+
+  ret = gnutls_hash (hash, idata + istart_byte, iend_byte - istart_byte);
+
+  if (ret < GNUTLS_E_SUCCESS)
+    {
+      gnutls_hash_deinit (hash, NULL);
+      error ("GnuTLS digest application failed: %s",
+            emacs_gnutls_strerror (ret));
+    }
+
+  gnutls_hash_output (hash, SSDATA (digest));
+  gnutls_hash_deinit (hash, NULL);
+
+  return digest;
+}
+
+#endif /* HAVE_GNUTLS3 */
+
 DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
-       doc: /* Return t if GnuTLS is available in this instance of Emacs.  */)
-     (void)
+       doc: /* Return list of capabilities if GnuTLS is available in this 
instance of Emacs.
+
+...if supported         : then...
+GnuTLS 3 or higher      : the list will contain `gnutls3'.
+GnuTLS MACs             : the list will contain `macs'.
+GnuTLS digests          : the list will contain `digests'.
+GnuTLS symmetric ciphers: the list will contain `ciphers'.
+GnuTLS AEAD ciphers     : the list will contain `AEAD-ciphers'.  */)
+  (void)
 {
+  Lisp_Object capabilities = Qnil;
+
 #ifdef HAVE_GNUTLS
-# ifdef WINDOWSNT
+
+# ifdef HAVE_GNUTLS3
+  capabilities = Fcons (intern("gnutls3"), capabilities);
+
+#  ifdef HAVE_GNUTLS3_DIGEST
+  capabilities = Fcons (intern("digests"), capabilities);
+#  endif
+
+#  ifdef HAVE_GNUTLS3_CIPHER
+  capabilities = Fcons (intern("ciphers"), capabilities);
+
+#   ifdef HAVE_GNUTLS3_AEAD
+  capabilities = Fcons (intern("AEAD-ciphers"), capabilities);
+#   endif
+
+#   ifdef HAVE_GNUTLS3_HMAC
+  capabilities = Fcons (intern("macs"), capabilities);
+#   endif
+#  endif  /* HAVE_GNUTLS3_CIPHER */
+# endif          /* HAVE_GNUTLS3 */
+
+#ifdef WINDOWSNT
   Lisp_Object found = Fassq (Qgnutls, Vlibrary_cache);
   if (CONSP (found))
     return XCDR (found);
   else
     {
       Lisp_Object status;
-      status = init_gnutls_functions () ? Qt : Qnil;
+      status = init_gnutls_functions () ? capabilities : Qnil;
       Vlibrary_cache = Fcons (Fcons (Qgnutls, status), Vlibrary_cache);
       return status;
     }
-# else /* !WINDOWSNT */
-  return Qt;
-# endif         /* !WINDOWSNT */
+#else  /* !WINDOWSNT */
+
+  return capabilities;
+
+#endif /* WINDOWSNT */
+
 #else  /* !HAVE_GNUTLS */
   return Qnil;
-#endif /* !HAVE_GNUTLS */
+#endif /* HAVE_GNUTLS */
 }
 
 void
@@ -1753,6 +2495,27 @@ syms_of_gnutls (void)
   DEFSYM (QCverify_flags, ":verify-flags");
   DEFSYM (QCverify_error, ":verify-error");
 
+  DEFSYM (QCcipher_id, ":cipher-id");
+  DEFSYM (QCcipher_aead_capable, ":cipher-aead-capable");
+  DEFSYM (QCcipher_blocksize, ":cipher-blocksize");
+  DEFSYM (QCcipher_keysize, ":cipher-keysize");
+  DEFSYM (QCcipher_tagsize, ":cipher-tagsize");
+  DEFSYM (QCcipher_keysize, ":cipher-keysize");
+  DEFSYM (QCcipher_ivsize, ":cipher-ivsize");
+
+  DEFSYM (QCmac_algorithm_id, ":mac-algorithm-id");
+  DEFSYM (QCmac_algorithm_noncesize, ":mac-algorithm-noncesize");
+  DEFSYM (QCmac_algorithm_keysize, ":mac-algorithm-keysize");
+  DEFSYM (QCmac_algorithm_length, ":mac-algorithm-length");
+
+  DEFSYM (QCdigest_algorithm_id, ":digest-algorithm-id");
+  DEFSYM (QCdigest_algorithm_length, ":digest-algorithm-length");
+
+  DEFSYM (QCtype, ":type");
+  DEFSYM (Qgnutls_type_cipher, "gnutls-symmetric-cipher");
+  DEFSYM (Qgnutls_type_mac_algorithm, "gnutls-mac-algorithm");
+  DEFSYM (Qgnutls_type_digest_algorithm, "gnutls-digest-algorithm");
+
   DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
   Fput (Qgnutls_e_interrupted, Qgnutls_code,
        make_number (GNUTLS_E_INTERRUPTED));
@@ -1780,6 +2543,16 @@ syms_of_gnutls (void)
   defsubr (&Sgnutls_peer_status);
   defsubr (&Sgnutls_peer_status_warning_describe);
 
+#ifdef HAVE_GNUTLS3
+  defsubr (&Sgnutls_ciphers);
+  defsubr (&Sgnutls_macs);
+  defsubr (&Sgnutls_digests);
+  defsubr (&Sgnutls_hash_mac);
+  defsubr (&Sgnutls_hash_digest);
+  defsubr (&Sgnutls_symmetric_encrypt);
+  defsubr (&Sgnutls_symmetric_decrypt);
+#endif
+
   DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level,
              doc: /* Logging level used by the GnuTLS functions.
 Set this larger than 0 to get debug output in the *Messages* buffer.
diff --git a/src/gnutls.h b/src/gnutls.h
index 3c84023..3ec86a8 100644
--- a/src/gnutls.h
+++ b/src/gnutls.h
@@ -23,6 +23,10 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
 
+#ifdef HAVE_GNUTLS3
+#include <gnutls/crypto.h>
+#endif
+
 #include "lisp.h"
 
 /* This limits the attempts to handshake per process (connection).  It
@@ -82,6 +86,7 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, 
ptrdiff_t nbyte);
 extern ptrdiff_t emacs_gnutls_record_check_pending (gnutls_session_t state);
 #ifdef WINDOWSNT
 extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err);
+extern int w32_gnutls_rnd (gnutls_rnd_level_t, void *, size_t);
 #endif
 extern Lisp_Object emacs_gnutls_deinit (Lisp_Object);
 extern Lisp_Object emacs_gnutls_global_init (void);
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 2d4abef..0c8395e 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -204,6 +204,31 @@ xg_display_open (char *display_name, Display **dpy)
   *dpy = gdpy ? GDK_DISPLAY_XDISPLAY (gdpy) : NULL;
 }
 
+/* Scaling/HiDPI functions. */
+static int
+xg_get_gdk_scale (void)
+{
+  const char *sscale = getenv ("GDK_SCALE");
+
+  if (sscale)
+    {
+      long scale = atol (sscale);
+      if (0 < scale)
+       return min (scale, INT_MAX);
+    }
+
+  return 1;
+}
+
+int
+xg_get_scale (struct frame *f)
+{
+#if GTK_CHECK_VERSION (3, 10, 0)
+  if (FRAME_GTK_WIDGET (f))
+    return gtk_widget_get_scale_factor (FRAME_GTK_WIDGET (f));
+#endif
+  return xg_get_gdk_scale ();
+}
 
 /* Close display DPY.  */
 
@@ -724,7 +749,8 @@ xg_show_tooltip (struct frame *f, int root_x, int root_y)
   if (x->ttip_window)
     {
       block_input ();
-      gtk_window_move (x->ttip_window, root_x, root_y);
+      gtk_window_move (x->ttip_window, root_x / xg_get_scale (f),
+                      root_y / xg_get_scale (f));
       gtk_widget_show_all (GTK_WIDGET (x->ttip_window));
       unblock_input ();
     }
@@ -836,21 +862,6 @@ xg_set_geometry (struct frame *f)
     }
 }
 
-static int
-xg_get_gdk_scale (void)
-{
-  const char *sscale = getenv ("GDK_SCALE");
-
-  if (sscale)
-    {
-      long scale = atol (sscale);
-      if (0 < scale)
-       return min (scale, INT_MAX);
-    }
-
-  return 1;
-}
-
 /* Function to handle resize of our frame.  As we have a Gtk+ tool bar
    and a Gtk+ menu bar, we get resize events for the edit part of the
    frame only.  We let Gtk+ deal with the Gtk+ parts.
@@ -912,12 +923,8 @@ xg_frame_set_char_size (struct frame *f, int width, int 
height)
   /* Do this before resize, as we don't know yet if we will be resized.  */
   x_clear_under_internal_border (f);
 
-  if (FRAME_VISIBLE_P (f))
-    {
-      int scale = xg_get_gdk_scale ();
-      totalheight /= scale;
-      totalwidth /= scale;
-    }
+  totalheight /= xg_get_scale (f);
+  totalwidth /= xg_get_scale (f);
 
   x_wm_set_size_hint (f, 0, 0);
 
@@ -1343,7 +1350,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool 
user_position)
   int min_rows = 0, min_cols = 0;
   int win_gravity = f->win_gravity;
   Lisp_Object fs_state, frame;
-  int scale = xg_get_gdk_scale ();
+  int scale = xg_get_scale (f);
 
   /* Don't set size hints during initialization; that apparently leads
      to a race condition.  See the thread at
@@ -3659,16 +3666,16 @@ update_theme_scrollbar_height (void)
 }
 
 int
-xg_get_default_scrollbar_width (void)
+xg_get_default_scrollbar_width (struct frame *f)
 {
-  return scroll_bar_width_for_theme * xg_get_gdk_scale ();
+  return scroll_bar_width_for_theme * xg_get_scale (f);
 }
 
 int
-xg_get_default_scrollbar_height (void)
+xg_get_default_scrollbar_height (struct frame *f)
 {
   /* Apparently there's no default height for themes.  */
-  return scroll_bar_width_for_theme * xg_get_gdk_scale ();
+  return scroll_bar_width_for_theme * xg_get_scale (f);
 }
 
 /* Return the scrollbar id for X Window WID on display DPY.
@@ -3858,7 +3865,7 @@ xg_update_scrollbar_pos (struct frame *f,
       GtkWidget *wfixed = f->output_data.x->edit_widget;
       GtkWidget *wparent = gtk_widget_get_parent (wscroll);
       gint msl;
-      int scale = xg_get_gdk_scale ();
+      int scale = xg_get_scale (f);
 
       top /= scale;
       left /= scale;
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 0abcb06..f0f2981 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -143,8 +143,8 @@ extern void xg_set_toolkit_horizontal_scroll_bar_thumb 
(struct scroll_bar *bar,
                                                        int position,
                                                        int whole);
 extern bool xg_event_is_for_scrollbar (struct frame *, const XEvent *);
-extern int xg_get_default_scrollbar_width (void);
-extern int xg_get_default_scrollbar_height (void);
+extern int xg_get_default_scrollbar_width (struct frame *f);
+extern int xg_get_default_scrollbar_height (struct frame *f);
 
 extern void update_frame_tool_bar (struct frame *f);
 extern void free_frame_tool_bar (struct frame *f);
@@ -156,6 +156,7 @@ extern void xg_frame_resized (struct frame *f,
 extern void xg_frame_set_char_size (struct frame *f, int width, int height);
 extern GtkWidget * xg_win_to_widget (Display *dpy, Window wdesc);
 
+extern int xg_get_scale (struct frame *f);
 extern void xg_display_open (char *display_name, Display **dpy);
 extern void xg_display_close (Display *dpy);
 extern GdkCursor * xg_create_default_cursor (Display *dpy);
diff --git a/src/image.c b/src/image.c
index 91749fb..76a19a6 100644
--- a/src/image.c
+++ b/src/image.c
@@ -4231,7 +4231,7 @@ xpm_load_image (struct frame *f,
       color_val = Qnil;
       if (!NILP (color_symbols) && !NILP (symbol_color))
        {
-         Lisp_Object specified_color = Fassoc (symbol_color, color_symbols);
+         Lisp_Object specified_color = Fassoc (symbol_color, color_symbols, 
Qnil);
 
          if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
            {
@@ -8086,83 +8086,76 @@ compute_image_size (size_t width, size_t height,
                    int *d_width, int *d_height)
 {
   Lisp_Object value;
-  int desired_width, desired_height;
+  int desired_width = -1, desired_height = -1, max_width = -1, max_height = -1;
   double scale = 1;
 
   value = image_spec_value (spec, QCscale, NULL);
   if (NUMBERP (value))
     scale = XFLOATINT (value);
 
+  value = image_spec_value (spec, QCmax_width, NULL);
+  if (NATNUMP (value))
+    max_width = min (XFASTINT (value), INT_MAX);
+
+  value = image_spec_value (spec, QCmax_height, NULL);
+  if (NATNUMP (value))
+    max_height = min (XFASTINT (value), INT_MAX);
+
   /* If width and/or height is set in the display spec assume we want
      to scale to those values.  If either h or w is unspecified, the
      unspecified should be calculated from the specified to preserve
      aspect ratio.  */
   value = image_spec_value (spec, QCwidth, NULL);
-  desired_width = NATNUMP (value) ?
-    min (XFASTINT (value) * scale, INT_MAX) : -1;
+  if (NATNUMP (value))
+    {
+      desired_width = min (XFASTINT (value) * scale, INT_MAX);
+      /* :width overrides :max-width. */
+      max_width = -1;
+    }
+
   value = image_spec_value (spec, QCheight, NULL);
-  desired_height = NATNUMP (value) ?
-    min (XFASTINT (value) * scale, INT_MAX) : -1;
+  if (NATNUMP (value))
+    {
+      desired_height = min (XFASTINT (value) * scale, INT_MAX);
+      /* :height overrides :max-height. */
+      max_height = -1;
+    }
+
+  /* If we have both width/height set explicitly, we skip past all the
+     aspect ratio-preserving computations below. */
+  if (desired_width != -1 && desired_height != -1)
+    goto out;
 
   width = width * scale;
   height = height * scale;
 
-  if (desired_width == -1)
+  if (desired_width != -1)
+    /* Width known, calculate height. */
+    desired_height = scale_image_size (desired_width, width, height);
+  else if (desired_height != -1)
+    /* Height known, calculate width. */
+    desired_width = scale_image_size (desired_height, height, width);
+  else
     {
-      value = image_spec_value (spec, QCmax_width, NULL);
-      if (NATNUMP (value))
-       {
-         int max_width = min (XFASTINT (value), INT_MAX);
-         if (max_width < width)
-           {
-             /* The image is wider than :max-width. */
-             desired_width = max_width;
-             if (desired_height == -1)
-               {
-                 desired_height = scale_image_size (desired_width,
-                                                    width, height);
-                 value = image_spec_value (spec, QCmax_height, NULL);
-                 if (NATNUMP (value))
-                   {
-                     int max_height = min (XFASTINT (value), INT_MAX);
-                     if (max_height < desired_height)
-                       {
-                         desired_height = max_height;
-                         desired_width = scale_image_size (desired_height,
-                                                           height, width);
-                       }
-                   }
-               }
-           }
-       }
+      desired_width = width;
+      desired_height = height;
     }
 
-  if (desired_height == -1)
+  if (max_width != -1 && desired_width > max_width)
     {
-      value = image_spec_value (spec, QCmax_height, NULL);
-      if (NATNUMP (value))
-       {
-         int max_height = min (XFASTINT (value), INT_MAX);
-         if (max_height < height)
-           desired_height = max_height;
-       }
+      /* The image is wider than :max-width. */
+      desired_width = max_width;
+      desired_height = scale_image_size (desired_width, width, height);
     }
 
-  if (desired_width != -1 && desired_height == -1)
-    /* w known, calculate h.  */
-    desired_height = scale_image_size (desired_width, width, height);
-
-  if (desired_width == -1 && desired_height != -1)
-    /* h known, calculate w.  */
-    desired_width = scale_image_size (desired_height, height, width);
-
-  /* We have no width/height settings, so just apply the scale. */
-  if (desired_width == -1 && desired_height == -1)
+  if (max_height != -1 && desired_height > max_height)
     {
-      desired_width = width;
-      desired_height = height;
+      /* The image is higher than :max-height. */
+      desired_height = max_height;
+      desired_width = scale_image_size (desired_height, height, width);
     }
 
+ out:
   *d_width = desired_width;
   *d_height = desired_height;
 }
diff --git a/src/indent.c b/src/indent.c
index adecc36..4c6dacd 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1947,6 +1947,57 @@ vmotion (register ptrdiff_t from, register ptrdiff_t 
from_byte,
                         -1, hscroll, 0, w);
 }
 
+/* Return the width taken by line-number display in window W.  */
+static void
+line_number_display_width (struct window *w, int *width, int *pixel_width)
+{
+  if (NILP (Vdisplay_line_numbers))
+    {
+      *width = 0;
+      *pixel_width = 0;
+    }
+  else
+    {
+      struct it it;
+      struct text_pos wstart;
+      bool saved_restriction = false;
+      ptrdiff_t count = SPECPDL_INDEX ();
+      SET_TEXT_POS_FROM_MARKER (wstart, w->start);
+      void *itdata = bidi_shelve_cache ();
+      /* We must start from window's start point, but it could be
+        outside the accessible region.  */
+      if (wstart.charpos < BEGV || wstart.charpos > ZV)
+       {
+         record_unwind_protect (save_restriction_restore,
+                                save_restriction_save ());
+         Fwiden ();
+         saved_restriction = true;
+       }
+      start_display (&it, w, wstart);
+      move_it_by_lines (&it, 1);
+      *width = it.lnum_width;
+      *pixel_width = it.lnum_pixel_width;
+      if (saved_restriction)
+       unbind_to (count, Qnil);
+      bidi_unshelve_cache (itdata, 0);
+    }
+}
+
+DEFUN ("line-number-display-width", Fline_number_display_width,
+       Sline_number_display_width, 0, 1, 0,
+       doc: /* Return the width used for displaying line numbers in the 
selected window.
+If optional argument PIXELWISE is non-nil, return the width in pixels,
+otherwise return the width in columns of the face used to display
+line numbers, `line-number'.  */)
+  (Lisp_Object pixelwise)
+{
+  int width, pixel_width;
+  line_number_display_width (XWINDOW (selected_window), &width, &pixel_width);
+  if (!NILP (pixelwise))
+    return make_number (pixel_width);
+  return make_number (width);
+}
+
 /* In window W (derived from WINDOW), return x coordinate for column
    COL (derived from COLUMN).  */
 static int
@@ -2068,9 +2119,19 @@ whether or not it is currently displayed in some window. 
 */)
          start_x = window_column_x (w, window, start_col, cur_col);
        }
 
-      itdata = bidi_shelve_cache ();
+      /* When displaying line numbers, we need to prime IT's
+        lnum_width with the value calculated at window's start, since
+        that's what normal window redisplay does.  Otherwise C-n/C-p
+        will sometimes err by one column.  */
+      int lnum_width = 0;
+      int lnum_pixel_width = 0;
+      if (!NILP (Vdisplay_line_numbers)
+         && !EQ (Vdisplay_line_numbers, Qvisual))
+       line_number_display_width (w, &lnum_width, &lnum_pixel_width);
       SET_TEXT_POS (pt, PT, PT_BYTE);
+      itdata = bidi_shelve_cache ();
       start_display (&it, w, pt);
+      it.lnum_width = lnum_width;
       first_x = it.first_visible_x;
       it_start = IT_CHARPOS (it);
 
@@ -2247,6 +2308,12 @@ whether or not it is currently displayed in some window. 
 */)
         an addition to the hscroll amount.  */
       if (lcols_given)
        {
+         /* If we are displaying line numbers, we could cross the
+            line where the width of the line-number display changes,
+            in which case we need to fix up the pixel coordinate
+            accordingly.  */
+         if (lnum_pixel_width > 0)
+           to_x += it.lnum_pixel_width - lnum_pixel_width;
          move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
          /* If we find ourselves in the middle of an overlay string
             which includes a newline after current string position,
@@ -2292,6 +2359,7 @@ syms_of_indent (void)
   defsubr (&Sindent_to);
   defsubr (&Scurrent_column);
   defsubr (&Smove_to_column);
+  defsubr (&Sline_number_display_width);
   defsubr (&Svertical_motion);
   defsubr (&Scompute_motion);
 }
diff --git a/src/intervals.c b/src/intervals.c
index d17d80a..0089ecb 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -224,7 +224,8 @@ intervals_equal (INTERVAL i0, INTERVAL i1)
    Pass FUNCTION two args: an interval, and ARG.  */
 
 void
-traverse_intervals_noorder (INTERVAL tree, void (*function) (INTERVAL, 
Lisp_Object), Lisp_Object arg)
+traverse_intervals_noorder (INTERVAL tree, void (*function) (INTERVAL, void *),
+                           void *arg)
 {
   /* Minimize stack usage.  */
   while (tree)
@@ -257,69 +258,6 @@ traverse_intervals (INTERVAL tree, ptrdiff_t position,
     }
 }
 
-#if 0
-
-static int icount;
-static int idepth;
-static int zero_length;
-
-/* These functions are temporary, for debugging purposes only.  */
-
-INTERVAL search_interval, found_interval;
-
-void
-check_for_interval (INTERVAL i)
-{
-  if (i == search_interval)
-    {
-      found_interval = i;
-      icount++;
-    }
-}
-
-INTERVAL
-search_for_interval (INTERVAL i, INTERVAL tree)
-{
-  icount = 0;
-  search_interval = i;
-  found_interval = NULL;
-  traverse_intervals_noorder (tree, &check_for_interval, Qnil);
-  return found_interval;
-}
-
-static void
-inc_interval_count (INTERVAL i)
-{
-  icount++;
-  if (LENGTH (i) == 0)
-    zero_length++;
-  if (depth > idepth)
-    idepth = depth;
-}
-
-int
-count_intervals (INTERVAL i)
-{
-  icount = 0;
-  idepth = 0;
-  zero_length = 0;
-  traverse_intervals_noorder (i, &inc_interval_count, Qnil);
-
-  return icount;
-}
-
-static INTERVAL
-root_interval (INTERVAL interval)
-{
-  register INTERVAL i = interval;
-
-  while (! ROOT_INTERVAL_P (i))
-    i = INTERVAL_PARENT (i);
-
-  return i;
-}
-#endif
-
 /* Assuming that a left child exists, perform the following operation:
 
      A           B
diff --git a/src/intervals.h b/src/intervals.h
index a0da6f3..9140e0c 100644
--- a/src/intervals.h
+++ b/src/intervals.h
@@ -242,8 +242,7 @@ extern void traverse_intervals (INTERVAL, ptrdiff_t,
                                 void (*) (INTERVAL, Lisp_Object),
                                 Lisp_Object);
 extern void traverse_intervals_noorder (INTERVAL,
-                                        void (*) (INTERVAL, Lisp_Object),
-                                        Lisp_Object);
+                                       void (*) (INTERVAL, void *), void *);
 extern INTERVAL split_interval_right (INTERVAL, ptrdiff_t);
 extern INTERVAL split_interval_left (INTERVAL, ptrdiff_t);
 extern INTERVAL find_interval (INTERVAL, ptrdiff_t);
diff --git a/src/keyboard.c b/src/keyboard.c
index 9e90899..804af85 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5127,6 +5127,7 @@ static short const scroll_bar_parts[] = {
   SYMBOL_INDEX (Qrightmost), SYMBOL_INDEX (Qend_scroll), SYMBOL_INDEX (Qratio)
 };
 
+#ifdef HAVE_WINDOW_SYSTEM
 /* An array of symbol indexes of internal border parts, indexed by an enum
    internal_border_part value.  Note that Qnil corresponds to
    internal_border_part_none and should not appear in Lisp events.  */
@@ -5137,6 +5138,7 @@ static short const internal_border_parts[] = {
   SYMBOL_INDEX (Qbottom_right_corner), SYMBOL_INDEX (Qbottom_edge),
   SYMBOL_INDEX (Qbottom_left_corner)
 };
+#endif
 
 /* A vector, indexed by button number, giving the down-going location
    of currently depressed buttons, both scroll bar and non-scroll bar.
diff --git a/src/keymap.c b/src/keymap.c
index b568f47..db9aa7c 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1292,7 +1292,7 @@ silly_event_symbol_error (Lisp_Object c)
   base = XCAR (parsed);
   name = Fsymbol_name (base);
   /* This alist includes elements such as ("RET" . "\\r").  */
-  assoc = Fassoc (name, exclude_keys);
+  assoc = Fassoc (name, exclude_keys, Qnil);
 
   if (! NILP (assoc))
     {
diff --git a/src/lisp.h b/src/lisp.h
index ff8dde2..cffaf95 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -838,13 +838,13 @@ make_lisp_symbol (struct Lisp_Symbol *sym)
 INLINE Lisp_Object
 builtin_lisp_symbol (int index)
 {
-  return make_lisp_symbol (lispsym + index);
+  return make_lisp_symbol (&lispsym[index].s);
 }
 
 INLINE void
 (CHECK_SYMBOL) (Lisp_Object x)
 {
- lisp_h_CHECK_SYMBOL (x);
+  lisp_h_CHECK_SYMBOL (x);
 }
 
 /* In the size word of a vector, this bit means the vector has been marked.  */
@@ -3386,6 +3386,7 @@ enum { NEXT_ALMOST_PRIME_LIMIT = 11 };
 extern EMACS_INT next_almost_prime (EMACS_INT) ATTRIBUTE_CONST;
 extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t);
 extern void sweep_weak_hash_tables (void);
+extern char *extract_data_from_object (Lisp_Object, ptrdiff_t *, ptrdiff_t *);
 EMACS_UINT hash_string (char const *, ptrdiff_t);
 EMACS_UINT sxhash (Lisp_Object, int);
 Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, float, float,
@@ -3874,7 +3875,6 @@ extern Lisp_Object vformat_string (const char *, va_list)
   ATTRIBUTE_FORMAT_PRINTF (1, 0);
 extern void un_autoload (Lisp_Object);
 extern Lisp_Object call_debugger (Lisp_Object arg);
-extern void *near_C_stack_top (void);
 extern void init_eval_once (void);
 extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...);
 extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
@@ -3965,6 +3965,7 @@ extern void syms_of_editfns (void);
 
 /* Defined in buffer.c.  */
 extern bool mouse_face_overlay_overlaps (Lisp_Object);
+extern Lisp_Object disable_line_numbers_overlay_at_eob (void);
 extern _Noreturn void nsberror (Lisp_Object);
 extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t);
 extern void adjust_overlays_for_delete (ptrdiff_t, ptrdiff_t);
diff --git a/src/lread.c b/src/lread.c
index 7c554ba..dbaadce 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -103,8 +103,20 @@ static Lisp_Object read_objects_map;
    (to reduce allocations), or nil.  */
 static Lisp_Object read_objects_completed;
 
-/* File for get_file_char to read from.  Use by load.  */
-static FILE *instream;
+/* File and lookahead for get-file-char and get-emacs-mule-file-char
+   to read from.  Used by Fload.  */
+static struct infile
+{
+  /* The input stream.  */
+  FILE *stream;
+
+  /* Lookahead byte count.  */
+  signed char lookahead;
+
+  /* Lookahead bytes, in reverse order.  Keep these here because it is
+     not portable to ungetc more than one byte at a time.  */
+  unsigned char buf[MAX_MULTIBYTE_LENGTH - 1];
+} *infile;
 
 /* For use within read-from-string (this reader is non-reentrant!!)  */
 static ptrdiff_t read_from_string_index;
@@ -149,7 +161,7 @@ static Lisp_Object Vloads_in_progress;
 static int read_emacs_mule_char (int, int (*) (int, Lisp_Object),
                                  Lisp_Object);
 
-static void readevalloop (Lisp_Object, FILE *, Lisp_Object, bool,
+static void readevalloop (Lisp_Object, struct infile *, Lisp_Object, bool,
                           Lisp_Object, Lisp_Object,
                           Lisp_Object, Lisp_Object);
 
@@ -340,14 +352,13 @@ readchar (Lisp_Object readcharfun, bool *multibyte)
   len = BYTES_BY_CHAR_HEAD (c);
   while (i < len)
     {
-      c = (*readbyte) (-1, readcharfun);
+      buf[i++] = c = (*readbyte) (-1, readcharfun);
       if (c < 0 || ! TRAILING_CODE_P (c))
        {
-         while (--i > 1)
+         for (i -= c < 0; 0 < --i; )
            (*readbyte) (buf[i], readcharfun);
          return BYTE8_TO_CHAR (buf[0]);
        }
-      buf[i++] = c;
     }
   return STRING_CHAR (buf);
 }
@@ -362,8 +373,9 @@ skip_dyn_bytes (Lisp_Object readcharfun, ptrdiff_t n)
   if (FROM_FILE_P (readcharfun))
     {
       block_input ();          /* FIXME: Not sure if it's needed.  */
-      fseek (instream, n, SEEK_CUR);
+      fseek (infile->stream, n - infile->lookahead, SEEK_CUR);
       unblock_input ();
+      infile->lookahead = 0;
     }
   else
     { /* We're not reading directly from a file.  In that case, it's difficult
@@ -385,8 +397,9 @@ skip_dyn_eof (Lisp_Object readcharfun)
   if (FROM_FILE_P (readcharfun))
     {
       block_input ();          /* FIXME: Not sure if it's needed.  */
-      fseek (instream, 0, SEEK_END);
+      fseek (infile->stream, 0, SEEK_END);
       unblock_input ();
+      infile->lookahead = 0;
     }
   else
     while (READCHAR >= 0);
@@ -459,15 +472,13 @@ readbyte_for_lambda (int c, Lisp_Object readcharfun)
 
 
 static int
-readbyte_from_file (int c, Lisp_Object readcharfun)
+readbyte_from_stdio (void)
 {
-  if (c >= 0)
-    {
-      block_input ();
-      ungetc (c, instream);
-      unblock_input ();
-      return 0;
-    }
+  if (infile->lookahead)
+    return infile->buf[--infile->lookahead];
+
+  int c;
+  FILE *instream = infile->stream;
 
   block_input ();
 
@@ -487,6 +498,19 @@ readbyte_from_file (int c, Lisp_Object readcharfun)
 }
 
 static int
+readbyte_from_file (int c, Lisp_Object readcharfun)
+{
+  if (c >= 0)
+    {
+      eassert (infile->lookahead < sizeof infile->buf);
+      infile->buf[infile->lookahead++] = c;
+      return 0;
+    }
+
+  return readbyte_from_stdio ();
+}
+
+static int
 readbyte_from_string (int c, Lisp_Object readcharfun)
 {
   Lisp_Object string = XCAR (readcharfun);
@@ -508,7 +532,7 @@ readbyte_from_string (int c, Lisp_Object readcharfun)
 }
 
 
-/* Read one non-ASCII character from INSTREAM.  The character is
+/* Read one non-ASCII character from INFILE.  The character is
    encoded in `emacs-mule' and the first byte is already read in
    C.  */
 
@@ -530,14 +554,13 @@ read_emacs_mule_char (int c, int (*readbyte) (int, 
Lisp_Object), Lisp_Object rea
   buf[i++] = c;
   while (i < len)
     {
-      c = (*readbyte) (-1, readcharfun);
+      buf[i++] = c = (*readbyte) (-1, readcharfun);
       if (c < 0xA0)
        {
-         while (--i > 1)
+         for (i -= c < 0; 0 < --i; )
            (*readbyte) (buf[i], readcharfun);
          return BYTE8_TO_CHAR (buf[0]);
        }
-      buf[i++] = c;
     }
 
   if (len == 2)
@@ -572,6 +595,20 @@ read_emacs_mule_char (int c, int (*readbyte) (int, 
Lisp_Object), Lisp_Object rea
 }
 
 
+/* An in-progress substitution of OBJECT for PLACEHOLDER.  */
+struct subst
+{
+  Lisp_Object object;
+  Lisp_Object placeholder;
+
+  /* Hash table of subobjects of OBJECT that might be circular.  If
+     Qt, all such objects might be circular.  */
+  Lisp_Object completed;
+
+  /* List of subobjects of OBJECT that have already been visited.  */
+  Lisp_Object seen;
+};
+
 static Lisp_Object read_internal_start (Lisp_Object, Lisp_Object,
                                         Lisp_Object);
 static Lisp_Object read0 (Lisp_Object);
@@ -580,9 +617,8 @@ static Lisp_Object read1 (Lisp_Object, int *, bool);
 static Lisp_Object read_list (bool, Lisp_Object);
 static Lisp_Object read_vector (Lisp_Object, bool);
 
-static Lisp_Object substitute_object_recurse (Lisp_Object, Lisp_Object,
-                                              Lisp_Object);
-static void substitute_in_interval (INTERVAL, Lisp_Object);
+static Lisp_Object substitute_object_recurse (struct subst *, Lisp_Object);
+static void substitute_in_interval (INTERVAL, void *);
 
 
 /* Get a character from the tty.  */
@@ -779,11 +815,9 @@ DEFUN ("get-file-char", Fget_file_char, Sget_file_char, 0, 
0, 0,
        doc: /* Don't use this yourself.  */)
   (void)
 {
-  register Lisp_Object val;
-  block_input ();
-  XSETINT (val, getc_unlocked (instream));
-  unblock_input ();
-  return val;
+  if (!infile)
+    error ("get-file-char misused");
+  return make_number (readbyte_from_stdio ());
 }
 
 
@@ -1028,6 +1062,15 @@ suffix_p (Lisp_Object string, const char *suffix)
   return string_len >= suffix_len && !strcmp (SSDATA (string) + string_len - 
suffix_len, suffix);
 }
 
+static void
+close_infile_unwind (void *arg)
+{
+  FILE *stream = arg;
+  eassert (infile == NULL || infile->stream == stream);
+  infile = NULL;
+  fclose (stream);
+}
+
 DEFUN ("load", Fload, Sload, 1, 5, 0,
        doc: /* Execute a file of Lisp code named FILE.
 First try FILE with `.elc' appended, then try with `.el', then try
@@ -1347,7 +1390,7 @@ Return t if the file exists and loads successfully.  */)
     }
   if (! stream)
     report_file_error ("Opening stdio stream", file);
-  set_unwind_protect_ptr (fd_index, fclose_unwind, stream);
+  set_unwind_protect_ptr (fd_index, close_infile_unwind, stream);
 
   if (! NILP (Vpurify_flag))
     Vpreloaded_file_list = Fcons (Fpurecopy (file), Vpreloaded_file_list);
@@ -1370,19 +1413,23 @@ Return t if the file exists and loads successfully.  */)
   specbind (Qinhibit_file_name_operation, Qnil);
   specbind (Qload_in_progress, Qt);
 
-  instream = stream;
+  struct infile input;
+  input.stream = stream;
+  input.lookahead = 0;
+  infile = &input;
+
   if (lisp_file_lexically_bound_p (Qget_file_char))
     Fset (Qlexical_binding, Qt);
 
   if (! version || version >= 22)
-    readevalloop (Qget_file_char, stream, hist_file_name,
+    readevalloop (Qget_file_char, &input, hist_file_name,
                  0, Qnil, Qnil, Qnil, Qnil);
   else
     {
       /* We can't handle a file which was compiled with
         byte-compile-dynamic by older version of Emacs.  */
       specbind (Qload_force_doc_strings, Qt);
-      readevalloop (Qget_emacs_mule_file_char, stream, hist_file_name,
+      readevalloop (Qget_emacs_mule_file_char, &input, hist_file_name,
                    0, Qnil, Qnil, Qnil, Qnil);
     }
   unbind_to (count, Qnil);
@@ -1813,7 +1860,7 @@ readevalloop_eager_expand_eval (Lisp_Object val, 
Lisp_Object macroexpand)
 
 static void
 readevalloop (Lisp_Object readcharfun,
-             FILE *stream,
+             struct infile *infile0,
              Lisp_Object sourcename,
              bool printflag,
              Lisp_Object unibyte, Lisp_Object readfun,
@@ -1913,7 +1960,7 @@ readevalloop (Lisp_Object readcharfun,
       if (b && first_sexp)
        whole_buffer = (BUF_PT (b) == BUF_BEG (b) && BUF_ZV (b) == BUF_Z (b));
 
-      instream = stream;
+      infile = infile0;
     read_next:
       c = READCHAR;
       if (c == ';')
@@ -2003,7 +2050,7 @@ readevalloop (Lisp_Object readcharfun,
     }
 
   build_load_history (sourcename,
-                     stream || whole_buffer);
+                     infile0 || whole_buffer);
 
   unbind_to (count, Qnil);
 }
@@ -2629,6 +2676,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
   bool uninterned_symbol = false;
   bool multibyte;
   char stackbuf[MAX_ALLOCA];
+  current_thread->stack_top = stackbuf;
 
   *pch = 0;
 
@@ -2943,11 +2991,17 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
                  saved_doc_string_size = nskip + extra;
                }
 
-             saved_doc_string_position = file_tell (instream);
+             FILE *instream = infile->stream;
+             saved_doc_string_position = (file_tell (instream)
+                                          - infile->lookahead);
 
-             /* Copy that many characters into saved_doc_string.  */
+             /* Copy that many bytes into saved_doc_string.  */
+             i = 0;
+             for (int n = min (nskip, infile->lookahead); 0 < n; n--)
+               saved_doc_string[i++]
+                 = c = infile->buf[--infile->lookahead];
              block_input ();
-             for (i = 0; i < nskip && c >= 0; i++)
+             for (; i < nskip && 0 <= c; i++)
                saved_doc_string[i] = c = getc_unlocked (instream);
              unblock_input ();
 
@@ -3067,7 +3121,8 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
                         }
                       else
                         {
-                         Fsubstitute_object_in_subtree (tem, placeholder);
+                         Flread__substitute_object_in_subtree
+                           (tem, placeholder, read_objects_completed);
 
                          /* ...and #n# will use the real value from now on.  */
                          i = hash_lookup (h, number, &hash);
@@ -3424,6 +3479,24 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
            if (! NILP (result))
              return unbind_to (count, result);
          }
+        if (!quoted && multibyte)
+          {
+            int ch = STRING_CHAR ((unsigned char *) read_buffer);
+            switch (ch)
+              {
+              case 0x2018: /* LEFT SINGLE QUOTATION MARK */
+              case 0x2019: /* RIGHT SINGLE QUOTATION MARK */
+              case 0x201B: /* SINGLE HIGH-REVERSED-9 QUOTATION MARK */
+              case 0x201C: /* LEFT DOUBLE QUOTATION MARK */
+              case 0x201D: /* RIGHT DOUBLE QUOTATION MARK */
+              case 0x201F: /* DOUBLE HIGH-REVERSED-9 QUOTATION MARK */
+              case 0x301E: /* DOUBLE PRIME QUOTATION MARK */
+              case 0xFF02: /* FULLWIDTH QUOTATION MARK */
+              case 0xFF07: /* FULLWIDTH APOSTROPHE */
+                xsignal2 (Qinvalid_read_syntax, build_string ("strange quote"),
+                          CALLN (Fstring, make_number (ch)));
+              }
+          }
        {
          Lisp_Object result;
          ptrdiff_t nbytes = p - read_buffer;
@@ -3473,26 +3546,16 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
     }
 }
 
-
-/* List of nodes we've seen during substitute_object_in_subtree.  */
-static Lisp_Object seen_list;
-
-DEFUN ("substitute-object-in-subtree", Fsubstitute_object_in_subtree,
-       Ssubstitute_object_in_subtree, 2, 2, 0,
-       doc: /* Replace every reference to PLACEHOLDER in OBJECT with OBJECT.  
*/)
-  (Lisp_Object object, Lisp_Object placeholder)
+DEFUN ("lread--substitute-object-in-subtree",
+       Flread__substitute_object_in_subtree,
+       Slread__substitute_object_in_subtree, 3, 3, 0,
+       doc: /* In OBJECT, replace every occurrence of PLACEHOLDER with OBJECT.
+COMPLETED is a hash table of objects that might be circular, or is t
+if any object might be circular.  */)
+  (Lisp_Object object, Lisp_Object placeholder, Lisp_Object completed)
 {
-  Lisp_Object check_object;
-
-  /* We haven't seen any objects when we start.  */
-  seen_list = Qnil;
-
-  /* Make all the substitutions.  */
-  check_object
-    = substitute_object_recurse (object, placeholder, object);
-
-  /* Clear seen_list because we're done with it.  */
-  seen_list = Qnil;
+  struct subst subst = { object, placeholder, completed, Qnil };
+  Lisp_Object check_object = substitute_object_recurse (&subst, object);
 
   /* The returned object here is expected to always eq the
      original.  */
@@ -3501,26 +3564,12 @@ DEFUN ("substitute-object-in-subtree", 
Fsubstitute_object_in_subtree,
   return Qnil;
 }
 
-/*  Feval doesn't get called from here, so no gc protection is needed.  */
-#define SUBSTITUTE(get_val, set_val)                   \
-  do {                                                 \
-    Lisp_Object old_value = get_val;                   \
-    Lisp_Object true_value                             \
-      = substitute_object_recurse (object, placeholder,        \
-                                  old_value);          \
-                                                       \
-    if (!EQ (old_value, true_value))                   \
-      {                                                        \
-       set_val;                                        \
-      }                                                        \
-  } while (0)
-
 static Lisp_Object
-substitute_object_recurse (Lisp_Object object, Lisp_Object placeholder, 
Lisp_Object subtree)
+substitute_object_recurse (struct subst *subst, Lisp_Object subtree)
 {
   /* If we find the placeholder, return the target object.  */
-  if (EQ (placeholder, subtree))
-    return object;
+  if (EQ (subst->placeholder, subtree))
+    return subst->object;
 
   /* For common object types that can't contain other objects, don't
      bother looking them up; we're done.  */
@@ -3530,15 +3579,16 @@ substitute_object_recurse (Lisp_Object object, 
Lisp_Object placeholder, Lisp_Obj
     return subtree;
 
   /* If we've been to this node before, don't explore it again.  */
-  if (!EQ (Qnil, Fmemq (subtree, seen_list)))
+  if (!EQ (Qnil, Fmemq (subtree, subst->seen)))
     return subtree;
 
   /* If this node can be the entry point to a cycle, remember that
      we've seen it.  It can only be such an entry point if it was made
      by #n=, which means that we can find it as a value in
-     read_objects_completed.  */
-  if (hash_lookup (XHASH_TABLE (read_objects_completed), subtree, NULL) >= 0)
-    seen_list = Fcons (subtree, seen_list);
+     COMPLETED.  */
+  if (EQ (subst->completed, Qt)
+      || hash_lookup (XHASH_TABLE (subst->completed), subtree, NULL) >= 0)
+    subst->seen = Fcons (subtree, subst->seen);
 
   /* Recurse according to subtree's type.
      Every branch must return a Lisp_Object.  */
@@ -3565,19 +3615,15 @@ substitute_object_recurse (Lisp_Object object, 
Lisp_Object placeholder, Lisp_Obj
        if (SUB_CHAR_TABLE_P (subtree))
          i = 2;
        for ( ; i < length; i++)
-         SUBSTITUTE (AREF (subtree, i),
-                     ASET (subtree, i, true_value));
+         ASET (subtree, i,
+               substitute_object_recurse (subst, AREF (subtree, i)));
        return subtree;
       }
 
     case Lisp_Cons:
-      {
-       SUBSTITUTE (XCAR (subtree),
-                   XSETCAR (subtree, true_value));
-       SUBSTITUTE (XCDR (subtree),
-                   XSETCDR (subtree, true_value));
-       return subtree;
-      }
+      XSETCAR (subtree, substitute_object_recurse (subst, XCAR (subtree)));
+      XSETCDR (subtree, substitute_object_recurse (subst, XCDR (subtree)));
+      return subtree;
 
     case Lisp_String:
       {
@@ -3585,11 +3631,8 @@ substitute_object_recurse (Lisp_Object object, 
Lisp_Object placeholder, Lisp_Obj
           substitute_in_interval contains part of the logic.  */
 
        INTERVAL root_interval = string_intervals (subtree);
-       AUTO_CONS (arg, object, placeholder);
-
        traverse_intervals_noorder (root_interval,
-                                   &substitute_in_interval, arg);
-
+                                   substitute_in_interval, subst);
        return subtree;
       }
 
@@ -3601,12 +3644,10 @@ substitute_object_recurse (Lisp_Object object, 
Lisp_Object placeholder, Lisp_Obj
 
 /*  Helper function for substitute_object_recurse.  */
 static void
-substitute_in_interval (INTERVAL interval, Lisp_Object arg)
+substitute_in_interval (INTERVAL interval, void *arg)
 {
-  Lisp_Object object      = Fcar (arg);
-  Lisp_Object placeholder = Fcdr (arg);
-
-  SUBSTITUTE (interval->plist, set_interval_plist (interval, true_value));
+  set_interval_plist (interval,
+                     substitute_object_recurse (arg, interval->plist));
 }
 
 
@@ -4704,7 +4745,7 @@ syms_of_lread (void)
 {
   defsubr (&Sread);
   defsubr (&Sread_from_string);
-  defsubr (&Ssubstitute_object_in_subtree);
+  defsubr (&Slread__substitute_object_in_subtree);
   defsubr (&Sintern);
   defsubr (&Sintern_soft);
   defsubr (&Sunintern);
@@ -5017,8 +5058,6 @@ that are loaded before your customizations are read!  */);
   read_objects_map = Qnil;
   staticpro (&read_objects_completed);
   read_objects_completed = Qnil;
-  staticpro (&seen_list);
-  seen_list = Qnil;
 
   Vloads_in_progress = Qnil;
   staticpro (&Vloads_in_progress);
diff --git a/src/nsfns.m b/src/nsfns.m
index 68eba8b..36748ce 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -3080,6 +3080,25 @@ The coordinates X and Y are interpreted in pixels 
relative to a position
   return Qnil;
 }
 
+DEFUN ("ns-mouse-absolute-pixel-position",
+       Fns_mouse_absolute_pixel_position,
+       Sns_mouse_absolute_pixel_position, 0, 0, 0,
+       doc: /* Return absolute position of mouse cursor in pixels.
+The position is returned as a cons cell (X . Y) of the
+coordinates of the mouse cursor position in pixels relative to a
+position (0, 0) of the selected frame's terminal. */)
+     (void)
+{
+  struct frame *f = SELECTED_FRAME ();
+  EmacsView *view = FRAME_NS_VIEW (f);
+  NSScreen *screen = [[view window] screen];
+  NSPoint pt = [NSEvent mouseLocation];
+
+  return Fcons(make_number(pt.x - screen.frame.origin.x),
+               make_number(screen.frame.size.height -
+                           (pt.y - screen.frame.origin.y)));
+}
+
 /* ==========================================================================
 
     Class implementations
@@ -3269,6 +3288,7 @@ be used as the image of the icon representing the frame.  
*/);
   defsubr (&Sns_frame_list_z_order);
   defsubr (&Sns_frame_restack);
   defsubr (&Sns_set_mouse_absolute_pixel_position);
+  defsubr (&Sns_mouse_absolute_pixel_position);
   defsubr (&Sx_display_mm_width);
   defsubr (&Sx_display_mm_height);
   defsubr (&Sx_display_screens);
diff --git a/src/nsterm.m b/src/nsterm.m
index bf83550..36d906a 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1570,6 +1570,7 @@ x_make_frame_visible (struct frame *f)
   if (!FRAME_VISIBLE_P (f))
     {
       EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f);
+      NSWindow *window = [view window];
 
       SET_FRAME_VISIBLE (f, 1);
       ns_raise_frame (f, ! FRAME_NO_FOCUS_ON_MAP (f));
@@ -1586,6 +1587,23 @@ x_make_frame_visible (struct frame *f)
           [view handleFS];
           unblock_input ();
         }
+
+      /* Making a frame invisible seems to break the parent->child
+         relationship, so reinstate it. */
+      if ([window parentWindow] == nil && FRAME_PARENT_FRAME (f) != NULL)
+        {
+          NSWindow *parent = [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window];
+
+          block_input ();
+          [parent addChildWindow: window
+                         ordered: NSWindowAbove];
+          unblock_input ();
+
+          /* If the parent frame moved while the child frame was
+             invisible, the child frame's position won't have been
+             updated.  Make sure it's in the right place now. */
+          x_set_offset(f, f->left_pos, f->top_pos, 0);
+        }
     }
 }
 
@@ -5479,6 +5497,19 @@ ns_term_shutdown (int sig)
         object:nil];
 #endif
 
+#ifdef NS_IMPL_COCOA
+  if ([NSApp activationPolicy] == NSApplicationActivationPolicyProhibited) {
+    /* Set the app's activation policy to regular when we run outside
+       of a bundle.  This is already done for us by Info.plist when we
+       run inside a bundle. */
+    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
+    [NSApp setApplicationIconImage:
+            [EmacsImage
+              allocInitFromFile:
+                build_string("icons/hicolor/128x128/apps/emacs.png")]];
+  }
+#endif
+
   ns_send_appdefined (-2);
 }
 
diff --git a/src/print.c b/src/print.c
index 50c75d7..12edf01 100644
--- a/src/print.c
+++ b/src/print.c
@@ -566,7 +566,7 @@ temp_output_buffer_setup (const char *bufname)
 
 static void print (Lisp_Object, Lisp_Object, bool);
 static void print_preprocess (Lisp_Object);
-static void print_preprocess_string (INTERVAL, Lisp_Object);
+static void print_preprocess_string (INTERVAL, void *);
 static void print_object (Lisp_Object, Lisp_Object, bool);
 
 DEFUN ("terpri", Fterpri, Sterpri, 0, 2, 0,
@@ -1214,7 +1214,7 @@ print_preprocess (Lisp_Object obj)
        case Lisp_String:
          /* A string may have text properties, which can be circular.  */
          traverse_intervals_noorder (string_intervals (obj),
-                                     print_preprocess_string, Qnil);
+                                     print_preprocess_string, NULL);
          break;
 
        case Lisp_Cons:
@@ -1263,7 +1263,7 @@ Fills `print-number-table'.  */)
 }
 
 static void
-print_preprocess_string (INTERVAL interval, Lisp_Object arg)
+print_preprocess_string (INTERVAL interval, void *arg)
 {
   print_preprocess (interval->plist);
 }
@@ -1748,7 +1748,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, 
bool escapeflag)
   char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT),
                max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t),
                     40))];
-
+  current_thread->stack_top = buf;
   maybe_quit ();
 
   /* Detect circularities and truncate them.  */
diff --git a/src/process.c b/src/process.c
index abd017b..1900951 100644
--- a/src/process.c
+++ b/src/process.c
@@ -951,7 +951,7 @@ DEFUN ("get-process", Fget_process, Sget_process, 1, 1, 0,
   if (PROCESSP (name))
     return name;
   CHECK_STRING (name);
-  return Fcdr (Fassoc (name, Vprocess_alist));
+  return Fcdr (Fassoc (name, Vprocess_alist, Qnil));
 }
 
 /* This is how commands for the user decode process arguments.  It
diff --git a/src/sysdep.c b/src/sysdep.c
index b522367..db99f53 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1772,7 +1772,7 @@ stack_overflow (siginfo_t *siginfo)
   /* The known top and bottom of the stack.  The actual stack may
      extend a bit beyond these boundaries.  */
   char *bot = stack_bottom;
-  char *top = near_C_stack_top ();
+  char *top = current_thread->stack_top;
 
   /* Log base 2 of the stack heuristic ratio.  This ratio is the size
      of the known stack divided by the size of the guard area past the
diff --git a/src/term.c b/src/term.c
index 3d7f4ad..87a4126 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1585,10 +1585,16 @@ produce_glyphs (struct it *it)
     {
       int absolute_x = (it->current_x
                        + it->continuation_lines_width);
+      int x0 = absolute_x;
+      /* Adjust for line numbers.  */
+      if (!NILP (Vdisplay_line_numbers))
+       absolute_x -= it->lnum_pixel_width;
       int next_tab_x
        = (((1 + absolute_x + it->tab_width - 1)
            / it->tab_width)
           * it->tab_width);
+      if (!NILP (Vdisplay_line_numbers))
+       next_tab_x += it->lnum_pixel_width;
       int nspaces;
 
       /* If part of the TAB has been displayed on the previous line
@@ -1596,7 +1602,7 @@ produce_glyphs (struct it *it)
         been incremented already by the part that fitted on the
         continued line.  So, we will get the right number of spaces
         here.  */
-      nspaces = next_tab_x - absolute_x;
+      nspaces = next_tab_x - x0;
 
       if (it->glyph_row)
        {
diff --git a/src/thread.c b/src/thread.c
index e378797..1f7ced3 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -595,14 +595,15 @@ thread_select (select_func *func, int max_fds, fd_set 
*rfds,
 static void
 mark_one_thread (struct thread_state *thread)
 {
-  struct handler *handler;
-  Lisp_Object tem;
+  /* Get the stack top now, in case mark_specpdl changes it.  */
+  void *stack_top = thread->stack_top;
 
   mark_specpdl (thread->m_specpdl, thread->m_specpdl_ptr);
 
-  mark_stack (thread->m_stack_bottom, thread->stack_top);
+  mark_stack (thread->m_stack_bottom, stack_top);
 
-  for (handler = thread->m_handlerlist; handler; handler = handler->next)
+  for (struct handler *handler = thread->m_handlerlist;
+       handler; handler = handler->next)
     {
       mark_object (handler->tag_or_ch);
       mark_object (handler->val);
@@ -610,6 +611,7 @@ mark_one_thread (struct thread_state *thread)
 
   if (thread->m_current_buffer)
     {
+      Lisp_Object tem;
       XSETBUFFER (tem, thread->m_current_buffer);
       mark_object (tem);
     }
diff --git a/src/thread.h b/src/thread.h
index 9e94de5..52b16f1 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -62,8 +62,14 @@ struct thread_state
   char *m_stack_bottom;
 #define stack_bottom (current_thread->m_stack_bottom)
 
-  /* An address near the top of the stack.  */
-  char *stack_top;
+  /* The address of an object near the C stack top, used to determine
+     which words need to be scanned by the garbage collector.  This is
+     also used to detect heuristically whether segmentation violation
+     address indicates stack overflow, as opposed to some internal
+     error in Emacs.  If the C function F calls G which calls H which
+     calls ... F, then at least one of the functions in the chain
+     should set this to the address of a local variable.  */
+  void *stack_top;
 
   struct catchtag *m_catchlist;
 #define catchlist (current_thread->m_catchlist)
diff --git a/src/w32fns.c b/src/w32fns.c
index b0842b5..457599f 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -467,7 +467,7 @@ if the entry is new.  */)
   block_input ();
 
   /* replace existing entry in w32-color-map or add new entry. */
-  entry = Fassoc (name, Vw32_color_map);
+  entry = Fassoc (name, Vw32_color_map, Qnil);
   if (NILP (entry))
     {
       entry = Fcons (name, rgb);
diff --git a/src/w32font.c b/src/w32font.c
index 67d2f6d..314d7ac 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -1627,7 +1627,7 @@ x_to_w32_charset (char * lpcs)
      Format of each entry is
        (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE)).
   */
-  this_entry = Fassoc (build_string (charset), Vw32_charset_info_alist);
+  this_entry = Fassoc (build_string (charset), Vw32_charset_info_alist, Qnil);
 
   if (NILP (this_entry))
     {
diff --git a/src/w32notify.c b/src/w32notify.c
index 2520581..e8bdef8 100644
--- a/src/w32notify.c
+++ b/src/w32notify.c
@@ -642,7 +642,7 @@ WATCH-DESCRIPTOR should be an object returned by 
`w32notify-add-watch'.  */)
   /* Remove the watch object from watch list.  Do this before freeing
      the object, do that even if we fail to free it, watch_list is
      kept free of junk.  */
-  watch_object = Fassoc (watch_descriptor, watch_list);
+  watch_object = Fassoc (watch_descriptor, watch_list, Qnil);
   if (!NILP (watch_object))
     {
       watch_list = Fdelete (watch_object, watch_list);
@@ -679,7 +679,7 @@ the watcher thread exits abnormally for any other reason.  
Removing the
 watch by calling `w32notify-rm-watch' also makes it invalid.  */)
      (Lisp_Object watch_descriptor)
 {
-  Lisp_Object watch_object = Fassoc (watch_descriptor, watch_list);
+  Lisp_Object watch_object = Fassoc (watch_descriptor, watch_list, Qnil);
 
   if (!NILP (watch_object))
     {
diff --git a/src/w32proc.c b/src/w32proc.c
index 0aa248a..76af55f 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -1622,38 +1622,43 @@ w32_executable_type (char * filename,
               /* Look for Cygwin DLL in the DLL import list. */
               IMAGE_DATA_DIRECTORY import_dir =
                 data_dir[IMAGE_DIRECTORY_ENTRY_IMPORT];
-              IMAGE_IMPORT_DESCRIPTOR * imports =
-               RVA_TO_PTR (import_dir.VirtualAddress,
-                           rva_to_section (import_dir.VirtualAddress,
-                                           nt_header),
-                           executable);
 
-              for ( ; imports->Name; imports++)
-                {
-                 IMAGE_SECTION_HEADER * section =
-                   rva_to_section (imports->Name, nt_header);
-                  char * dllname = RVA_TO_PTR (imports->Name, section,
-                                               executable);
-
-                  /* The exact name of the Cygwin DLL has changed with
-                     various releases, but hopefully this will be
-                     reasonably future-proof.  */
-                  if (strncmp (dllname, "cygwin", 6) == 0)
-                    {
-                      *is_cygnus_app = TRUE;
-                      break;
-                    }
-                 else if (strncmp (dllname, "msys-", 5) == 0)
+             /* Import directory can be missing in .NET DLLs.  */
+             if (import_dir.VirtualAddress != 0)
+               {
+                 IMAGE_IMPORT_DESCRIPTOR * imports =
+                   RVA_TO_PTR (import_dir.VirtualAddress,
+                               rva_to_section (import_dir.VirtualAddress,
+                                               nt_header),
+                               executable);
+
+                 for ( ; imports->Name; imports++)
                    {
-                     /* This catches both MSYS 1.x and MSYS2
-                        executables (the DLL name is msys-1.0.dll and
-                        msys-2.0.dll, respectively).  There doesn't
-                        seem to be a reason to distinguish between
-                        the two, for now.  */
-                     *is_msys_app = TRUE;
-                     break;
+                     IMAGE_SECTION_HEADER * section =
+                       rva_to_section (imports->Name, nt_header);
+                     char * dllname = RVA_TO_PTR (imports->Name, section,
+                                                  executable);
+
+                     /* The exact name of the Cygwin DLL has changed with
+                        various releases, but hopefully this will be
+                        reasonably future-proof.  */
+                     if (strncmp (dllname, "cygwin", 6) == 0)
+                       {
+                         *is_cygnus_app = TRUE;
+                         break;
+                       }
+                     else if (strncmp (dllname, "msys-", 5) == 0)
+                       {
+                         /* This catches both MSYS 1.x and MSYS2
+                            executables (the DLL name is msys-1.0.dll and
+                            msys-2.0.dll, respectively).  There doesn't
+                            seem to be a reason to distinguish between
+                            the two, for now.  */
+                         *is_msys_app = TRUE;
+                         break;
+                       }
                    }
-                }
+               }
             }
        }
     }
diff --git a/src/w32term.c b/src/w32term.c
index c37805c..0f7bb93 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -6110,7 +6110,7 @@ x_calc_absolute_position (struct frame *f)
 
           list = CDR(list);
 
-          geometry = Fassoc (Qgeometry, attributes);
+          geometry = Fassoc (Qgeometry, attributes, Qnil);
           if (!NILP (geometry))
             {
               monitor_left = Fnth (make_number (1), geometry);
diff --git a/src/xdisp.c b/src/xdisp.c
index 1c316fa..422912e 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -290,6 +290,7 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include <stdio.h>
 #include <stdlib.h>
 #include <limits.h>
+#include <math.h>
 
 #include "lisp.h"
 #include "atimer.h"
@@ -324,7 +325,7 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
 #endif
 
-#define INFINITY 10000000
+#define DISP_INFINITY 10000000
 
 /* Holds the list (error).  */
 static Lisp_Object list_of_error;
@@ -832,6 +833,8 @@ static bool cursor_row_fully_visible_p (struct window *, 
bool, bool);
 static bool update_menu_bar (struct frame *, bool, bool);
 static bool try_window_reusing_current_matrix (struct window *);
 static int try_window_id (struct window *);
+static void maybe_produce_line_number (struct it *);
+static bool should_produce_line_number (struct it *);
 static bool display_line (struct it *, int);
 static int display_mode_lines (struct window *);
 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
@@ -843,6 +846,8 @@ static const char *decode_mode_spec (struct window *, int, 
int, Lisp_Object *);
 static void display_menu_bar (struct window *);
 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
                                      ptrdiff_t *);
+static void pint2str (register char *, register int, register ptrdiff_t);
+
 static int display_string (const char *, Lisp_Object, Lisp_Object,
                            ptrdiff_t, ptrdiff_t, struct it *, int, int, int, 
int);
 static void compute_line_metrics (struct it *);
@@ -1321,6 +1326,15 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int 
*x, int *y,
   if (charpos >= 0 && CHARPOS (top) > charpos)
     return visible_p;
 
+  /* Some Lisp hook could call us in the middle of redisplaying this
+     very window.  If, by some bad luck, we are retrying redisplay
+     because we found that the mode-line height and/or header-line
+     height needs to be updated, the assignment of mode_line_height
+     and header_line_height below could disrupt that, due to the
+     selected/nonselected window dance during mode-line display, and
+     we could infloop.  Avoid that.  */
+  int prev_mode_line_height = w->mode_line_height;
+  int prev_header_line_height = w->header_line_height;
   /* Compute exact mode line heights.  */
   if (window_wants_mode_line (w))
     {
@@ -1667,6 +1681,10 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int 
*x, int *y,
     fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
 #endif
 
+  /* Restore potentially overwritten values.  */
+  w->mode_line_height = prev_mode_line_height;
+  w->header_line_height = prev_header_line_height;
+
   return visible_p;
 }
 
@@ -6764,7 +6782,7 @@ reseat_to_string (struct it *it, const char *s, 
Lisp_Object string,
      FIELD_WIDTH < 0 means infinite field width.  This is useful for
      padding with `-' at the end of a mode line.  */
   if (field_width < 0)
-    field_width = INFINITY;
+    field_width = DISP_INFINITY;
   /* Implementation note: We deliberately don't enlarge
      it->bidi_it.string.schars here to fit it->end_charpos, because
      the bidi iterator cannot produce characters out of thin air.  */
@@ -8613,6 +8631,7 @@ move_it_in_display_line_to (struct it *it,
   ptrdiff_t closest_pos UNINIT;
   ptrdiff_t prev_pos = IT_CHARPOS (*it);
   bool saw_smaller_pos = prev_pos < to_charpos;
+  bool line_number_pending = false;
 
   /* Don't produce glyphs in produce_glyphs.  */
   saved_glyph_row = it->glyph_row;
@@ -8661,9 +8680,20 @@ move_it_in_display_line_to (struct it *it,
        || (it->method == GET_FROM_DISPLAY_VECTOR               \
           && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
 
-  /* If there's a line-/wrap-prefix, handle it.  */
-  if (it->hpos == 0 && it->method == GET_FROM_BUFFER)
-    handle_line_prefix (it);
+  if (it->hpos == 0)
+    {
+      /* If line numbers are being displayed, produce a line number.  */
+      if (should_produce_line_number (it))
+       {
+         if (it->current_x == it->first_visible_x)
+           maybe_produce_line_number (it);
+         else
+           line_number_pending = true;
+       }
+      /* If there's a line-/wrap-prefix, handle it.  */
+      if (it->method == GET_FROM_BUFFER)
+       handle_line_prefix (it);
+    }
 
   if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
     SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
@@ -9030,6 +9060,15 @@ move_it_in_display_line_to (struct it *it,
 
              if (new_x > it->first_visible_x)
                {
+                 /* If we have reached the visible portion of the
+                    screen line, produce the line number if needed.  */
+                 if (line_number_pending)
+                   {
+                     line_number_pending = false;
+                     it->current_x = it->first_visible_x;
+                     maybe_produce_line_number (it);
+                     it->current_x += new_x - it->first_visible_x;
+                   }
                  /* Glyph is visible.  Increment number of glyphs that
                     would be displayed.  */
                  ++it->hpos;
@@ -13069,6 +13108,43 @@ hscroll_window_tree (Lisp_Object window)
            }
          bool row_r2l_p = cursor_row->reversed_p;
          bool hscl = hscrolling_current_line_p (w);
+         int x_offset = 0;
+         /* When line numbers are displayed, we need to account for
+            the horizontal space they consume.  */
+         if (!NILP (Vdisplay_line_numbers))
+           {
+             struct glyph *g;
+             if (!row_r2l_p)
+               {
+                 for (g = cursor_row->glyphs[TEXT_AREA];
+                      g < cursor_row->glyphs[TEXT_AREA]
+                        + cursor_row->used[TEXT_AREA];
+                      g++)
+                   {
+                     if (!(NILP (g->object) && g->charpos < 0))
+                       break;
+                     x_offset += g->pixel_width;
+                   }
+               }
+             else
+               {
+                 for (g = cursor_row->glyphs[TEXT_AREA]
+                        + cursor_row->used[TEXT_AREA];
+                      g > cursor_row->glyphs[TEXT_AREA];
+                      g--)
+                   {
+                     if (!(NILP ((g - 1)->object) && (g - 1)->charpos < 0))
+                       break;
+                     x_offset += (g - 1)->pixel_width;
+                   }
+               }
+           }
+         if (cursor_row->truncated_on_left_p)
+           {
+             /* On TTY frames, don't count the left truncation glyph.  */
+             struct frame *f = XFRAME (WINDOW_FRAME (w));
+             x_offset -= (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
+           }
 
          text_area_width = window_box_width (w, TEXT_AREA);
 
@@ -13101,7 +13177,7 @@ hscroll_window_tree (Lisp_Object window)
                 inside the left margin and the window is already
                 hscrolled.  */
              && ((!row_r2l_p
-                  && ((w->hscroll && w->cursor.x <= h_margin)
+                  && ((w->hscroll && w->cursor.x <= h_margin + x_offset)
                       || (cursor_row->enabled_p
                           && cursor_row->truncated_on_right_p
                           && (w->cursor.x >= text_area_width - h_margin))))
@@ -13119,7 +13195,8 @@ hscroll_window_tree (Lisp_Object window)
                           && cursor_row->truncated_on_right_p
                           && w->cursor.x <= h_margin)
                          || (w->hscroll
-                             && (w->cursor.x >= text_area_width - h_margin))))
+                             && (w->cursor.x >= (text_area_width - h_margin
+                                                 - x_offset)))))
                  /* This last condition is needed when moving
                     vertically from an hscrolled line to a short line
                     that doesn't need to be hscrolled.  If we omit
@@ -13150,7 +13227,7 @@ hscroll_window_tree (Lisp_Object window)
              if (hscl)
                it.first_visible_x = window_hscroll_limited (w, it.f)
                                     * FRAME_COLUMN_WIDTH (it.f);
-             it.last_visible_x = INFINITY;
+             it.last_visible_x = DISP_INFINITY;
              move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
              /* If the line ends in an overlay string with a newline,
                 we might infloop, because displaying the window will
@@ -14796,15 +14873,12 @@ set_cursor_from_row (struct window *w, struct 
glyph_row *row,
          while (glyph > end + 1
                 && NILP (glyph->object)
                 && glyph->charpos < 0)
-           {
-             --glyph;
-             x -= glyph->pixel_width;
-           }
+           --glyph;
          if (NILP (glyph->object) && glyph->charpos < 0)
            --glyph;
          /* By default, in reversed rows we put the cursor on the
             rightmost (first in the reading order) glyph.  */
-         for (g = end + 1; g < glyph; g++)
+         for (x = 0, g = end + 1; g < glyph; g++)
            x += g->pixel_width;
          while (end < glyph
                 && NILP ((end + 1)->object)
@@ -15835,7 +15909,7 @@ compute_window_start_on_continuation_line (struct 
window *w)
             So, we're looking for the display line start with the
             minimum distance from the old window start.  */
          pos_before_pt = pos = it.current.pos;
-         min_distance = INFINITY;
+         min_distance = DISP_INFINITY;
          while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
                 distance < min_distance)
            {
@@ -15941,6 +16015,17 @@ try_cursor_movement (Lisp_Object window, struct 
text_pos startp,
       && !windows_or_buffers_changed
       && !f->cursor_type_changed
       && NILP (Vshow_trailing_whitespace)
+      /* When display-line-numbers is in relative mode, moving point
+        requires to redraw the entire window.  */
+      && !EQ (Vdisplay_line_numbers, Qrelative)
+      && !EQ (Vdisplay_line_numbers, Qvisual)
+      /* When the current line number should be displayed in a
+        distinct face, moving point cannot be handled in optimized
+        way as below.  */
+      && !(!NILP (Vdisplay_line_numbers)
+          && NILP (Finternal_lisp_face_equal_p (Qline_number,
+                                                Qline_number_current_line,
+                                                w->frame)))
       /* This code is not used for mini-buffer for the sake of the case
         of redisplaying to replace an echo area message; since in
         that case the mini-buffer contents per se are usually
@@ -16788,10 +16873,15 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
          XBUFFER (w->contents)->text->redisplay = false;
          safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
 
-         if (w->redisplay || XBUFFER (w->contents)->text->redisplay)
+         if (w->redisplay || XBUFFER (w->contents)->text->redisplay
+             || ((EQ (Vdisplay_line_numbers, Qrelative)
+                  || EQ (Vdisplay_line_numbers, Qvisual))
+                 && row != MATRIX_FIRST_TEXT_ROW (w->desired_matrix)))
            {
-             /* pre-redisplay-function made changes (e.g. move the region)
-                that require another round of redisplay.  */
+             /* Either pre-redisplay-function made changes (e.g. move
+                the region), or we moved point in a window that is
+                under display-line-numbers = relative mode.  We need
+                another round of redisplay.  */
              clear_glyph_matrix (w->desired_matrix);
              if (!try_window (window, startp, 0))
                goto need_larger_matrices;
@@ -17592,15 +17682,21 @@ try_window_reusing_current_matrix (struct window *w)
   if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
     return false;
 
+  /* Clear the desired matrix for the display below.  */
+  clear_glyph_matrix (w->desired_matrix);
+
+  /* Give up if line numbers are being displayed, because reusing the
+     current matrix might use the wrong width for line-number
+     display.  */
+  if (!NILP (Vdisplay_line_numbers))
+    return false;
+
   /* The variable new_start now holds the new window start.  The old
      start `start' can be determined from the current matrix.  */
   SET_TEXT_POS_FROM_MARKER (new_start, w->start);
   start = start_row->minpos;
   start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
 
-  /* Clear the desired matrix for the display below.  */
-  clear_glyph_matrix (w->desired_matrix);
-
   if (CHARPOS (new_start) <= CHARPOS (start))
     {
       /* Don't use this method if the display starts with an ellipsis
@@ -18423,6 +18519,16 @@ try_window_id (struct window *w)
   if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing)))
     GIVE_UP (23);
 
+  /* Give up if display-line-numbers is in relative mode, or when the
+     current line's number needs to be displayed in a distinct face.  */
+  if (EQ (Vdisplay_line_numbers, Qrelative)
+      || EQ (Vdisplay_line_numbers, Qvisual)
+      || (!NILP (Vdisplay_line_numbers)
+         && NILP (Finternal_lisp_face_equal_p (Qline_number,
+                                               Qline_number_current_line,
+                                               w->frame))))
+    GIVE_UP (24);
+
   /* Make sure beg_unchanged and end_unchanged are up to date.  Do it
      only if buffer has really changed.  The reason is that the gap is
      initially at Z for freshly visited files.  The code below would
@@ -19070,7 +19176,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, 
int area)
       || glyph->type == GLYPHLESS_GLYPH)
     {
       fprintf (stderr,
-              "  %5"pD"d     %c %9"pI"d   %c %3d 0x%06x      %c %4d 
%1.1d%1.1d\n",
+              "  %5"pD"d     %c %9"pD"d   %c %3d 0x%06x      %c %4d 
%1.1d%1.1d\n",
               glyph - row->glyphs[TEXT_AREA],
               (glyph->type == CHAR_GLYPH
                ? 'C'
@@ -19095,7 +19201,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, 
int area)
   else if (glyph->type == STRETCH_GLYPH)
     {
       fprintf (stderr,
-              "  %5"pD"d     %c %9"pI"d   %c %3d 0x%06x      %c %4d 
%1.1d%1.1d\n",
+              "  %5"pD"d     %c %9"pD"d   %c %3d 0x%06x      %c %4d 
%1.1d%1.1d\n",
               glyph - row->glyphs[TEXT_AREA],
               'S',
               glyph->charpos,
@@ -19116,7 +19222,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, 
int area)
   else if (glyph->type == IMAGE_GLYPH)
     {
       fprintf (stderr,
-              "  %5"pD"d     %c %9"pI"d   %c %3d 0x%06x      %c %4d 
%1.1d%1.1d\n",
+              "  %5"pD"d     %c %9"pD"d   %c %3d 0x%06x      %c %4d 
%1.1d%1.1d\n",
               glyph - row->glyphs[TEXT_AREA],
               'I',
               glyph->charpos,
@@ -19137,7 +19243,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, 
int area)
   else if (glyph->type == COMPOSITE_GLYPH)
     {
       fprintf (stderr,
-              "  %5"pD"d     %c %9"pI"d   %c %3d 0x%06x",
+              "  %5"pD"d     %c %9"pD"d   %c %3d 0x%06x",
               glyph - row->glyphs[TEXT_AREA],
               '+',
               glyph->charpos,
@@ -19198,7 +19304,7 @@ dump_glyph_row (struct glyph_row *row, int vpos, int 
glyphs)
       fprintf (stderr, "Row     Start       End Used oE><\\CTZFesm     X    Y  
  W    H    V    A    P\n");
       fprintf (stderr, 
"==============================================================================\n");
 
-      fprintf (stderr, "%3d %9"pI"d %9"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
+      fprintf (stderr, "%3d %9"pD"d %9"pD"d %4d %1.1d%1.1d%1.1d%1.1d\
 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d  %4d %4d %4d %4d %4d %4d %4d\n",
               vpos,
               MATRIX_ROW_START_CHARPOS (row),
@@ -19227,7 +19333,7 @@ dump_glyph_row (struct glyph_row *row, int vpos, int 
glyphs)
       fprintf (stderr, "    %9"pD"d %9"pD"d\t%5d\n", 
row->start.overlay_string_index,
               row->end.overlay_string_index,
               row->continuation_lines_width);
-      fprintf (stderr, "    %9"pI"d %9"pI"d\n",
+      fprintf (stderr, "    %9"pD"d %9"pD"d\n",
               CHARPOS (row->start.string_pos),
               CHARPOS (row->end.string_pos));
       fprintf (stderr, "    %9d %9d\n", row->start.dpvec_index,
@@ -19304,7 +19410,7 @@ with numeric argument, its value is passed as the 
GLYPHS flag.  */)
   struct window *w = XWINDOW (selected_window);
   struct buffer *buffer = XBUFFER (w->contents);
 
-  fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
+  fprintf (stderr, "PT = %"pD"d, BEGV = %"pD"d. ZV = %"pD"d\n",
           BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
   fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
           w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
@@ -20669,6 +20775,366 @@ find_row_edges (struct it *it, struct glyph_row *row,
     row->maxpos = it->current.pos;
 }
 
+/* Like display_count_lines, but capable of counting outside of the
+   current narrowed region.  */
+static ptrdiff_t
+display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
+                              ptrdiff_t count, ptrdiff_t *byte_pos_ptr)
+{
+  if (!display_line_numbers_widen || (BEGV == BEG && ZV == Z))
+    return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
+
+  ptrdiff_t val;
+  ptrdiff_t pdl_count = SPECPDL_INDEX ();
+  record_unwind_protect (save_restriction_restore, save_restriction_save ());
+  Fwiden ();
+  val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
+  unbind_to (pdl_count, Qnil);
+  return val;
+}
+
+/* Count the number of screen lines in window IT->w between character
+   position IT_CHARPOS(*IT) and the line showing that window's point.  */
+static ptrdiff_t
+display_count_lines_visually (struct it *it)
+{
+  struct it tem_it;
+  ptrdiff_t to;
+  struct text_pos from;
+
+  /* If we already calculated a relative line number, use that.  This
+     trick relies on the fact that visual lines (a.k.a. "glyph rows")
+     are laid out sequentially, one by one, for each sequence of calls
+     to display_line or other similar function that follows a call to
+     init_iterator.  */
+  if (it->lnum_bytepos > 0)
+    return it->lnum + 1;
+  else
+    {
+      ptrdiff_t count = SPECPDL_INDEX ();
+
+      if (IT_CHARPOS (*it) <= PT)
+       {
+         from = it->current.pos;
+         to = PT;
+       }
+      else
+       {
+         SET_TEXT_POS (from, PT, PT_BYTE);
+         to = IT_CHARPOS (*it);
+       }
+      start_display (&tem_it, it->w, from);
+      /* Need to disable visual mode temporarily, since otherwise the
+        call to move_it_to will cause infinite recursion.  */
+      specbind (Qdisplay_line_numbers, Qrelative);
+      /* Some redisplay optimizations could invoke us very far from
+        PT, which will make the caller painfully slow.  There should
+        be no need to go too far beyond the window's bottom, as any
+        such optimization will fail to show point anyway.  */
+      move_it_to (&tem_it, to, -1,
+                 tem_it.last_visible_y
+                 + (SCROLL_LIMIT + 10) * FRAME_LINE_HEIGHT (tem_it.f),
+                 -1, MOVE_TO_POS | MOVE_TO_Y);
+      unbind_to (count, Qnil);
+      return IT_CHARPOS (*it) <= PT ? -tem_it.vpos : tem_it.vpos;
+    }
+}
+
+/* Produce the line-number glyphs for the current glyph_row.  If
+   IT->glyph_row is non-NULL, populate the row with the produced
+   glyphs.  */
+static void
+maybe_produce_line_number (struct it *it)
+{
+  ptrdiff_t last_line = it->lnum;
+  ptrdiff_t start_from, bytepos;
+  ptrdiff_t this_line;
+  bool first_time = false;
+  ptrdiff_t beg_byte = display_line_numbers_widen ? BEG_BYTE : BEGV_BYTE;
+  ptrdiff_t z_byte = display_line_numbers_widen ? Z_BYTE : ZV_BYTE;
+  void *itdata = bidi_shelve_cache ();
+
+  if (EQ (Vdisplay_line_numbers, Qvisual))
+    this_line = display_count_lines_visually (it);
+  else
+    {
+      if (!last_line)
+       {
+         /* If possible, reuse data cached by line-number-mode.  */
+         if (it->w->base_line_number > 0
+             && it->w->base_line_pos > 0
+             && it->w->base_line_pos <= IT_CHARPOS (*it)
+             /* line-number-mode always displays narrowed line
+                numbers, so we cannot use its data if the user wants
+                line numbers that disregard narrowing.  */
+             && !(display_line_numbers_widen
+                  && (BEG_BYTE != BEGV_BYTE || Z_BYTE != ZV_BYTE)))
+           {
+             start_from = CHAR_TO_BYTE (it->w->base_line_pos);
+             last_line = it->w->base_line_number - 1;
+           }
+         else
+           start_from = beg_byte;
+         if (!it->lnum_bytepos)
+           first_time = true;
+       }
+      else
+       start_from = it->lnum_bytepos;
+
+      /* Paranoia: what if someone changes the narrowing since the
+        last time display_line was called?  Shouldn't really happen,
+        but who knows what some crazy Lisp invoked by :eval could do?  */
+      if (!(beg_byte <= start_from && start_from <= z_byte))
+       {
+         last_line = 0;
+         start_from = beg_byte;
+       }
+
+      this_line =
+       last_line + display_count_lines_logically (start_from,
+                                                  IT_BYTEPOS (*it),
+                                                  IT_CHARPOS (*it), &bytepos);
+      eassert (this_line > 0 || (this_line == 0 && start_from == beg_byte));
+      eassert (bytepos == IT_BYTEPOS (*it));
+    }
+
+  /* Record the line number information.  */
+  if (this_line != last_line || !it->lnum_bytepos)
+    {
+      it->lnum = this_line;
+      it->lnum_bytepos = IT_BYTEPOS (*it);
+    }
+
+  /* Produce the glyphs for the line number.  */
+  struct it tem_it;
+  char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
+  bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false;
+  ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
+  int lnum_face_id = merge_faces (it->f, Qline_number, 0, DEFAULT_FACE_ID);
+  int current_lnum_face_id
+    = merge_faces (it->f, Qline_number_current_line, 0, DEFAULT_FACE_ID);
+  /* Compute point's line number if needed.  */
+  if ((EQ (Vdisplay_line_numbers, Qrelative)
+       || EQ (Vdisplay_line_numbers, Qvisual)
+       || lnum_face_id != current_lnum_face_id)
+      && !it->pt_lnum)
+    {
+      ptrdiff_t ignored;
+      if (PT_BYTE > it->lnum_bytepos && !EQ (Vdisplay_line_numbers, Qvisual))
+       it->pt_lnum =
+         this_line + display_count_lines_logically (it->lnum_bytepos, PT_BYTE,
+                                                    PT, &ignored);
+      else
+       it->pt_lnum = display_count_lines_logically (beg_byte, PT_BYTE, PT,
+                                                    &ignored);
+    }
+  /* Compute the required width if needed.  */
+  if (!it->lnum_width)
+    {
+      if (NATNUMP (Vdisplay_line_numbers_width))
+       it->lnum_width = XFASTINT (Vdisplay_line_numbers_width);
+
+      /* Max line number to be displayed cannot be more than the one
+        corresponding to the last row of the desired matrix.  */
+      ptrdiff_t max_lnum;
+
+      if (NILP (Vdisplay_line_numbers_current_absolute)
+         && (EQ (Vdisplay_line_numbers, Qrelative)
+             || EQ (Vdisplay_line_numbers, Qvisual)))
+       /* We subtract one more because the current line is always
+          zero in this mode.  */
+       max_lnum = it->w->desired_matrix->nrows - 2;
+      else if (EQ (Vdisplay_line_numbers, Qvisual))
+       max_lnum = it->pt_lnum + it->w->desired_matrix->nrows - 1;
+      else
+       max_lnum = this_line + it->w->desired_matrix->nrows - 1 - it->vpos;
+      max_lnum = max (1, max_lnum);
+      it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1);
+      eassert (it->lnum_width > 0);
+    }
+  if (EQ (Vdisplay_line_numbers, Qrelative))
+    lnum_offset = it->pt_lnum;
+  else if (EQ (Vdisplay_line_numbers, Qvisual))
+    lnum_offset = 0;
+
+  /* Under 'relative', display the absolute line number for the
+     current line, unless the user requests otherwise.  */
+  ptrdiff_t lnum_to_display = eabs (this_line - lnum_offset);
+  if ((EQ (Vdisplay_line_numbers, Qrelative)
+       || EQ (Vdisplay_line_numbers, Qvisual))
+      && lnum_to_display == 0
+      && !NILP (Vdisplay_line_numbers_current_absolute))
+    lnum_to_display = it->pt_lnum + 1;
+  /* In L2R rows we need to append the blank separator, in R2L
+     rows we need to prepend it.  But this function is usually
+     called when no display elements were produced from the
+     following line, so the paragraph direction might be unknown.
+     Therefore we cheat and add 2 blanks, one on either side.  */
+  pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
+  strcat (lnum_buf, " ");
+
+  /* Setup for producing the glyphs.  */
+  init_iterator (&tem_it, it->w, -1, -1, &scratch_glyph_row,
+                /* FIXME: Use specialized face.  */
+                DEFAULT_FACE_ID);
+  scratch_glyph_row.reversed_p = false;
+  scratch_glyph_row.used[TEXT_AREA] = 0;
+  SET_TEXT_POS (tem_it.position, 0, 0);
+  tem_it.avoid_cursor_p = true;
+  tem_it.bidi_p = true;
+  tem_it.bidi_it.type = WEAK_EN;
+  /* According to UAX#9, EN goes up 2 levels in L2R paragraph and
+     1 level in R2L paragraphs.  Emulate that, assuming we are in
+     an L2R paragraph.  */
+  tem_it.bidi_it.resolved_level = 2;
+
+  /* Produce glyphs for the line number in a scratch glyph_row.  */
+  int n_glyphs_before;
+  for (const char *p = lnum_buf; *p; p++)
+    {
+      /* For continuation lines and lines after ZV, instead of a line
+        number, produce a blank prefix of the same width.  Use the
+        default face for the blank field beyond ZV.  */
+      if (beyond_zv)
+       tem_it.face_id = it->base_face_id;
+      else if (lnum_face_id != current_lnum_face_id
+              && (EQ (Vdisplay_line_numbers, Qvisual)
+                  ? this_line == 0
+                  : this_line == it->pt_lnum))
+       tem_it.face_id = current_lnum_face_id;
+      else
+       tem_it.face_id = lnum_face_id;
+      if (beyond_zv
+         /* Don't display the same line number more than once.  */
+         || (!EQ (Vdisplay_line_numbers, Qvisual)
+             && (it->continuation_lines_width > 0
+                 || (this_line == last_line && !first_time))))
+       tem_it.c = tem_it.char_to_display = ' ';
+      else
+       tem_it.c = tem_it.char_to_display = *p;
+      tem_it.len = 1;
+      n_glyphs_before = scratch_glyph_row.used[TEXT_AREA];
+      /* Make sure these glyphs will have a "position" of -1.  */
+      SET_TEXT_POS (tem_it.position, -1, -1);
+      PRODUCE_GLYPHS (&tem_it);
+
+      /* Stop producing glyphs if we don't have enough space on
+        this line.  FIXME: should we refrain from producing the
+        line number at all in that case?  */
+      if (tem_it.current_x > tem_it.last_visible_x)
+       {
+         scratch_glyph_row.used[TEXT_AREA] = n_glyphs_before;
+         break;
+       }
+    }
+
+  /* Record the width in pixels we need for the line number display.  */
+  it->lnum_pixel_width = tem_it.current_x;
+  /* Copy the produced glyphs into IT's glyph_row.  */
+  struct glyph *g = scratch_glyph_row.glyphs[TEXT_AREA];
+  struct glyph *e = g + scratch_glyph_row.used[TEXT_AREA];
+  struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL;
+  short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL;
+
+  eassert (it->glyph_row == NULL || it->glyph_row->used[TEXT_AREA] == 0);
+
+  for ( ; g < e; g++)
+    {
+      it->current_x += g->pixel_width;
+      /* The following is important when this function is called
+        from move_it_in_display_line_to: HPOS is incremented only
+        when we are in the visible portion of the glyph row.  */
+      if (it->current_x > it->first_visible_x)
+       it->hpos++;
+      if (p)
+       {
+         *p++ = *g;
+         (*u)++;
+       }
+    }
+
+  /* Update IT's metrics due to glyphs produced for line numbers.  */
+  if (it->glyph_row)
+    {
+      struct glyph_row *row = it->glyph_row;
+
+      it->max_ascent = max (row->ascent, tem_it.max_ascent);
+      it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
+      it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
+      it->max_phys_descent = max (row->phys_height - row->phys_ascent,
+                                 tem_it.max_phys_descent);
+    }
+  else
+    {
+      it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
+      it->max_descent = max (it->max_descent, tem_it.max_descent);
+      it->max_phys_ascent = max (it->max_phys_ascent, tem_it.max_phys_ascent);
+      it->max_phys_descent = max (it->max_phys_descent, 
tem_it.max_phys_descent);
+    }
+
+  bidi_unshelve_cache (itdata, false);
+}
+
+/* Return true if this glyph row needs a line number to be produced
+   for it.  */
+static bool
+should_produce_line_number (struct it *it)
+{
+  if (NILP (Vdisplay_line_numbers))
+    return false;
+
+  /* Don't display line numbers in minibuffer windows.  */
+  if (MINI_WINDOW_P (it->w))
+    return false;
+
+#ifdef HAVE_WINDOW_SYSTEM
+  /* Don't display line number in tooltip frames.  */
+  if (FRAMEP (tip_frame) && EQ (WINDOW_FRAME (it->w), tip_frame))
+    return false;
+#endif
+
+  /* If the character at current position has a non-nil special
+     property, disable line numbers for this row.  This is for
+     packages such as company-mode, which need this for their tricky
+     layout, where line numbers get in the way.  */
+  Lisp_Object val = Fget_char_property (make_number (IT_CHARPOS (*it)),
+                                       Qdisplay_line_numbers_disable,
+                                       it->window);
+  /* For ZV, we need to also look in empty overlays at that point,
+     because get-char-property always returns nil for ZV, except if
+     the property is in 'default-text-properties'.  */
+  if (NILP (val) && IT_CHARPOS (*it) >= ZV)
+    val = disable_line_numbers_overlay_at_eob ();
+  return NILP (val) ? true : false;
+}
+
+/* Return true if ROW has no glyphs except those inserted by the
+   display engine.  This is needed for indicate-empty-lines and
+   similar features when the glyph row starts with glyphs which didn't
+   come from buffer or string.  */
+static bool
+row_text_area_empty (struct glyph_row *row)
+{
+  if (!row->reversed_p)
+    {
+      for (struct glyph *g = row->glyphs[TEXT_AREA];
+          g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
+          g++)
+       if (!NILP (g->object) || g->charpos > 0)
+         return false;
+    }
+  else
+    {
+      for (struct glyph *g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
+          g > row->glyphs[TEXT_AREA];
+          g--)
+       if (!NILP ((g - 1)->object) || (g - 1)->charpos > 0)
+         return false;
+    }
+
+  return true;
+}
+
 /* Construct the glyph row IT->glyph_row in the desired matrix of
    IT->w from text at the current position of IT.  See dispextern.h
    for an overview of struct it.  Value is true if
@@ -20739,6 +21205,8 @@ display_line (struct it *it, int cursor_vpos)
       (window_hscroll_limited (it->w, it->f) - it->w->min_hscroll)
       * FRAME_COLUMN_WIDTH (it->f);
 
+  bool line_number_needed = should_produce_line_number (it);
+
   /* Move over display elements that are not visible because we are
      hscrolled.  This may stop at an x-position < first_visible_x
      if the first glyph is partially visible or if we hit a line end.  */
@@ -20774,9 +21242,17 @@ display_line (struct it *it, int cursor_vpos)
         are hscrolled to the left of the left edge of the window.  */
       min_pos = CHARPOS (this_line_min_pos);
       min_bpos = BYTEPOS (this_line_min_pos);
+
+      /* Produce line number, if needed.  */
+      if (line_number_needed)
+       maybe_produce_line_number (it);
     }
   else if (it->area == TEXT_AREA)
     {
+      /* Line numbers should precede the line-prefix or wrap-prefix.  */
+      if (line_number_needed)
+       maybe_produce_line_number (it);
+
       /* We only do this when not calling move_it_in_display_line_to
         above, because that function calls itself handle_line_prefix.  */
       handle_line_prefix (it);
@@ -20838,6 +21314,7 @@ display_line (struct it *it, int cursor_vpos)
         buffer reached.  */
       if (!get_next_display_element (it))
        {
+         bool row_has_glyphs = false;
          /* Maybe add a space at the end of this line that is used to
             display the cursor there under X.  Set the charpos of the
             first glyph of blank lines not corresponding to any text
@@ -20846,14 +21323,17 @@ display_line (struct it *it, int cursor_vpos)
            row->exact_window_width_line_p = true;
          else if ((append_space_for_newline (it, true)
                    && row->used[TEXT_AREA] == 1)
-                  || row->used[TEXT_AREA] == 0)
+                  || row->used[TEXT_AREA] == 0
+                  || (row_has_glyphs = row_text_area_empty (row)))
            {
              row->glyphs[TEXT_AREA]->charpos = -1;
-             row->displays_text_p = false;
+             /* Don't reset the displays_text_p flag if we are
+                displaying line numbers or line-prefix.  */
+             if (!row_has_glyphs)
+               row->displays_text_p = false;
 
              if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
-                 && (!MINI_WINDOW_P (it->w)
-                     || (minibuf_level && EQ (it->window, minibuf_window))))
+                 && (!MINI_WINDOW_P (it->w)))
                row->indicate_empty_line_p = true;
            }
 
@@ -20935,6 +21415,10 @@ display_line (struct it *it, int cursor_vpos)
             process the prefix now.  */
          if (it->area == TEXT_AREA && pending_handle_line_prefix)
            {
+             /* Line numbers should precede the line-prefix or wrap-prefix.  */
+             if (line_number_needed)
+               maybe_produce_line_number (it);
+
              pending_handle_line_prefix = false;
              handle_line_prefix (it);
            }
@@ -22006,7 +22490,7 @@ Value is the new character position of point.  */)
         reach point, in order to start from its X coordinate.  So we
         need to disregard the window's horizontal extent in that case.  */
       if (it.line_wrap == TRUNCATE)
-       it.last_visible_x = INFINITY;
+       it.last_visible_x = DISP_INFINITY;
 
       if (it.cmp_it.id < 0
          && it.method == GET_FROM_STRING
@@ -22099,7 +22583,7 @@ Value is the new character position of point.  */)
            {
              start_display (&it, w, pt);
              if (it.line_wrap == TRUNCATE)
-               it.last_visible_x = INFINITY;
+               it.last_visible_x = DISP_INFINITY;
              reseat_at_previous_visible_line_start (&it);
              it.current_x = it.current_y = it.hpos = 0;
              if (pt_vpos != 0)
@@ -22859,7 +23343,7 @@ display_mode_element (struct it *it, int depth, int 
field_width, int precision,
                    props = oprops;
                  }
 
-               aelt = Fassoc (elt, mode_line_proptrans_alist);
+               aelt = Fassoc (elt, mode_line_proptrans_alist, Qnil);
                if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
                  {
                    /* AELT is what we want.  Move it to the front
@@ -27616,6 +28100,10 @@ x_produce_glyphs (struct it *it)
            {
              int tab_width = it->tab_width * font->space_width;
              int x = it->current_x + it->continuation_lines_width;
+             int x0 = x;
+             /* Adjust for line numbers, if needed.   */
+             if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width)
+               x -= it->lnum_pixel_width;
              int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * 
tab_width;
 
              /* If the distance from the current position to the next tab
@@ -27623,8 +28111,12 @@ x_produce_glyphs (struct it *it)
                 tab stop after that.  */
              if (next_tab_x - x < font->space_width)
                next_tab_x += tab_width;
+             if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width)
+               next_tab_x += (it->lnum_pixel_width
+                              - ((it->w->hscroll * font->space_width)
+                                 % tab_width));
 
-             it->pixel_width = next_tab_x - x;
+             it->pixel_width = next_tab_x - x0;
              it->nglyphs = 1;
              if (FONT_TOO_HIGH (font))
                {
@@ -28325,7 +28817,7 @@ set_frame_cursor_types (struct frame *f, Lisp_Object 
arg)
 
   /* By default, set up the blink-off state depending on the on-state.  */
 
-  tem = Fassoc (arg, Vblink_cursor_alist);
+  tem = Fassoc (arg, Vblink_cursor_alist, Qnil);
   if (!NILP (tem))
     {
       FRAME_BLINK_OFF_CURSOR (f)
@@ -28463,7 +28955,7 @@ get_window_cursor_type (struct window *w, struct glyph 
*glyph, int *width,
   /* Cursor is blinked off, so determine how to "toggle" it.  */
 
   /* First look for an entry matching the buffer's cursor-type in 
blink-cursor-alist.  */
-  if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP 
(alt_cursor)))
+  if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist, Qnil), 
!NILP (alt_cursor)))
     return get_specified_cursor_type (XCDR (alt_cursor), width);
 
   /* Then see if frame has specified a specific blink off cursor type.  */
@@ -31708,6 +32200,12 @@ They are still logged to the *Messages* buffer.  */);
   /* Name of the face used to highlight trailing whitespace.  */
   DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
 
+  /* Names of the faces used to display line numbers.  */
+  DEFSYM (Qline_number, "line-number");
+  DEFSYM (Qline_number_current_line, "line-number-current-line");
+  /* Name of a text property which disables line-number display.  */
+  DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable");
+
   /* Name and number of the face used to highlight escape glyphs.  */
   DEFSYM (Qescape_glyph, "escape-glyph");
 
@@ -32215,6 +32713,54 @@ To add a prefix to continuation lines, use 
`wrap-prefix'.  */);
   DEFSYM (Qline_prefix, "line-prefix");
   Fmake_variable_buffer_local (Qline_prefix);
 
+  DEFVAR_LISP ("display-line-numbers", Vdisplay_line_numbers,
+    doc: /* Non-nil means display line numbers.
+If the value is t, display the absolute number of each line of a buffer
+shown in a window.  Absolute line numbers count from the beginning of
+the current narrowing, or from buffer beginning.  If the value is
+`relative', display for each line not containing the window's point its
+relative number instead, i.e. the number of the line relative to the
+line showing the window's point.
+
+In either case, line numbers are displayed at the beginning of each
+non-continuation line that displays buffer text, i.e. after each newline
+character that comes from the buffer.  The value `visual' is like
+`relative' but counts screen lines instead of buffer lines.  In practice
+this means that continuation lines count as well when calculating the
+relative number of a line.
+
+Lisp programs can disable display of a line number of a particular
+buffer line by putting the `display-line-numbers-disable' text property
+or overlay property on the first visible character of that line.  */);
+  Vdisplay_line_numbers = Qnil;
+  DEFSYM (Qdisplay_line_numbers, "display-line-numbers");
+  Fmake_variable_buffer_local (Qdisplay_line_numbers);
+  DEFSYM (Qrelative, "relative");
+  DEFSYM (Qvisual, "visual");
+
+  DEFVAR_LISP ("display-line-numbers-width", Vdisplay_line_numbers_width,
+    doc: /* Minimum width of space reserved for line number display.
+A positive number means reserve that many columns for line numbers,
+even if the actual number needs less space.
+The default value of nil means compute the space dynamically.
+Any other value is treated as nil.  */);
+  Vdisplay_line_numbers_width = Qnil;
+  DEFSYM (Qdisplay_line_numbers_width, "display-line-numbers-width");
+  Fmake_variable_buffer_local (Qdisplay_line_numbers_width);
+
+  DEFVAR_LISP ("display-line-numbers-current-absolute",
+              Vdisplay_line_numbers_current_absolute,
+    doc: /* Non-nil means display absolute number of current line.
+This variable has effect only when `display-line-numbers' is
+either `relative' or `visual'.  */);
+  Vdisplay_line_numbers_current_absolute = Qt;
+
+  DEFVAR_BOOL ("display-line-numbers-widen", display_line_numbers_widen,
+    doc: /* Non-nil means display line numbers disregarding any narrowing.  
*/);
+  display_line_numbers_widen = false;
+  DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen");
+  Fmake_variable_buffer_local (Qdisplay_line_numbers_widen);
+
   DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
     doc: /* Non-nil means don't eval Lisp during redisplay.  */);
   inhibit_eval_during_redisplay = false;
diff --git a/src/xfns.c b/src/xfns.c
index d8bf974..2f8c9c2 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -2062,7 +2062,7 @@ x_set_scroll_bar_default_width (struct frame *f)
   int unit = FRAME_COLUMN_WIDTH (f);
 #ifdef USE_TOOLKIT_SCROLL_BARS
 #ifdef USE_GTK
-  int minw = xg_get_default_scrollbar_width ();
+  int minw = xg_get_default_scrollbar_width (f);
 #else
   int minw = 16;
 #endif
@@ -2083,7 +2083,7 @@ x_set_scroll_bar_default_height (struct frame *f)
   int height = FRAME_LINE_HEIGHT (f);
 #ifdef USE_TOOLKIT_SCROLL_BARS
 #ifdef USE_GTK
-  int min_height = xg_get_default_scrollbar_height ();
+  int min_height = xg_get_default_scrollbar_height (f);
 #else
   int min_height = 16;
 #endif
diff --git a/src/xfont.c b/src/xfont.c
index b73596c..85fccf0 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -505,7 +505,8 @@ xfont_list (struct frame *f, Lisp_Object spec)
       Lisp_Object alter;
 
       if ((alter = Fassoc (SYMBOL_NAME (registry),
-                          Vface_alternative_font_registry_alist),
+                          Vface_alternative_font_registry_alist,
+                          Qnil),
           CONSP (alter)))
        {
          /* Pointer to REGISTRY-ENCODING field.  */
diff --git a/src/xmenu.c b/src/xmenu.c
index 6c8a0c5..64df151 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1271,6 +1271,11 @@ create_and_show_popup_menu (struct frame *f, 
widget_value *first_wv,
 
                              /* Child of win.  */
                              &dummy_window);
+#ifdef HAVE_GTK3
+      /* Use window scaling factor to adjust position for hidpi screens. */
+      x /= xg_get_scale (f);
+      y /= xg_get_scale (f);
+#endif
       unblock_input ();
       popup_x_y.x = x;
       popup_x_y.y = y;
diff --git a/test/Makefile.in b/test/Makefile.in
index 414eca9..ba823ec 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -136,7 +136,8 @@ endif
        $(AM_V_ELC)$(emacs) -f batch-byte-compile $<
 
 ## Save logs, and show logs for failed tests.
-WRITE_LOG = > $@ 2>&1 || { STAT=$$?; cat $@; exit $$STAT; }
+WRITE_LOG = $(if $(and ${EMACS_HYDRA_CI}, $(findstring tramp, $@)), |& tee $@, 
> $@ 2>&1) \
+               || { STAT=$$?; cat $@; exit $$STAT; }
 
 ifeq ($(TEST_LOAD_EL), yes)
 testloadfile = $*.el
diff --git a/test/data/emacs-module/mod-test.c 
b/test/data/emacs-module/mod-test.c
index eee9466..42e1c2b 100644
--- a/test/data/emacs-module/mod-test.c
+++ b/test/data/emacs-module/mod-test.c
@@ -235,6 +235,27 @@ Fmod_test_invalid_load (emacs_env *env, ptrdiff_t nargs, 
emacs_value *args,
   return invalid_stored_value;
 }
 
+/* An invalid finalizer: Finalizers are run during garbage collection,
+   where Lisp code can’t be executed.  -module-assertions tests for
+   this case.  */
+
+static emacs_env *current_env;
+
+static void
+invalid_finalizer (void *ptr)
+{
+  current_env->intern (current_env, "nil");
+}
+
+static emacs_value
+Fmod_test_invalid_finalizer (emacs_env *env, ptrdiff_t nargs, emacs_value 
*args,
+                             void *data)
+{
+  current_env = env;
+  env->make_user_ptr (env, invalid_finalizer, NULL);
+  return env->funcall (env, env->intern (env, "garbage-collect"), 0, NULL);
+}
+
 
 /* Lisp utilities for easier readability (simple wrappers).  */
 
@@ -300,6 +321,8 @@ emacs_module_init (struct emacs_runtime *ert)
   DEFUN ("mod-test-vector-eq", Fmod_test_vector_eq, 2, 2, NULL, NULL);
   DEFUN ("mod-test-invalid-store", Fmod_test_invalid_store, 0, 0, NULL, NULL);
   DEFUN ("mod-test-invalid-load", Fmod_test_invalid_load, 0, 0, NULL, NULL);
+  DEFUN ("mod-test-invalid-finalizer", Fmod_test_invalid_finalizer, 0, 0,
+         NULL, NULL);
 
 #undef DEFUN
 
diff --git a/test/lisp/dired-tests.el b/test/lisp/dired-tests.el
index 1b814ba..6933145 100644
--- a/test/lisp/dired-tests.el
+++ b/test/lisp/dired-tests.el
@@ -21,7 +21,7 @@
 (require 'ert)
 (require 'dired)
 (require 'nadvice)
-
+(require 'ls-lisp)
 
 (ert-deftest dired-autoload ()
   "Tests to see whether dired-x has been autoloaded"
@@ -38,19 +38,21 @@
          (file      "test")
          (full-name (expand-file-name file dir))
          (regexp    "bar")
-         (dired-always-read-filesystem t))
+         (dired-always-read-filesystem t) buffers)
     (if (file-exists-p dir)
         (delete-directory dir 'recursive))
     (make-directory dir)
     (with-temp-file full-name (insert "foo"))
-    (find-file-noselect full-name)
-    (dired dir)
+    (push (find-file-noselect full-name) buffers)
+    (push (dired dir) buffers)
     (with-temp-file full-name (insert "bar"))
     (dired-mark-files-containing-regexp regexp)
     (unwind-protect
         (should (equal (dired-get-marked-files nil nil nil 'distinguish-1-mark)
                        `(t ,full-name)))
       ;; Clean up
+      (dolist (buf buffers)
+        (when (buffer-live-p buf) (kill-buffer buf)))
       (delete-directory dir 'recursive))))
 
 (ert-deftest dired-test-bug25609 ()
@@ -60,7 +62,8 @@
          (target (expand-file-name (file-name-nondirectory from) to))
          (nested (expand-file-name (file-name-nondirectory from) target))
          (dired-dwim-target t)
-         (dired-recursive-copies 'always)) ; Don't prompt me.
+         (dired-recursive-copies 'always) ; Don't prompt me.
+         buffers)
     (advice-add 'dired-query ; Don't ask confirmation to overwrite a file.
                 :override
                 (lambda (_sym _prompt &rest _args) (setq dired-query t))
@@ -70,8 +73,8 @@
                 (lambda (_prompt _coll &optional _pred _match init _hist _def 
_inherit _keymap)
                   init)
                 '((name . "advice-completing-read")))
-    (dired to)
-    (dired-other-window temporary-file-directory)
+    (push (dired to) buffers)
+    (push (dired-other-window temporary-file-directory) buffers)
     (dired-goto-file from)
     (dired-do-copy)
     (dired-do-copy); Again.
@@ -79,10 +82,98 @@
         (progn
           (should (file-exists-p target))
           (should-not (file-exists-p nested)))
+      (dolist (buf buffers)
+        (when (buffer-live-p buf) (kill-buffer buf)))
       (delete-directory from 'recursive)
       (delete-directory to 'recursive)
       (advice-remove 'dired-query "advice-dired-query")
       (advice-remove 'completing-read "advice-completing-read"))))
 
+(ert-deftest dired-test-bug27243 ()
+  "Test for http://debbugs.gnu.org/27243 ."
+  (let ((test-dir (make-temp-file "test-dir-" t))
+        (dired-auto-revert-buffer t) buffers)
+    (with-current-buffer (find-file-noselect test-dir)
+      (make-directory "test-subdir"))
+    (push (dired test-dir) buffers)
+    (unwind-protect
+        (let ((buf (current-buffer))
+              (pt1 (point))
+              (test-file (concat (file-name-as-directory "test-subdir")
+                                 "test-file")))
+          (write-region "Test" nil test-file nil 'silent nil 'excl)
+          ;; Sanity check: point should now be on the subdirectory.
+          (should (equal (dired-file-name-at-point)
+                         (concat (file-name-as-directory test-dir)
+                                 (file-name-as-directory "test-subdir"))))
+          (push (dired-find-file) buffers)
+          (let ((pt2 (point)))          ; Point is on test-file.
+            (switch-to-buffer buf)
+            ;; Sanity check: point should now be back on the subdirectory.
+            (should (eq (point) pt1))
+            ;; Case 1: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27243#5
+            (push (dired-find-file) buffers)
+            (should (eq (point) pt2))
+            ;; Case 2: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27243#28
+            (push (dired test-dir) buffers)
+            (should (eq (point) pt1))))
+      (dolist (buf buffers)
+        (when (buffer-live-p buf) (kill-buffer buf)))
+      (delete-directory test-dir t))))
+
+(ert-deftest dired-test-bug27693 ()
+  "Test for http://debbugs.gnu.org/27693 ."
+  (let ((dir (expand-file-name "lisp" source-directory))
+        (size "")
+        ls-lisp-use-insert-directory-program buf)
+    (unwind-protect
+        (progn
+          (setq buf (dired (list dir "simple.el" "subr.el"))
+                size (number-to-string
+                      (file-attribute-size
+                       (file-attributes (dired-get-filename)))))
+          (search-backward-regexp size nil t)
+          (should (looking-back "[[:space:]]" (1- (point)))))
+      (when (buffer-live-p buf) (kill-buffer buf)))))
+
+(ert-deftest dired-test-bug7131 ()
+  "Test for http://debbugs.gnu.org/7131 ."
+  (let* ((dir (expand-file-name "lisp" source-directory))
+         (buf (dired dir)))
+    (unwind-protect
+        (progn
+          (setq buf (dired (list dir "simple.el")))
+          (dired-toggle-marks)
+          (should-not (cdr (dired-get-marked-files)))
+          (kill-buffer buf)
+          (setq buf (dired (list dir "simple.el"))
+                buf (dired dir))
+          (dired-toggle-marks)
+          (should (cdr (dired-get-marked-files))))
+      (when (buffer-live-p buf) (kill-buffer buf)))))
+
+(ert-deftest dired-test-bug27762 ()
+  "Test for http://debbugs.gnu.org/27762 ."
+  :expected-result :failed
+  (let* ((dir source-directory)
+         (default-directory dir)
+         (files (mapcar (lambda (f) (concat "src/" f))
+                        (directory-files
+                         (expand-file-name "src") nil "\\.*\\.c\\'")))
+         ls-lisp-use-insert-directory-program buf)
+    (unwind-protect
+        (let ((file1 "src/cygw32.c")
+              (file2 "src/atimer.c"))
+          (setq buf (dired (nconc (list dir) files)))
+          (dired-goto-file (expand-file-name file2 default-directory))
+          (should-not (looking-at "^   -")) ; Must be 2 spaces not 3.
+          (setq files (cons file1 (delete file1 files)))
+          (kill-buffer buf)
+          (setq buf (dired (nconc (list dir) files)))
+          (should (looking-at "src"))
+          (next-line) ; File names must be aligned.
+          (should (looking-at "src")))
+      (when (buffer-live-p buf) (kill-buffer buf)))))
+
 (provide 'dired-tests)
 ;; dired-tests.el ends here
diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el
index c4ccec7..c6ffccc 100644
--- a/test/lisp/electric-tests.el
+++ b/test/lisp/electric-tests.el
@@ -694,6 +694,8 @@ baz\"\""
   :bindings '((electric-quote-context-sensitive . t))
   :test-in-comments nil :test-in-strings nil)
 
+;; Simulate ‘markdown-mode’: it sets both ‘comment-start’ and
+;; ‘comment-use-syntax’, but derives from ‘text-mode’.
 (define-electric-pair-test electric-quote-markdown-in-text
   "" "'" :expected-string "’" :expected-point 2
   :modes '(text-mode)
@@ -703,6 +705,7 @@ baz\"\""
                           (lambda ()
                             (save-excursion (search-backward "`" nil t)))
                           nil :local))
+  :bindings '((comment-start . "<!--") (comment-use-syntax . t))
   :test-in-comments nil :test-in-strings nil)
 
 (define-electric-pair-test electric-quote-markdown-in-code
@@ -714,6 +717,7 @@ baz\"\""
                           (lambda ()
                             (save-excursion (search-backward "`" nil t)))
                           nil :local))
+  :bindings '((comment-start . "<!--") (comment-use-syntax . t))
   :test-in-comments nil :test-in-strings nil)
 
 (provide 'electric-tests)
diff --git a/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el 
b/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el
index 241ca65..3df2157 100644
--- a/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el
+++ b/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el
@@ -192,7 +192,7 @@
 (ert-deftest eieio-test-method-order-list-6 ()
   ;; FIXME repeated intermittent failures on hydra (bug#24503)
   ;; ((:STATIC C) (:STATIC C-base1) (:STATIC C-base2)) != ((:STATIC C))")
-  (skip-unless (not (getenv "NIX_STORE")))
+  (skip-unless (not (getenv "EMACS_HYDRA_CI")))
   (let ((eieio-test-method-order-list nil)
        (ans '(
               (:STATIC C)
diff --git a/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el 
b/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el
index c34560a..1a6ab9d 100644
--- a/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el
+++ b/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el
@@ -894,7 +894,7 @@ Subclasses to override slot attributes.")
 
 (ert-deftest eieio-test-37-obsolete-name-in-constructor ()
   ;; FIXME repeated intermittent failures on hydra (bug#24503)
-  (skip-unless (not (getenv "NIX_STORE")))
+  (skip-unless (not (getenv "EMACS_HYDRA_CI")))
   (should (equal (eieio--testing "toto") '("toto" 2))))
 
 (ert-deftest eieio-autoload ()
diff --git a/test/lisp/emacs-lisp/map-tests.el 
b/test/lisp/emacs-lisp/map-tests.el
index 07e85cc..15b0655 100644
--- a/test/lisp/emacs-lisp/map-tests.el
+++ b/test/lisp/emacs-lisp/map-tests.el
@@ -63,6 +63,11 @@ Evaluate BODY for each created map.
   (with-maps-do map
     (should (= 5 (map-elt map 7 5)))))
 
+(ert-deftest test-map-elt-testfn ()
+  (let ((map (list (cons "a" 1) (cons "b" 2))))
+    (should-not (map-elt map "a"))
+    (should (map-elt map "a" nil 'equal))))
+
 (ert-deftest test-map-elt-with-nil-value ()
   (should (null (map-elt '((a . 1)
                            (b))
@@ -94,6 +99,13 @@ Evaluate BODY for each created map.
     (should (eq (map-elt alist 2)
                 'b))))
 
+(ert-deftest test-map-put-testfn-alist ()
+  (let ((alist (list (cons "a" 1) (cons "b" 2))))
+    (map-put alist "a" 3 'equal)
+    (should-not (cddr alist))
+    (map-put alist "a" 9)
+    (should (cddr alist))))
+
 (ert-deftest test-map-put-return-value ()
   (let ((ht (make-hash-table)))
     (should (eq (map-put ht 'a 'hello) 'hello))))
diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el
index 8b7945c..8f353b7 100644
--- a/test/lisp/emacs-lisp/rx-tests.el
+++ b/test/lisp/emacs-lisp/rx-tests.el
@@ -33,5 +33,15 @@
                                   (number-sequence ?< ?\])
                                   (number-sequence ?- ?:))))))
 
+(ert-deftest rx-pcase ()
+  (should (equal (pcase "a 1 2 3 1 1 b"
+                   ((rx (let u (+ digit)) space
+                        (let v (+ digit)) space
+                        (let v (+ digit)) space
+                        (backref u) space
+                        (backref 1))
+                    (list u v)))
+                 '("1" "3"))))
+
 (provide 'rx-tests)
 ;; rx-tests.el ends here.
diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el
index 8d05cea..3456d31 100644
--- a/test/lisp/filenotify-tests.el
+++ b/test/lisp/filenotify-tests.el
@@ -173,8 +173,8 @@ Return nil when any other file notification watch is still 
active."
       tramp-verbose 0
       tramp-message-show-message nil)
 
-;; This shall happen on hydra only.
-(when (getenv "NIX_STORE")
+;; This should happen on hydra only.
+(when (getenv "EMACS_HYDRA_CI")
   (add-to-list 'tramp-remote-path 'tramp-own-remote-path))
 
 ;; We do not want to try and fail `file-notify-add-watch'.
diff --git a/test/lisp/ibuffer-tests.el b/test/lisp/ibuffer-tests.el
index b9f7fe7..af75aa0 100644
--- a/test/lisp/ibuffer-tests.el
+++ b/test/lisp/ibuffer-tests.el
@@ -32,7 +32,7 @@
 (declare-function ibuffer-format-qualifier "ibuf-ext" (qualifier))
 (declare-function ibuffer-unary-operand "ibuf-ext" (filter))
 
-(ert-deftest ibuffer-autoload ()
+(ert-deftest ibuffer-0autoload ()       ; sort first
   "Tests to see whether ibuffer has been autoloaded"
   (skip-unless (not (featurep 'ibuf-ext)))
   (should
@@ -76,7 +76,7 @@
 
 (ert-deftest ibuffer-save-filters ()
   "Tests that `ibuffer-save-filters' saves in the proper format."
-  (skip-unless (featurep 'ibuf-ext))
+  (require 'ibuf-ext)
   (let ((ibuffer-save-with-custom nil)
         (ibuffer-saved-filters nil)
         (test1 '((mode . org-mode)
@@ -150,6 +150,7 @@
 
 ;; Test Filter Inclusion
 (let* (test-buffer-list  ; accumulated buffers to clean up
+       test-file-list
        ;; Utility functions without polluting the environment
        (set-buffer-mode
         (lambda (buffer mode)
@@ -192,6 +193,7 @@
                  (file    (make-temp-file prefix nil suffix))
                  (buf     (find-file-noselect file t)))
             (push buf test-buffer-list) ; record for cleanup
+            (push file test-file-list)
             (funcall set-buffer-mode buf mode)
             (funcall set-buffer-contents buf size include)
             buf)))
@@ -213,6 +215,8 @@
        (clean-up
         (lambda ()
           "Restore all emacs state modified during the tests"
+          (dolist (f test-file-list)
+            (and f (file-exists-p f) (delete-file f)))
           (while test-buffer-list       ; created temporary buffers
             (let ((buf (pop test-buffer-list)))
               (with-current-buffer buf (bury-buffer)) ; ensure not selected
@@ -220,7 +224,7 @@
   ;; Tests
   (ert-deftest ibuffer-filter-inclusion-1 ()
     "Tests inclusion using basic filter combinators with a single buffer."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let ((buf
                (funcall create-file-buffer "ibuf-test-1" :size 100
@@ -263,7 +267,7 @@
 
   (ert-deftest ibuffer-filter-inclusion-2 ()
     "Tests inclusion of basic filters in combination on a single buffer."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let ((buf
                (funcall create-file-buffer "ibuf-test-2" :size 200
@@ -298,7 +302,7 @@
 
   (ert-deftest ibuffer-filter-inclusion-3 ()
     "Tests inclusion with filename filters on specified buffers."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let* ((bufA
                 (funcall create-file-buffer "ibuf-test-3.a" :size 50
@@ -332,7 +336,7 @@
 
   (ert-deftest ibuffer-filter-inclusion-4 ()
     "Tests inclusion with various filters on a single buffer."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let ((buf
                (funcall create-file-buffer "ibuf-test-4"
@@ -366,7 +370,7 @@
 
   (ert-deftest ibuffer-filter-inclusion-5 ()
     "Tests inclusion with various filters on a single buffer."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let ((buf
                (funcall create-non-file-buffer "ibuf-test-5.el"
@@ -392,7 +396,7 @@
 
   (ert-deftest ibuffer-filter-inclusion-6 ()
     "Tests inclusion using saved filters and DeMorgan's laws."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let ((buf
                (funcall create-non-file-buffer "*ibuf-test-6*" :size 65
@@ -425,7 +429,7 @@
 
   (ert-deftest ibuffer-filter-inclusion-7 ()
     "Tests inclusion with various filters on a single buffer."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let ((buf
                (funcall create-non-file-buffer "ibuf-test-7"
@@ -446,7 +450,7 @@
 
   (ert-deftest ibuffer-filter-inclusion-8 ()
     "Tests inclusion with various filters."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let ((bufA
                (funcall create-non-file-buffer "ibuf-test-8a"
@@ -534,7 +538,7 @@
   ;; Tests
   (ert-deftest ibuffer-decompose-filter ()
     "Tests `ibuffer-decompose-filter' for and, or, not, and saved."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let ((ibuf (funcall get-test-ibuffer)))
           (with-current-buffer ibuf
@@ -583,7 +587,7 @@
 
   (ert-deftest ibuffer-and-filter ()
     "Tests `ibuffer-and-filter' in an Ibuffer buffer."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let ((ibuf (funcall get-test-ibuffer)))
           (with-current-buffer ibuf
@@ -660,7 +664,7 @@
 
   (ert-deftest ibuffer-or-filter ()
     "Tests `ibuffer-or-filter' in an Ibuffer buffer."
-    (skip-unless (featurep 'ibuf-ext))
+    (require 'ibuf-ext)
     (unwind-protect
         (let ((ibuf (funcall get-test-ibuffer)))
           (with-current-buffer ibuf
@@ -737,7 +741,7 @@
 
 (ert-deftest ibuffer-format-qualifier ()
   "Tests string recommendation of filter from `ibuffer-format-qualifier'."
-  (skip-unless (featurep 'ibuf-ext))
+  (require 'ibuf-ext)
   (let ((test1 '(mode . org-mode))
         (test2 '(size-lt . 100))
         (test3 '(derived-mode . prog-mode))
@@ -802,7 +806,7 @@
 
 (ert-deftest ibuffer-unary-operand ()
   "Tests `ibuffer-unary-operand': (not cell) or (not . cell) -> cell."
-  (skip-unless (featurep 'ibuf-ext))
+  (require 'ibuf-ext)
   (should (equal (ibuffer-unary-operand '(not . (mode "foo")))
                  '(mode "foo")))
   (should (equal (ibuffer-unary-operand '(not (mode "foo")))
diff --git a/test/lisp/international/ucs-normalize-tests.el 
b/test/lisp/international/ucs-normalize-tests.el
index d85efe2..02a4bba 100644
--- a/test/lisp/international/ucs-normalize-tests.el
+++ b/test/lisp/international/ucs-normalize-tests.el
@@ -26,15 +26,13 @@
 ;; If there are lines marked as failing (see
 ;; `ucs-normalize-tests--failing-lines-part1' and
 ;; `ucs-normalize-tests--failing-lines-part2'), they may need to be
-;; adjusted when NormalizationTest.txt is updated.  To get a list of
-;; currently failing lines, set those 2 variables to nil, run the
-;; tests, and inspect the values of
-;; `ucs-normalize-tests--part1-rule1-failed-lines' and
-;; `ucs-normalize-tests--part1-rule2-failed-chars', respectively.
+;; adjusted when NormalizationTest.txt is updated.  Run the function
+;; `ucs-normalize-check-failing-lines' to see what changes are needed.
 
 ;;; Code:
 
 (eval-when-compile (require 'cl-lib))
+(require 'seq)
 (require 'ert)
 (require 'ucs-normalize)
 
@@ -44,83 +42,98 @@
 (defun ucs-normalize-tests--parse-column ()
   (let ((chars nil)
         (term nil))
-    (while (and (not (equal term ";"))
+    (while (and (not (eq term ?\;))
                 (looking-at "\\([[:xdigit:]]\\{4,6\\}\\)\\([; ]\\)"))
-      (let ((code-point (match-string 1)))
-        (setq term (match-string 2))
+      (let ((code-point (match-string-no-properties 1)))
+        (setq term (char-after (match-beginning 2)))
         (goto-char (match-end 0))
         (push (string-to-number code-point 16) chars)))
-    (nreverse chars)))
+    (apply #'string (nreverse chars))))
 
-(defmacro ucs-normalize-tests--normalize (norm str)
+(defconst ucs-normalize-tests--norm-buf (generate-new-buffer " 
*ucs-normalizing-buffer*"))
+
+(defmacro ucs-normalize-tests--normalization-equal-p (norm str equal-to)
   "Like `ucs-normalize-string' but reuse current buffer for efficiency.
 And NORM is one of the symbols `NFC', `NFD', `NFKC', `NFKD' for brevity."
   (let ((norm-alist '((NFC . ucs-normalize-NFC-region)
                       (NFD . ucs-normalize-NFD-region)
                       (NFKC . ucs-normalize-NFKC-region)
                       (NFKD . ucs-normalize-NFKD-region))))
-    `(save-restriction
-       (narrow-to-region (point) (point))
+    `(with-current-buffer ucs-normalize-tests--norm-buf
+       (erase-buffer)
        (insert ,str)
-       (funcall #',(cdr (assq norm norm-alist)) (point-min) (point-max))
-       (delete-and-extract-region (point-min) (point-max)))))
+       (,(cdr (assq norm norm-alist)) (point-min) (point-max))
+       (goto-char (point-min))
+       (insert ,equal-to)
+       (eq (compare-buffer-substrings nil nil (point) nil (point) nil) 0))))
+
+(defmacro ucs-normalize-tests--normalization-chareq-p (norm char char-eq-to)
+  "Like `ucs-normalize-string' but reuse current buffer for efficiency.
+And NORM is one of the symbols `NFC', `NFD', `NFKC', `NFKD' for brevity."
+  (let ((norm-alist '((NFC . ucs-normalize-NFC-region)
+                      (NFD . ucs-normalize-NFD-region)
+                      (NFKC . ucs-normalize-NFKC-region)
+                      (NFKD . ucs-normalize-NFKD-region))))
+    `(with-current-buffer ucs-normalize-tests--norm-buf
+       (erase-buffer)
+       (insert ,char)
+       (,(cdr (assq norm norm-alist)) (point-min) (point-max))
+       (and (eq (buffer-size) 1)
+            (eq (char-after (point-min)) ,char-eq-to)))))
 
 (defvar ucs-normalize-tests--chars-part1 nil)
 
-(defun ucs-normalize-tests--invariants-hold-p (&rest columns)
+(defsubst ucs-normalize-tests--rule1-holds-p (source nfc nfd nfkc nfkd)
   "Check 1st conformance rule.
 The following invariants must be true for all conformant implementations..."
   (when ucs-normalize-tests--chars-part1
-    ;; See `ucs-normalize-tests--invariants-rule2-hold-p'.
+    ;; See `ucs-normalize-tests--rule2-holds-p'.
     (aset ucs-normalize-tests--chars-part1
-          (caar columns) 1))
-  (cl-destructuring-bind (source nfc nfd nfkc nfkd)
-      (mapcar (lambda (c) (apply #'string c)) columns)
-    (and
-     ;; c2 ==  toNFC(c1) ==  toNFC(c2) ==  toNFC(c3)
-     (equal nfc (ucs-normalize-tests--normalize NFC source))
-     (equal nfc (ucs-normalize-tests--normalize NFC nfc))
-     (equal nfc (ucs-normalize-tests--normalize NFC nfd))
-     ;; c4 ==  toNFC(c4) ==  toNFC(c5)
-     (equal nfkc (ucs-normalize-tests--normalize NFC nfkc))
-     (equal nfkc (ucs-normalize-tests--normalize NFC nfkd))
-
-     ;; c3 ==  toNFD(c1) ==  toNFD(c2) ==  toNFD(c3)
-     (equal nfd (ucs-normalize-tests--normalize NFD source))
-     (equal nfd (ucs-normalize-tests--normalize NFD nfc))
-     (equal nfd (ucs-normalize-tests--normalize NFD nfd))
-     ;; c5 ==  toNFD(c4) ==  toNFD(c5)
-     (equal nfkd (ucs-normalize-tests--normalize NFD nfkc))
-     (equal nfkd (ucs-normalize-tests--normalize NFD nfkd))
-
-     ;; c4 == toNFKC(c1) == toNFKC(c2) == toNFKC(c3) == toNFKC(c4) == 
toNFKC(c5)
-     (equal nfkc (ucs-normalize-tests--normalize NFKC source))
-     (equal nfkc (ucs-normalize-tests--normalize NFKC nfc))
-     (equal nfkc (ucs-normalize-tests--normalize NFKC nfd))
-     (equal nfkc (ucs-normalize-tests--normalize NFKC nfkc))
-     (equal nfkc (ucs-normalize-tests--normalize NFKC nfkd))
-
-     ;; c5 == toNFKD(c1) == toNFKD(c2) == toNFKD(c3) == toNFKD(c4) == 
toNFKD(c5)
-     (equal nfkd (ucs-normalize-tests--normalize NFKD source))
-     (equal nfkd (ucs-normalize-tests--normalize NFKD nfc))
-     (equal nfkd (ucs-normalize-tests--normalize NFKD nfd))
-     (equal nfkd (ucs-normalize-tests--normalize NFKD nfkc))
-     (equal nfkd (ucs-normalize-tests--normalize NFKD nfkd)))))
-
-(defun ucs-normalize-tests--invariants-rule2-hold-p (char)
+          (aref source 0) 1))
+  (and
+   ;; c2 ==  toNFC(c1) ==  toNFC(c2) ==  toNFC(c3)
+   (ucs-normalize-tests--normalization-equal-p NFC source nfc)
+   (ucs-normalize-tests--normalization-equal-p NFC nfc nfc)
+   (ucs-normalize-tests--normalization-equal-p NFC nfd nfc)
+   ;; c4 ==  toNFC(c4) ==  toNFC(c5)
+   (ucs-normalize-tests--normalization-equal-p NFC nfkc nfkc)
+   (ucs-normalize-tests--normalization-equal-p NFC nfkd nfkc)
+
+   ;; c3 ==  toNFD(c1) ==  toNFD(c2) ==  toNFD(c3)
+   (ucs-normalize-tests--normalization-equal-p NFD source nfd)
+   (ucs-normalize-tests--normalization-equal-p NFD nfc nfd)
+   (ucs-normalize-tests--normalization-equal-p NFD nfd nfd)
+   ;; c5 ==  toNFD(c4) ==  toNFD(c5)
+   (ucs-normalize-tests--normalization-equal-p NFD nfkc nfkd)
+   (ucs-normalize-tests--normalization-equal-p NFD nfkd nfkd)
+
+   ;; c4 == toNFKC(c1) == toNFKC(c2) == toNFKC(c3) == toNFKC(c4) == toNFKC(c5)
+   (ucs-normalize-tests--normalization-equal-p NFKC source nfkc)
+   (ucs-normalize-tests--normalization-equal-p NFKC nfc nfkc)
+   (ucs-normalize-tests--normalization-equal-p NFKC nfd nfkc)
+   (ucs-normalize-tests--normalization-equal-p NFKC nfkc nfkc)
+   (ucs-normalize-tests--normalization-equal-p NFKC nfkd nfkc)
+
+   ;; c5 == toNFKD(c1) == toNFKD(c2) == toNFKD(c3) == toNFKD(c4) == toNFKD(c5)
+   (ucs-normalize-tests--normalization-equal-p NFKD source nfkd)
+   (ucs-normalize-tests--normalization-equal-p NFKD nfc nfkd)
+   (ucs-normalize-tests--normalization-equal-p NFKD nfd nfkd)
+   (ucs-normalize-tests--normalization-equal-p NFKD nfkc nfkd)
+   (ucs-normalize-tests--normalization-equal-p NFKD nfkd nfkd)))
+
+(defsubst ucs-normalize-tests--rule2-holds-p (X)
  "Check 2nd conformance rule.
 For every code point X assigned in this version of Unicode that is not 
specifically
 listed in Part 1, the following invariants must be true for all conformant
 implementations:
 
   X == toNFC(X) == toNFD(X) == toNFKC(X) == toNFKD(X)"
- (let ((X (string char)))
-   (and (equal X (ucs-normalize-tests--normalize NFC X))
-        (equal X (ucs-normalize-tests--normalize NFD X))
-        (equal X (ucs-normalize-tests--normalize NFKC X))
-        (equal X (ucs-normalize-tests--normalize NFKD X)))))
+ (and (ucs-normalize-tests--normalization-chareq-p NFC X X)
+      (ucs-normalize-tests--normalization-chareq-p NFD X X)
+      (ucs-normalize-tests--normalization-chareq-p NFKC X X)
+      (ucs-normalize-tests--normalization-chareq-p NFKD X X)))
 
-(cl-defun ucs-normalize-tests--invariants-failing-for-part (part &optional 
skip-lines &key progress-str)
+(cl-defun ucs-normalize-tests--rule1-failing-for-partX (part &optional 
skip-lines &key progress-str)
   "Returns a list of failed line numbers."
   (with-temp-buffer
     (insert-file-contents ucs-normalize-test-data-file)
@@ -136,8 +149,8 @@ implementations:
                                                  progress-str beg-line end-line
                                                  0 nil 0.5))
                for line from beg-line to (1- end-line)
-               unless (or (= (following-char) ?#)
-                          (ucs-normalize-tests--invariants-hold-p
+               unless (or (eq (following-char) ?#)
+                          (ucs-normalize-tests--rule1-holds-p
                            (ucs-normalize-tests--parse-column)
                            (ucs-normalize-tests--parse-column)
                            (ucs-normalize-tests--parse-column)
@@ -148,7 +161,7 @@ implementations:
                do (forward-line)
                if reporter do (progress-reporter-update reporter line)))))
 
-(defun ucs-normalize-tests--invariants-failing-for-lines (lines)
+(defun ucs-normalize-tests--rule1-failing-for-lines (lines)
   "Returns a list of failed line numbers."
   (with-temp-buffer
     (insert-file-contents ucs-normalize-test-data-file)
@@ -156,7 +169,7 @@ implementations:
     (cl-loop for prev-line = 1 then line
              for line in lines
              do (forward-line (- line prev-line))
-             unless (ucs-normalize-tests--invariants-hold-p
+             unless (ucs-normalize-tests--rule1-holds-p
                      (ucs-normalize-tests--parse-column)
                      (ucs-normalize-tests--parse-column)
                      (ucs-normalize-tests--parse-column)
@@ -165,7 +178,7 @@ implementations:
              collect line)))
 
 (ert-deftest ucs-normalize-part0 ()
-  (should-not (ucs-normalize-tests--invariants-failing-for-part 0)))
+  (should-not (ucs-normalize-tests--rule1-failing-for-partX 0)))
 
 (defconst ucs-normalize-tests--failing-lines-part1
   (list 15131 15132 15133 15134 15135 15136 15137 15138
@@ -195,6 +208,8 @@ implementations:
   "A list of line numbers.")
 (defvar ucs-normalize-tests--part1-rule2-failed-chars nil
   "A list of code points.")
+(defvar ucs-normalize-tests--part2-rule1-failed-lines nil
+  "A list of line numbers.")
 
 (defun ucs-normalize-tests--part1-rule2 (chars-part1)
   (let ((reporter (make-progress-reporter "UCS Normalize Test Part1, rule 2"
@@ -204,11 +219,11 @@ implementations:
      (lambda (char-range listed-in-part)
        (unless (eq listed-in-part 1)
          (if (characterp char-range)
-             (progn (unless (ucs-normalize-tests--invariants-rule2-hold-p 
char-range)
+             (progn (unless (ucs-normalize-tests--rule2-holds-p char-range)
                       (push char-range failed-chars))
                     (progress-reporter-update reporter char-range))
            (cl-loop for char from (car char-range) to (cdr char-range)
-                    unless (ucs-normalize-tests--invariants-rule2-hold-p char)
+                    unless (ucs-normalize-tests--rule2-holds-p char)
                     do (push char failed-chars)
                     do (progress-reporter-update reporter char)))))
      chars-part1)
@@ -219,59 +234,103 @@ implementations:
   :tags '(:expensive-test)
   ;; This takes a long time, so make sure we're compiled.
   (dolist (fun '(ucs-normalize-tests--part1-rule2
-                 ucs-normalize-tests--invariants-failing-for-part
-                 ucs-normalize-tests--invariants-hold-p
-                 ucs-normalize-tests--invariants-rule2-hold-p))
+                 ucs-normalize-tests--rule1-failing-for-partX
+                 ucs-normalize-tests--rule1-holds-p
+                 ucs-normalize-tests--rule2-holds-p))
     (or (byte-code-function-p (symbol-function fun))
         (byte-compile fun)))
   (let ((ucs-normalize-tests--chars-part1 (make-char-table 
'ucs-normalize-tests t)))
-    (should-not
-     (setq ucs-normalize-tests--part1-rule1-failed-lines
-           (ucs-normalize-tests--invariants-failing-for-part
-            1 ucs-normalize-tests--failing-lines-part1
-            :progress-str "UCS Normalize Test Part1, rule 1")))
-    (should-not (setq ucs-normalize-tests--part1-rule2-failed-chars
-                      (ucs-normalize-tests--part1-rule2
-                       ucs-normalize-tests--chars-part1)))))
+    (setq ucs-normalize-tests--part1-rule1-failed-lines
+          (ucs-normalize-tests--rule1-failing-for-partX
+           1 ucs-normalize-tests--failing-lines-part1
+           :progress-str "UCS Normalize Test Part1, rule 1"))
+    (setq ucs-normalize-tests--part1-rule2-failed-chars
+          (ucs-normalize-tests--part1-rule2
+           ucs-normalize-tests--chars-part1))
+    (should-not ucs-normalize-tests--part1-rule1-failed-lines)
+    (should-not ucs-normalize-tests--part1-rule2-failed-chars)))
 
 (ert-deftest ucs-normalize-part1-failing ()
   :expected-result :failed
   (skip-unless ucs-normalize-tests--failing-lines-part1)
   (should-not
-   (ucs-normalize-tests--invariants-failing-for-lines
+   (ucs-normalize-tests--rule1-failing-for-lines
     ucs-normalize-tests--failing-lines-part1)))
 
 (defconst ucs-normalize-tests--failing-lines-part2
-  (list 18328 18330 18332 18334 18336 18338 18340 18342
-        18344 18346 18348 18350 18352 18354 18356 18358
-        18360 18362 18364 18366 18368 18370 18372 18374
-        18376 18378 18380 18382 18384 18386 18388 18390
-        18392 18394 18396 18398 18400 18402 18404 18406
-        18408 18410 18412 18414 18416 18418 18420 18422
-        18424 18426 18494 18496 18498 18500 18502 18504
-        18506 18508 18510 18512 18514 18516 18518 18520
-        18522 18524 18526 18528 18530 18532 18534 18536
-        18538 18540 18542 18544 18546 18548 18550 18552
-        18554 18556 18558 18560 18562 18564 18566 18568
-        18570 18572 18574 18576 18578 18580 18582 18584
-        18586 18588 18590 18592 18594 18596))
+  (list 17656 17658 18006 18007 18008 18009 18010 18011
+        18012 18340 18342 18344 18346 18348 18350 18352
+        18354 18356 18358 18360 18362 18364 18366 18368
+        18370 18372 18374 18376 18378 18380 18382 18384
+        18386 18388 18390 18392 18394 18396 18398 18400
+        18402 18404 18406 18408 18410 18412 18414 18416
+        18418 18420 18422 18424 18426 18428 18430 18432
+        18434 18436 18438 18440 18442 18444 18446 18448
+        18450 18518 18520 18522 18524 18526 18528 18530
+        18532 18534 18536 18538 18540 18542 18544 18546
+        18548 18550 18552 18554 18556 18558 18560 18562
+        18564 18566 18568 18570 18572 18574 18576 18578
+        18580 18582 18584 18586 18588 18590 18592 18594
+        18596 18598 18600 18602 18604 18606 18608 18610
+        18612 18614 18616 18618 18620))
 
 (ert-deftest ucs-normalize-part2 ()
   :tags '(:expensive-test)
   (should-not
-   (ucs-normalize-tests--invariants-failing-for-part
-    2 ucs-normalize-tests--failing-lines-part2
-    :progress-str "UCS Normalize Test Part2")))
+   (setq ucs-normalize-tests--part2-rule1-failed-lines
+         (ucs-normalize-tests--rule1-failing-for-partX
+          2 ucs-normalize-tests--failing-lines-part2
+          :progress-str "UCS Normalize Test Part2"))))
 
 (ert-deftest ucs-normalize-part2-failing ()
   :expected-result :failed
   (skip-unless ucs-normalize-tests--failing-lines-part2)
   (should-not
-   (ucs-normalize-tests--invariants-failing-for-lines
+   (ucs-normalize-tests--rule1-failing-for-lines
     ucs-normalize-tests--failing-lines-part2)))
 
 (ert-deftest ucs-normalize-part3 ()
   (should-not
-   (ucs-normalize-tests--invariants-failing-for-part 3)))
+   (ucs-normalize-tests--rule1-failing-for-partX 3)))
+
+(defun ucs-normalize-tests--insert-failing-lines (var newval)
+  (insert (format "`%s' should be updated to:\n
+\(defconst %s
+  (list " var var))
+  (dolist (linos (seq-partition newval 8))
+    (insert (mapconcat #'number-to-string linos " ") "\n"))
+  (insert ")\)"))
+
+(defun ucs-normalize-check-failing-lines ()
+  (interactive)
+  (let ((ucs-normalize-tests--failing-lines-part1 nil)
+        (ucs-normalize-tests--failing-lines-part2 nil))
+    (setq ucs-normalize-tests--part1-rule1-failed-lines nil)
+    (setq ucs-normalize-tests--part1-rule2-failed-chars nil)
+    (setq ucs-normalize-tests--part2-rule1-failed-lines nil)
+    (ert "\\`ucs-normalize"))
+
+  (with-current-buffer (get-buffer-create "*ucs normalize change bad lines*")
+    (erase-buffer)
+    (unless (equal ucs-normalize-tests--part1-rule1-failed-lines
+                   ucs-normalize-tests--failing-lines-part1)
+      (ucs-normalize-tests--insert-failing-lines
+       'ucs-normalize-tests--failing-lines-part1
+       ucs-normalize-tests--part1-rule1-failed-lines))
+
+    (when ucs-normalize-tests--part1-rule2-failed-chars
+      (insert (format "Some characters failed rule 2!\n\n%S"
+                      `(list 
,@ucs-normalize-tests--part1-rule2-failed-chars))))
+
+    (unless (equal ucs-normalize-tests--part2-rule1-failed-lines
+                   ucs-normalize-tests--failing-lines-part2)
+      (ucs-normalize-tests--insert-failing-lines
+       'ucs-normalize-tests--failing-lines-part2
+       ucs-normalize-tests--part2-rule1-failed-lines))
+    (if (> (buffer-size) 0)
+        (if noninteractive
+            (princ (buffer-string) standard-output)
+          (display-buffer (current-buffer)))
+      (message "No changes to failing lines needed"))))
 
 ;;; ucs-normalize-tests.el ends here
diff --git a/test/lisp/net/gnutls-tests.el b/test/lisp/net/gnutls-tests.el
new file mode 100644
index 0000000..9dbb6c0
--- /dev/null
+++ b/test/lisp/net/gnutls-tests.el
@@ -0,0 +1,295 @@
+;;; gnutls-tests.el --- Test suite for gnutls.el
+
+;; Copyright (C) 2017 Free Software Foundation, Inc.
+
+;; Author: Ted Zlatanov <address@hidden>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Run this with `GNUTLS_TEST_VERBOSE=1' to get verbose debugging.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl)
+(require 'gnutls)
+(require 'hex-util)
+
+(defvar gnutls-tests-message-prefix "")
+
+(defsubst gnutls-tests-message (format-string &rest args)
+  (when (getenv "GNUTLS_TEST_VERBOSE")
+    (apply #'message (concat "gnutls-tests: " gnutls-tests-message-prefix 
format-string) args)))
+
+;; Minor convenience to see strings more easily (without binary data).
+(defsubst gnutls-tests-hexstring-equal (a b)
+  (and (stringp a) (stringp b) (string-equal (encode-hex-string a) 
(encode-hex-string b))))
+
+(defvar gnutls-tests-internal-macs-upcased
+  (mapcar (lambda (sym) (cons sym (intern (upcase (symbol-name sym)))))
+          (secure-hash-algorithms)))
+
+(defvar gnutls-tests-tested-macs
+  (when (gnutls-available-p)
+    (remove-duplicates
+     (append (mapcar 'cdr gnutls-tests-internal-macs-upcased)
+             (mapcar 'car (gnutls-macs))))))
+
+(defvar gnutls-tests-tested-digests
+  (when (gnutls-available-p)
+    (remove-duplicates
+     (append (mapcar 'cdr gnutls-tests-internal-macs-upcased)
+             (mapcar 'car (gnutls-digests))))))
+
+(defvar gnutls-tests-tested-ciphers
+  (when (gnutls-available-p)
+    (remove-duplicates
+    ; these cause FPEs or SEGVs
+     (remove-if (lambda (e) (memq e '(ARCFOUR-128)))
+                (mapcar 'car (gnutls-ciphers))))))
+
+(defvar gnutls-tests-mondo-strings
+  (list
+   ""
+   "some data"
+   "lots and lots of data lots and lots of data lots and lots of data lots and 
lots of data lots and lots of data lots and lots of data lots and lots of data 
lots and lots of data lots and lots of data lots and lots of data lots and lots 
of data lots and lots of data lots and lots of data lots and lots of data lots 
and lots of data lots and lots of data lots and lots of data lots and lots of 
data lots and lots of data lots and lots of data lots and lots of data "
+   "data and more data to go over the block limit!"
+   "data and more data to go over the block limit"
+   (format "some random data %d%d" (random) (random))))
+
+(ert-deftest test-gnutls-000-availability ()
+  "Test the GnuTLS hashes and ciphers availability."
+  (skip-unless (memq 'gnutls3 (gnutls-available-p)))
+  (setq gnutls-tests-message-prefix "availability: ")
+  (should (> (length gnutls-tests-internal-macs-upcased) 5))
+  (let ((macs (gnutls-macs))
+        (digests (gnutls-digests))
+        (ciphers (gnutls-ciphers)))
+    (dolist (mac gnutls-tests-tested-macs)
+      (let ((plist (cdr (assq mac macs))))
+        (gnutls-tests-message "MAC %s %S" mac plist)
+        (dolist (prop '(:mac-algorithm-id :mac-algorithm-length 
:mac-algorithm-keysize :mac-algorithm-noncesize))
+          (should (plist-get plist prop)))
+        (should (eq 'gnutls-mac-algorithm (plist-get plist :type)))))
+    (dolist (digest gnutls-tests-tested-digests)
+      (let ((plist (cdr (assq digest digests))))
+        (gnutls-tests-message "digest %s %S" digest plist)
+        (dolist (prop '(:digest-algorithm-id :digest-algorithm-length))
+          (should (plist-get plist prop)))
+        (should (eq 'gnutls-digest-algorithm (plist-get plist :type)))))
+    (dolist (cipher gnutls-tests-tested-ciphers)
+      (let ((plist (cdr (assq cipher ciphers))))
+        (gnutls-tests-message "cipher %s %S" cipher plist)
+        (dolist (prop '(:cipher-id :cipher-blocksize :cipher-keysize 
:cipher-ivsize))
+          (should (plist-get plist prop)))
+        (should (eq 'gnutls-symmetric-cipher (plist-get plist :type)))))))
+
+(ert-deftest test-gnutls-000-data-extractions ()
+  "Test the GnuTLS data extractions against the built-in `secure-hash'."
+  (skip-unless (memq 'digests (gnutls-available-p)))
+  (setq gnutls-tests-message-prefix "data extraction: ")
+  (dolist (input gnutls-tests-mondo-strings)
+    ;; Test buffer extraction
+    (with-temp-buffer
+      (insert input)
+      (insert "not ASCII: не e английски")
+      (dolist (step '(0 1 2 3 4 5))
+        (let ((spec (list (current-buffer) ; a buffer spec
+                          (point-min)
+                          (max (point-min) (- step (point-max)))))
+              (spec2 (list (buffer-string) ; a string spec
+                           (point-min)
+                           (max (point-min) (- step (point-max))))))
+          (should (gnutls-tests-hexstring-equal
+                   (gnutls-hash-digest 'MD5 spec)
+                   (apply 'secure-hash 'md5 (append spec '(t)))))
+          (should (gnutls-tests-hexstring-equal
+                   (gnutls-hash-digest 'MD5 spec2)
+                   (apply 'secure-hash 'md5 (append spec2 '(t))))))))))
+
+(ert-deftest test-gnutls-001-hashes-internal-digests ()
+  "Test the GnuTLS hash digests against the built-in `secure-hash'."
+  (skip-unless (memq 'digests (gnutls-available-p)))
+  (setq gnutls-tests-message-prefix "digest internal verification: ")
+  (let ((macs (gnutls-macs)))
+    (dolist (mcell gnutls-tests-internal-macs-upcased)
+      (let ((plist (cdr (assq (cdr mcell) macs))))
+        (gnutls-tests-message "Checking digest MAC %S %S" mcell plist)
+        (dolist (input gnutls-tests-mondo-strings)
+          ;; Test buffer extraction
+          (with-temp-buffer
+            (insert input)
+            (should (gnutls-tests-hexstring-equal
+                     (gnutls-hash-digest (cdr mcell) (current-buffer))
+                     (secure-hash (car mcell) (current-buffer) nil nil t))))
+          (should (gnutls-tests-hexstring-equal
+                   (gnutls-hash-digest (cdr mcell) input)
+                   (secure-hash (car mcell) input nil nil t))))))))
+
+(ert-deftest test-gnutls-002-hashes-digests ()
+  "Test some GnuTLS hash digests against pre-defined outputs."
+  (skip-unless (memq 'digests (gnutls-available-p)))
+  (setq gnutls-tests-message-prefix "digest external verification: ")
+  (let ((macs (gnutls-macs)))
+    (dolist (test '(("57edf4a22be3c955ac49da2e2107b67a" 
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
 MD5)
+                    ("d174ab98d277d9f5a5611c2c9f419d9f" 
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" MD5)
+                    ("c3fcd3d76192e4007dfb496cca67e13b" 
"abcdefghijklmnopqrstuvwxyz" MD5)
+                    ("f96b697d7cb7938d525a2f31aaf161d0" "message digest" MD5)
+                    ("900150983cd24fb0d6963f7d28e17f72" "abc" MD5)
+                    ("0cc175b9c0f1b6a831c399e269772661" "a" MD5)
+                    ("a9993e364706816aba3e25717850c26c9cd0d89d" "abc" SHA1)
+                    ("a9993e364706816aba3e25717850c26c9cd0d89d" "abc" 
"SHA1"))) ; check string ID for digest
+      (destructuring-bind (hash input mac) test
+        (let ((plist (cdr (assq mac macs)))
+              result resultb)
+        (gnutls-tests-message "%s %S" mac plist)
+        (setq result (encode-hex-string (gnutls-hash-digest mac input)))
+        (gnutls-tests-message "%S => result %S" test result)
+        (should (string-equal result hash))
+        ;; Test buffer extraction
+        (with-temp-buffer
+          (insert input)
+          (setq resultb (encode-hex-string (gnutls-hash-digest mac 
(current-buffer))))
+          (gnutls-tests-message "%S => result from buffer %S" test resultb)
+          (should (string-equal resultb hash))))))))
+
+(ert-deftest test-gnutls-003-hashes-hmacs ()
+  "Test some predefined GnuTLS HMAC outputs for SHA256."
+  (skip-unless (memq 'macs (gnutls-available-p)))
+  (setq gnutls-tests-message-prefix "HMAC verification: ")
+  (let ((macs (gnutls-macs)))
+    (dolist (test 
'(("f5c5021e60d9686fef3bb0414275fe4163bece61d9a95fec7a273746a437b986" "hello\n" 
"test" SHA256)
+                    
("46b75292b81002fd873e89c532a1b8545d6efc9822ee938feba6de2723161a67" "more and 
more data goes into a file to exceed the buffer size" "test" SHA256)
+                    
("81568ba71fa2c5f33cc84bf362466988f98eba3735479100b4e8908acad87ac4" "more and 
more data goes into a file to exceed the buffer size" "very long key goes here 
to exceed the key size" SHA256)
+                    
("4bc830005783a73b8112f4bd5f4aa5f92e05b51e9b55c0cd6f9a7bee48371def" "more and 
more data goes into a file to exceed the buffer size" "" "SHA256") ; check 
string ID for HMAC
+                    
("4bc830005783a73b8112f4bd5f4aa5f92e05b51e9b55c0cd6f9a7bee48371def" "more and 
more data goes into a file to exceed the buffer size" "" SHA256)))
+      (destructuring-bind (hash input key mac) test
+        (let ((plist (cdr (assq mac macs)))
+              result)
+          (gnutls-tests-message "%s %S" mac plist)
+          (setq result (encode-hex-string (gnutls-hash-mac mac (copy-sequence 
key) input)))
+          (gnutls-tests-message "%S => result %S" test result)
+          (should (string-equal result hash)))))))
+
+
+(defun gnutls-tests-pad-or-trim (s exact)
+  "Pad or trim string S to EXACT numeric size."
+  (if (and (consp s) (eq 'iv-auto (nth 0 s)))
+      s
+    (let ((e (number-to-string exact)))
+      (format (concat "%" e "." e "s") s))))
+
+(defun gnutls-tests-pad-to-multiple (s blocksize)
+  "Pad string S to BLOCKSIZE numeric size."
+  (let* ((e (if (string= s "")
+               blocksize
+              (* blocksize (ceiling (length s) blocksize))))
+         (out (concat s (make-string (- e (length s)) ? ))))
+    ;; (gnutls-tests-message "padding %S to length %d for blocksize %d: => %S" 
s e blocksize out)
+    out))
+
+;; ;;; Testing from the command line:
+;; ;;; echo 
e36a9d13c15a6df23a59a6337d6132b8f7cd5283cb4784b81141b52343a18e5f5e5ee8f5553c23167409dd222478bc30
 | perl -lne 'print pack "H*", $_' | openssl enc -aes-128-ctr -d  -nosalt -K 
6d796b657932 -iv 696e697432 | od -x
+(ert-deftest test-gnutls-004-symmetric-ciphers ()
+  "Test the GnuTLS symmetric ciphers"
+  (skip-unless (memq 'ciphers (gnutls-available-p)))
+  (setq gnutls-tests-message-prefix "symmetric cipher verification: ")
+  ;; we expect at least 10 ciphers
+  (should (> (length (gnutls-ciphers)) 10))
+  (let ((keys '("mykey" "mykey2"))
+        (inputs gnutls-tests-mondo-strings)
+        (ivs '("" "-abc123-" "init" "ini2"))
+        (ciphers (remove-if
+                  (lambda (c) (plist-get (cdr (assq c (gnutls-ciphers)))
+                                    :cipher-aead-capable))
+                  gnutls-tests-tested-ciphers)))
+
+    (dolist (cipher ciphers)
+      (dolist (iv ivs)
+        (dolist (input inputs)
+          (dolist (key keys)
+            (gnutls-tests-message "%S, starting key %S IV %S input %S" (assq 
cipher (gnutls-ciphers)) key iv input)
+            (let* ((cplist (cdr (assq cipher (gnutls-ciphers))))
+                   (key (gnutls-tests-pad-or-trim key (plist-get cplist 
:cipher-keysize)))
+                   (input (gnutls-tests-pad-to-multiple input (plist-get 
cplist :cipher-blocksize)))
+                   (iv (gnutls-tests-pad-or-trim iv (plist-get cplist 
:cipher-ivsize)))
+                   (output (gnutls-symmetric-encrypt cplist (copy-sequence 
key) iv input))
+                   (data (nth 0 output))
+                   (actual-iv (nth 1 output))
+                   (reverse-output (gnutls-symmetric-decrypt cplist 
(copy-sequence key) actual-iv data))
+                   (reverse (nth 0 reverse-output)))
+              (gnutls-tests-message "%s %S" cipher cplist)
+              (gnutls-tests-message "key %S IV %S input %S => hexdata %S and 
reverse %S" key iv input (encode-hex-string data) reverse)
+              (should-not (gnutls-tests-hexstring-equal input data))
+              (should-not (gnutls-tests-hexstring-equal data reverse))
+              (should (gnutls-tests-hexstring-equal input reverse)))))))))
+
+(ert-deftest test-gnutls-005-aead-ciphers ()
+  "Test the GnuTLS AEAD ciphers"
+  (skip-unless (memq 'AEAD-ciphers (gnutls-available-p)))
+  (setq gnutls-tests-message-prefix "AEAD verification: ")
+  (let ((keys '("mykey" "mykey2"))
+        (inputs gnutls-tests-mondo-strings)
+        (ivs '("" "-abc123-" "init" "ini2"))
+        (auths '(nil
+                 ""
+                 "auth data"
+                 "auth and auth of data auth and auth of data auth and auth of 
data auth and auth of data auth and auth of data auth and auth of data auth and 
auth of data auth and auth of data auth and auth of data auth and auth of data 
auth and auth of data auth and auth of data auth and auth of data auth and auth 
of data auth and auth of data auth and auth of data auth and auth of data auth 
and auth of data auth and auth of data auth and auth of data auth and auth of 
data "
+                 "AUTH data and more data to go over the block limit!"
+                 "AUTH data and more data to go over the block limit"))
+        (ciphers (remove-if
+                  (lambda (c) (or (null (plist-get (cdr (assq c 
(gnutls-ciphers)))
+                                              :cipher-aead-capable))))
+                  gnutls-tests-tested-ciphers))
+        actual-ivlist)
+
+    (dolist (cipher ciphers)
+      (dolist (input inputs)
+        (dolist (auth auths)
+          (dolist (key keys)
+            (let* ((cplist (cdr (assq cipher (gnutls-ciphers))))
+                   (key (gnutls-tests-pad-or-trim key (plist-get cplist 
:cipher-keysize)))
+                   (input (gnutls-tests-pad-to-multiple input (plist-get 
cplist :cipher-blocksize)))
+                   (ivsize (plist-get cplist :cipher-ivsize)))
+              (should (>= ivsize 12))   ; as per the RFC
+              (dolist (iv (append ivs (list (list 'iv-auto ivsize))))
+
+                (gnutls-tests-message "%S, starting key %S IV %S input %S auth 
%S" (assq cipher (gnutls-ciphers)) key iv input auth)
+                (let* ((iv (gnutls-tests-pad-or-trim iv (plist-get cplist 
:cipher-ivsize)))
+                       (output (gnutls-symmetric-encrypt cplist (copy-sequence 
key) iv input (copy-sequence auth)))
+                       (data (nth 0 output))
+                       (actual-iv (nth 1 output))
+                       (reverse-output (gnutls-symmetric-decrypt cplist 
(copy-sequence key) actual-iv data auth))
+                       (reverse (nth 0 reverse-output)))
+                  ;; GNUTLS_RND_NONCE should be good enough to ensure this.
+                  (should-not (member (secure-hash 'sha384 actual-iv 0 ivsize) 
actual-ivlist))
+                  (cond
+                   ((stringp iv)
+                    (should (equal iv actual-iv)))
+                   ((consp iv)
+                    (push (secure-hash 'sha384 actual-iv 0 ivsize) 
actual-ivlist)
+                    (gnutls-tests-message "IV list length: %d" (length 
actual-ivlist))))
+
+                  (gnutls-tests-message "%s %S" cipher cplist)
+                  (gnutls-tests-message "key %S IV %S input %S auth %S => 
hexdata %S and reverse %S" key iv input auth (encode-hex-string data) reverse)
+                  (should-not (gnutls-tests-hexstring-equal input data))
+                  (should-not (gnutls-tests-hexstring-equal data reverse))
+                  (should (gnutls-tests-hexstring-equal input 
reverse)))))))))))
+
+(provide 'gnutls-tests)
+;;; gnutls-tests.el ends here
diff --git a/test/lisp/net/network-stream-tests.el 
b/test/lisp/net/network-stream-tests.el
index e7bb3e8..9ee3a28 100644
--- a/test/lisp/net/network-stream-tests.el
+++ b/test/lisp/net/network-stream-tests.el
@@ -280,8 +280,11 @@
                       (< (setq times (1+ times)) 10))
             (sit-for 0.1))
           (should proc)
-          (while (eq (process-status proc) 'connect)
-            (sit-for 0.1)))
+          (setq times 0)
+          (while (and (eq (process-status proc) 'connect)
+                      (< (setq times (1+ times)) 10))
+            (sit-for 0.1))
+          (skip-unless (not (eq (process-status proc) 'connect))))
       (if (process-live-p server) (delete-process server)))
     (setq status (gnutls-peer-status proc))
     (should (consp status))
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 6c02daa..bb1bafa 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -86,8 +86,8 @@
       tramp-message-show-message nil
       tramp-persistency-file-name nil)
 
-;; This shall happen on hydra only.
-(when (getenv "NIX_STORE")
+;; This should happen on hydra only.
+(when (getenv "EMACS_HYDRA_CI")
   (add-to-list 'tramp-remote-path 'tramp-own-remote-path))
 
 (defvar tramp--test-expensive-test
@@ -132,12 +132,12 @@ If QUOTED is non-nil, the local part of the file is 
quoted."
     (make-temp-name "tramp-test")
     (if local temporary-file-directory tramp-test-temporary-file-directory))))
 
-;; Don't print messages in nested `tramp--instrument-test-case' calls.
-(defvar tramp--instrument-test-case-p nil
-  "Whether `tramp--instrument-test-case' run.
+;; Don't print messages in nested `tramp--test-instrument-test-case' calls.
+(defvar tramp--test-instrument-test-case-p nil
+  "Whether `tramp--test-instrument-test-case' run.
 This shall used dynamically bound only.")
 
-(defmacro tramp--instrument-test-case (verbose &rest body)
+(defmacro tramp--test-instrument-test-case (verbose &rest body)
   "Run BODY with `tramp-verbose' equal VERBOSE.
 Print the the content of the Tramp debug buffer, if BODY does not
 eval properly in `should' or `should-not'.  `should-error' is not
@@ -150,9 +150,9 @@ handled properly.  BODY shall not contain a timeout."
          (cons "^make-symbolic-link not supported$" debug-ignored-errors))
         inhibit-message)
      (unwind-protect
-        (let ((tramp--instrument-test-case-p t)) ,@body)
+        (let ((tramp--test-instrument-test-case-p t)) ,@body)
        ;; Unwind forms.
-       (when (and (null tramp--instrument-test-case-p) (> tramp-verbose 3))
+       (when (and (null tramp--test-instrument-test-case-p) (> tramp-verbose 
3))
         (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
           (with-current-buffer (tramp-get-connection-buffer v)
             (message "%s" (buffer-string)))
@@ -161,7 +161,7 @@ handled properly.  BODY shall not contain a timeout."
 
 (defsubst tramp--test-message (fmt-string &rest arguments)
   "Emit a message into ERT *Messages*."
-  (tramp--instrument-test-case 0
+  (tramp--test-instrument-test-case 0
     (apply
      'tramp-message
      (tramp-dissect-file-name tramp-test-temporary-file-directory) 0
@@ -169,7 +169,7 @@ handled properly.  BODY shall not contain a timeout."
 
 (defsubst tramp--test-backtrace ()
   "Dump a backtrace into ERT *Messages*."
-  (tramp--instrument-test-case 10
+  (tramp--test-instrument-test-case 10
     (tramp-backtrace
      (tramp-dissect-file-name tramp-test-temporary-file-directory))))
 
@@ -3699,11 +3699,14 @@ process sentinels.  They shall not disturb each other."
            (process-file-side-effects t)
            ;; Suppress nasty messages.
            (inhibit-message t)
+          ;; Do not run delayed timers.
+          (timer-max-repeats 0)
+          ;; Number of asynchronous processes for test.
            (number-proc 10)
            ;; On hydra, timings are bad.
            (timer-repeat
             (cond
-             ((getenv "NIX_STORE") 10)
+             ((getenv "EMACS_HYDRA_CI") 10)
              (t 1)))
            ;; We must distinguish due to performance reasons.
            (timer-operation
@@ -3726,16 +3729,26 @@ process sentinels.  They shall not disturb each other."
               0 timer-repeat
               (lambda ()
                 (when buffers
-                  (let ((default-directory tmp-name)
+                  (let ((time (float-time))
+                        (default-directory tmp-name)
                         (file
                          (buffer-name (nth (random (length buffers)) 
buffers))))
-                    (funcall timer-operation file))))))
+                    (tramp--test-message
+                     "Start timer %s %s" file (current-time-string))
+                    (funcall timer-operation file)
+                    ;; Adjust timer if it takes too much time.
+                    (when (> (- (float-time) time) timer-repeat)
+                      (setq timer-repeat (* 1.5 timer-repeat))
+                      (setf (timer--repeat-delay timer) timer-repeat)
+                      (tramp--test-message "Increase timer %s" timer-repeat))
+                    (tramp--test-message
+                     "Stop timer %s %s" file (current-time-string)))))))
 
             ;; Create temporary buffers.  The number of buffers
             ;; corresponds to the number of processes; it could be
             ;; increased in order to make pressure on Tramp.
             (dotimes (_i number-proc)
-              (add-to-list 'buffers (generate-new-buffer "foo")))
+              (setq buffers (cons (generate-new-buffer "foo") buffers)))
 
             ;; Open asynchronous processes.  Set process filter and sentinel.
             (dolist (buf buffers)
@@ -3776,17 +3789,30 @@ process sentinels.  They shall not disturb each other."
                        (proc (get-buffer-process buf))
                        (file (process-get proc 'foo))
                        (count (process-get proc 'bar)))
+                  (tramp--test-message
+                   "Start action %d %s %s" count buf (current-time-string))
                   ;; Regular operation.
                   (if (= count 0)
                       (should-not (file-attributes file))
                     (should (file-attributes file)))
                   ;; Send string to process.
+                  (tramp--test-message
+                   "Trace 1 action %d %s %s" count buf (current-time-string))
                   (process-send-string proc (format "%s\n" (buffer-name buf)))
+                  (tramp--test-message
+                   "Trace 2 action %d %s %s" count buf (current-time-string))
                   (accept-process-output proc 0.1 nil 0)
                   ;; Regular operation.
+                  (tramp--test-message
+                   "Trace 3 action %d %s %s" count buf (current-time-string))
                   (if (= count 2)
-                      (should-not (file-attributes file))
+                      (if (= (length buffers) 1)
+                          (tramp--test-instrument-test-case 10
+                            (should-not (file-attributes file)))
+                        (should-not (file-attributes file)))
                     (should (file-attributes file)))
+                  (tramp--test-message
+                   "Stop action %d %s %s" count buf (current-time-string))
                   (process-put proc 'bar (1+ count))
                   (unless (process-live-p proc)
                     (setq buffers (delq buf buffers))))))
@@ -3794,6 +3820,8 @@ process sentinels.  They shall not disturb each other."
             ;; Checks.  All process output shall exists in the
             ;; respective buffers.  All created files shall be
             ;; deleted.
+            (tramp--test-message
+             "Check %s" (current-time-string))
             (dolist (buf buffers)
               (with-current-buffer buf
                 (should (string-equal (format "%s\n" buf) (buffer-string)))))
@@ -3857,8 +3885,6 @@ process sentinels.  They shall not disturb each other."
 (ert-deftest tramp-test39-unload ()
   "Check that Tramp and its subpackages unload completely.
 Since it unloads Tramp, it shall be the last test to run."
-  ;; Mark as failed until all symbols are unbound.
-  :expected-result (if (featurep 'tramp) :failed :passed)
   :tags '(:expensive-test)
   (skip-unless noninteractive)
 
@@ -3869,21 +3895,31 @@ Since it unloads Tramp, it shall be the last test to 
run."
     (should-not (all-completions "tramp" (delq 'tramp-tests features)))
     ;; `file-name-handler-alist' must be clean.
     (should-not (all-completions "tramp" (mapcar 'cdr 
file-name-handler-alist)))
-    ;; There shouldn't be left a bound symbol.  We do not regard our
-    ;; test symbols, and the Tramp unload hooks.
+    ;; There shouldn't be left a bound symbol, except buffer-local
+    ;; variables, and autoload functions.  We do not regard our test
+    ;; symbols, and the Tramp unload hooks.
     (mapatoms
      (lambda (x)
-       (and (or (boundp x) (functionp x))
+       (and (or (and (boundp x) (null (local-variable-if-set-p x)))
+               (and (functionp x) (null (autoloadp (symbol-function x)))))
            (string-match "^tramp" (symbol-name x))
            (not (string-match "^tramp--?test" (symbol-name x)))
            (not (string-match "unload-hook$" (symbol-name x)))
            (ert-fail (format "`%s' still bound" x)))))
+    ;; The defstruct `tramp-file-name' and all its internal functions
+    ;; shall be purged.
+    (should-not (cl--find-class 'tramp-file-name))
+    (mapatoms
+     (lambda (x)
+       (and (string-match "tramp-file-name" (symbol-name x))
+            (functionp x)
+            (ert-fail (format "Structure function `%s' still exists" x)))))
     ;; There shouldn't be left a hook function containing a Tramp
     ;; function.  We do not regard the Tramp unload hooks.
     (mapatoms
      (lambda (x)
        (and (boundp x)
-           (string-match "-hooks?$" (symbol-name x))
+           (string-match "-\\(hook\\|function\\)s?$" (symbol-name x))
            (not (string-match "unload-hook$" (symbol-name x)))
            (consp (symbol-value x))
            (ignore-errors (all-completions "tramp" (symbol-value x)))
@@ -3904,11 +3940,7 @@ Since it unloads Tramp, it shall be the last test to 
run."
 ;; * Fix `tramp-test05-expand-file-name-relative' in `expand-file-name'.
 ;; * Fix `tramp-test06-directory-file-name' for `ftp'.
 ;; * Fix `tramp-test27-start-file-process' on MS Windows (`process-send-eof'?).
-;; * Fix Bug#27009.  Set expected error of
-;;   `tramp-test29-environment-variables-and-port-numbers'.
 ;; * Fix Bug#16928 in `tramp-test36-asynchronous-requests'.
-;; * Fix `tramp-test39-unload' (Not all symbols are unbound).  Set
-;;   expected error.
 
 (defun tramp-test-all (&optional interactive)
   "Run all tests for \\[tramp]."
diff --git a/test/lisp/ses-tests.el b/test/lisp/ses-tests.el
new file mode 100644
index 0000000..8fff6f7
--- /dev/null
+++ b/test/lisp/ses-tests.el
@@ -0,0 +1,175 @@
+;;; ses-tests.el --- Tests for ses.el              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015-2017 Free Software Foundation, Inc.
+
+;; Author: Vincent Belaïche <address@hidden>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'ses)
+
+
+;; PLAIN FORMULA TESTS
+;; ======================================================================
+
+(ert-deftest ses-tests-lowlevel-plain-formula ()
+  "Check that setting A1 to 1 and A2 to (1+ A1), makes A2 value
+equal to 2. This is done with low level functions calls, not like
+interactively."
+  (let ((ses-initial-size '(2 . 1)))
+    (with-temp-buffer
+      (ses-mode)
+      (dolist (c '((0 0 1) (1 0 (1+ A1))))
+        (apply 'ses-cell-set-formula c)
+        (apply 'ses-calculate-cell (list (car c) (cadr c) nil)))
+      (should (eq A2 2)))))
+
+(ert-deftest ses-tests-plain-formula ()
+  "Check that setting A1 to 1 and A2 to (1+ A1), makes A2 value
+equal to 2. This is done  using interactive calls."
+  (let ((ses-initial-size '(2 . 1)))
+    (with-temp-buffer
+      (ses-mode)
+      (dolist (c '((0 0 1) (1 0 (1+ A1))))
+        (apply 'funcall-interactively 'ses-edit-cell c))
+      (ses-command-hook)
+      (should (eq A2 2)))))
+
+;; PLAIN CELL RENAMING TESTS
+;; ======================================================================
+
+(ert-deftest ses-tests-lowlevel-renamed-cell ()
+  "Check that renaming A1 to `foo' and setting `foo' to 1 and A2 to (1+ foo), 
makes A2 value equal to 2.
+This is done using low level functions, `ses-rename-cell' is not
+called but instead we use text replacement in the buffer
+previously passed in text mode."
+  (let ((ses-initial-size '(2 . 1)))
+    (with-temp-buffer
+      (ses-mode)
+      (dolist (c '((0 0 1) (1 0 (1+ A1))))
+        (apply 'ses-cell-set-formula c)
+        (apply 'ses-calculate-cell (list (car c) (cadr c) nil)))
+      (ses-write-cells)
+      (text-mode)
+      (goto-char (point-min))
+      (while (re-search-forward "\\<A1\\>" nil t)
+        (replace-match "foo" t t))
+      (ses-mode)
+      (should-not  (local-variable-p 'A1))
+      (should (eq foo 1))
+      (should (equal (ses-cell-formula 1 0) '(ses-safe-formula (1+ foo))))
+      (should (eq A2 2)))))
+
+(ert-deftest ses-tests-renamed-cell ()
+  "Check that renaming A1 to `foo' and setting `foo' to 1 and A2
+to (1+ foo), makes A2 value equal to 2."
+  (let ((ses-initial-size '(2 . 1)))
+    (with-temp-buffer
+      (ses-mode)
+      (ses-rename-cell 'foo (ses-get-cell 0 0))
+      (dolist (c '((0 0 1) (1 0 (1+ foo))))
+        (apply 'funcall-interactively 'ses-edit-cell c))
+      (ses-command-hook)
+      (should-not  (local-variable-p 'A1))
+      (should (eq foo 1))
+      (should (equal (ses-cell-formula 1 0) '(1+ foo)))
+      (should (eq A2 2)))))
+
+(ert-deftest ses-tests-renamed-cell-after-setting ()
+  "Check that setting A1 to 1 and A2 to (1+ A1), and then
+renaming A1 to `foo' makes `foo' value equal to 2."
+  (let ((ses-initial-size '(2 . 1)))
+    (with-temp-buffer
+      (ses-mode)
+      (dolist (c '((0 0 1) (1 0 (1+ A1))))
+        (apply 'funcall-interactively 'ses-edit-cell c))
+      (ses-command-hook); deferred recalc
+      (ses-rename-cell 'foo (ses-get-cell 0 0))
+      (should-not  (local-variable-p 'A1))
+      (should (eq foo 1))
+      (should (equal (ses-cell-formula 1 0) '(1+ foo)))
+      (should (eq A2 2)))))
+
+(ert-deftest ses-tests-renaming-cell-with-one-symbol-formula ()
+  "Check that setting A1 to 1 and A2 to A1, and then renaming A1
+to `foo' makes `foo' value equal to 1. Then set A1 to 2 and check
+that `foo' becomes 2."
+  (let ((ses-initial-size '(3 . 1)))
+    (with-temp-buffer
+      (ses-mode)
+      (dolist (c '((0 0 1) (1 0 A1)))
+        (apply 'funcall-interactively 'ses-edit-cell c))
+      (ses-command-hook); deferred recalc
+      (ses-rename-cell 'foo (ses-get-cell 0 0))
+      (ses-command-hook); deferred recalc
+      (should-not  (local-variable-p 'A1))
+      (should (eq foo 1))
+      (should (equal (ses-cell-formula 1 0) 'foo))
+      (should (eq A2 1))
+      (funcall-interactively 'ses-edit-cell 0 0 2)
+      (ses-command-hook); deferred recalc
+      (should (eq A2 2))
+      (should (eq foo 2)))))
+
+
+;; ROW INSERTION TESTS
+;; ======================================================================
+
+(ert-deftest ses-tests-plain-row-insertion ()
+  "Check that setting A1 to 1 and A2 to (1+ A1), and then jumping
+to A2 and inserting a row, makes A2 value empty, and A3 equal to
+2."
+  (let ((ses-initial-size '(2 . 1)))
+    (with-temp-buffer
+      (ses-mode)
+      (dolist (c '((0 0 1) (1 0 (1+ A1))))
+        (apply 'funcall-interactively 'ses-edit-cell c))
+      (ses-command-hook)
+      (ses-jump 'A2)
+      (ses-insert-row 1)
+      (ses-command-hook)
+      (should-not A2)
+      (should (eq A3 2)))))
+
+; (defvar ses-tests-trigger nil)
+
+(ert-deftest ses-tests-renamed-cells-row-insertion ()
+  "Check that setting A1 to 1 and A2 to (1+ A1), and then renaming A1 to `foo' 
and A2 to `bar' jumping
+to `bar' and inserting a row, makes A2 value empty, and `bar' equal to
+2."
+  (setq ses-tests-trigger nil)
+  (let ((ses-initial-size '(2 . 1)))
+    (with-temp-buffer
+      (ses-mode)
+      (dolist (c '((0 0 1) (1 0 (1+ A1))))
+        (apply 'funcall-interactively 'ses-edit-cell c))
+      (ses-command-hook)
+      (ses-rename-cell 'foo (ses-get-cell 0 0))
+      (ses-command-hook)
+      (ses-rename-cell 'bar (ses-get-cell 1 0))
+      (ses-command-hook)
+      (should (eq bar 2))
+      (ses-jump 'bar)
+      (ses-insert-row 1)
+      (ses-command-hook)
+      (should-not A2)
+      (should (eq bar 2)))))
+
+
+(provide 'ses-tests)
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index 54f4ab5..7e50429 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -258,9 +258,9 @@ This exercises `backtrace-frame', and indirectly 
`mapbacktrace'."
     (should (equal (mapbacktrace #'error unbound) nil)))
   ;; First frame is backtrace-related function
   (should (equal (backtrace-frame 0) '(t backtrace-frame 0)))
-  (should (equal (catch 'ret
-                   (mapbacktrace (lambda (&rest args) (throw 'ret args))))
-                 '(t mapbacktrace ((lambda (&rest args) (throw 'ret args))) 
nil)))
+  (let ((throw-args (lambda (&rest args) (throw 'ret args))))
+    (should (equal (catch 'ret (mapbacktrace throw-args))
+                   `(t mapbacktrace (,throw-args) nil))))
   ;; Past-end NFRAMES is silently ignored
   (should (equal (backtrace-frame most-positive-fixnum) nil)))
 
diff --git a/test/manual/BidiCharacterTest.txt 
b/test/manual/BidiCharacterTest.txt
index 7e04d6c..a3d2b46 100644
--- a/test/manual/BidiCharacterTest.txt
+++ b/test/manual/BidiCharacterTest.txt
@@ -1,6 +1,6 @@
-# BidiCharacterTest-9.0.0.txt
-# Date: 2016-01-15, 22:30:00 GMT [LI]
-# © 2016 Unicode®, Inc.
+# BidiCharacterTest-10.0.0.txt
+# Date: 2017-03-09, 00:30:00 GMT [LI]
+# © 2017 Unicode®, Inc.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
 # Unicode Character Database
diff --git a/test/manual/etags/CTAGS.good b/test/manual/etags/CTAGS.good
index 13bb37c..519315c 100644
--- a/test/manual/etags/CTAGS.good
+++ b/test/manual/etags/CTAGS.good
@@ -202,6 +202,7 @@ ${CHECKOBJS}        make-src/Makefile       /^${CHECKOBJS}: 
CFLAGS=-g3 -DNULLFREECHECK=0$/
 =\relax        tex-src/texinfo.tex     /^\\let\\subsubsection=\\relax$/
 =\relax        tex-src/texinfo.tex     /^\\let\\appendix=\\relax$/
 =\smartitalic  tex-src/texinfo.tex     /^\\let\\cite=\\smartitalic$/
+=starts-with-equals!   scm-src/test.scm        /^(define =starts-with-equals! 
#t)$/
 >      tex-src/texinfo.tex     /^\\def>{{\\tt \\gtr}}$/
 >field1        forth-src/test-forth.fth        /^   9   field   >field1$/
 >field2        forth-src/test-forth.fth        /^   5   field   >field2$/
@@ -2750,6 +2751,7 @@ current-idle-time c-src/emacs/src/keyboard.c      /^DEFUN 
("current-idle-time", Fcurr
 current-input-mode     c-src/emacs/src/keyboard.c      /^DEFUN 
("current-input-mode", Fcurrent_input_mode, /
 current_kboard c-src/emacs/src/keyboard.c      85
 current_lb_is_new      c-src/etags.c   2926
+curry-test     scm-src/test.scm        /^(define (((((curry-test a) b) c) d) 
e)$/
 cursor_position        cp-src/screen.cpp       /^void cursor_position(void)$/
 cursor_x       cp-src/screen.cpp       15
 cursor_y       cp-src/screen.cpp       15
@@ -3037,6 +3039,7 @@ foo       ruby-src/test1.ru       /^    attr_reader :foo$/
 foo!   ruby-src/test1.ru       /^    def foo!$/
 foo1   ruby-src/test1.ru       /^    attr_reader(:foo1, :bar1, # comment$/
 foo2   ruby-src/test1.ru       /^    alias_method ( :foo2, #cmmt$/
+foo==bar       el-src/TAGTEST.EL       /^(defun foo==bar () (message "hi"))  ; 
Bug#5624$/
 foobar c-src/c.c       /^int foobar() {;}$/
 foobar c.c     /^extern void foobar (void) __attribute__ ((section /
 foobar2        c-src/h.h       20
@@ -3161,6 +3164,9 @@ header    c-src/emacs/src/lisp.h  1672
 header c-src/emacs/src/lisp.h  1826
 header_size    c-src/emacs/src/lisp.h  1471
 heapsize       c-src/emacs/src/gmalloc.c       361
+hello  scm-src/test.scm        /^(define hello "Hello, Emacs!")$/
+hello  scm-src/test.scm        /^(set! hello "Hello, world!")$/
+hello-world    scm-src/test.scm        /^(define (hello-world)$/
 help   c-src/etags.c   193
 helpPanel      objcpp-src/SimpleCalc.M /^- helpPanel:sender$/
 help_char_p    c-src/emacs/src/keyboard.c      /^help_char_p (Lisp_Object c)$/
@@ -4317,10 +4323,12 @@ test    erl-src/gs_dialog.erl   /^test() ->$/
 test   go-src/test1.go /^func test(p plus) {$/
 test   make-src/Makefile       /^test:$/
 test   php-src/ptest.php       /^test $/
+test-begin     scm-src/test.scm        /^(define-syntax test-begin$/
 test.me22b     lua-src/test.lua        /^   local function test.me22b (one)$/
 test.me_22a    lua-src/test.lua        /^   function test.me_22a(one, two)$/
 test_undefined c-src/emacs/src/keyboard.c      /^test_undefined (Lisp_Object 
binding)$/
 texttreelist   prol-src/natded.prolog  /^texttreelist([]).$/
+there-is-a-=-in-the-middle!    scm-src/test.scm        /^(define 
(there-is-a-=-in-the-middle!) #t)$/
 this   c-src/a/b/b.c   1
 this-command-keys      c-src/emacs/src/keyboard.c      /^DEFUN 
("this-command-keys", Fthis_command_keys, St/
 this-command-keys-vector       c-src/emacs/src/keyboard.c      /^DEFUN 
("this-command-keys-vector", Fthis_command_k/
diff --git a/test/manual/etags/ETAGS.good_1 b/test/manual/etags/ETAGS.good_1
index 6c4a02a..cd9cd4a 100644
--- a/test/manual/etags/ETAGS.good_1
+++ b/test/manual/etags/ETAGS.good_1
@@ -2143,10 +2143,11 @@ main(37,571
        class D 41,622
                D(43,659
 
-el-src/TAGTEST.EL,148
+el-src/TAGTEST.EL,179
 (foo::defmumble bletch 1,0
-(defalias 'pending-delete-mode pending-delete-mode5,102
-(defalias (quote explicitly-quoted-pending-delete-mode)8,175
+(defun foo==bar foo==bar2,33
+(defalias 'pending-delete-mode pending-delete-mode6,149
+(defalias (quote explicitly-quoted-pending-delete-mode)9,222
 
 el-src/emacs/lisp/progmodes/etags.el,5069
 (defvar tags-file-name 34,1034
@@ -3135,6 +3136,15 @@ module A9,57
     alias_method ( :foo2,foo237,586
 A::Constant Constant42,655
 
+scm-src/test.scm,260
+(define hello 1,0
+(set! hello 3,32
+(define (hello-world)5,62
+(define (there-is-a-=-in-the-middle!)there-is-a-=-in-the-middle!10,128
+(define =starts-with-equals! =starts-with-equals!12,171
+(define (((((curry-test 14,205
+(define-syntax test-begin17,265
+
 tex-src/testenv.tex,52
 \newcommand{\nm}\nm4,77
 \section{blah}blah8,139
@@ -3145,11 +3155,11 @@ tex-src/gzip.texi,303
 @node Overview,83,2705
 @node Sample,166,7272
 @node Invoking gzip,Invoking gzip210,8828
address@hidden Advanced usage,Advanced usage357,13495
address@hidden Environment,420,15207
address@hidden Tapes,437,15768
address@hidden Problems,460,16767
address@hidden Concept Index,Concept Index473,17287
address@hidden Advanced usage,Advanced usage357,13496
address@hidden Environment,420,15208
address@hidden Tapes,437,15769
address@hidden Problems,460,16768
address@hidden Concept Index,Concept Index473,17288
 
 tex-src/texinfo.tex,30627
 \def\texinfoversion{\texinfoversion26,1032
diff --git a/test/manual/etags/ETAGS.good_2 b/test/manual/etags/ETAGS.good_2
index fa784d2..54fd00e 100644
--- a/test/manual/etags/ETAGS.good_2
+++ b/test/manual/etags/ETAGS.good_2
@@ -2712,10 +2712,11 @@ main(37,571
        class D 41,622
                D(43,659
 
-el-src/TAGTEST.EL,148
+el-src/TAGTEST.EL,179
 (foo::defmumble bletch 1,0
-(defalias 'pending-delete-mode pending-delete-mode5,102
-(defalias (quote explicitly-quoted-pending-delete-mode)8,175
+(defun foo==bar foo==bar2,33
+(defalias 'pending-delete-mode pending-delete-mode6,149
+(defalias (quote explicitly-quoted-pending-delete-mode)9,222
 
 el-src/emacs/lisp/progmodes/etags.el,5188
 (defvar tags-file-name 34,1034
@@ -3708,6 +3709,15 @@ module A9,57
     alias_method ( :foo2,foo237,586
 A::Constant Constant42,655
 
+scm-src/test.scm,260
+(define hello 1,0
+(set! hello 3,32
+(define (hello-world)5,62
+(define (there-is-a-=-in-the-middle!)there-is-a-=-in-the-middle!10,128
+(define =starts-with-equals! =starts-with-equals!12,171
+(define (((((curry-test 14,205
+(define-syntax test-begin17,265
+
 tex-src/testenv.tex,52
 \newcommand{\nm}\nm4,77
 \section{blah}blah8,139
@@ -3718,11 +3728,11 @@ tex-src/gzip.texi,303
 @node Overview,83,2705
 @node Sample,166,7272
 @node Invoking gzip,Invoking gzip210,8828
address@hidden Advanced usage,Advanced usage357,13495
address@hidden Environment,420,15207
address@hidden Tapes,437,15768
address@hidden Problems,460,16767
address@hidden Concept Index,Concept Index473,17287
address@hidden Advanced usage,Advanced usage357,13496
address@hidden Environment,420,15208
address@hidden Tapes,437,15769
address@hidden Problems,460,16768
address@hidden Concept Index,Concept Index473,17288
 
 tex-src/texinfo.tex,30627
 \def\texinfoversion{\texinfoversion26,1032
diff --git a/test/manual/etags/ETAGS.good_3 b/test/manual/etags/ETAGS.good_3
index 547dee2..508427c 100644
--- a/test/manual/etags/ETAGS.good_3
+++ b/test/manual/etags/ETAGS.good_3
@@ -2520,10 +2520,11 @@ main(37,571
                D(43,659
                int x;44,694
 
-el-src/TAGTEST.EL,148
+el-src/TAGTEST.EL,179
 (foo::defmumble bletch 1,0
-(defalias 'pending-delete-mode pending-delete-mode5,102
-(defalias (quote explicitly-quoted-pending-delete-mode)8,175
+(defun foo==bar foo==bar2,33
+(defalias 'pending-delete-mode pending-delete-mode6,149
+(defalias (quote explicitly-quoted-pending-delete-mode)9,222
 
 el-src/emacs/lisp/progmodes/etags.el,5069
 (defvar tags-file-name 34,1034
@@ -3542,6 +3543,15 @@ module A9,57
     alias_method ( :foo2,foo237,586
 A::Constant Constant42,655
 
+scm-src/test.scm,260
+(define hello 1,0
+(set! hello 3,32
+(define (hello-world)5,62
+(define (there-is-a-=-in-the-middle!)there-is-a-=-in-the-middle!10,128
+(define =starts-with-equals! =starts-with-equals!12,171
+(define (((((curry-test 14,205
+(define-syntax test-begin17,265
+
 tex-src/testenv.tex,52
 \newcommand{\nm}\nm4,77
 \section{blah}blah8,139
@@ -3552,11 +3562,11 @@ tex-src/gzip.texi,303
 @node Overview,83,2705
 @node Sample,166,7272
 @node Invoking gzip,Invoking gzip210,8828
address@hidden Advanced usage,Advanced usage357,13495
address@hidden Environment,420,15207
address@hidden Tapes,437,15768
address@hidden Problems,460,16767
address@hidden Concept Index,Concept Index473,17287
address@hidden Advanced usage,Advanced usage357,13496
address@hidden Environment,420,15208
address@hidden Tapes,437,15769
address@hidden Problems,460,16768
address@hidden Concept Index,Concept Index473,17288
 
 tex-src/texinfo.tex,30627
 \def\texinfoversion{\texinfoversion26,1032
diff --git a/test/manual/etags/ETAGS.good_4 b/test/manual/etags/ETAGS.good_4
index 2c50ec1..460e31b 100644
--- a/test/manual/etags/ETAGS.good_4
+++ b/test/manual/etags/ETAGS.good_4
@@ -2307,10 +2307,11 @@ main(37,571
        class D 41,622
                D(43,659
 
-el-src/TAGTEST.EL,148
+el-src/TAGTEST.EL,179
 (foo::defmumble bletch 1,0
-(defalias 'pending-delete-mode pending-delete-mode5,102
-(defalias (quote explicitly-quoted-pending-delete-mode)8,175
+(defun foo==bar foo==bar2,33
+(defalias 'pending-delete-mode pending-delete-mode6,149
+(defalias (quote explicitly-quoted-pending-delete-mode)9,222
 
 el-src/emacs/lisp/progmodes/etags.el,5069
 (defvar tags-file-name 34,1034
@@ -3299,6 +3300,15 @@ module A9,57
     alias_method ( :foo2,foo237,586
 A::Constant Constant42,655
 
+scm-src/test.scm,260
+(define hello 1,0
+(set! hello 3,32
+(define (hello-world)5,62
+(define (there-is-a-=-in-the-middle!)there-is-a-=-in-the-middle!10,128
+(define =starts-with-equals! =starts-with-equals!12,171
+(define (((((curry-test 14,205
+(define-syntax test-begin17,265
+
 tex-src/testenv.tex,52
 \newcommand{\nm}\nm4,77
 \section{blah}blah8,139
@@ -3309,11 +3319,11 @@ tex-src/gzip.texi,303
 @node Overview,83,2705
 @node Sample,166,7272
 @node Invoking gzip,Invoking gzip210,8828
address@hidden Advanced usage,Advanced usage357,13495
address@hidden Environment,420,15207
address@hidden Tapes,437,15768
address@hidden Problems,460,16767
address@hidden Concept Index,Concept Index473,17287
address@hidden Advanced usage,Advanced usage357,13496
address@hidden Environment,420,15208
address@hidden Tapes,437,15769
address@hidden Problems,460,16768
address@hidden Concept Index,Concept Index473,17288
 
 tex-src/texinfo.tex,30627
 \def\texinfoversion{\texinfoversion26,1032
diff --git a/test/manual/etags/ETAGS.good_5 b/test/manual/etags/ETAGS.good_5
index 2b43103..b7a3160 100644
--- a/test/manual/etags/ETAGS.good_5
+++ b/test/manual/etags/ETAGS.good_5
@@ -3253,10 +3253,11 @@ main(37,571
                D(43,659
                int x;44,694
 
-el-src/TAGTEST.EL,148
+el-src/TAGTEST.EL,179
 (foo::defmumble bletch 1,0
-(defalias 'pending-delete-mode pending-delete-mode5,102
-(defalias (quote explicitly-quoted-pending-delete-mode)8,175
+(defun foo==bar foo==bar2,33
+(defalias 'pending-delete-mode pending-delete-mode6,149
+(defalias (quote explicitly-quoted-pending-delete-mode)9,222
 
 el-src/emacs/lisp/progmodes/etags.el,5188
 (defvar tags-file-name 34,1034
@@ -4279,6 +4280,15 @@ module A9,57
     alias_method ( :foo2,foo237,586
 A::Constant Constant42,655
 
+scm-src/test.scm,260
+(define hello 1,0
+(set! hello 3,32
+(define (hello-world)5,62
+(define (there-is-a-=-in-the-middle!)there-is-a-=-in-the-middle!10,128
+(define =starts-with-equals! =starts-with-equals!12,171
+(define (((((curry-test 14,205
+(define-syntax test-begin17,265
+
 tex-src/testenv.tex,52
 \newcommand{\nm}\nm4,77
 \section{blah}blah8,139
@@ -4289,11 +4299,11 @@ tex-src/gzip.texi,303
 @node Overview,83,2705
 @node Sample,166,7272
 @node Invoking gzip,Invoking gzip210,8828
address@hidden Advanced usage,Advanced usage357,13495
address@hidden Environment,420,15207
address@hidden Tapes,437,15768
address@hidden Problems,460,16767
address@hidden Concept Index,Concept Index473,17287
address@hidden Advanced usage,Advanced usage357,13496
address@hidden Environment,420,15208
address@hidden Tapes,437,15769
address@hidden Problems,460,16768
address@hidden Concept Index,Concept Index473,17288
 
 tex-src/texinfo.tex,30627
 \def\texinfoversion{\texinfoversion26,1032
diff --git a/test/manual/etags/ETAGS.good_6 b/test/manual/etags/ETAGS.good_6
index 2cb0d05..a75fd80 100644
--- a/test/manual/etags/ETAGS.good_6
+++ b/test/manual/etags/ETAGS.good_6
@@ -3253,10 +3253,11 @@ main(37,571
                D(D::D43,659
                int x;D::x44,694
 
-el-src/TAGTEST.EL,148
+el-src/TAGTEST.EL,179
 (foo::defmumble bletch 1,0
-(defalias 'pending-delete-mode pending-delete-mode5,102
-(defalias (quote explicitly-quoted-pending-delete-mode)8,175
+(defun foo==bar foo==bar2,33
+(defalias 'pending-delete-mode pending-delete-mode6,149
+(defalias (quote explicitly-quoted-pending-delete-mode)9,222
 
 el-src/emacs/lisp/progmodes/etags.el,5188
 (defvar tags-file-name 34,1034
@@ -4279,6 +4280,15 @@ module A9,57
     alias_method ( :foo2,foo237,586
 A::Constant Constant42,655
 
+scm-src/test.scm,260
+(define hello 1,0
+(set! hello 3,32
+(define (hello-world)5,62
+(define (there-is-a-=-in-the-middle!)there-is-a-=-in-the-middle!10,128
+(define =starts-with-equals! =starts-with-equals!12,171
+(define (((((curry-test 14,205
+(define-syntax test-begin17,265
+
 tex-src/testenv.tex,52
 \newcommand{\nm}\nm4,77
 \section{blah}blah8,139
@@ -4289,11 +4299,11 @@ tex-src/gzip.texi,303
 @node Overview,83,2705
 @node Sample,166,7272
 @node Invoking gzip,Invoking gzip210,8828
address@hidden Advanced usage,Advanced usage357,13495
address@hidden Environment,420,15207
address@hidden Tapes,437,15768
address@hidden Problems,460,16767
address@hidden Concept Index,Concept Index473,17287
address@hidden Advanced usage,Advanced usage357,13496
address@hidden Environment,420,15208
address@hidden Tapes,437,15769
address@hidden Problems,460,16768
address@hidden Concept Index,Concept Index473,17288
 
 tex-src/texinfo.tex,30627
 \def\texinfoversion{\texinfoversion26,1032
diff --git a/test/manual/etags/Makefile b/test/manual/etags/Makefile
index 07ad0f4..c1df703 100644
--- a/test/manual/etags/Makefile
+++ b/test/manual/etags/Makefile
@@ -25,12 +25,13 @@ PSSRC=$(addprefix ./ps-src/,rfc1245.ps)
 PROLSRC=$(addprefix ./prol-src/,ordsets.prolog natded.prolog)
 PYTSRC=$(addprefix ./pyt-src/,server.py)
 RBSRC=$(addprefix ./ruby-src/,test.rb test1.ru)
+SCMSRC=$(addprefix ./scm-src/,test.scm)
 TEXSRC=$(addprefix ./tex-src/,testenv.tex gzip.texi texinfo.tex nonewline.tex)
 YSRC=$(addprefix ./y-src/,parse.y parse.c atest.y cccp.c cccp.y)
 SRCS=${ADASRC} ${ASRC} ${CSRC} ${CPSRC} ${ELSRC} ${ERLSRC} ${FSRC}\
      ${FORTHSRC} ${GOSRC} ${HTMLSRC} ${JAVASRC} ${LUASRC} ${MAKESRC}\
      ${OBJCSRC} ${OBJCPPSRC} ${PASSRC} ${PHPSRC} ${PERLSRC} ${PSSRC}\
-     ${PROLSRC} ${PYTSRC} ${RBSRC} ${TEXSRC} ${YSRC}
+     ${PROLSRC} ${PYTSRC} ${RBSRC} ${SCMSRC} ${TEXSRC} ${YSRC}
 NONSRCS=./f-src/entry.strange ./erl-src/lists.erl ./cp-src/clheir.hpp.gz
 
 ETAGS_PROG=../../../lib-src/etags
diff --git a/test/manual/etags/el-src/TAGTEST.EL 
b/test/manual/etags/el-src/TAGTEST.EL
index acf0baf..89a6791 100644
--- a/test/manual/etags/el-src/TAGTEST.EL
+++ b/test/manual/etags/el-src/TAGTEST.EL
@@ -1,4 +1,5 @@
 (foo::defmumble bletch beuarghh)
+(defun foo==bar () (message "hi"))  ; Bug#5624
 ;;; Ctags test file for lisp mode.
 
 ;; from emacs/lisp/delsel.el:76:
diff --git a/test/manual/etags/scm-src/test.scm 
b/test/manual/etags/scm-src/test.scm
new file mode 100644
index 0000000..e3921e7
--- /dev/null
+++ b/test/manual/etags/scm-src/test.scm
@@ -0,0 +1,20 @@
+(define hello "Hello, Emacs!")
+
+(set! hello "Hello, world!")
+
+(define (hello-world)
+  (display hello)
+  (newline))
+
+;; Bug 5624
+(define (there-is-a-=-in-the-middle!) #t)
+
+(define =starts-with-equals! #t)
+
+(define (((((curry-test a) b) c) d) e)
+  (list a b c d e))
+
+(define-syntax test-begin
+  (syntax-rules ()
+    ((test-begin exp ...)
+     ((lambda () exp ...)))))
diff --git a/test/manual/image-size-tests.el b/test/manual/image-size-tests.el
index 577c765..ad43426 100644
--- a/test/manual/image-size-tests.el
+++ b/test/manual/image-size-tests.el
@@ -25,8 +25,8 @@
 (defmacro im-should (image width height &rest props)
   `(let ((im (im-image ,image ,@props)))
      (unless (im-compare im ,width ,height)
-       (error "%s didn't succeed; size is %s"
-              ',props (image-size im t)))))
+       (error "%s %s didn't succeed; size is %s"
+              ',image ',props (image-size im t)))))
 
 (defun im-image (type &rest props)
   (let ((image-scaling-factor 1))
@@ -67,6 +67,9 @@
   ;; Both max-width/height.
   (im-should :w 100 50 :max-width 100 :max-height 75)
   (im-should :w 50 25 :max-width 100 :max-height 25)
+  ;; :width and :max-height (max-height wins).
+  (im-should :w 400 200 :width 400 :max-height 200)
+  (im-should :w 400 200 :width 500 :max-height 200)
 
   ;; Test the image that's taller than it is wide.
   (im-should :h 100 200)
@@ -87,6 +90,9 @@
   ;; Both max-width/height.
   (im-should :h 50 100 :max-width 75 :max-height 100)
   (im-should :h 25 50 :max-width 25 :max-height 100)
+  ;; :height and :max-width (max-width wins).
+  (im-should :h 200 400 :height 400 :max-width 200)
+  (im-should :h 200 400 :height 500 :max-width 200)
   )
 
 ;;; image-size-tests.el ends here
diff --git a/test/manual/indent/perl.perl b/test/manual/indent/perl.perl
index f86a09b..06f32e7 100755
--- a/test/manual/indent/perl.perl
+++ b/test/manual/indent/perl.perl
@@ -53,6 +53,14 @@ EOF1
 bar
 EOF2
 
+print <<~"EOF1" . <<\EOF2 . s/he"llo/th'ere/;
+foo
+EOF2
+   bar
+   EOF1
+bar
+EOF2
+
 print $'; # This should not start a string!
 
 print "hello" for /./;
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el
index a4994b6..2aa85f0 100644
--- a/test/src/emacs-module-tests.el
+++ b/test/src/emacs-module-tests.el
@@ -182,37 +182,66 @@ changes."
   (should (equal (help-function-arglist #'mod-test-sum)
                  '(arg1 arg2))))
 
-(ert-deftest module--test-assertions ()
-  "Check that -module-assertions work."
+(defmacro module--with-temp-directory (name &rest body)
+  "Bind NAME to the name of a temporary directory and evaluate BODY.
+NAME must be a symbol.  Delete the temporary directory after BODY
+exits normally or non-locally.  NAME will be bound to the
+directory name (not the directory file name) of the temporary
+directory."
+  (declare (indent 1))
+  (cl-check-type name symbol)
+  `(let ((,name (file-name-as-directory
+                 (make-temp-file "emacs-module-test" :directory))))
+     (unwind-protect
+         (progn ,@body)
+       (delete-directory ,name :recursive))))
+
+(defmacro module--test-assertion (pattern &rest body)
+  "Test that PATTERN matches the assertion triggered by BODY.
+Run Emacs as a subprocess, load the test module `mod-test-file',
+and evaluate BODY.  Verify that Emacs aborts and prints a module
+assertion message that matches PATTERN.  PATTERN is evaluated and
+must evaluate to a regular expression string."
+  (declare (indent 1))
+  ;; To contain any core dumps.
+  `(module--with-temp-directory tempdir
+     (with-temp-buffer
+       (let* ((default-directory tempdir)
+              (status (call-process mod-test-emacs nil t nil
+                                    "-batch" "-Q" "-module-assertions" "-eval"
+                                    ,(prin1-to-string
+                                      `(progn
+                                         (require 'mod-test ,mod-test-file)
+                                         ,@body)))))
+         (should (stringp status))
+         ;; eg "Aborted" or "Abort trap: 6"
+         (should (string-prefix-p "Abort" status))
+         (search-backward "Emacs module assertion: ")
+         (goto-char (match-end 0))
+         (should (string-match-p ,pattern
+                                 (buffer-substring-no-properties
+                                  (point) (point-max))))))))
+
+(ert-deftest module--test-assertions--load-non-live-object ()
+  "Check that -module-assertions verify that non-live objects
+aren’t accessed."
   (skip-unless (file-executable-p mod-test-emacs))
   ;; This doesn’t yet cause undefined behavior.
   (should (eq (mod-test-invalid-store) 123))
-  ;; To contain any core dumps.
-  (let ((tempdir (make-temp-file "emacs-module-test" t)))
-    (unwind-protect
-        (with-temp-buffer
-          (should (string-match-p
-                   "Abort" ; eg "Aborted" or "Abort trap: 6"
-                   (let ((default-directory tempdir))
-                     (call-process mod-test-emacs nil t nil
-                                   "-batch" "-Q" "-module-assertions" "-eval"
-                                   (prin1-to-string
-                                    `(progn
-                                       (require 'mod-test ,mod-test-file)
-                                       ;; Storing and reloading a local
-                                       ;; value causes undefined behavior,
-                                       ;; which should be detected by the
-                                       ;; module assertions.
-                                       (mod-test-invalid-store)
-                                       (mod-test-invalid-load)))))))
-          (search-backward "Emacs module assertion:")
-          (should (string-match-p (rx bos "Emacs module assertion: "
-                                      "Emacs value not found in "
-                                      (+ digit) " values of "
-                                      (+ digit) " environments" eos)
-                                  (buffer-substring-no-properties
-                                   (line-beginning-position)
-                                   (line-end-position)))))
-      (delete-directory tempdir t))))
+  (module--test-assertion (rx "Emacs value not found in "
+                              (+ digit) " values of "
+                              (+ digit) " environments\n")
+    ;; Storing and reloading a local value causes undefined behavior,
+    ;; which should be detected by the module assertions.
+    (mod-test-invalid-store)
+    (mod-test-invalid-load)))
+
+(ert-deftest module--test-assertions--call-emacs-from-gc ()
+  "Check that -module-assertions prevents calling Emacs functions
+during garbage collection."
+  (skip-unless (file-executable-p mod-test-emacs))
+  (module--test-assertion
+      (rx "Module function called during garbage collection\n")
+    (mod-test-invalid-finalizer)))
 
 ;;; emacs-module-tests.el ends here
diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el
index 2e46345..e294859 100644
--- a/test/src/fns-tests.el
+++ b/test/src/fns-tests.el
@@ -373,6 +373,12 @@
     (should-error (assoc 3 d1) :type 'wrong-type-argument)
     (should-error (assoc 3 d2) :type 'wrong-type-argument)))
 
+(ert-deftest test-assoc-testfn ()
+  (let ((alist '(("a" . 1) ("b" . 2))))
+    (should-not (assoc "a" alist #'ignore))
+    (should (eq (assoc "b" alist #'string-equal) (cadr alist)))
+    (should-not (assoc "b" alist #'eq))))
+
 (ert-deftest test-cycle-rassq ()
   (let ((c1 (cyc1 '(0 . 1)))
         (c2 (cyc2 '(0 . 1) '(0 . 2)))
diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el
index 98cbb6a..dd5a200 100644
--- a/test/src/lread-tests.el
+++ b/test/src/lread-tests.el
@@ -142,6 +142,23 @@ literals (Bug#20852)."
                            "unescaped character literals "
                            "`?\"', `?(', `?)', `?;', `?[', `?]' detected!")))))
 
+(ert-deftest lread-tests--funny-quote-symbols ()
+  "Check that 'smart quotes' or similar trigger errors in symbol names."
+  (dolist (quote-char
+           '(#x2018 ;; LEFT SINGLE QUOTATION MARK
+             #x2019 ;; RIGHT SINGLE QUOTATION MARK
+             #x201B ;; SINGLE HIGH-REVERSED-9 QUOTATION MARK
+             #x201C ;; LEFT DOUBLE QUOTATION MARK
+             #x201D ;; RIGHT DOUBLE QUOTATION MARK
+             #x201F ;; DOUBLE HIGH-REVERSED-9 QUOTATION MARK
+             #x301E ;; DOUBLE PRIME QUOTATION MARK
+             #xFF02 ;; FULLWIDTH QUOTATION MARK
+             #xFF07 ;; FULLWIDTH APOSTROPHE
+             ))
+    (let ((str (format "%cfoo" quote-char)))
+     (should-error (read str) :type 'invalid-read-syntax)
+     (should (eq (read (concat "\\" str)) (intern str))))))
+
 (ert-deftest lread-test-bug26837 ()
   "Test for http://debbugs.gnu.org/26837 ."
   (let ((load-path (cons
@@ -164,4 +181,10 @@ literals (Bug#20852)."
                    (concat (format-message "Loading `%s': " file-name)
                            "old-style backquotes detected!")))))
 
+(ert-deftest lread-lread--substitute-object-in-subtree ()
+  (let ((x (cons 0 1)))
+    (setcar x x)
+    (lread--substitute-object-in-subtree x 1 t)
+    (should (eq x (cdr x)))))
+
 ;;; lread-tests.el ends here



reply via email to

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