texlive[50246] Master/texmf-dist: l3 (5mar19)

commits+karl at tug.org commits+karl at tug.org
Tue Mar 5 23:35:15 CET 2019


Revision: 50246
          http://tug.org/svn/texlive?view=revision&revision=50246
Author:   karl
Date:     2019-03-05 23:35:14 +0100 (Tue, 05 Mar 2019)
Log Message:
-----------
l3 (5mar19)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3experimental/README.md
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3benchmark/l3benchmark.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3cctab/l3cctab.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3color/l3color.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.tex
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3str-convert.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3str-format.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3sys-shell/l3sys-shell.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/xcoffins/xcoffins.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/xgalley/l3galley.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/xgalley/xgalley.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3kernel/README.md
    trunk/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3obsolete.txt
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex
    trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3packages/README.md
    trunk/Master/texmf-dist/doc/latex/l3packages/l3keys2e/l3keys2e.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xfp/xfp.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xfrac/xfrac.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xparse/xparse.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xtemplate/xtemplate.pdf
    trunk/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins
    trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-convert.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3final.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.ins
    trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.ins
    trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.ins
    trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins
    trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.ins
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3cctab/l3cctab.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3color/l3color.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-convert.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvipdfmx.def
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvips.def
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvisvgm.def
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3pdfmode.def
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def
    trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3experimental/CHANGELOG.md	2019-03-05 22:35:14 UTC (rev 50246)
@@ -7,6 +7,17 @@
 
 ## [Unreleased]
 
+## [2019-03-05]
+
+### Added
+
+- Support for drawing layers
+- `\draw_point:nn` to allow 'fast' processing of co-ordinates
+
+### Changed
+
+- Update `l3draw` transformation names
+
 ## [2019-01-28]
 
 ### Changed
@@ -59,7 +70,8 @@
 - New `l3color` module using `xcolor`-like expression syntax
 - New `l3draw` module, based on `pgf` layer of the TikZ system
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2019-01-28...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2019-03-05...HEAD
+[2019-03-05]: https://github.com/latex3/latex3/compare/2019-01-28...2019-03-05
 [2019-01-28]: https://github.com/latex3/latex3/compare/2018-10-31...2019-01-28
 [2018-10-31]: https://github.com/latex3/latex3/compare/2018-10-26...2018-10-31
 [2018-10-26]: https://github.com/latex3/latex3/compare/2018-10-17...2018-10-26

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3experimental/README.md	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3experimental/README.md	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,7 @@
 Experimental LaTeX3 Concepts
 ============================
 
-Release 2019-01-28
+Release 2019-03-05
 
 Overview
 --------

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3benchmark/l3benchmark.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3cctab/l3cctab.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3color/l3color.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.tex	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw-code.tex	2019-03-05 22:35:14 UTC (rev 50246)
@@ -39,6 +39,8 @@
 \clist_gput_right:Nn \g_docinput_clist
   {
     l3draw.dtx            ,
+    l3draw-boxes.dtx      ,
+    l3draw-layers.dtx     ,
     l3draw-paths.dtx      ,
     l3draw-points.dtx     ,
     l3draw-scopes.dtx     ,

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3draw/l3draw.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3str-convert.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3str-format.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3sys-shell/l3sys-shell.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/xcoffins/xcoffins.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/xgalley/l3galley.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/xgalley/xgalley.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md	2019-03-05 22:35:14 UTC (rev 50246)
@@ -7,6 +7,39 @@
 
 ## [Unreleased]
 
+## [2019-03-05]
+
+### Added
+
+- `\str_log:n`, `\str_log:N`
+- `TF` versions for `\file_get_...:nN` and `\ior_(str_)get:NN` functions
+- `undo-recent-deprecations` option
+- `factorial` function in `l3fp`
+
+### Changed
+
+- Return values from `\file_get:nnN`, `\file_get_...:nN`, `\ior_get:NN`,
+  `\sys_shell_get:nnN`
+- Moved coffin affine transformations to stable
+- Moved `\prop_count:N` to stable
+- Moved `\tl_count_tokens:n` to stable
+- Completed emulation of e-type argument when `\expanded` is unavailable
+- Renamed `\token_get_prefix_spec:N`, `\token_get_arg_spec:N`,
+  `\token_get_replacement_spec:N` as `\cs_prefix_spec:N`,
+  `\cs_argument_spec:N`, `\cs_replacement_spec:N`, respectively
+- Made expandable messages expand their result, like usual messages
+- Made deprecation errors less intrusive by default
+- Stopped providing do-nothing `\color` macro when undefined
+
+### Fixed
+
+- Treatment of inherited keys when setting only known keys (see #548)
+
+### Removed
+
+- Experimental `\skip_split_finite_else_action:nnNN`
+- Experimental `\tl_reverse_tokens:n`
+
 ## [2019-02-15]
 
 ### Changed
@@ -23,8 +56,8 @@
 
 ### Added
 
-- Support for return of whole path by \cs{keys_set_known:nnN}-like
-  function \cs{keys_set_known:nnnN} (see #508)
+- Support for return of whole path by `\keys_set_known:nnN`-like
+  function `\keys_set_known:nnnN` (see #508)
 - `.prop_(g)put:N` key property (see #444)
 
 ### Fixed
@@ -298,7 +331,8 @@
 - Step func­tions have been added for dim vari­ables,
   e.g. `\dim_step_in­line:nnnn`
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2019-02-15...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2019-03-05...HEAD
+[2019-03-05]: https://github.com/latex3/latex3/compare/2019-02-15...2019-03-05
 [2019-02-15]: https://github.com/latex3/latex3/compare/2019-02-03...2019-02-15
 [2019-02-03]: https://github.com/latex3/latex3/compare/2019-01-28...2019-02-03
 [2019-01-28]: https://github.com/latex3/latex3/compare/2019-01-13...2019-01-28

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/README.md	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/README.md	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,7 @@
 LaTeX3 Programming Conventions
 ==============================
 
-Release 2019-02-15
+Release 2019-03-05
 
 Overview
 --------

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex	2019-03-05 22:35:14 UTC (rev 50246)
@@ -54,7 +54,7 @@
          {latex-team at latex-project.org}%
    }%
 }
-\date{Released 2019-02-15}
+\date{Released 2019-03-05}
 
 \pagenumbering{roman}
 \maketitle

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3obsolete.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3obsolete.txt	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3obsolete.txt	2019-03-05 22:35:14 UTC (rev 50246)
@@ -76,6 +76,9 @@
 \tl_set_from_file:Nnn             2020
 \tl_set_from_file_x:cnn           2020
 \tl_set_from_file_x:Nnn           2020
+\token_get_arg_spec:N             2020
+\token_get_prefix_spec:N          2020
+\token_get_replacement_spec:N     2020
 \uptex_...:D                      2019
 \utex_...:D                       2019
 \vbox_unpack_clear:c              2020

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex	2019-03-05 22:35:14 UTC (rev 50246)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2019-02-15}
+\date{Released 2019-03-05}
 
 \begin{document}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex	2019-03-05 22:35:14 UTC (rev 50246)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2019-02-15}
+\date{Released 2019-03-05}
 
 \newcommand{\TF}{\textit{(TF)}}
 
@@ -94,7 +94,7 @@
   functions.
   \item \cs{tl_trim_spaces:n} now requires a variable number of
   expansions to fully expand, rather than exactly two.  Of course,
-  \texttt{x}-type expansion still correctly evaluates this function.
+  \texttt{x}-type or \texttt{e}-type expansion still correctly evaluates this function.
 \end{itemize}
 
 \section{July 2012}
@@ -110,7 +110,7 @@
 \begin{itemize}
   \item \cs{lua_now:x} is now a standard \texttt{x}-type expansion of
     \cs{lua_now:n}, which does no expansion. Engine-level expansion is moved
-    to \cs{lua_now_x:n}, reflecting the fact that this is non-standard in the
+    to \cs{lua_now:e}, reflecting the fact that this is non-standard in the
     same way as for example \cs{str_if_eq_x:nn(TF)}.
 \end{itemize}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex	2019-03-05 22:35:14 UTC (rev 50246)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2019-02-15}
+\date{Released 2019-03-05}
 
 \newcommand{\TF}{\textit{(TF)}}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex	2019-03-05 22:35:14 UTC (rev 50246)
@@ -53,7 +53,7 @@
          {latex-team at latex-project.org}%
    }%
 }
-\date{Released 2019-02-15}
+\date{Released 2019-03-05}
 
 \pagenumbering{roman}
 \maketitle

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex	2019-03-05 22:35:14 UTC (rev 50246)
@@ -321,7 +321,7 @@
 \paragraph{Fully expandable functions}
 \hypertarget{expstar}{Some functions are fully expandable},
 which allows them to be used within
-an \texttt{x}-type argument (in plain \TeX{} terms, inside an \cs{edef}),
+an \texttt{x}-type or \texttt{e}-type argument (in plain \TeX{} terms, inside an \tn{edef} or \tn{expanded}),
 as well as within an \texttt{f}-type argument.
 These fully expandable functions are indicated in the documentation by
 a star:

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md	2019-03-05 22:35:14 UTC (rev 50246)
@@ -7,8 +7,16 @@
 
 ## [Unreleased]
 
-## [2018-10-17]
+## [2019-03-05]
 
+### Added
+- `xparse`: b-type argument to grab body of environments
+
+### Changed
+- `xparse`: make \IfBooleanTF safer
+- `xparse`: clearer error messages, especially for environments
+- `xparse`: when defining an environment, trim spaces at ends of its name
+
 ## [2018-09-24]
 
 ### Changed
@@ -32,8 +40,8 @@
 - Switch to ISO date format
 - Improve cross-module use of internal functions
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2018-10-17...HEAD
-[2018-10-17]: https://github.com/latex3/latex3/compare/2018-09-24...2018-10-17
+[Unreleased]: https://github.com/latex3/latex3/compare/2019-03-05...HEAD
+[2019-03-05]: https://github.com/latex3/latex3/compare/2019-09-24...2019-03-05
 [2018-09-24]: https://github.com/latex3/latex3/compare/2018-08-23...2018-09-24
 [2018-08-23]: https://github.com/latex3/latex3/compare/2018-05-12...2018-08-23
 [2018-05-12]: https://github.com/latex3/latex3/compare/2018-04-30...2018-05-12

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3packages/README.md	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/doc/latex/l3packages/README.md	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,7 @@
 LaTeX3 High-Level Concepts
 ==========================
 
-Release 2018-10-17
+Release 2019-03-05
 
 Overview
 --------
@@ -122,6 +122,6 @@
 
 -----
 
-<p>Copyright (C) 1998-2011,2015-2018 The LaTeX3 Project <br />
+<p>Copyright (C) 1998-2011,2015-2019 The LaTeX3 Project <br />
 <a href="http://latex-project.org/">http://latex-project.org/</a> <br />
 All rights reserved.</p>

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/l3keys2e/l3keys2e.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xfp/xfp.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xfrac/xfrac.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xparse/xparse.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xtemplate/xtemplate.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -128,7 +128,7 @@
 %
 %    \begin{macrocode}
 %<*package>
-\ProvidesExplPackage{l3benchmark}{2019-01-28}{}
+\ProvidesExplPackage{l3benchmark}{2019-03-05}{}
   {L3 Experimental benchmarking}
 %</package>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3cctab/l3cctab.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -150,7 +150,7 @@
 %
 %    \begin{macrocode}
 %<*package>
-\ProvidesExplPackage{l3cctab}{2019-01-28}{}
+\ProvidesExplPackage{l3cctab}{2019-03-05}{}
   {L3 Experimental category code tables}
 %</package>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -265,7 +265,7 @@
 %
 %    \begin{macrocode}
 %<*package>
-\ProvidesExplPackage{l3color}{2019-01-28}{}
+\ProvidesExplPackage{l3color}{2019-03-05}{}
   {L3 Experimental color support}
 %</package>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Added: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -0,0 +1,216 @@
+% \iffalse meta-comment
+%
+%% File: l3draw-layers.dtx
+%
+% Copyright (C) 2019 The LaTeX3 Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file
+%
+%    http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3experimental bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+%    https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\RequirePackage{expl3}
+\documentclass[full]{l3doc}
+\begin{document}
+  \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+%   The \pkg{l3draw-layers} package\\ Layers^^A
+% }
+%
+% \author{^^A
+%  The \LaTeX3 Project\thanks
+%    {^^A
+%      E-mail:
+%        \href{mailto:latex-team at latex-project.org}
+%          {latex-team at latex-project.org}^^A
+%    }^^A
+% }
+%
+% \date{Released 2019-03-05}
+%
+% \maketitle
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3draw-layers} implementation}
+%
+%    \begin{macrocode}
+%<*initex|package>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<@@=draw>
+%    \end{macrocode}
+%
+% \subsection{User interface}
+%
+% \begin{macro}{\draw_layer_new:n}
+%    \begin{macrocode}
+\cs_new_protected:Npn \draw_layer_new:n #1
+  {
+    \str_if_eq:nnTF {#1} { main }
+      { \msg_error:nnn { draw } { main-reserved } }
+      {
+        \box_new:c { g_@@_layer_ #1 _box }
+        \box_new:c { l_@@_layer_ #1 _box }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_layer_tl}
+%   The name of the current layer: we start off with |main|.
+%    \begin{macrocode}
+\tl_new:N \l_@@_layer_tl
+\tl_set:Nn \l_@@_layer_tl { main }
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_layer_close_bool}
+%   Used to track if a layer needs to be closed.
+%    \begin{macrocode}
+\bool_new:N \l_@@_layer_close_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_draw_layers_clist, \g_@@_layers_clist}
+%   The list of layers to use starts off with just the |main| one.
+%    \begin{macrocode}
+\clist_new:N \l_draw_layers_clist
+\clist_set:Nn \l_draw_layers_clist { main }
+\clist_new:N \g_@@_layers_clist
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\draw_layer_begin:n}
+% \begin{macro}{\draw_layer_end:}
+%   Layers may be called multiple times and have to work when nested. That
+%   drives a bit of grouping to get everything in order. Layers have to be zero
+%   width, so they get set as we go along.
+%    \begin{macrocode}
+\cs_new_protected:Npn \draw_layer_begin:n #1
+  {
+    \group_begin:
+      \box_if_exist:cTF { g_@@_layer_ #1 _box }
+        {
+          \str_if_eq:VnTF \l_@@_layer_tl {#1}
+            { \bool_set_false:N \l_@@_layer_close_bool }
+            {
+              \bool_set_true:N \l_@@_layer_close_bool
+              \tl_set:Nn \l_@@_layer_tl {#1}
+              \box_gset_wd:cn { g_@@_layer_ #1 _box } { 0pt }
+              \hbox_gset:cw { g_@@_layer_ #1 _box }
+                \box_use_drop:c { g_@@_layer_ #1 _box }
+                \group_begin:
+            }
+          \draw_linewidth:n { \l_draw_default_linewidth_dim }
+        }
+        {
+          \str_if_eq:nnTF {#1} { main }
+            { \msg_error:nnn { draw } { unknown-layer } {#1} }
+            { \msg_error:nnn { draw } { main-layer } }
+        }
+  }
+\cs_new_protected:Npn \draw_layer_end:
+  {
+      \bool_if:NT \l_@@_layer_close_bool
+        {
+            \group_end:
+          \hbox_gset_end:
+        }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Internal cross-links}
+%
+% \begin{macro}{\@@_layers_insert:}
+%   The |main| layer is special, otherwise just dump the layer box inside
+%   a scope.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_layers_insert:
+  {
+    \clist_map_inline:Nn \l_draw_layers_clist
+      {
+        \str_if_eq:nnTF {##1} { main }
+          {
+            \box_set_wd:Nn \l_@@_layer_main_box { 0pt }
+            \box_use_drop:N \l_@@_layer_main_box
+          }
+          {
+            \driver_draw_scope_begin:
+            \box_gset_wd:cn { g_@@_layer_ ##1 _box } { 0pt }
+            \box_use_drop:c { g_@@_layer_ ##1 _box }
+            \driver_draw_scope_end:
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_layers_save:, \@@_layers_restore:}
+%   Simple save/restore functions.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_layers_save:
+  {
+    \clist_map_inline:Nn \l_draw_layers_clist
+      {
+        \str_if_eq:nnF {##1} { main }
+          {
+            \box_set_eq:cc { l_@@_layer_ ##1 _box }
+              { g_@@_layer_ ##1 _box }
+          }
+      }
+  }
+\cs_new_protected:Npn \@@_layers_restore:
+  {
+    \clist_map_inline:Nn \l_draw_layers_clist
+      {
+        \str_if_eq:nnF {##1} { main }
+          {
+            \box_gset_eq:cc { g_@@_layer_ ##1 _box }
+              { l_@@_layer_ ##1 _box }
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\msg_new:nnnn { draw } { main-layer }
+  { Material~cannot~be~added~to~'main'~layer. }
+  { The~main~layer~may~only~be~accessed~at~the~top~level. }
+\msg_new:nnn { draw } { main-reserved }
+  { The~'main'~layer~is~reserved. }
+\msg_new:nnnn { draw } { unknown-layer }
+  { Layer~'#1'~has~not~been~created. }
+  { You~have~tried~to~use~layer~'#1',~but~it~was~never~set~up. }
+% \end{macrocode}
+%
+%    \begin{macrocode}
+%</initex|package>
+%    \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex


Property changes on: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -254,15 +254,12 @@
   }
 \cs_new_protected:Npn \draw_path_curveto:nnn #1#2#3
   {
-    \@@_point_process:nnn
+    \@@_point_process:nnnn
       {
-        \@@_point_process:nn
-          {
-            \@@_path_mark_corner:
-            \@@_path_curveto:nnnnnn
-          }
-          { \draw_point_transform:n {#1} }
+        \@@_path_mark_corner:
+        \@@_path_curveto:nnnnnn
       }
+      { \draw_point_transform:n {#1} }
       { \draw_point_transform:n {#2} }
       { \draw_point_transform:n {#3} }
   }
@@ -303,16 +300,12 @@
   { \@@_point_process:nn { \@@_path_lineto:nn } {#1} }
 \cs_new_protected:Npn \draw_path_canvas_curveto:nnn #1#2#3
   {
-    \@@_point_process:nnn
+    \@@_point_process:nnnn
       {
-        \@@_point_process:nn
-          {
-            \@@_path_mark_corner:
-            \@@_path_curveto:nnnnnn
-          }
-          {#1}
+        \@@_path_mark_corner:
+        \@@_path_curveto:nnnnnn
       }
-      {#2} {#3}
+      {#1} {#2} {#3}
   }
 %    \end{macrocode}
 % \end{macro}
@@ -514,14 +507,11 @@
         \@@_point_transform_noshift:n
           { \draw_point_polar:nnn { #1 #4 90 } {#7} {#8} }
       }
-    \@@_point_process:nn
+    \@@_point_process:nnn
+      { \@@_path_arc_auxiv:nnnn }
       {
-        \@@_point_process:nn
-          { \@@_path_arc_auxiv:nnnn }
-          {
-            \draw_point_transform:n
-              { \draw_point_polar:nnn {#1} {#5} {#6} }
-          }
+        \draw_point_transform:n
+          { \draw_point_polar:nnn {#1} {#5} {#6} }
       }
       {
         \draw_point_transform:n
@@ -624,12 +614,9 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \draw_path_ellipse:nnn #1#2#3
   {
-    \@@_point_process:nnn
-      {
-        \@@_point_process:nn
-          { \@@_path_ellipse:nnnnnn }
-          { \draw_point_transform:n {#1} }
-      }
+    \@@_point_process:nnnn
+      { \@@_path_ellipse:nnnnnn }
+      { \draw_point_transform:n {#1} }
       { \@@_point_transform_noshift:n {#2} }
       { \@@_point_transform_noshift:n {#3} }
   }

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -67,7 +67,7 @@
 % Equivalents of following \pkg{pgf} functions are deliberately omitted:
 % \begin{itemize}
 %   \item \cs{pgfpointorigin}: Can be given explicitly as |0pt,0pt|.
-%   \item \cs{pgfpoint}, \cs{pgfpointadd}, \cs{pgfpointdiff},
+%   \item \cs{pgfpointadd}, \cs{pgfpointdiff},
 %     \cs{pgfpointscale}: Can be given explicitly.
 %   \item \cs{pgfextractx}, \cs{pgfextracty}: Available by applying
 %     \cs{use_i:nn}/\cs{use_ii:nn} or similar to the \texttt{x}-type
@@ -93,11 +93,17 @@
 % \subsection{Support functions}
 %
 % \begin{macro}[EXP]{\@@_point_process:nn}
-% \begin{macro}[EXP]{\@@_point_process_auxi:nn, \@@_point_process_auxi:fn}
+% \begin{macro}[EXP]{\@@_point_process_auxi:nn}
 % \begin{macro}[EXP]{\@@_point_process_auxii:nw}
 % \begin{macro}[EXP]{\@@_point_process:nnn}
-% \begin{macro}[EXP]{\@@_point_process_auxiii:nnn, \@@_point_process_auxiii:ffn}
+% \begin{macro}[EXP]{\@@_point_process_auxiii:nnn}
 % \begin{macro}[EXP]{\@@_point_process_auxiv:nw}
+% \begin{macro}[EXP]{\@@_point_process:nnnn}
+% \begin{macro}[EXP]{\@@_point_process_auxv:nnnn}
+% \begin{macro}[EXP]{\@@_point_process_auxvi:nw}
+% \begin{macro}[EXP]{\@@_point_process:nnnnn}
+% \begin{macro}[EXP]{\@@_point_process_auxvii:nnnnn}
+% \begin{macro}[EXP]{\@@_point_process_auxviii:nw}
 %   Execute whatever code is passed to extract the $x$ and $y$ co-ordinates.
 %   The first argument here should itself absorb two arguments. There is
 %   also a version to deal with two co-ordinates: common enough to justify a
@@ -105,18 +111,17 @@
 %    \begin{macrocode}
 \cs_new:Npn \@@_point_process:nn #1#2
   {
-    \@@_point_process_auxi:fn
+    \exp_args:Nf \@@_point_process_auxi:nn
       { \@@_point_to_dim:n {#2} }
       {#1}
   }
 \cs_new:Npn \@@_point_process_auxi:nn #1#2
   { \@@_point_process_auxii:nw {#2} #1 \q_stop }
-\cs_generate_variant:Nn \@@_point_process_auxi:nn { f }
 \cs_new:Npn \@@_point_process_auxii:nw #1 #2 , #3 \q_stop
   { #1 {#2} {#3} }
 \cs_new:Npn \@@_point_process:nnn #1#2#3
   {
-    \@@_point_process_auxiii:ffn
+    \exp_args:Nff \@@_point_process_auxiii:nnn
       { \@@_point_to_dim:n {#2} }
       { \@@_point_to_dim:n {#3} }
       {#1}
@@ -123,9 +128,38 @@
   }
 \cs_new:Npn \@@_point_process_auxiii:nnn #1#2#3
   { \@@_point_process_auxiv:nw {#3} #1 \q_mark #2 \q_stop }
-\cs_generate_variant:Nn \@@_point_process_auxiii:nnn { ff }
 \cs_new:Npn \@@_point_process_auxiv:nw #1 #2 , #3 \q_mark #4 , #5 \q_stop
   { #1 {#2} {#3} {#4} {#5} }
+\cs_new:Npn \@@_point_process:nnnn #1#2#3#4
+  {
+    \exp_args:Nfff \@@_point_process_auxv:nnnn
+      { \@@_point_to_dim:n {#2} }
+      { \@@_point_to_dim:n {#3} }
+      { \@@_point_to_dim:n {#4} }
+      {#1}
+  }
+\cs_new:Npn \@@_point_process_auxv:nnnn #1#2#3#4
+  { \@@_point_process_auxvi:nw {#4} #1 \q_mark #2 \q_mark #3 \q_stop }
+\cs_new:Npn \@@_point_process_auxvi:nw
+  #1 #2 , #3 \q_mark #4 , #5 \q_mark #6 , #7 \q_stop
+  { #1 {#2} {#3} {#4} {#5} {#6} {#7} }
+\cs_new:Npn \@@_point_process:nnnnn #1#2#3#4#5
+  {
+    \exp_args:Nffff \@@_point_process_auxvii:nnnnn
+      { \@@_point_to_dim:n {#2} }
+      { \@@_point_to_dim:n {#3} }
+      { \@@_point_to_dim:n {#4} }
+      { \@@_point_to_dim:n {#5} }
+      {#1}
+  }
+\cs_new:Npn \@@_point_process_auxvii:nnnnn #1#2#3#4#5
+  {
+    \@@_point_process_auxviii:nw
+      {#5} #1 \q_mark #2 \q_mark #3 \q_mark #4 \q_stop
+  }
+\cs_new:Npn \@@_point_process_auxviii:nw
+  #1 #2 , #3 \q_mark #4 , #5 \q_mark #6 , #7 \q_mark #8 , #9 \q_stop
+  { #1 {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9} }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -133,6 +167,12 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}[EXP]{\@@_point_to_dim:n}
 % \begin{macro}[EXP]{\@@_point_to_dim_aux:n, \@@_point_to_dim_aux:f}
@@ -225,24 +265,21 @@
 %    \begin{macrocode}
 \cs_new:Npn \draw_point_intersect_lines:nnnn #1#2#3#4
   {
-    \@@_point_process:nnn
-      {
-        \@@_point_process:nnn
-          { \@@_point_intersect_lines:nnnnnnnn } {#3} {#4}
-      }
-      {#1} {#2}
+    \@@_point_process:nnnnn
+      { \@@_point_intersect_lines:nnnnnnnn }
+      {#1} {#2} {#3} {#4}
   }
 %    \end{macrocode}
 %   At this stage we have all of the information we need, fully expanded:
 %   \begin{enumerate}[label = \#\arabic*, font = \ttfamily]
+%     \item $x_{1}$
+%     \item $y_{1}$
+%     \item $x_{2}$
+%     \item $y_{2}$
 %     \item $x_{3}$
 %     \item $y_{3}$
 %     \item $x_{4}$
 %     \item $y_{4}$
-%     \item $x_{1}$
-%     \item $y_{1}$
-%     \item $x_{2}$
-%     \item $y_{2}$
 %   \end{enumerate}
 %   so now just have to do all of the calculation.
 %    \begin{macrocode}
@@ -519,18 +556,14 @@
 %    \begin{macrocode}
 \cs_new:Npn \draw_point_interpolate_arcaxes:nnnnnn #1#2#3#4#5#6
   {
-    \@@_point_process:nnn
-      {
-        \@@_point_process:nn
-          { \@@_point_interpolate_arcaxes_auxi:nnnnnnnnn {#1} {#5} {#6} }
-          {#4}
-      }
-      {#2} {#3}
+    \@@_point_process:nnnn
+      { \@@_point_interpolate_arcaxes_auxi:nnnnnnnnn {#1} {#5} {#6} }
+      {#2} {#3} {#4}
   }
 \cs_new:Npn \@@_point_interpolate_arcaxes_auxi:nnnnnnnnn #1#2#3#4#5#6#7#8#9
   {
     \@@_point_interpolate_arcaxes_auxii:fnnnnnnnn
-      { \fp_eval:n {#1} } {#2} {#3} {#6} {#7} {#8} {#9} {#4} {#5}
+      { \fp_eval:n {#1} } {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9}
   }
 %    \end{macrocode}
 %   At this stage, the three co-ordinate pairs are fully expanded but somewhat
@@ -613,19 +646,15 @@
 %    \begin{macrocode}
 \cs_new:Npn \draw_point_interpolate_curve:nnnnnn #1#2#3#4#5
   {
-    \@@_point_process:nnn
-      {
-        \@@_point_process:nnn
-          { \@@_point_interpolate_curve_auxi:nnnnnnnnn {#1} }
-          {#4} {#5}
-      }
-      {#2} {#3}
+    \@@_point_process:nnnnn
+      { \@@_point_interpolate_curve_auxi:nnnnnnnnn {#1} }
+      {#2} {#3} {#4} {#5}
   }
 \cs_new:Npn \@@_point_interpolate_curve_auxi:nnnnnnnnn #1#2#3#4#5#6#7#8#9
   {
     \@@_point_interpolate_curve_auxii:fnnnnnnnn
       { \fp_eval:n {#1} }
-      {#6} {#7} {#8} {#9} {#2} {#3} {#4} {#5}
+      {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9}
   }
 %    \end{macrocode}
 %   At this stage, everything is fully expanded and back in the input order.

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -82,10 +82,11 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_main_box}
-%   Box for setting the drawing.
+% \begin{variable}{\l_@@_layer_main_box, \l_@@_layer_main_box}
+%   Box for setting the drawing itself and the top-level layer.
 %    \begin{macrocode}
 \box_new:N \l_@@_main_box
+\box_new:N \l_@@_layer_main_box
 %    \end{macrocode}
 % \end{variable}
 %
@@ -115,7 +116,8 @@
 %   mechanism largely as it then sets up the internal data structures. It may be
 %   that a coffin construct is better here in the longer term: that may become
 %   clearer as the code is completed. As we need to avoid any insertion of
-%   baseline skips, the outer box here has to be an |hbox|.
+%   baseline skips, the outer box here has to be an |hbox|. To allow for
+%   layers, there is some box nesting: notice that we 
 %    \begin{macrocode}
 \cs_new_protected:Npn \draw_begin:
   {
@@ -136,9 +138,13 @@
         \draw_join_miter:
         \draw_miterlimit:n { 10 }
         \draw_dash_pattern:nn { } { 0cm }
+        \hbox_set:Nw \l_@@_layer_main_box
   }
 \cs_new_protected:Npn \draw_end:
   {
+          \exp_args:NNNV \hbox_set_end:
+          \clist_set:Nn \l_draw_layers_clist \l_draw_layers_clist
+          \@@_layers_insert:
         \driver_draw_end:
       \hbox_set_end:
       \dim_compare:nNnT \g_@@_xmin_dim = \c_max_dim
@@ -244,9 +250,11 @@
     \draw_path_scope_begin:
     \draw_transform_matrix_reset:
     \draw_transform_shift_reset:
+    \@@_layers_save:
   }
 \cs_new_protected:Npn \draw_suspend_end:
   {
+    \@@_layers_restore:
     \draw_path_scope_end:
     \@@_scope_bb_end:
   }

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -121,14 +121,14 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\draw_transform_matrix:nnnn}
-% \begin{macro}{\draw_transform_shift:n}
-% \begin{macro}{\@@_transform_shift:nn}
+% \begin{macro}{\draw_transform_matrix_absolute:nnnn}
+% \begin{macro}{\draw_transform_shift_absolute:n}
+% \begin{macro}{\@@_transform_shift_absolute:nn}
 %   Setting the transform matrix is straight-forward, with just a bit
 %   of expansion to sort out. With the mechanism active, the identity
 %   matrix is set.
 %    \begin{macrocode}
-\cs_new_protected:Npn \draw_transform_matrix:nnnn #1#2#3#4
+\cs_new_protected:Npn \draw_transform_matrix_absolute:nnnn #1#2#3#4
   {
     \fp_set:Nn \l_@@_matrix_a_fp {#1}
     \fp_set:Nn \l_@@_matrix_b_fp {#2}
@@ -144,12 +144,12 @@
       { \bool_set_false:N \l_@@_matrix_active_bool }
       { \bool_set_true:N \l_@@_matrix_active_bool }
   }
-\cs_new_protected:Npn \draw_transform_shift:n #1
+\cs_new_protected:Npn \draw_transform_shift_absolute:n #1
   {
     \@@_point_process:nn
-      { \@@_transform_shift:nn } {#1}
+      { \@@_transform_shift_absolute:nn } {#1}
   }
-\cs_new_protected:Npn \@@_transform_shift:nn #1#2
+\cs_new_protected:Npn \@@_transform_shift_absolute:nn #1#2
   {
     \dim_set:Nn \l_@@_xshift_dim {#1}
     \dim_set:Nn \l_@@_yshift_dim {#2}
@@ -159,18 +159,18 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\draw_transform_matrix_concat:nnnn}
-% \begin{macro}{\@@_transform_concat:nnnn}
-% \begin{macro}{\draw_transform_shift_concat:n}
-% \begin{macro}{\@@_transform_shift_concat:nn}
+% \begin{macro}{\draw_transform_matrix:nnnn}
+% \begin{macro}{\@@_transform:nnnn}
+% \begin{macro}{\draw_transform_shift:n}
+% \begin{macro}{\@@_transform_shift:nn}
 %   Much the same story for adding to an existing matrix, with a bit of
 %   pre-expansion so that the calculation uses \enquote{frozen} values.
 %    \begin{macrocode}
-\cs_new_protected:Npn \draw_transform_matrix_concat:nnnn #1#2#3#4
+\cs_new_protected:Npn \draw_transform_matrix:nnnn #1#2#3#4
   {
     \use:x
       {
-        \@@_transform_concat:nnnn
+        \@@_transform:nnnn
           { \fp_eval:n {#1} }
           { \fp_eval:n {#2} }
           { \fp_eval:n {#3} }
@@ -177,11 +177,11 @@
           { \fp_eval:n {#4} }
       }
   }
-\cs_new_protected:Npn \@@_transform_concat:nnnn #1#2#3#4
+\cs_new_protected:Npn \@@_transform:nnnn #1#2#3#4
   {
     \use:x
       {
-        \draw_transform_matrix:nnnn
+        \draw_transform_matrix_absolute:nnnn
           { #1 * \l_@@_matrix_a_fp + #2 * \l_@@_matrix_c_fp }
           { #1 * \l_@@_matrix_b_fp + #2 * \l_@@_matrix_d_fp }
           { #3 * \l_@@_matrix_a_fp + #4 * \l_@@_matrix_c_fp }
@@ -188,12 +188,12 @@
           { #3 * \l_@@_matrix_b_fp + #4 * \l_@@_matrix_d_fp }
         }
   }
-\cs_new_protected:Npn \draw_transform_shift_concat:n #1
+\cs_new_protected:Npn \draw_transform_shift:n #1
   {
     \@@_point_process:nn
-      { \@@_transform_shift_concat:nn } {#1}
+      { \@@_transform_shift:nn } {#1}
   }
-\cs_new_protected:Npn \@@_transform_shift_concat:nn #1#2
+\cs_new_protected:Npn \@@_transform_shift:nn #1#2
   {
     \dim_set:Nn \l_@@_xshift_dim { \l_@@_xshift_dim + #1 }
     \dim_set:Nn \l_@@_yshift_dim { \l_@@_yshift_dim + #2 }
@@ -267,12 +267,12 @@
   {
     \use:x
       {
-        \draw_transform_matrix:nnnn
+        \draw_transform_matrix_absolute:nnnn
           { #3 - #1 }
           { #4 - #2 }
           { #5 - #1 }
           { #6 - #2 }
-        \draw_transform_shift:n { #1 , #2 }
+        \draw_transform_shift_absolute:n { #1 , #2 }
       }
   }
 %    \end{macrocode}
@@ -287,19 +287,19 @@
 %   Lots of shortcuts.
 %    \begin{macrocode}
 \cs_new_protected:Npn \draw_transform_scale:n #1
-  { \draw_transform_matrix_concat:nnnn { #1 } { 0 } { 0 } { #1 } }
+  { \draw_transform_matrix:nnnn { #1 } { 0 } { 0 } { #1 } }
 \cs_new_protected:Npn \draw_transform_xscale:n #1
-  { \draw_transform_matrix_concat:nnnn { #1 } { 0 } { 0 } { 1 } }
+  { \draw_transform_matrix:nnnn { #1 } { 0 } { 0 } { 1 } }
 \cs_new_protected:Npn \draw_transform_yscale:n #1
-  { \draw_transform_matrix_concat:nnnn { 1 } { 0 } { 0 } { #1 } }
+  { \draw_transform_matrix:nnnn { 1 } { 0 } { 0 } { #1 } }
 \cs_new_protected:Npn \draw_transform_xshift:n #1
-  { \draw_transform_shift_concat:n { #1 , 0 } }
+  { \draw_transform_shift:n { #1 , 0pt } }
 \cs_new_protected:Npn \draw_transform_yshift:n #1
-  { \draw_transform_shift_concat:n { 0 , #1 } }
+  { \draw_transform_shift:n { 0pt , #1 } }
 \cs_new_protected:Npn \draw_transform_xslant:n #1
-  { \draw_transform_matrix_concat:nnnn { 1 } { 0 } { #1 } { 1 } }
+  { \draw_transform_matrix:nnnn { 1 } { 0 } { #1 } { 1 } }
 \cs_new_protected:Npn \draw_transform_yslant:n #1
-  { \draw_transform_matrix_concat:nnnn { 1 } { #1 } { 0 } { 1 } }
+  { \draw_transform_matrix:nnnn { 1 } { #1 } { 0 } { 1 } }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -324,7 +324,7 @@
   }
 \cs_generate_variant:Nn \@@_transform_rotate:n { f }
 \cs_new_protected:Npn \@@_transform_rotate:nn #1#2
-  { \draw_transform_matrix_concat:nnnn {#1} {#2} { -#2 } { #1 } }
+  { \draw_transform_matrix:nnnn {#1} {#2} { -#2 } { #1 } }
 \cs_generate_variant:Nn \@@_transform_rotate:nn { ff }
 %    \end{macrocode}
 % \end{macro}

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -111,7 +111,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -941,7 +941,7 @@
 %   \end{demo}
 %   \begin{demo}
 %     \draw_begin:
-%       \draw_transform_matrix:nnnn { 2 } { 0 } { 1 } { 2 }
+%       \draw_transform_matrix_absolute:nnnn { 2 } { 0 } { 1 } { 2 }
 %       \draw_path_moveto:n { 0cm , 0cm }
 %       \draw_path_lineto:n { 0cm , 1cm }
 %       \draw_path_use_clear:n { stroke }
@@ -991,23 +991,24 @@
 % is transparent to the drawing code so is not tracked.
 %
 % \begin{function}
-%   {\draw_transform_matrix:nnnn, \draw_transform_matrix_concat:nnnn}
+%   {\draw_transform_matrix:nnnn, \draw_transform_matrix_absolute:nnnn}
 %   \begin{syntax}
 %     \cs{draw_transform_matrix:nnnn}
 %       \Arg{a} \Arg{b} \Arg{c} \Arg{d}
 %   \end{syntax}
 %   Applies the transformation matrix $[ \meta{a} \meta{b} \meta{c} \meta{d}]$.
-%   The basic version over-writes the current matrix, the |concat| version
-%   concatenates.
+%   The basic applies the transformation in addition to those active; the
+%   |absolute| version overwrites any active transformation.
 %   This assignment is local.
 % \end{function}
 %
-% \begin{function}{\draw_transform_shift:n, \draw_transform_shift_concat:n}
+% \begin{function}{\draw_transform_shift:n, \draw_transform_shift_absolute:n}
 %   \begin{syntax}
 %     \cs{draw_transform_shift:n} \Arg{vector}
 %   \end{syntax}
-%   Applies the transformation \meta{vector} to points. The basic version
-%   over-writes the current vector, the |concat| version concatenates.
+%   Applies the transformation \meta{vector} to points.
+%   The basic applies the vector in addition to those active; the
+%   |absolute| version overwrites any active vector.
 %   This assignment is local.
 % \end{function}
 %
@@ -1091,6 +1092,41 @@
 %   This assignment is local.
 % \end{function}
 %
+% \subsection{Layers}
+%
+% Drawing layers may be used to alter the way in which elements are stacked
+% on top of one another. In particular, they are useful when the nature of
+% an element depends on another, but where it needs to be behind it's
+% \enquote{parent}. A classic example is a filled background: this needs to
+% know the size of the material it is behind.
+%
+% All drawings feature a layer called |main|. This layer should always be
+% present, and is the one which \enquote{non-layered} content is added to.
+%
+% \begin{function}{\draw_layer_new:n}
+%   \begin{syntax}
+%     \cs{draw_layer_new:n} \Arg{layer}
+%   \end{syntax}
+%   Creates a new \meta{layer} which can then be used in drawing. The layer
+%   |main| is pre-defined.
+% \end{function}
+%
+% \begin{function}{\draw_layer_begin:n, \draw_layer_end:}
+%   \begin{syntax}
+%     \cs{draw_layer_begin:n} \Arg{layer}
+%     ...
+%     \cs{draw_layer_end:}
+%   \end{syntax}
+%   Begin and end collection of material for the \meta{layer}, which should
+%   previously have been created (and which cannot be |main|). Material
+%   collected for the layer is available globally within the current drawing.
+% \end{function}
+%
+% \begin{variable}{\l_draw_layers_clist}
+%   The list of active layers: may be given anywhere before \cs{draw_end:}.
+%   The |main| layer should always be included.
+% \end{variable}
+%
 % \end{documentation}
 %
 % \begin{implementation}
@@ -1107,7 +1143,7 @@
 %
 %    \begin{macrocode}
 %<*package>
-\ProvidesExplPackage{l3draw}{2019-01-28}{}
+\ProvidesExplPackage{l3draw}{2019-03-05}{}
   {L3 Experimental core drawing support}
 %</package>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins	2019-03-05 22:35:14 UTC (rev 50246)
@@ -57,6 +57,7 @@
   {
     \from{l3draw.dtx}            {package}
     \from{l3draw-boxes.dtx}      {package}
+    \from{l3draw-layers.dtx}     {package}
     \from{l3draw-paths.dtx}      {package}
     \from{l3draw-points.dtx}     {package}
     \from{l3draw-scopes.dtx}     {package}

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-convert.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-convert.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-convert.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -234,7 +234,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{l3str-convert}{2019-01-28}{}
+\ProvidesExplPackage{l3str-convert}{2019-03-05}{}
   {L3 Experimental string encoding conversions}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -48,7 +48,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -164,7 +164,7 @@
 %
 %    \begin{macrocode}
 %<*package>
-\ProvidesExplPackage{l3str-format}{2019-01-28}{}
+\ProvidesExplPackage{l3str-format}{2019-03-05}{}
   {L3 Experimental string formatting}
 %</package>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -136,7 +136,7 @@
 %
 %    \begin{macrocode}
 %<*package>
-\ProvidesExplPackage{l3sys-shell}{2019-01-28}{}
+\ProvidesExplPackage{l3sys-shell}{2019-03-05}{}
   {L3 Experimental system shell functions}
 %</package>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -56,7 +56,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -675,7 +675,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xcoffins}{2019-01-28}{}
+\ProvidesExplPackage{xcoffins}{2019-03-05}{}
   {L3 Experimental design level coffins}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -61,7 +61,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -687,7 +687,7 @@
 %
 %    \begin{macrocode}
 %<*package>
-\ProvidesExplPackage{l3galley}{2019-01-28}{}
+\ProvidesExplPackage{l3galley}{2019-03-05}{}
   {L3 Experimental galley code}
 %</package>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -47,7 +47,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-01-28}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -734,7 +734,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xgalley}{2019-01-28}{}
+\ProvidesExplPackage{xgalley}{2019-03-05}{}
   {L3 Experimental galley}
 \RequirePackage{xparse,xtemplate,l3galley}
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -23,7 +23,7 @@
 % for those people who are interested.
 %
 %<*driver|generic|package>
-\def\ExplFileDate{2019-02-15}%
+\def\ExplFileDate{2019-03-05}%
 %</driver|generic|package>
 %<*driver>
 \documentclass[full]{l3doc}
@@ -51,7 +51,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -917,6 +917,12 @@
 % the option name alone is equivalent to using the option with the
 % \texttt{true} value.
 %
+% \DescribeOption{undo-recent-deprecations}
+% The \texttt{undo-recent-deprecations} option suppresses deprecation
+% errors for the first six months after a command is deprecated.  It is
+% intended as a last resort measure for users of packages that were not
+% updated in time.
+%
 % \DescribeOption{check-declarations}
 % All variables used in \LaTeX3 code should be declared. This is enforced
 % by \TeX{} for variable types based on \TeX{} registers, but not for those
@@ -1190,6 +1196,7 @@
 % \begin{macro}[int]{\expl at create@bool at option}
 % \begin{variable}[int]
 %   {
+%     \l at expl@undo at recent@deprecations at bool ,
 %     \l at expl@check at declarations@bool ,
 %     \l at expl@log at functions@bool ,
 %     \l at expl@enable at debug@bool
@@ -1213,6 +1220,8 @@
     \newcommand*#2{}%
     \chardef #2=0 %
   }%
+\expl at create@bool at option
+  {undo-recent-deprecations}\l at expl@undo at recent@deprecations at bool
 \expl at create@bool at option{check-declarations}\l at expl@check at declarations@bool
 \expl at create@bool at option{log-functions}\l at expl@log at functions@bool
 \expl at create@bool at option{enable-debug}\l at expl@enable at debug@bool
@@ -1242,10 +1251,6 @@
 % \end{variable}
 % \end{macro}
 %
-% \begin{macro}{\GetIdInfo}
-%   This is implemented right at the start of \texttt{l3bootstrap.dtx}.
-% \end{macro}
-%
 % \begin{macro}{\ProvidesExplPackage, \ProvidesExplClass, \ProvidesExplFile}
 %   For other packages and classes building on this one it is convenient
 %   not to need \cs{ExplSyntaxOn} each time.
@@ -1282,18 +1287,6 @@
 \fi
 %    \end{macrocode}
 %
-% \begin{macro}{\color}
-%   The \cs{color} macro must be defined for showing coffin poles, so
-%   a no-op version is provided here.
-%    \begin{macrocode}
-\AtBeginDocument
-  {
-    \cs_if_exist:NF \color
-      { \DeclareRobustCommand \color [2] [ ] { } }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{variable}{\l__expl_driver_tl}
 % \begin{variable}{\l__expl_native_drivers_bool}
 %   With the code now loaded, options can be handled using a real key--value
@@ -1434,6 +1427,7 @@
 %    \begin{macrocode}
 \keys_define:nn { expl }
   {
+    undo-recent-deprecations .bool_set:N = \l at expl@undo at recent@deprecations at bool,
     check-declarations .bool_set:N = \l at expl@check at declarations@bool,
     log-functions      .bool_set:N = \l at expl@log at functions@bool
   }
@@ -1667,6 +1661,7 @@
 %
 % \begin{variable}[int]
 %   {
+%     \l at expl@undo at recent@deprecations at bool ,
 %     \l at expl@check at declarations@bool ,
 %     \l at expl@log at functions@bool ,
 %     \l at expl@enable at debug@bool
@@ -1675,6 +1670,7 @@
 %  the two variables are defined to do nothing.
 %  Appropriate value before input of the loader.
 %    \begin{macrocode}
+\chardef \l at expl@undo at recent@deprecations at bool = 0 %
 \chardef \l at expl@check at declarations@bool = 0 %
 \chardef \l at expl@log at functions@bool = 0 %
 \chardef \l at expl@enable at debug@bool = 0 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -163,7 +163,7 @@
 %      Create a new function with the \texttt{protected} restriction,
 %      such as \cs{cs_set_protected:Npn}. The parameter may contain
 %      \cs{par} tokens but the function will not expand within an
-%      \texttt{x}-type expansion.
+%      \texttt{x}-type or \texttt{e}-type expansion.
 % \end{description}
 %
 % Finally, the functions in
@@ -244,7 +244,7 @@
 %   \emph{etc.}) will be replaced by those absorbed by the function.
 %   When the \meta{function} is used the \meta{parameters} absorbed
 %   cannot contain \cs{par} tokens. The \meta{function} will not
-%   expand within an \texttt{x}-type argument. The definition is global
+%   expand within an \texttt{x}-type or \texttt{e}-type argument. The definition is global
 %   and an error results if the \meta{function} is already defined.
 % \end{function}
 %
@@ -289,7 +289,7 @@
 %   \emph{etc.}) will be replaced by those absorbed by the function.
 %   The assignment of a meaning to the \meta{function} is restricted to
 %   the current \TeX{} group level. The \meta{function} will
-%   not expand within an \texttt{x}-type argument.
+%   not expand within an \texttt{x}-type or \texttt{e}-type argument.
 % \end{function}
 %
 % \begin{function}
@@ -307,7 +307,7 @@
 %   cannot contain \cs{par} tokens. The assignment of a meaning
 %   to the \meta{function} is restricted to the current \TeX{} group
 %   level. The \meta{function} will not expand within an
-%   \texttt{x}-type argument.
+%   \texttt{x}-type or \texttt{e}-type argument.
 % \end{function}
 %
 % \begin{function}{\cs_gset:Npn, \cs_gset:cpn, \cs_gset:Npx, \cs_gset:cpx}
@@ -353,7 +353,7 @@
 %   The assignment of a meaning to the \meta{function} is \emph{not}
 %   restricted to the current \TeX{} group level: the assignment is
 %   global. The \meta{function} will not expand within an
-%   \texttt{x}-type argument.
+%   \texttt{x}-type or \texttt{e}-type argument.
 % \end{function}
 %
 % \begin{function}
@@ -441,7 +441,7 @@
 %   (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
 %   function.  When the \meta{function} is used the \meta{parameters}
 %   absorbed cannot contain \cs{par} tokens. The \meta{function} will not
-%   expand within an \texttt{x}-type argument. The definition is global and
+%   expand within an \texttt{x}-type or \texttt{e}-type argument. The definition is global and
 %   an error results if the \meta{function} is already defined.
 % \end{function}
 %
@@ -512,7 +512,7 @@
 %   (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
 %   function.  When the \meta{function} is used the \meta{parameters}
 %   absorbed cannot contain \cs{par} tokens. The \meta{function} will not
-%   expand within an \texttt{x}-type argument.
+%   expand within an \texttt{x}-type or \texttt{e}-type argument.
 %   The assignment of a meaning to the \meta{function} is restricted to
 %   the current \TeX{} group level.
 % \end{function}
@@ -581,7 +581,7 @@
 %   (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
 %   function.  When the \meta{function} is used the \meta{parameters}
 %   absorbed cannot contain \cs{par} tokens. The \meta{function} will not
-%   expand within an \texttt{x}-type argument.
+%   expand within an \texttt{x}-type or \texttt{e}-type argument.
 %   The assignment of a meaning to the \meta{function} is global.
 % \end{function}
 %
@@ -794,7 +794,7 @@
 %   of category code $10$. The result does \emph{not} include
 %   the current escape token, contrarily to \cs{token_to_str:N}.
 %   Full expansion of this function requires exactly $2$ expansion
-%   steps, and so an \texttt{x}-type expansion, or two
+%   steps, and so an \texttt{x}-type or \texttt{e}-type expansion, or two
 %   \texttt{o}-type expansions are required to
 %   convert the \meta{control sequence} to a sequence of characters
 %   in the input stream. In most cases, an \texttt{f}-expansion
@@ -802,7 +802,7 @@
 %   of the result.
 % \end{function}
 %
-% \section{Analysing control sequence names}
+% \section{Analysing control sequences}
 %
 % \begin{function}[EXP, added = 2018-04-06]{\cs_split_function:N}
 %   \begin{syntax}
@@ -819,6 +819,70 @@
 %   (other).
 % \end{function}
 %
+% The next three functions decompose \TeX{} macros into their
+% constituent parts: if the \meta{token} passed is not a macro then no
+% decomposition can occur. In the latter case, all three functions leave
+% \cs{scan_stop:} in the input stream.
+%
+% \begin{function}[EXP, added = 2019-02-27]{\cs_prefix_spec:N}
+%   \begin{syntax}
+%     \cs{cs_prefix_spec:N} \meta{token}
+%   \end{syntax}
+%   If the \meta{token} is a macro, this function leaves the applicable
+%   \TeX{} prefixes in input stream as a string of tokens of category
+%   code $12$ (with spaces having category code $10$). Thus for example
+%   \begin{verbatim}
+%     \cs_set:Npn \next:nn #1#2 { x #1~y #2 }
+%     \cs_prefix_spec:N \next:nn
+%   \end{verbatim}
+%   leaves |\long| in the input stream. If the \meta{token} is
+%   not a macro then \cs{scan_stop:} is left in the input stream.
+%   \begin{texnote}
+%     The prefix can be empty, |\long|, |\protected| or
+%     |\protected\long| with backslash replaced by the current escape
+%     character.
+%   \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2019-02-27]{\cs_argument_spec:N}
+%   \begin{syntax}
+%     \cs{cs_argument_spec:N} \meta{token}
+%   \end{syntax}
+%   If the \meta{token} is a macro, this function leaves the primitive
+%   \TeX{} argument specification in input stream as a string of
+%   character tokens of category code $12$ (with spaces having category
+%   code $10$). Thus for example
+%   \begin{verbatim}
+%     \cs_set:Npn \next:nn #1#2 { x #1 y #2 }
+%     \cs_argument_spec:N \next:nn
+%   \end{verbatim}
+%   leaves |#1#2| in the input stream. If the \meta{token} is
+%   not a macro then \cs{scan_stop:} is left in the input stream.
+%   \begin{texnote}
+%     If the argument specification contains the string |->|, then the
+%     function produces incorrect results.
+%   \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP, added = 2019-02-27]{\cs_replacement_spec:N}
+%   \begin{syntax}
+%     \cs{cs_replacement_spec:N} \meta{token}
+%   \end{syntax}
+%   If the \meta{token} is a macro, this function leaves the replacement
+%   text in input stream as a string of character tokens of category
+%   code $12$ (with spaces having category code $10$). Thus for example
+%   \begin{verbatim}
+%     \cs_set:Npn \next:nn #1#2 { x #1~y #2 }
+%     \cs_replacement_spec:N \next:nn
+%   \end{verbatim}
+%   leaves \verb*|x#1 y#2| in the input stream. If the \meta{token} is
+%   not a macro then \cs{scan_stop:} is left in the input stream.
+%   \begin{texnote}
+%     If the argument specification contains the string |->|, then the
+%     function produces incorrect results.
+%   \end{texnote}
+% \end{function}
+%
 % \section{Using or removing tokens and arguments}
 %
 % Tokens in the input can be read and used or read and discarded.
@@ -1931,8 +1995,7 @@
 % \begin{variable}{\g_@@_deprecation_on_tl, \g_@@_deprecation_off_tl}
 %   Some commands were more recently deprecated and not yet removed;
 %   only make these into errors if the user requests it.  This relies on
-%   two token lists, mostly filled up by calls to
-%   \cs{__kernel_patch_deprecation:nnNNpn} in each module.
+%   two token lists, filled up in \pkg{l3deprecation}.
 %    \begin{macrocode}
 \__kernel_if_debug:TF
   {
@@ -1956,82 +2019,6 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\__kernel_patch_deprecation:nnNNpn}
-% \begin{macro}{\@@_deprecation_aux:nnNnn}
-%   Grab a definition (at present, must be \cs{cs_new_protected:Npn} or \cs{cs_new:Npn}).
-%   Add to \cs{g_@@_deprecation_on_tl} some code that makes the
-%   defined macro |#3| outer (and defines it as an error).  Add to
-%   \cs{g_@@_deprecation_off_tl} the definition itself.  In both
-%   cases we undefine the token with \cs{tex_let:D} to avoid taking a
-%   potentially outer macro as the argument of some \pkg{expl3}
-%   function.  Finally, define the macro itself: if it is protected,
-%   make it produce a warning then redefine and call itself.  The macro
-%   initially takes no parameters:
-%   together with the \texttt{x}-expanding assignment and \cs{exp_not:n}
-%   this gives a convenient way of storing the macro's definition in
-%   itself in order to only produce the warning once for each macro.
-%   If debugging is disabled, \cs{__kernel_patch_deprecation:nnNNpn} lets the
-%   definition happen.
-%    \begin{macrocode}
-\__kernel_if_debug:TF
-  {
-    \cs_set_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2#3#4#5#
-      {
-        \if_meaning:w \cs_new_protected:Npn #3
-          \exp_after:wN \use_i:nn
-        \else:
-          \if_meaning:w \cs_new:Npn #3
-            \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nn
-          \else:
-            \__kernel_msg_error:nnx { kernel } { debug-unpatchable }
-              { \token_to_str:N #3 ~(for~deprecation) }
-            \exp_after:wN \exp_after:wN \exp_after:wN \use_none:nn
-          \fi:
-        \fi:
-        { \@@_deprecation_aux:nnNnn {#1} {#2} #4 {#5} }
-        { \@@_deprecation_expandable:nnNnn {#1} {#2} #4 {#5} }
-      }
-    \cs_set_protected:Npn \@@_deprecation_aux:nnNnn #1#2#3#4#5
-      {
-        \tl_gput_right:Nn \g_@@_deprecation_on_tl
-          {
-            \tex_let:D #3 \scan_stop:
-            \__kernel_deprecation_error:Nnn #3 {#2} {#1}
-          }
-        \tl_gput_right:Nn \g_@@_deprecation_off_tl
-          {
-            \tex_let:D #3 \scan_stop:
-            \cs_set_protected:Npn #3 #4 {#5}
-          }
-        \cs_new_protected:Npx #3
-          {
-            \exp_not:N \__kernel_msg_warning:nnxxx
-              { kernel } { deprecated-command }
-              {#1} { \token_to_str:N #3 } { \tl_to_str:n {#2} }
-            \exp_not:n { \cs_gset_protected:Npn #3 #4 {#5} }
-            \exp_not:N #3
-          }
-      }
-    \cs_set_protected:Npn \@@_deprecation_expandable:nnNnn #1#2#3#4#5
-      {
-        \tl_gput_right:Nn \g_@@_deprecation_on_tl
-          {
-            \tex_let:D #3 \scan_stop:
-            \__kernel_deprecation_error:Nnn #3 {#2} {#1}
-          }
-        \tl_gput_right:Nn \g_@@_deprecation_off_tl
-          {
-            \tex_let:D #3 \scan_stop:
-            \cs_set:Npn #3 #4 {#5}
-          }
-        \cs_new:Npn #3 #4 {#5}
-      }
-  }
-  { \cs_set_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2 { } }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
 % \begin{macro}
 %   {\__kernel_patch:nnNNpn, \__kernel_patch_conditional:nNNpnn}
 % \begin{macro}
@@ -3470,6 +3457,60 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \subsection{Decomposing a macro definition}
+%
+% \begin{macro}{\cs_prefix_spec:N}
+% \begin{macro}{\cs_argument_spec:N}
+% \begin{macro}{\cs_replacement_spec:N}
+% \begin{macro}{\@@_prefix_arg_replacement:wN}
+%   We sometimes want to test if a control sequence can be expanded to
+%   reveal a hidden value. However, we cannot just expand the macro
+%   blindly as it may have arguments and none might be
+%   present. Therefore we define these functions to pick either the
+%   prefix(es), the argument specification, or the replacement text from
+%   a macro. All of this information is returned as characters with
+%   catcode~$12$. If the token in question isn't a macro, the token
+%   \cs{scan_stop:} is returned instead.
+%    \begin{macrocode}
+\use:x
+  {
+    \exp_not:n { \cs_new:Npn \@@_prefix_arg_replacement:wN #1 }
+    \tl_to_str:n { macro : } \exp_not:n { #2 -> #3 \q_stop #4 }
+  }
+  { #4 {#1} {#2} {#3} }
+\cs_new:Npn \cs_prefix_spec:N #1
+  {
+    \token_if_macro:NTF #1
+      {
+        \exp_after:wN \@@_prefix_arg_replacement:wN
+          \token_to_meaning:N #1 \q_stop \use_i:nnn
+      }
+      { \scan_stop: }
+  }
+\cs_new:Npn \cs_argument_spec:N #1
+  {
+    \token_if_macro:NTF #1
+      {
+        \exp_after:wN \@@_prefix_arg_replacement:wN
+          \token_to_meaning:N #1 \q_stop \use_ii:nnn
+      }
+      { \scan_stop: }
+  }
+\cs_new:Npn \cs_replacement_spec:N #1
+  {
+    \token_if_macro:NTF #1
+      {
+        \exp_after:wN \@@_prefix_arg_replacement:wN
+          \token_to_meaning:N #1 \q_stop \use_iii:nnn
+      }
+      { \scan_stop: }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Doing nothing functions}
 %
 % \begin{macro}[EXP]{\prg_do_nothing:}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -22,103 +22,6 @@
 %
 % for those people who are interested.
 %
-%<*driver|package>
-% \begin{macro}{\GetIdInfo}
-% \begin{macro}{\GetIdInfoAuxI, \GetIdInfoAuxII, \GetIdInfoAuxIII}
-%   The idea here is to extract out the information needed from a standard
-%   \textsc{svn} \texttt{Id} line, but to avoid a line that would get
-%   changed when the file is checked in. Hence the fact that none of the
-%   lines here include both a dollar sign and the \texttt{Id} keyword!
-%
-%   At this stage, no test has taken place for the \eTeX{} extensions, and
-%   so using \tn{protected} could give an error. To avoid that, it is used
-%   by csname: if it's not available, the bootstrap code will bail out at
-%   the point of testing for the necessary primitives, while if it is available
-%   then \cs{GetIdInfo} and so on will be properly protected. All of this is
-%   then done in a group to avoid leaving \tn{protected} about as equivalent
-%   to \tn{relax} if the extensions are unavailable.
-%    \begin{macrocode}
-\begingroup
-  \csname protected\endcsname\gdef\GetIdInfo
-    {%
-      \begingroup
-        \catcode 32 = 10 %
-        \GetIdInfoAuxI
-    }%
-%    \end{macrocode}
-%   A first check for a completely empty \textsc{svn} field. If that is
-%   not the case, there is a second case when a file created using
-%   \texttt{svn cp} but has not been checked in. That leaves a special
-%   marker \texttt{-1} version, which has no further data. Dealing correctly
-%   with that is the reason for the space in the line to use
-%   \cs{GetIdInforAuxII}.
-%    \begin{macrocode}
-  \csname protected\endcsname\gdef\GetIdInfoAuxI$#1$#2%
-    {%
-      \def\tempa{#1}%
-      \def\tempb{Id}%
-      \ifx\tempa\tempb
-        \def\tempa
-          {%
-            \endgroup
-            \def\ExplFileDate{0000/00/00}%
-            \def\ExplFileDescription{#2}%
-            \def\ExplFileName{[unknown]}%
-            \def\ExplFileExtension{[unknown extension]}%
-            \def\ExplFileVersion{-1}%
-          }%
-      \else
-        \def\tempa
-          {%
-            \endgroup
-            \def\ExplFileDescription{#2}%
-            \GetIdInfoAuxII$#1 $%
-          }%
-      \fi
-      \tempa
-    }%
-%    \end{macrocode}
-%   Here, |#1| is |Id|, |#2| is the file name, |#3| is the extension,
-%   |#4| is the version, |#5| is the check in date and |#6| is the check in
-%   time and user, plus some trailing spaces. If |#4| is the marker |-1| value
-%   then |#5| and |#6| are empty.
-%    \begin{macrocode}
-  \csname protected\endcsname\gdef\GetIdInfoAuxII$#1 #2.#3 #4 #5 #6$%
-    {%
-      \def\ExplFileName{#2}%
-      \def\ExplFileExtension{#3}%
-      \def\ExplFileVersion{#4}%
-      \begingroup
-        \def\tempa{#4}%
-        \def\tempb{-1}%
-        \ifx\tempa\tempb
-          \def\tempa
-            {%
-              \endgroup
-              \def\ExplFileDate{0000/00/00}%
-            }%
-        \else
-          \def\tempa
-            {%
-              \endgroup
-              \GetIdInfoAuxIII$#5$%
-            }%
-        \fi
-        \tempa
-    }%
-%    \end{macrocode}
-%   Convert an \textsc{svn}-style date into a \LaTeX{}-style one.
-%    \begin{macrocode}
-  \csname protected\endcsname\gdef\GetIdInfoAuxIII$#1-#2-#3$%
-    {%
-      \def\ExplFileDate{#1/#2/#3}%
-    }%
-\endgroup
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%</driver|package>
 %<*driver>
 \documentclass[full,kernel]{l3doc}
 \begin{document}
@@ -140,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -2270,50 +2270,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{Deprecated functions}
-%
-% \begin{macro}
-%   {
-%     \box_set_eq_clear:NN, \box_set_eq_clear:cN,
-%     \box_set_eq_clear:Nc, \box_set_eq_clear:cc
-%   }
-% \begin{macro}
-%   {
-%     \box_gset_eq_clear:NN, \box_gset_eq_clear:cN,
-%     \box_gset_eq_clear:Nc, \box_gset_eq_clear:cc
-%   }
 %    \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \box_set_eq_drop:N }
-\cs_new_protected:Npn \box_set_eq_clear:NN #1#2
-  { \tex_setbox:D #1 \tex_box:D #2 }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \box_gset_eq_drop:N }
-\cs_new_protected:Npn \box_gset_eq_clear:NN #1#2
-  { \tex_global:D \tex_setbox:D #1 \tex_box:D #2 }
-\cs_generate_variant:Nn \box_set_eq_clear:NN  { c , Nc , cc }
-\cs_generate_variant:Nn \box_gset_eq_clear:NN { c , Nc , cc }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\hbox_unpack_clear:N, \hbox_unpack_clear:c}
-%    \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \hbox_unpack_drop:N }
-\cs_new_protected:Npn \hbox_unpack_clear:N
-  { \hbox_unpack_drop:N }
-\cs_generate_variant:Nn \hbox_unpack_clear:N { c }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\vbox_unpack_clear:N, \vbox_unpack_clear:c}
-%    \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \vbox_unpack_drop:N }
-\cs_new_protected:Npn \vbox_unpack_clear:N
-  { \vbox_unpack_drop:N }
-\cs_generate_variant:Nn \vbox_unpack_clear:N { c }
-%    \end{macrocode}
-% \end{macro}
-%
-%    \begin{macrocode}
 %</initex|package>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -203,47 +203,6 @@
 %   operation is applied.
 % \end{function}
 %
-% \section{Additions to \pkg{l3coffins}}
-%
-% \begin{function}[updated = 2019-01-23]
-%   {
-%     \coffin_resize:Nnn, \coffin_resize:cnn,
-%     \coffin_gresize:Nnn, \coffin_gresize:cnn
-%   }
-%   \begin{syntax}
-%     \cs{coffin_resize:Nnn} \meta{coffin} \Arg{width} \Arg{total-height}
-%   \end{syntax}
-%   Resized the \meta{coffin} to \meta{width} and \meta{total-height},
-%   both of which should be given as dimension expressions.
-% \end{function}
-%
-% \begin{function}
-%   {
-%     \coffin_rotate:Nn, \coffin_rotate:cn,
-%     \coffin_grotate:Nn, \coffin_grotate:cn
-%   }
-%   \begin{syntax}
-%     \cs{coffin_rotate:Nn} \meta{coffin} \Arg{angle}
-%   \end{syntax}
-%   Rotates the \meta{coffin} by the given \meta{angle} (given in
-%   degrees counter-clockwise). This process rotates both the
-%   coffin content and poles. Multiple rotations do not result in
-%   the bounding box of the coffin growing unnecessarily.
-% \end{function}
-%
-% \begin{function}[updated = 2019-01-23]
-%   {
-%     \coffin_scale:Nnn, \coffin_scale:cnn,
-%     \coffin_gscale:Nnn, \coffin_gscale:cnn
-%   }
-%   \begin{syntax}
-%     \cs{coffin_scale:Nnn} \meta{coffin} \Arg{x-scale} \Arg{y-scale}
-%   \end{syntax}
-%   Scales the \meta{coffin} by a factors \meta{x-scale} and
-%   \meta{y-scale} in the horizontal and vertical directions,
-%   respectively. The two scale factors should be given as real numbers.
-% \end{function}
-%
 % \section{Additions to \pkg{l3expan}}
 %
 % \begin{function}[added = 2018-04-04, updated = 2019-02-08]
@@ -340,9 +299,10 @@
 %
 % \section{Additions to \pkg{l3file}}
 %
-% \begin{function}[added = 2017-07-11]{\file_get_mdfive_hash:nN}
+% \begin{function}[noTF, added = 2017-07-11, updated = 2019-02-16]
+%   {\file_get_mdfive_hash:nN}
 %   \begin{syntax}
-%     \cs{file_get_mdfive_hash:nN} \Arg{file name} \meta{str var}
+%     \cs{file_get_mdfive_hash:nN} \Arg{file name} \meta{tl var}
 %   \end{syntax}
 %   Searches for \meta{file name} using the current \TeX{} search
 %   path and the additional paths controlled by \cs{file_path_include:n}.
@@ -355,9 +315,10 @@
 %   Where the file is not found, the \meta{str var} will be empty.
 % \end{function}
 %
-% \begin{function}[added = 2017-07-09]{\file_get_size:nN}
+% \begin{function}[noTF, added = 2017-07-09, updated = 2019-02-16]
+%   {\file_get_size:nN}
 %   \begin{syntax}
-%     \cs{file_get_size:nN} \Arg{file name} \meta{str var}
+%     \cs{file_get_size:nN} \Arg{file name} \meta{tl var}
 %   \end{syntax}
 %   Searches for \meta{file name} using the current \TeX{} search
 %   path and the additional paths controlled by \cs{file_path_include:n}.
@@ -366,9 +327,10 @@
 %   This is not available in older versions of \XeTeX{}.
 % \end{function}
 %
-% \begin{function}[added = 2017-07-09]{\file_get_timestamp:nN}
+% \begin{function}[noTF, added = 2017-07-09, updated = 2019-02-16]
+%   {\file_get_timestamp:nN}
 %   \begin{syntax}
-%     \cs{file_get_timestamp:nN} \Arg{file name} \meta{str var}
+%     \cs{file_get_timestamp:nN} \Arg{file name} \meta{tl var}
 %   \end{syntax}
 %   Searches for \meta{file name} using the current \TeX{} search
 %   path and the additional paths controlled by \cs{file_path_include:n}.
@@ -532,14 +494,15 @@
 % having a similar interface as non-expandable messages, expandable
 % errors must be handled internally very differently from normal error
 % messages, as none of the tools to print to the terminal or the log
-% file are expandable.  As a result, the message text and arguments are
-% not expanded, and messages must be very short (with default settings,
+% file are expandable.  As a result, short-hands such as |\{| or |\\| do
+% not work, and messages must be very short (with default settings,
 % they are truncated after approximately 50 characters).  It is
 % advisable to ensure that the message is understandable even when
-% truncated.  Another particularity of expandable messages is that they
+% truncated, by putting the most important information up front.
+% Another particularity of expandable messages is that they
 % cannot be redirected or turned off by the user.
 %
-% \begin{function}[EXP, added = 2015-08-06]
+% \begin{function}[EXP, added = 2015-08-06, updated = 2019-02-28]
 %   {
 %     \msg_expandable_error:nnnnnn ,
 %     \msg_expandable_error:nnnnn  ,
@@ -636,14 +599,6 @@
 %
 % \section{Additions to \pkg{l3prop}}
 %
-% \begin{function}[EXP]{\prop_count:N, \prop_count:c}
-%   \begin{syntax}
-%     \cs{prop_count:N} \meta{property list}
-%   \end{syntax}
-%   Leaves the number of key--value pairs in the \meta{property list} in
-%   the input stream as an \meta{integer denotation}.
-% \end{function}
-%
 % \begin{function}[rEXP]
 %   {\prop_map_tokens:Nn, \prop_map_tokens:cn}
 %   \begin{syntax}
@@ -857,24 +812,10 @@
 %   input stream according to the sign of the result.
 % \end{function}
 %
-% \begin{function}{\skip_split_finite_else_action:nnNN}
-%   \begin{syntax}
-%     \cs{skip_split_finite_else_action:nnNN} \Arg{skipexpr} \Arg{action}
-%     ~~\meta{dimen_1} \meta{dimen_2}
-%   \end{syntax}
-%   Checks if the \meta{skipexpr} contains finite glue. If it does then it
-%   assigns
-%   \meta{dimen_1} the stretch component and \meta{dimen_2} the shrink
-%   component. If
-%   it contains infinite glue set \meta{dimen_1} and \meta{dimen_2} to $0$\,pt
-%   and place |#2| into the input stream: this is usually an error or
-%   warning message of some sort.
-% \end{function}
-%
 % \section{Additions to \pkg{l3sys}}
 %
-% \begin{function}[added = 2019-01-16]{\sys_shell_get:nnN}
-% \begin{function}[TF,added = 2019-01-16]{\sys_shell_get:nnN}
+% \begin{function}[noTF, added = 2019-01-16, updated = 2019-02-16]
+%   {\sys_shell_get:nnN}
 %   \begin{syntax}
 %     \cs{sys_shell_get:nnN} \Arg{shell~command} \Arg{setup} \meta{tl~var}
 %     \cs{sys_shell_get:nnNTF} \Arg{shell~command} \Arg{setup} \meta{tl~var} \Arg{true code} \Arg{false code}
@@ -884,13 +825,13 @@
 %   \cs{tl_to_str:n}.  Category codes may need to be set appropriately
 %   via the \meta{setup} argument, which is run just before running the
 %   \meta{shell command} (in a group).
-%   If shell escape is disabled, the \meta{tl~var} will be empty.
+%   If shell escape is disabled, the \meta{tl~var} will be set to
+%   \cs{q_no_value} in the non-branching version.
 %   Note that quote characters (|"|) \emph{cannot} be used inside the
 %   \meta{shell command}.  The \cs{sys_shell_get:nnNTF} conditional
 %   returns \texttt{true} if the shell is available and no quote is
 %   detected, and \texttt{false} otherwise.
 % \end{function}
-% \end{function}
 %
 % \begin{variable}[added = 2018-05-02]{\c_sys_engine_version_str}
 %   The version string of the current engine, in the same form as
@@ -1034,38 +975,6 @@
 %   Token groups (|{|\ldots|}|) are not single tokens.
 % \end{function}
 %
-% \begin{function}[EXP]{\tl_reverse_tokens:n}
-%   \begin{syntax}
-%     \cs{tl_reverse_tokens:n} \Arg{tokens}
-%   \end{syntax}
-%   This function, which works directly on \TeX{} tokens, reverses
-%   the order of the \meta{tokens}: the first becomes the last and
-%   the last becomes first. Spaces are preserved. The reversal
-%   also operates within brace groups, but the braces themselves
-%   are not exchanged, as this would lead to an unbalanced token
-%   list. For instance, \cs{tl_reverse_tokens:n} |{a~{b()}}|
-%   leaves |{)(b}~a| in the input stream. This function requires
-%   two steps of expansion.
-%   \begin{texnote}
-%     The result is returned within the \tn{unexpanded}
-%     primitive (\cs{exp_not:n}), which means that the token
-%     list does not expand further when appearing in an \texttt{x}-type
-%     argument expansion.
-%   \end{texnote}
-% \end{function}
-%
-% \begin{function}[EXP]{\tl_count_tokens:n}
-%   \begin{syntax}
-%     \cs{tl_count_tokens:n} \Arg{tokens}
-%   \end{syntax}
-%   Counts the number of \TeX{} tokens in the \meta{tokens} and leaves
-%   this information in the input stream. Every token, including spaces and
-%   braces, contributes one to the total; thus for instance, the token count of
-%   |a~{bc}| is $6$.
-%   This function requires three expansions,
-%   giving an \meta{integer denotation}.
-% \end{function}
-%
 % \begin{function}[EXP, added = 2014-06-30, updated = 2016-01-12]
 %   {
 %     \tl_lower_case:n,  \tl_upper_case:n,  \tl_mixed_case:n,
@@ -1662,544 +1571,6 @@
 % \end{macro}
 % \end{macro}
 %
-% \subsection{Additions to \pkg{l3coffins}}
-%
-%    \begin{macrocode}
-%<@@=coffin>
-%    \end{macrocode}
-%
-% \subsubsection{Rotating coffins}
-%
-% \begin{variable}{\l_@@_sin_fp}
-% \begin{variable}{\l_@@_cos_fp}
-%   Used for rotations to get the sine and cosine values.
-%    \begin{macrocode}
-\fp_new:N \l_@@_sin_fp
-\fp_new:N \l_@@_cos_fp
-%    \end{macrocode}
-% \end{variable}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_bounding_prop}
-%   A property list for the bounding box of a coffin. This is only needed
-%   during the rotation, so there is just the one.
-%    \begin{macrocode}
-\prop_new:N \l_@@_bounding_prop
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_corners_prop, \l_@@_poles_prop}
-%   Used to avoid needing to track scope for intermediate steps.
-%    \begin{macrocode}
-\prop_new:N \l_@@_corners_prop
-\prop_new:N \l_@@_poles_prop
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_bounding_shift_dim}
-%   The shift of the bounding box of a coffin from the real content.
-%    \begin{macrocode}
-\dim_new:N \l_@@_bounding_shift_dim
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_left_corner_dim}
-% \begin{variable}{\l_@@_right_corner_dim}
-% \begin{variable}{\l_@@_bottom_corner_dim}
-% \begin{variable}{\l_@@_top_corner_dim}
-%   These are used to hold maxima for the various corner values: these
-%   thus define the minimum size of the bounding box after rotation.
-%    \begin{macrocode}
-\dim_new:N \l_@@_left_corner_dim
-\dim_new:N \l_@@_right_corner_dim
-\dim_new:N \l_@@_bottom_corner_dim
-\dim_new:N \l_@@_top_corner_dim
-%    \end{macrocode}
-% \end{variable}
-% \end{variable}
-% \end{variable}
-% \end{variable}
-%
-% \begin{macro}
-%   {
-%     \coffin_rotate:Nn, \coffin_rotate:cn,
-%     \coffin_grotate:Nn, \coffin_grotate:cn
-%   }
-% \begin{macro}{\@@_rotate:NnNN}
-%   Rotating a coffin requires several steps which can be conveniently
-%   run together. The sine and cosine of the angle in degrees are
-%   computed.  This is then used to set \cs{l_@@_sin_fp} and
-%   \cs{l_@@_cos_fp}, which are carried through unchanged for the rest
-%   of the procedure.
-%    \begin{macrocode}
-\cs_new_protected:Npn \coffin_rotate:Nn #1#2
-  { \@@_rotate:NnNN #1 {#2} \box_rotate:Nn \prop_set_eq:cN }
-\cs_new_protected:Npn \coffin_grotate:Nn #1#2
-  { \@@_rotate:NnNN #1 {#2} \box_grotate:Nn \prop_gset_eq:cN }
-\cs_new_protected:Npn \@@_rotate:NnNN #1#2#3#4
-  {
-    \fp_set:Nn \l_@@_sin_fp { sind ( #2 ) }
-    \fp_set:Nn \l_@@_cos_fp { cosd ( #2 ) }
-%    \end{macrocode}
-%   Use a local copy of the property lists to avoid needing to pass the
-%   name and scope around.
-%    \begin{macrocode}
-    \prop_set_eq:Nc \l_@@_corners_prop
-      { coffin ~ \@@_to_value:N #1 ~ corners }
-    \prop_set_eq:Nc \l_@@_poles_prop
-      { coffin ~ \@@_to_value:N #1 ~ poles }
-%    \end{macrocode}
-%   The corners and poles of the coffin can now be rotated around the
-%    origin. This is best achieved using mapping functions.
-%    \begin{macrocode}
-    \prop_map_inline:Nn \l_@@_corners_prop
-      { \@@_rotate_corner:Nnnn #1 {##1} ##2 }
-    \prop_map_inline:Nn \l_@@_poles_prop
-      { \@@_rotate_pole:Nnnnnn #1 {##1} ##2 }
-%    \end{macrocode}
-%   The bounding box of the coffin needs to be rotated, and to do this
-%   the corners have to be found first. They are then rotated in the same
-%   way as the corners of the coffin material itself.
-%    \begin{macrocode}
-    \@@_set_bounding:N #1
-    \prop_map_inline:Nn \l_@@_bounding_prop
-      { \@@_rotate_bounding:nnn {##1} ##2 }
-%    \end{macrocode}
-%   At this stage, there needs to be a calculation to find where the
-%   corners of the content and the box itself will end up.
-%    \begin{macrocode}
-    \@@_find_corner_maxima:N #1
-    \@@_find_bounding_shift:
-    #3 #1 {#2}
-%    \end{macrocode}
-%   The correction of the box position itself takes place here. The idea
-%   is that the bounding box for a coffin is tight up to the content, and
-%   has the reference point at the bottom-left. The $x$-direction is
-%   handled by moving the content by the difference in the positions of
-%   the bounding box and the content left edge. The $y$-direction is
-%   dealt with by moving the box down by any depth it has acquired. The
-%   internal box is used here to allow for the next step.
-%    \begin{macrocode}
-    \hbox_set:Nn \l_@@_internal_box
-      {
-        \tex_kern:D
-          \dim_eval:n
-            { \l_@@_bounding_shift_dim - \l_@@_left_corner_dim }
-          \exp_stop_f:
-        \box_move_down:nn { \l_@@_bottom_corner_dim }
-          { \box_use:N #1 }
-      }
-%    \end{macrocode}
-%   If there have been any previous rotations then the size of the
-%   bounding box will be bigger than the contents. This can be corrected
-%   easily by setting the size of the box to the height and width of the
-%   content. As this operation requires setting box dimensions and these
-%   transcend grouping, the safe way to do this is to use the internal box
-%   and to reset the result into the target box.
-%    \begin{macrocode}
-    \box_set_ht:Nn \l_@@_internal_box
-      { \l_@@_top_corner_dim - \l_@@_bottom_corner_dim }
-    \box_set_dp:Nn \l_@@_internal_box { 0 pt }
-    \box_set_wd:Nn \l_@@_internal_box
-      { \l_@@_right_corner_dim - \l_@@_left_corner_dim }
-    \hbox_set:Nn #1 { \box_use_drop:N \l_@@_internal_box }
-%    \end{macrocode}
-%   The final task is to move the poles and corners such that they are
-%   back in alignment with the box reference point.
-%    \begin{macrocode}
-    \prop_map_inline:Nn \l_@@_corners_prop
-      { \@@_shift_corner:Nnnn #1 {##1} ##2 }
-    \prop_map_inline:Nn \l_@@_poles_prop
-      { \@@_shift_pole:Nnnnnn #1 {##1} ##2 }
-%    \end{macrocode}
-%   Update the coffin data.
-%    \begin{macrocode}
-    #4 { coffin ~ \@@_to_value:N #1 ~ corners }
-      \l_@@_corners_prop
-    #4 { coffin ~ \@@_to_value:N #1 ~ poles }
-      \l_@@_poles_prop
-  }
-\cs_generate_variant:Nn \coffin_rotate:Nn { c }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_set_bounding:N}
-%   The bounding box corners for a coffin are easy enough to find: this
-%   is the same code as for the corners of the material itself, but
-%   using a dedicated property list.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_set_bounding:N #1
-  {
-    \prop_put:Nnx \l_@@_bounding_prop { tl }
-      { { 0 pt } { \dim_eval:n { \box_ht:N #1 } } }
-    \prop_put:Nnx \l_@@_bounding_prop { tr }
-      {
-        { \dim_eval:n { \box_wd:N #1 } }
-        { \dim_eval:n { \box_ht:N #1 } }
-      }
-    \dim_set:Nn \l_@@_internal_dim { -\box_dp:N #1 }
-    \prop_put:Nnx \l_@@_bounding_prop { bl }
-      { { 0 pt } { \dim_use:N \l_@@_internal_dim } }
-    \prop_put:Nnx \l_@@_bounding_prop { br }
-      {
-        { \dim_eval:n { \box_wd:N #1 } }
-        { \dim_use:N \l_@@_internal_dim }
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_rotate_bounding:nnn}
-% \begin{macro}{\@@_rotate_corner:Nnnn}
-%   Rotating the position of the corner of the coffin is just a case
-%   of treating this as a vector from the reference point. The same
-%   treatment is used for the corners of the material itself and the
-%   bounding box.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_rotate_bounding:nnn #1#2#3
-  {
-    \@@_rotate_vector:nnNN {#2} {#3} \l_@@_x_dim \l_@@_y_dim
-    \prop_put:Nnx \l_@@_bounding_prop {#1}
-      { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
-  }
-\cs_new_protected:Npn \@@_rotate_corner:Nnnn #1#2#3#4
-  {
-    \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
-    \prop_put:Nnx \l_@@_corners_prop {#2}
-      { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_rotate_pole:Nnnnnn}
-%   Rotating a single pole simply means shifting the co-ordinate of
-%   the pole and its direction. The rotation here is about the bottom-left
-%   corner of the coffin.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_rotate_pole:Nnnnnn #1#2#3#4#5#6
-  {
-    \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
-    \@@_rotate_vector:nnNN {#5} {#6}
-      \l_@@_x_prime_dim \l_@@_y_prime_dim
-    \prop_put:Nnx \l_@@_poles_prop {#2}
-      {
-        { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
-        { \dim_use:N \l_@@_x_prime_dim }
-        { \dim_use:N \l_@@_y_prime_dim }
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_rotate_vector:nnNN}
-%   A rotation function, which needs only an input vector (as dimensions)
-%   and an output space. The values \cs{l_@@_cos_fp} and
-%   \cs{l_@@_sin_fp} should previously have been set up correctly.
-%   Working this way means that the floating point work is kept to a
-%   minimum: for any given rotation the sin and cosine values do no
-%   change, after all.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_rotate_vector:nnNN #1#2#3#4
-  {
-    \dim_set:Nn #3
-      {
-        \fp_to_dim:n
-          {
-              \dim_to_fp:n {#1} * \l_@@_cos_fp
-            - \dim_to_fp:n {#2} * \l_@@_sin_fp
-          }
-      }
-    \dim_set:Nn #4
-      {
-        \fp_to_dim:n
-          {
-              \dim_to_fp:n {#1} * \l_@@_sin_fp
-            + \dim_to_fp:n {#2} * \l_@@_cos_fp
-          }
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_find_corner_maxima:N}
-% \begin{macro}{\@@_find_corner_maxima_aux:nn}
-%   The idea here is to find the extremities of the content of the
-%   coffin. This is done by looking for the smallest values for the bottom
-%   and left corners, and the largest values for the top and right
-%   corners. The values start at the maximum dimensions so that the
-%   case where all are positive or all are negative works out correctly.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_find_corner_maxima:N #1
-  {
-    \dim_set:Nn \l_@@_top_corner_dim   { -\c_max_dim }
-    \dim_set:Nn \l_@@_right_corner_dim { -\c_max_dim }
-    \dim_set:Nn \l_@@_bottom_corner_dim { \c_max_dim }
-    \dim_set:Nn \l_@@_left_corner_dim   { \c_max_dim }
-    \prop_map_inline:Nn \l_@@_corners_prop
-      { \@@_find_corner_maxima_aux:nn ##2 }
-  }
-\cs_new_protected:Npn \@@_find_corner_maxima_aux:nn #1#2
-  {
-    \dim_set:Nn \l_@@_left_corner_dim
-     { \dim_min:nn { \l_@@_left_corner_dim } {#1} }
-    \dim_set:Nn \l_@@_right_corner_dim
-     { \dim_max:nn { \l_@@_right_corner_dim } {#1} }
-    \dim_set:Nn \l_@@_bottom_corner_dim
-     { \dim_min:nn { \l_@@_bottom_corner_dim } {#2} }
-    \dim_set:Nn \l_@@_top_corner_dim
-     { \dim_max:nn { \l_@@_top_corner_dim } {#2} }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_find_bounding_shift:}
-% \begin{macro}{\@@_find_bounding_shift_aux:nn}
-%   The approach to finding the shift for the bounding box is similar to
-%   that for the corners. However, there is only one value needed here and
-%   a fixed input property list, so things are a bit clearer.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_find_bounding_shift:
-  {
-    \dim_set:Nn \l_@@_bounding_shift_dim { \c_max_dim }
-    \prop_map_inline:Nn \l_@@_bounding_prop
-      { \@@_find_bounding_shift_aux:nn ##2 }
-  }
-\cs_new_protected:Npn \@@_find_bounding_shift_aux:nn #1#2
-  {
-    \dim_set:Nn \l_@@_bounding_shift_dim
-      { \dim_min:nn { \l_@@_bounding_shift_dim } {#1} }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_shift_corner:Nnnn}
-% \begin{macro}{\@@_shift_pole:Nnnnnn}
-%   Shifting the corners and poles of a coffin means subtracting the
-%   appropriate values from the $x$- and $y$-components. For
-%   the poles, this means that the direction vector is unchanged.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_shift_corner:Nnnn #1#2#3#4
-  {
-    \prop_put:Nnx \l_@@_corners_prop {#2}
-      {
-        { \dim_eval:n { #3 - \l_@@_left_corner_dim } }
-        { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } }
-      }
-  }
-\cs_new_protected:Npn \@@_shift_pole:Nnnnnn #1#2#3#4#5#6
-  {
-    \prop_put:Nnx \l_@@_poles_prop {#2}
-      {
-        { \dim_eval:n { #3 - \l_@@_left_corner_dim } }
-        { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } }
-        {#5} {#6}
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \subsubsection{Resizing coffins}
-%
-% \begin{variable}{\l_@@_scale_x_fp}
-% \begin{variable}{\l_@@_scale_y_fp}
-%   Storage for the scaling factors in $x$ and $y$, respectively.
-%    \begin{macrocode}
-\fp_new:N \l_@@_scale_x_fp
-\fp_new:N \l_@@_scale_y_fp
-%    \end{macrocode}
-% \end{variable}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_scaled_total_height_dim}
-% \begin{variable}{\l_@@_scaled_width_dim}
-%   When scaling, the values given have to be turned into absolute values.
-%    \begin{macrocode}
-\dim_new:N \l_@@_scaled_total_height_dim
-\dim_new:N \l_@@_scaled_width_dim
-%    \end{macrocode}
-% \end{variable}
-% \end{variable}
-%
-% \begin{macro}
-%   {
-%     \coffin_resize:Nnn, \coffin_resize:cnn,
-%     \coffin_gresize:Nnn, \coffin_gresize:cnn
-%   }
-% \begin{macro}{\@@_resize:NnnNN}
-%   Resizing a coffin begins by setting up the user-friendly names for
-%   the dimensions of the coffin box. The new sizes are then turned into
-%   scale factor. This is the same operation as takes place for the
-%   underlying box, but that operation is grouped and so the same
-%   calculation is done here.
-%    \begin{macrocode}
-\cs_new_protected:Npn \coffin_resize:Nnn #1#2#3
-  {
-    \@@_resize:NnnNN #1 {#2} {#3}
-      \box_resize_to_wd_and_ht_plus_dp:Nnn
-      \prop_set_eq:cN
-  }
-\cs_generate_variant:Nn \coffin_resize:Nnn { c }
-\cs_new_protected:Npn \coffin_gresize:Nnn #1#2#3
-  {
-    \@@_resize:NnnNN #1 {#2} {#3}
-      \box_gresize_to_wd_and_ht_plus_dp:Nnn
-      \prop_gset_eq:cN
-  }
-\cs_generate_variant:Nn \coffin_gresize:Nnn { c }
-\cs_new_protected:Npn \@@_resize:NnnNN #1#2#3#4#5
-  {  
-    \fp_set:Nn \l_@@_scale_x_fp
-      { \dim_to_fp:n {#2} / \dim_to_fp:n { \coffin_wd:N #1 } }
-    \fp_set:Nn \l_@@_scale_y_fp
-      {
-          \dim_to_fp:n {#3}
-        / \dim_to_fp:n { \coffin_ht:N #1 + \coffin_dp:N #1 }
-      }
-    #4 #1 {#2} {#3}
-    \@@_resize_common:NnnN #1 {#2} {#3} #5
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_resize_common:NnnN}
-%   The poles and corners of the coffin are scaled to the appropriate
-%   places before actually resizing the underlying box.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_resize_common:NnnN #1#2#3#4
-  {
-    \prop_set_eq:Nc \l_@@_corners_prop
-      { coffin ~ \@@_to_value:N #1 ~ corners }
-    \prop_set_eq:Nc \l_@@_poles_prop
-      { coffin ~ \@@_to_value:N #1 ~ poles }
-    \prop_map_inline:Nn \l_@@_corners_prop
-      { \@@_scale_corner:Nnnn #1 {##1} ##2 }
-    \prop_map_inline:Nn \l_@@_poles_prop
-      { \@@_scale_pole:Nnnnnn #1 {##1} ##2 }
-%    \end{macrocode}
-%   Negative $x$-scaling values place the poles in the wrong
-%   location: this is corrected here.
-%    \begin{macrocode}
-    \fp_compare:nNnT \l_@@_scale_x_fp < \c_zero_fp
-      {
-        \prop_map_inline:Nn \l_@@_corners_prop
-          { \@@_x_shift_corner:Nnnn #1 {##1} ##2 }
-        \prop_map_inline:Nn \l_@@_poles_prop
-          { \@@_x_shift_pole:Nnnnnn #1 {##1} ##2 }
-      }
-    #4 { coffin ~ \@@_to_value:N #1 ~ corners }
-      \l_@@_corners_prop
-    #4 { coffin ~ \@@_to_value:N #1 ~ poles }
-      \l_@@_poles_prop  
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}
-%   {
-%     \coffin_scale:Nnn, \coffin_scale:cnn,
-%     \coffin_gscale:Nnn, \coffin_gscale:cnn
-%   }
-% \begin{macro}{\coffin_scale:NnnNN}
-%   For scaling, the opposite calculation is done to find the new
-%   dimensions for the coffin. Only the total height is needed, as this
-%   is the shift required for corners and poles. The scaling is done
-%   the \TeX{} way as this works properly with floating point values
-%   without needing to use the \texttt{fp} module.
-%    \begin{macrocode}
-\cs_new_protected:Npn \coffin_scale:Nnn #1#2#3
-  { \@@_scale:NnnNN #1 {#2} {#3} \box_scale:Nnn \prop_set_eq:cN }
-\cs_generate_variant:Nn \coffin_scale:Nnn { c }
-\cs_new_protected:Npn \coffin_gscale:Nnn #1#2#3
-  { \@@_scale:NnnNN #1 {#2} {#3} \box_gscale:Nnn \prop_gset_eq:cN }
-\cs_generate_variant:Nn \coffin_gscale:Nnn { c }
-\cs_new_protected:Npn \@@_scale:NnnNN #1#2#3#4#5
-  {
-    \fp_set:Nn \l_@@_scale_x_fp {#2}
-    \fp_set:Nn \l_@@_scale_y_fp {#3}
-    #4 #1 { \l_@@_scale_x_fp } { \l_@@_scale_y_fp }
-    \dim_set:Nn \l_@@_internal_dim
-      { \coffin_ht:N #1 + \coffin_dp:N #1 }
-    \dim_set:Nn \l_@@_scaled_total_height_dim
-      { \fp_abs:n { \l_@@_scale_y_fp } \l_@@_internal_dim }
-    \dim_set:Nn \l_@@_scaled_width_dim
-      { -\fp_abs:n { \l_@@_scale_x_fp  } \coffin_wd:N #1 }
-    \@@_resize_common:NnnN #1
-      { \l_@@_scaled_width_dim } { \l_@@_scaled_total_height_dim }
-      #5
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_scale_vector:nnNN}
-%   This functions scales a vector from the origin using the pre-set scale
-%   factors in $x$ and $y$. This is a much less complex operation
-%   than rotation, and as a result the code is a lot clearer.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_scale_vector:nnNN #1#2#3#4
-  {
-    \dim_set:Nn #3
-      { \fp_to_dim:n { \dim_to_fp:n {#1} * \l_@@_scale_x_fp } }
-    \dim_set:Nn #4
-      { \fp_to_dim:n { \dim_to_fp:n {#2} * \l_@@_scale_y_fp } }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_scale_corner:Nnnn}
-% \begin{macro}{\@@_scale_pole:Nnnnnn}
-%   Scaling both corners and poles is a simple calculation using the
-%   preceding vector scaling.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_scale_corner:Nnnn #1#2#3#4
-  {
-    \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
-    \prop_put:Nnx \l_@@_corners_prop {#2}
-      { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
-  }
-\cs_new_protected:Npn \@@_scale_pole:Nnnnnn #1#2#3#4#5#6
-  {
-    \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
-    \prop_put:Nnx \l_@@_poles_prop {#2}
-      {
-        { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
-        {#5} {#6}
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_x_shift_corner:Nnnn}
-% \begin{macro}{\@@_x_shift_pole:Nnnnnn}
-%   These functions correct for the $x$ displacement that takes
-%   place with a negative horizontal scaling.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_x_shift_corner:Nnnn #1#2#3#4
-  {
-    \prop_put:Nnx \l_@@_corners_prop {#2}
-      {
-        { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
-      }
-  }
-\cs_new_protected:Npn \@@_x_shift_pole:Nnnnnn #1#2#3#4#5#6
-  {
-    \prop_put:Nnx \l_@@_poles_prop {#2}
-      {
-        { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
-        {#5} {#6}
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
 % \subsection{Additions to \pkg{l3fp-convert}}
 %
 %    \begin{macrocode}
@@ -2234,44 +1605,63 @@
 %   coverage varies in other engines.
 %    \begin{macrocode}
 \cs_new_protected:Npn \file_get_mdfive_hash:nN #1#2
+  { \file_get_mdfive_hash:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \file_get_size:nN #1#2
+  { \file_get_size:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \file_get_timestamp:nN #1#2
+  { \file_get_timestamp:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\prg_new_protected_conditional:Npnn \file_get_mdfive_hash:nN #1#2 { T , F , TF }
   { \@@_get_details:nnN {#1} { mdfivesum } {#2} }
-\cs_new_protected:Npn \file_get_size:nN #1#2
+\prg_new_protected_conditional:Npnn \file_get_size:nN #1#2 { T , F , TF }
   { \@@_get_details:nnN {#1} { size } {#2} }
-\cs_new_protected:Npn \file_get_timestamp:nN #1#2
+\prg_new_protected_conditional:Npnn \file_get_timestamp:nN #1#2 { T , F , TF }
   { \@@_get_details:nnN {#1} { moddate } {#2} }
 \cs_new_protected:Npn \@@_get_details:nnN #1#2#3
   {
-    \file_get_full_name:nN {#1} \l_@@_full_name_str
-    \str_set:Nx #3
+    \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
       {
-        \use:c { tex_file #2 :D } \exp_after:wN
-          { \l_@@_full_name_str }
+        \tl_set:Nx #3
+          {
+            \use:c { tex_file #2 :D } \exp_after:wN
+              { \l_@@_full_name_tl }
+          }
+        \prg_return_true:  
       }
+      { \prg_return_false: }
   }
 \sys_if_engine_luatex:TF
   {
     \cs_set_protected:Npn \@@_get_details:nnN #1#2#3
       {
-        \file_get_full_name:nN {#1} \l_@@_full_name_str
-        \str_set:Nx #3
+        \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
           {
-            \lua_now:e
+            \tl_set:Nx #3
               {
-                l3kernel.file#2
-                  ( " \lua_escape:e { \l_@@_full_name_str } " )
+                \lua_now:e
+                  {
+                    l3kernel.file#2
+                      ( " \lua_escape:e { \l_@@_full_name_tl } " )
+                  }
               }
+            \prg_return_true:
           }
-       }
+          { \prg_return_false: }
+      }
   }
   {
-    \cs_set_protected:Npn \file_get_mdfive_hash:nN #1#2
+    \prg_set_protected_conditional:Npnn \file_get_mdfive_hash:nN #1#2
+      { T , F ,  TF }
       {
-        \file_get_full_name:nN {#1} \l_@@_full_name_str
-        \tl_set:Nx #2
+        \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
           {
-            \tex_mdfivesum:D file \exp_after:wN
-              { \l_@@_full_name_str }
+            \tl_set:Nx #2
+              {
+                \tex_mdfivesum:D file \exp_after:wN
+                  { \l_@@_full_name_tl }
+              }
+            \prg_return_true:
           }
+          { \prg_return_false: }
       }
     \cs_if_exist:NF \tex_filesize:D
       {
@@ -2281,6 +1671,7 @@
             \__kernel_msg_error:nnx
               { kernel } { primitive-not-available }
               { \exp_not:c { (pdf)file #2 } }
+            \prg_return_false:
           }
       }
   }
@@ -2301,16 +1692,14 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \file_if_exist_input:n #1
   {
-    \file_get_full_name:nN {#1} \l_@@_full_name_str
-    \str_if_empty:NF \l_@@_full_name_str
-      { \@@_input:V \l_@@_full_name_str }
+    \file_get_full_name:nNT {#1} \l_@@_full_name_tl
+      { \@@_input:V \l_@@_full_name_tl }
   }
 \cs_new_protected:Npn \file_if_exist_input:nF #1#2
   {
-    \file_get_full_name:nN {#1} \l_@@_full_name_str
-    \str_if_empty:NTF \l_@@_full_name_str
+    \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
+      { \@@_input:V \l_@@_full_name_tl }
       {#2}
-      { \@@_input:V \l_@@_full_name_str }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2401,10 +1790,14 @@
 %    \begin{macrocode}
 \cs_new:Npn \msg_expandable_error:nnnnnn #1#2#3#4#5#6
   {
-    \exp_args:Nf \@@_expandable_error_module:nn
+    \exp_args:Ne \@@_expandable_error_module:nn
       {
-        \exp_args:Nf \tl_to_str:n
-          { \use:c { \c_@@_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+        \exp_args:Nc \exp_args:Noooo
+          { \c_@@_text_prefix_tl #1 / #2 }
+          { \tl_to_str:n {#3} }
+          { \tl_to_str:n {#4} }
+          { \tl_to_str:n {#5} }
+          { \tl_to_str:n {#6} }
       }
       {#1}
   }
@@ -2516,27 +1909,6 @@
 %<@@=prop>
 %    \end{macrocode}
 %
-% \begin{macro}[EXP]{\prop_count:N, \prop_count:c}
-% \begin{macro}[EXP]{\@@_count:nn}
-%   Counting the key--value pairs in a property list is done using the
-%   same approach as for other count functions: turn each entry into a
-%   \texttt{+1} then use integer evaluation to actually do the
-%   mathematics.
-%    \begin{macrocode}
-\cs_new:Npn \prop_count:N #1
-  {
-    \int_eval:n
-      {
-        0
-        \prop_map_function:NN #1 \@@_count:nn
-      }
-  }
-\cs_new:Npn \@@_count:nn #1#2 { + 1 }
-\cs_generate_variant:Nn \prop_count:N { c }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
 % \begin{macro}[rEXP]{\prop_map_tokens:Nn, \prop_map_tokens:cn}
 % \begin{macro}{\@@_map_tokens:nwwn}
 %   The mapping is very similar to \cs{prop_map_function:NN}.  The
@@ -2878,34 +2250,6 @@
 %    \end{macrocode}
 % \end{macro}
 %
-%    \begin{macrocode}
-%<@@=skip>
-%    \end{macrocode}
-%
-% \begin{macro}{\skip_split_finite_else_action:nnNN}
-%   This macro is useful when performing error checking in certain
-%   circumstances. If the \meta{skip} register holds finite glue it sets
-%   |#3| and |#4| to the stretch and shrink component, resp. If it holds
-%   infinite glue set |#3| and |#4| to zero and issue the special action
-%   |#2| which is probably an error message.
-%   Assignments are local.
-%    \begin{macrocode}
-\cs_new:Npn \skip_split_finite_else_action:nnNN #1#2#3#4
-  {
-    \skip_if_finite:nTF {#1}
-      {
-        #3 = \tex_gluestretch:D #1 \scan_stop:
-        #4 = \tex_glueshrink:D  #1 \scan_stop:
-      }
-      {
-        #3 = \c_zero_skip
-        #4 = \c_zero_skip
-        #2
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \subsection{Additions to \pkg{l3sys}}
 %
 %    \begin{macrocode}
@@ -3045,7 +2389,7 @@
 \cs_new_protected:Npn \sys_shell_get:nnN #1#2#3
   {
     \sys_shell_get:nnNF {#1} {#2} #3
-      { \tl_clear:N #3 }
+      { \tl_set:Nn #3 { \q_no_value } }
   }
 \prg_new_protected_conditional:Npnn \sys_shell_get:nnN #1#2#3 { T , F , TF }
   {
@@ -3062,8 +2406,8 @@
         \prg_return_false:
       }
       {
-        \if_false: { \fi:
         \group_begin:
+          \if_false: { \fi:
           \int_set_eq:NN \tex_tracingnesting:D \c_zero_int
           \exp_args:No \tex_everyeof:D { \c_@@_marker_tl }
           #2 \scan_stop:
@@ -3222,122 +2566,6 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[EXP]{\tl_reverse_tokens:n}
-% \begin{macro}[EXP]{\@@_reverse_group:nn}
-%   The same as \cs{tl_reverse:n} but with recursion within brace groups.
-%    \begin{macrocode}
-\cs_new:Npn \tl_reverse_tokens:n #1
-  {
-    \__kernel_exp_not:w \exp_after:wN
-      {
-        \exp:w
-        \@@_act:NNNnn
-          \@@_reverse_normal:nN
-          \@@_reverse_group:nn
-          \@@_reverse_space:n
-          { }
-          {#1}
-      }
-  }
-\cs_new:Npn \@@_reverse_group:nn #1
-  {
-    \@@_act_group_recurse:Nnn
-      \@@_act_reverse_output:n
-      { \tl_reverse_tokens:n }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \begin{macro}[EXP]{\@@_act_group_recurse:Nnn}
-%   In many applications of \cs{@@_act:NNNnn}, we need to recursively
-%   apply some transformation within brace groups, then output. In this
-%   code, |#1| is the output function, |#2| is the transformation,
-%   which should expand in two steps, and |#3| is the group.
-%    \begin{macrocode}
-\cs_new:Npn \@@_act_group_recurse:Nnn #1#2#3
-  {
-    \exp_args:Nf #1
-      { \exp_after:wN \exp_after:wN \exp_after:wN { #2 {#3} } }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\tl_count_tokens:n}
-% \begin{macro}[EXP]{\@@_act_count_normal:nN,
-%     \@@_act_count_group:nn, \@@_act_count_space:n}
-%   The token count is computed through an \cs{int_eval:n} construction.
-%   Each \texttt{1+} is output to the \emph{left}, into the integer
-%   expression, and the sum is ended by the \cs{exp_end:} inserted by
-%   \cs{@@_act_end:wn} (which is technically implemented as  \cs{c_zero_int}).
-%   Somewhat a hack!
-%    \begin{macrocode}
-\cs_new:Npn \tl_count_tokens:n #1
-  {
-    \int_eval:n
-      {
-        \@@_act:NNNnn
-          \@@_act_count_normal:nN
-          \@@_act_count_group:nn
-          \@@_act_count_space:n
-          { }
-          {#1}
-      }
-  }
-\cs_new:Npn \@@_act_count_normal:nN #1 #2 { 1 + }
-\cs_new:Npn \@@_act_count_space:n #1 { 1 + }
-\cs_new:Npn \@@_act_count_group:nn #1 #2
-  { 2 + \tl_count_tokens:n {#2} + }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \subsubsection{Deprecated functions}
-%
-% \begin{macro}[deprecated = 2020-12-31]
-%   {
-%     \tl_set_from_file:Nnn, \tl_set_from_file:cnn,
-%     \tl_gset_from_file:Nnn, \tl_gset_from_file:cnn,
-%     \tl_set_from_file_x:Nnn, \tl_set_from_file_x:cnn,
-%     \tl_gset_from_file_x:Nnn, \tl_gset_from_file_x:cnn
-%   }
-%    \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_set_from_file:Nnn #1#2#3
-  { \file_get:nnN {#3} {#2} #1 }
-\cs_generate_variant:Nn \tl_set_from_file:Nnn { c }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_gset_from_file:Nnn #1#2#3
-  {
-    \group_begin:
-      \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
-      \tl_gset_eq:NN #1 \l_@@_internal_a_tl
-    \group_end:
-  }
-\cs_generate_variant:Nn \tl_gset_from_file:Nnn { c }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_set_from_file_x:Nnn #1#2#3
-  {
-    \group_begin:
-      \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
-      #2 \scan_stop:
-      \tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl }
-    \exp_args:NNNo \group_end:
-    \tl_set:Nn #1 \l_@@_internal_a_tl
-  }
-\cs_generate_variant:Nn \tl_set_from_file_x:Nnn { c }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_gset_from_file_x:Nnn #1#2#3
-  {
-    \group_begin:
-      \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
-      #2 \scan_stop:
-      \tl_gset:Nx #1 { \l_@@_internal_a_tl }
-    \group_end:
-  }
-\cs_generate_variant:Nn \tl_gset_from_file_x:Nnn { c }
-%    \end{macrocode}
-% \end{macro}
-%
 % \subsubsection{Unicode case changing}
 %
 % The mechanisms needed for case changing are somewhat involved, particularly

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 %% File: l3clist.dtx
-% 
+%
 % Copyright (C) 2004-2011 Frank Mittelbach, The LaTeX3 Project
 %           (C) 2012-2019 The LaTeX3 Project
 %
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -337,7 +337,7 @@
 %   \begin{texnote}
 %     The result is returned within \tn{unexpanded}, which means that the
 %     comma list does not expand further when appearing in an
-%     \texttt{x}-type argument expansion.
+%     \texttt{x}-type or \texttt{e}-type argument expansion.
 %   \end{texnote}
 % \end{function}
 %
@@ -584,7 +584,8 @@
 % in the previous section: a comma list should either be used as an
 % ordered data type or as a stack, but not in both ways.
 %
-% \begin{function}[updated = 2012-05-14]{\clist_get:NN, \clist_get:cN}
+% \begin{function}[noTF, added = 2012-05-14, updated = 2019-02-16]
+%   {\clist_get:NN, \clist_get:cN}
 %   \begin{syntax}
 %     \cs{clist_get:NN} \meta{comma list} \meta{token list variable}
 %   \end{syntax}
@@ -591,23 +592,10 @@
 %   Stores the left-most item from a \meta{comma list} in the
 %   \meta{token list variable} without removing it from the
 %   \meta{comma list}. The \meta{token list variable} is assigned locally.
-%   If the \meta{comma list} is empty the \meta{token list variable}
-%   is set to the marker value \cs{q_no_value}.
+%   In the non-branching version, if the \meta{comma list} is empty the
+%   \meta{token list variable} is set to the marker value \cs{q_no_value}.
 % \end{function}
 %
-% \begin{function}[TF, added = 2012-05-14]{\clist_get:NN, \clist_get:cN}
-%   \begin{syntax}
-%     \cs{clist_get:NNTF} \meta{comma list} \meta{token list variable} \Arg{true code} \Arg{false code}
-%   \end{syntax}
-%   If the \meta{comma list} is empty, leaves the \meta{false code} in the
-%   input stream.  The value of the \meta{token list variable} is
-%   not defined in this case and should not be relied upon.  If the
-%   \meta{comma list} is non-empty, stores the top item from the
-%   \meta{comma list} in the \meta{token list variable} without removing it
-%   from the \meta{comma list}. The \meta{token list variable} is assigned
-%   locally.
-% \end{function}
-%
 % \begin{function}[updated = 2011-09-06]{\clist_pop:NN, \clist_pop:cN}
 %   \begin{syntax}
 %     \cs{clist_pop:NN} \meta{comma list} \meta{token list variable}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -100,7 +100,7 @@
 %
 % \section{Setting coffin content and poles}
 %
-% \begin{function}[added = 2011-08-17, updated = 2011-09-03]
+% \begin{function}[added = 2011-08-17, updated = 2019-01-21]
 %   {
 %     \hcoffin_set:Nn, \hcoffin_set:cn,
 %     \hcoffin_gset:Nn, \hcoffin_gset:cn
@@ -187,6 +187,47 @@
 %   \meta{offset} should be given as a dimension expression.
 % \end{function}
 %
+% \section{Coffin affine transformations}
+%
+% \begin{function}[updated = 2019-01-23]
+%   {
+%     \coffin_resize:Nnn, \coffin_resize:cnn,
+%     \coffin_gresize:Nnn, \coffin_gresize:cnn
+%   }
+%   \begin{syntax}
+%     \cs{coffin_resize:Nnn} \meta{coffin} \Arg{width} \Arg{total-height}
+%   \end{syntax}
+%   Resized the \meta{coffin} to \meta{width} and \meta{total-height},
+%   both of which should be given as dimension expressions.
+% \end{function}
+%
+% \begin{function}
+%   {
+%     \coffin_rotate:Nn, \coffin_rotate:cn,
+%     \coffin_grotate:Nn, \coffin_grotate:cn
+%   }
+%   \begin{syntax}
+%     \cs{coffin_rotate:Nn} \meta{coffin} \Arg{angle}
+%   \end{syntax}
+%   Rotates the \meta{coffin} by the given \meta{angle} (given in
+%   degrees counter-clockwise). This process rotates both the
+%   coffin content and poles. Multiple rotations do not result in
+%   the bounding box of the coffin growing unnecessarily.
+% \end{function}
+%
+% \begin{function}[updated = 2019-01-23]
+%   {
+%     \coffin_scale:Nnn, \coffin_scale:cnn,
+%     \coffin_gscale:Nnn, \coffin_gscale:cnn
+%   }
+%   \begin{syntax}
+%     \cs{coffin_scale:Nnn} \meta{coffin} \Arg{x-scale} \Arg{y-scale}
+%   \end{syntax}
+%   Scales the \meta{coffin} by a factors \meta{x-scale} and
+%   \meta{y-scale} in the horizontal and vertical directions,
+%   respectively. The two scale factors should be given as real numbers.
+% \end{function}
+%
 % \section{Joining and using coffins}
 %
 % \begin{function}[updated = 2019-01-22]
@@ -1277,6 +1318,537 @@
 % \end{macro}
 % \end{macro}
 %
+% \subsection{Affine transformations}
+%
+% \begin{variable}{\l_@@_sin_fp}
+% \begin{variable}{\l_@@_cos_fp}
+%   Used for rotations to get the sine and cosine values.
+%    \begin{macrocode}
+\fp_new:N \l_@@_sin_fp
+\fp_new:N \l_@@_cos_fp
+%    \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_bounding_prop}
+%   A property list for the bounding box of a coffin. This is only needed
+%   during the rotation, so there is just the one.
+%    \begin{macrocode}
+\prop_new:N \l_@@_bounding_prop
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_corners_prop, \l_@@_poles_prop}
+%   Used to avoid needing to track scope for intermediate steps.
+%    \begin{macrocode}
+\prop_new:N \l_@@_corners_prop
+\prop_new:N \l_@@_poles_prop
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_bounding_shift_dim}
+%   The shift of the bounding box of a coffin from the real content.
+%    \begin{macrocode}
+\dim_new:N \l_@@_bounding_shift_dim
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_left_corner_dim}
+% \begin{variable}{\l_@@_right_corner_dim}
+% \begin{variable}{\l_@@_bottom_corner_dim}
+% \begin{variable}{\l_@@_top_corner_dim}
+%   These are used to hold maxima for the various corner values: these
+%   thus define the minimum size of the bounding box after rotation.
+%    \begin{macrocode}
+\dim_new:N \l_@@_left_corner_dim
+\dim_new:N \l_@@_right_corner_dim
+\dim_new:N \l_@@_bottom_corner_dim
+\dim_new:N \l_@@_top_corner_dim
+%    \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}
+%   {
+%     \coffin_rotate:Nn, \coffin_rotate:cn,
+%     \coffin_grotate:Nn, \coffin_grotate:cn
+%   }
+% \begin{macro}{\@@_rotate:NnNNN}
+%   Rotating a coffin requires several steps which can be conveniently
+%   run together. The sine and cosine of the angle in degrees are
+%   computed.  This is then used to set \cs{l_@@_sin_fp} and
+%   \cs{l_@@_cos_fp}, which are carried through unchanged for the rest
+%   of the procedure.
+%    \begin{macrocode}
+\cs_new_protected:Npn \coffin_rotate:Nn #1#2
+  { \@@_rotate:NnNNN #1 {#2} \box_rotate:Nn \prop_set_eq:cN \hbox_set:Nn }
+\cs_generate_variant:Nn \coffin_rotate:Nn { c }
+\cs_new_protected:Npn \coffin_grotate:Nn #1#2
+  { \@@_rotate:NnNNN #1 {#2} \box_grotate:Nn \prop_gset_eq:cN \hbox_gset:Nn }
+\cs_generate_variant:Nn \coffin_grotate:Nn { c }
+\cs_new_protected:Npn \@@_rotate:NnNNN #1#2#3#4#5
+  {
+    \fp_set:Nn \l_@@_sin_fp { sind ( #2 ) }
+    \fp_set:Nn \l_@@_cos_fp { cosd ( #2 ) }
+%    \end{macrocode}
+%   Use a local copy of the property lists to avoid needing to pass the
+%   name and scope around.
+%    \begin{macrocode}
+    \prop_set_eq:Nc \l_@@_corners_prop
+      { coffin ~ \@@_to_value:N #1 ~ corners }
+    \prop_set_eq:Nc \l_@@_poles_prop
+      { coffin ~ \@@_to_value:N #1 ~ poles }
+%    \end{macrocode}
+%   The corners and poles of the coffin can now be rotated around the
+%    origin. This is best achieved using mapping functions.
+%    \begin{macrocode}
+    \prop_map_inline:Nn \l_@@_corners_prop
+      { \@@_rotate_corner:Nnnn #1 {##1} ##2 }
+    \prop_map_inline:Nn \l_@@_poles_prop
+      { \@@_rotate_pole:Nnnnnn #1 {##1} ##2 }
+%    \end{macrocode}
+%   The bounding box of the coffin needs to be rotated, and to do this
+%   the corners have to be found first. They are then rotated in the same
+%   way as the corners of the coffin material itself.
+%    \begin{macrocode}
+    \@@_set_bounding:N #1
+    \prop_map_inline:Nn \l_@@_bounding_prop
+      { \@@_rotate_bounding:nnn {##1} ##2 }
+%    \end{macrocode}
+%   At this stage, there needs to be a calculation to find where the
+%   corners of the content and the box itself will end up.
+%    \begin{macrocode}
+    \@@_find_corner_maxima:N #1
+    \@@_find_bounding_shift:
+    #3 #1 {#2}
+%    \end{macrocode}
+%   The correction of the box position itself takes place here. The idea
+%   is that the bounding box for a coffin is tight up to the content, and
+%   has the reference point at the bottom-left. The $x$-direction is
+%   handled by moving the content by the difference in the positions of
+%   the bounding box and the content left edge. The $y$-direction is
+%   dealt with by moving the box down by any depth it has acquired. The
+%   internal box is used here to allow for the next step.
+%    \begin{macrocode}
+    \hbox_set:Nn \l_@@_internal_box
+      {
+        \tex_kern:D
+          \dim_eval:n
+            { \l_@@_bounding_shift_dim - \l_@@_left_corner_dim }
+          \exp_stop_f:
+        \box_move_down:nn { \l_@@_bottom_corner_dim }
+          { \box_use:N #1 }
+      }
+%    \end{macrocode}
+%   If there have been any previous rotations then the size of the
+%   bounding box will be bigger than the contents. This can be corrected
+%   easily by setting the size of the box to the height and width of the
+%   content. As this operation requires setting box dimensions and these
+%   transcend grouping, the safe way to do this is to use the internal box
+%   and to reset the result into the target box.
+%    \begin{macrocode}
+    \box_set_ht:Nn \l_@@_internal_box
+      { \l_@@_top_corner_dim - \l_@@_bottom_corner_dim }
+    \box_set_dp:Nn \l_@@_internal_box { 0pt }
+    \box_set_wd:Nn \l_@@_internal_box
+      { \l_@@_right_corner_dim - \l_@@_left_corner_dim }
+    #5 #1 { \box_use_drop:N \l_@@_internal_box }
+%    \end{macrocode}
+%   The final task is to move the poles and corners such that they are
+%   back in alignment with the box reference point.
+%    \begin{macrocode}
+    \prop_map_inline:Nn \l_@@_corners_prop
+      { \@@_shift_corner:Nnnn #1 {##1} ##2 }
+    \prop_map_inline:Nn \l_@@_poles_prop
+      { \@@_shift_pole:Nnnnnn #1 {##1} ##2 }
+%    \end{macrocode}
+%   Update the coffin data.
+%    \begin{macrocode}
+    #4 { coffin ~ \@@_to_value:N #1 ~ corners }
+      \l_@@_corners_prop
+    #4 { coffin ~ \@@_to_value:N #1 ~ poles }
+      \l_@@_poles_prop
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_bounding:N}
+%   The bounding box corners for a coffin are easy enough to find: this
+%   is the same code as for the corners of the material itself, but
+%   using a dedicated property list.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_bounding:N #1
+  {
+    \prop_put:Nnx \l_@@_bounding_prop { tl }
+      { { 0pt } { \dim_eval:n { \box_ht:N #1 } } }
+    \prop_put:Nnx \l_@@_bounding_prop { tr }
+      {
+        { \dim_eval:n { \box_wd:N #1 } }
+        { \dim_eval:n { \box_ht:N #1 } }
+      }
+    \dim_set:Nn \l_@@_internal_dim { -\box_dp:N #1 }
+    \prop_put:Nnx \l_@@_bounding_prop { bl }
+      { { 0pt } { \dim_use:N \l_@@_internal_dim } }
+    \prop_put:Nnx \l_@@_bounding_prop { br }
+      {
+        { \dim_eval:n { \box_wd:N #1 } }
+        { \dim_use:N \l_@@_internal_dim }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_rotate_bounding:nnn}
+% \begin{macro}{\@@_rotate_corner:Nnnn}
+%   Rotating the position of the corner of the coffin is just a case
+%   of treating this as a vector from the reference point. The same
+%   treatment is used for the corners of the material itself and the
+%   bounding box.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_bounding:nnn #1#2#3
+  {
+    \@@_rotate_vector:nnNN {#2} {#3} \l_@@_x_dim \l_@@_y_dim
+    \prop_put:Nnx \l_@@_bounding_prop {#1}
+      { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
+  }
+\cs_new_protected:Npn \@@_rotate_corner:Nnnn #1#2#3#4
+  {
+    \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+    \prop_put:Nnx \l_@@_corners_prop {#2}
+      { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_rotate_pole:Nnnnnn}
+%   Rotating a single pole simply means shifting the co-ordinate of
+%   the pole and its direction. The rotation here is about the bottom-left
+%   corner of the coffin.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_pole:Nnnnnn #1#2#3#4#5#6
+  {
+    \@@_rotate_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+    \@@_rotate_vector:nnNN {#5} {#6}
+      \l_@@_x_prime_dim \l_@@_y_prime_dim
+    \prop_put:Nnx \l_@@_poles_prop {#2}
+      {
+        { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
+        { \dim_use:N \l_@@_x_prime_dim }
+        { \dim_use:N \l_@@_y_prime_dim }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_rotate_vector:nnNN}
+%   A rotation function, which needs only an input vector (as dimensions)
+%   and an output space. The values \cs{l_@@_cos_fp} and
+%   \cs{l_@@_sin_fp} should previously have been set up correctly.
+%   Working this way means that the floating point work is kept to a
+%   minimum: for any given rotation the sin and cosine values do no
+%   change, after all.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_rotate_vector:nnNN #1#2#3#4
+  {
+    \dim_set:Nn #3
+      {
+        \fp_to_dim:n
+          {
+              \dim_to_fp:n {#1} * \l_@@_cos_fp
+            - \dim_to_fp:n {#2} * \l_@@_sin_fp
+          }
+      }
+    \dim_set:Nn #4
+      {
+        \fp_to_dim:n
+          {
+              \dim_to_fp:n {#1} * \l_@@_sin_fp
+            + \dim_to_fp:n {#2} * \l_@@_cos_fp
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_find_corner_maxima:N}
+% \begin{macro}{\@@_find_corner_maxima_aux:nn}
+%   The idea here is to find the extremities of the content of the
+%   coffin. This is done by looking for the smallest values for the bottom
+%   and left corners, and the largest values for the top and right
+%   corners. The values start at the maximum dimensions so that the
+%   case where all are positive or all are negative works out correctly.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_find_corner_maxima:N #1
+  {
+    \dim_set:Nn \l_@@_top_corner_dim   { -\c_max_dim }
+    \dim_set:Nn \l_@@_right_corner_dim { -\c_max_dim }
+    \dim_set:Nn \l_@@_bottom_corner_dim { \c_max_dim }
+    \dim_set:Nn \l_@@_left_corner_dim   { \c_max_dim }
+    \prop_map_inline:Nn \l_@@_corners_prop
+      { \@@_find_corner_maxima_aux:nn ##2 }
+  }
+\cs_new_protected:Npn \@@_find_corner_maxima_aux:nn #1#2
+  {
+    \dim_set:Nn \l_@@_left_corner_dim
+     { \dim_min:nn { \l_@@_left_corner_dim } {#1} }
+    \dim_set:Nn \l_@@_right_corner_dim
+     { \dim_max:nn { \l_@@_right_corner_dim } {#1} }
+    \dim_set:Nn \l_@@_bottom_corner_dim
+     { \dim_min:nn { \l_@@_bottom_corner_dim } {#2} }
+    \dim_set:Nn \l_@@_top_corner_dim
+     { \dim_max:nn { \l_@@_top_corner_dim } {#2} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_find_bounding_shift:}
+% \begin{macro}{\@@_find_bounding_shift_aux:nn}
+%   The approach to finding the shift for the bounding box is similar to
+%   that for the corners. However, there is only one value needed here and
+%   a fixed input property list, so things are a bit clearer.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_find_bounding_shift:
+  {
+    \dim_set:Nn \l_@@_bounding_shift_dim { \c_max_dim }
+    \prop_map_inline:Nn \l_@@_bounding_prop
+      { \@@_find_bounding_shift_aux:nn ##2 }
+  }
+\cs_new_protected:Npn \@@_find_bounding_shift_aux:nn #1#2
+  {
+    \dim_set:Nn \l_@@_bounding_shift_dim
+      { \dim_min:nn { \l_@@_bounding_shift_dim } {#1} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_shift_corner:Nnnn}
+% \begin{macro}{\@@_shift_pole:Nnnnnn}
+%   Shifting the corners and poles of a coffin means subtracting the
+%   appropriate values from the $x$- and $y$-components. For
+%   the poles, this means that the direction vector is unchanged.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_shift_corner:Nnnn #1#2#3#4
+  {
+    \prop_put:Nnx \l_@@_corners_prop {#2}
+      {
+        { \dim_eval:n { #3 - \l_@@_left_corner_dim } }
+        { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } }
+      }
+  }
+\cs_new_protected:Npn \@@_shift_pole:Nnnnnn #1#2#3#4#5#6
+  {
+    \prop_put:Nnx \l_@@_poles_prop {#2}
+      {
+        { \dim_eval:n { #3 - \l_@@_left_corner_dim } }
+        { \dim_eval:n { #4 - \l_@@_bottom_corner_dim } }
+        {#5} {#6}
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_scale_x_fp}
+% \begin{variable}{\l_@@_scale_y_fp}
+%   Storage for the scaling factors in $x$ and $y$, respectively.
+%    \begin{macrocode}
+\fp_new:N \l_@@_scale_x_fp
+\fp_new:N \l_@@_scale_y_fp
+%    \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_scaled_total_height_dim}
+% \begin{variable}{\l_@@_scaled_width_dim}
+%   When scaling, the values given have to be turned into absolute values.
+%    \begin{macrocode}
+\dim_new:N \l_@@_scaled_total_height_dim
+\dim_new:N \l_@@_scaled_width_dim
+%    \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}
+%   {
+%     \coffin_resize:Nnn, \coffin_resize:cnn,
+%     \coffin_gresize:Nnn, \coffin_gresize:cnn
+%   }
+% \begin{macro}{\@@_resize:NnnNN}
+%   Resizing a coffin begins by setting up the user-friendly names for
+%   the dimensions of the coffin box. The new sizes are then turned into
+%   scale factor. This is the same operation as takes place for the
+%   underlying box, but that operation is grouped and so the same
+%   calculation is done here.
+%    \begin{macrocode}
+\cs_new_protected:Npn \coffin_resize:Nnn #1#2#3
+  {
+    \@@_resize:NnnNN #1 {#2} {#3}
+      \box_resize_to_wd_and_ht_plus_dp:Nnn
+      \prop_set_eq:cN
+  }
+\cs_generate_variant:Nn \coffin_resize:Nnn { c }
+\cs_new_protected:Npn \coffin_gresize:Nnn #1#2#3
+  {
+    \@@_resize:NnnNN #1 {#2} {#3}
+      \box_gresize_to_wd_and_ht_plus_dp:Nnn
+      \prop_gset_eq:cN
+  }
+\cs_generate_variant:Nn \coffin_gresize:Nnn { c }
+\cs_new_protected:Npn \@@_resize:NnnNN #1#2#3#4#5
+  {  
+    \fp_set:Nn \l_@@_scale_x_fp
+      { \dim_to_fp:n {#2} / \dim_to_fp:n { \coffin_wd:N #1 } }
+    \fp_set:Nn \l_@@_scale_y_fp
+      {
+          \dim_to_fp:n {#3}
+        / \dim_to_fp:n { \coffin_ht:N #1 + \coffin_dp:N #1 }
+      }
+    #4 #1 {#2} {#3}
+    \@@_resize_common:NnnN #1 {#2} {#3} #5
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_resize_common:NnnN}
+%   The poles and corners of the coffin are scaled to the appropriate
+%   places before actually resizing the underlying box.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_resize_common:NnnN #1#2#3#4
+  {
+    \prop_set_eq:Nc \l_@@_corners_prop
+      { coffin ~ \@@_to_value:N #1 ~ corners }
+    \prop_set_eq:Nc \l_@@_poles_prop
+      { coffin ~ \@@_to_value:N #1 ~ poles }
+    \prop_map_inline:Nn \l_@@_corners_prop
+      { \@@_scale_corner:Nnnn #1 {##1} ##2 }
+    \prop_map_inline:Nn \l_@@_poles_prop
+      { \@@_scale_pole:Nnnnnn #1 {##1} ##2 }
+%    \end{macrocode}
+%   Negative $x$-scaling values place the poles in the wrong
+%   location: this is corrected here.
+%    \begin{macrocode}
+    \fp_compare:nNnT \l_@@_scale_x_fp < \c_zero_fp
+      {
+        \prop_map_inline:Nn \l_@@_corners_prop
+          { \@@_x_shift_corner:Nnnn #1 {##1} ##2 }
+        \prop_map_inline:Nn \l_@@_poles_prop
+          { \@@_x_shift_pole:Nnnnnn #1 {##1} ##2 }
+      }
+    #4 { coffin ~ \@@_to_value:N #1 ~ corners }
+      \l_@@_corners_prop
+    #4 { coffin ~ \@@_to_value:N #1 ~ poles }
+      \l_@@_poles_prop  
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \coffin_scale:Nnn, \coffin_scale:cnn,
+%     \coffin_gscale:Nnn, \coffin_gscale:cnn
+%   }
+% \begin{macro}{\coffin_scale:NnnNN}
+%   For scaling, the opposite calculation is done to find the new
+%   dimensions for the coffin. Only the total height is needed, as this
+%   is the shift required for corners and poles. The scaling is done
+%   the \TeX{} way as this works properly with floating point values
+%   without needing to use the \texttt{fp} module.
+%    \begin{macrocode}
+\cs_new_protected:Npn \coffin_scale:Nnn #1#2#3
+  { \@@_scale:NnnNN #1 {#2} {#3} \box_scale:Nnn \prop_set_eq:cN }
+\cs_generate_variant:Nn \coffin_scale:Nnn { c }
+\cs_new_protected:Npn \coffin_gscale:Nnn #1#2#3
+  { \@@_scale:NnnNN #1 {#2} {#3} \box_gscale:Nnn \prop_gset_eq:cN }
+\cs_generate_variant:Nn \coffin_gscale:Nnn { c }
+\cs_new_protected:Npn \@@_scale:NnnNN #1#2#3#4#5
+  {
+    \fp_set:Nn \l_@@_scale_x_fp {#2}
+    \fp_set:Nn \l_@@_scale_y_fp {#3}
+    #4 #1 { \l_@@_scale_x_fp } { \l_@@_scale_y_fp }
+    \dim_set:Nn \l_@@_internal_dim
+      { \coffin_ht:N #1 + \coffin_dp:N #1 }
+    \dim_set:Nn \l_@@_scaled_total_height_dim
+      { \fp_abs:n { \l_@@_scale_y_fp } \l_@@_internal_dim }
+    \dim_set:Nn \l_@@_scaled_width_dim
+      { -\fp_abs:n { \l_@@_scale_x_fp  } \coffin_wd:N #1 }
+    \@@_resize_common:NnnN #1
+      { \l_@@_scaled_width_dim } { \l_@@_scaled_total_height_dim }
+      #5
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_scale_vector:nnNN}
+%   This functions scales a vector from the origin using the pre-set scale
+%   factors in $x$ and $y$. This is a much less complex operation
+%   than rotation, and as a result the code is a lot clearer.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_scale_vector:nnNN #1#2#3#4
+  {
+    \dim_set:Nn #3
+      { \fp_to_dim:n { \dim_to_fp:n {#1} * \l_@@_scale_x_fp } }
+    \dim_set:Nn #4
+      { \fp_to_dim:n { \dim_to_fp:n {#2} * \l_@@_scale_y_fp } }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_scale_corner:Nnnn}
+% \begin{macro}{\@@_scale_pole:Nnnnnn}
+%   Scaling both corners and poles is a simple calculation using the
+%   preceding vector scaling.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_scale_corner:Nnnn #1#2#3#4
+  {
+    \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+    \prop_put:Nnx \l_@@_corners_prop {#2}
+      { { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim } }
+  }
+\cs_new_protected:Npn \@@_scale_pole:Nnnnnn #1#2#3#4#5#6
+  {
+    \@@_scale_vector:nnNN {#3} {#4} \l_@@_x_dim \l_@@_y_dim
+    \prop_put:Nnx \l_@@_poles_prop {#2}
+      {
+        { \dim_use:N \l_@@_x_dim } { \dim_use:N \l_@@_y_dim }
+        {#5} {#6}
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_x_shift_corner:Nnnn}
+% \begin{macro}{\@@_x_shift_pole:Nnnnnn}
+%   These functions correct for the $x$ displacement that takes
+%   place with a negative horizontal scaling.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_x_shift_corner:Nnnn #1#2#3#4
+  {
+    \prop_put:Nnx \l_@@_corners_prop {#2}
+      {
+        { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
+      }
+  }
+\cs_new_protected:Npn \@@_x_shift_pole:Nnnnnn #1#2#3#4#5#6
+  {
+    \prop_put:Nnx \l_@@_poles_prop {#2}
+      {
+        { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
+        {#5} {#6}
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Aligning and typesetting of coffins}
 %
 % \begin{macro}
@@ -1698,6 +2270,14 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{macro}{\@@_color:n}
+%   Calls \tn{color}, and otherwise does nothing if \tn{color} is not defined.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_color:n #1
+  { \cs_if_exist:NT \color { \color {#1} } }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\coffin_mark_handle:Nnnn, \coffin_mark_handle:cnnn}
 % \begin{macro}{\@@_mark_handle_aux:nnnnNnn}
 %   Marking a single handle is relatively easy. The standard attachment
@@ -1714,7 +2294,7 @@
         \hbox:n { \tex_vrule:D width 1pt height 1pt \scan_stop: } % TODO
 %</initex>
 %<*package>
-        \color {#4}
+        \@@_color:n {#4}
         \rule { 1pt } { 1pt }
 %</package>
       }
@@ -1726,7 +2306,7 @@
         % TODO
 %</initex>
 %<*package>
-        \color {#4}
+        \@@_color:n {#4}
 %</package>
         \l_@@_display_font_tl
         ( \tl_to_str:n { #2 , #3 } )
@@ -1783,7 +2363,7 @@
         \hbox:n { \tex_vrule:D width 1pt height 1pt \scan_stop: } % TODO
 %</initex>
 %<*package>
-        \color {#2}
+        \@@_color:n {#2}
         \rule { 1pt } { 1pt }
 %</package>
       }
@@ -1829,7 +2409,7 @@
                 % TODO
 %</initex>
 %<*package>
-                \color {#6}
+                \@@_color:n {#6}
 %</package>
                 \l_@@_display_font_tl
                 ( \tl_to_str:n { #1 , ##1 } )

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -54,6 +54,31 @@
 % A few commands have had to be deprecated over the years.  This module
 % defines deprecated and deleted commands to produce an error.
 %
+% The life of a deprecated command has several stages.
+% \begin{itemize}
+% \item When we decide it should be eventually removed the command's
+%   definition is put in this file \pkg{l3deprecation.dtx} and the name
+%   of the command is added to the list in \pkg{l3obsolete.txt}.  The
+%   command remains defined by default for $12$ or more months,
+%   typically until the end of a year.  During that time, if \pkg{expl3}
+%   is loaded with any of the options \texttt{check-declarations} or
+%   \texttt{log-functions} or \texttt{enable-debug} typically used in
+%   package test files, the command will produce a warning.
+% \item Then by default the command produces an error for all users,
+%   which can be suppressed for $6$ months through the option
+%   \texttt{undo-recent-deprecations}.
+% \item After this $6$-month grace period, the command irreversibly
+%   produces an error.  Its original definition can then be removed from
+%   the sources, leaving only the error definition.  In
+%   \pkg{l3obsolete.txt} its name is moved from the \enquote{Deprecated
+%   functions and variables} list to the \enquote{Removed functions and
+%   variables} list.
+% \end{itemize}
+% Package authors are encouraged to have a test file with
+% \cs{debug_on:n} |{deprecation}|, which makes commands at all stages of
+% this list into errors.  This helps detect uses of deprecated commands
+% before user complain.
+%
 % \end{documentation}
 %
 % \begin{implementation}
@@ -68,6 +93,238 @@
 %<@@=deprecation>
 %    \end{macrocode}
 %
+% \subsection{Helpers and variables}
+%
+% \begin{variable}{\l_@@_grace_period_bool}
+%   This is set to \texttt{true} when the deprecated command that is
+%   being defined is in its grace period, meaning between the time it
+%   becomes an error by default and the time $6$~months later where even
+%   \texttt{undo-recent-deprecations} stops restoring it.
+%    \begin{macrocode}
+\bool_new:N \l_@@_grace_period_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_date_compare:nNnTF, \@@_date_compare_aux:w}
+%   Expects |#1| and |#3| to be dates in the format YYYY-MM-DD (but
+%   accepts YYYY or YYYY-MM too, filling in zeros for the missing data).
+%   Compares them using |#2| (one of |<|, |=|, |>|).
+%    \begin{macrocode}
+\cs_new:Npn \@@_date_compare:nNnTF #1#2#3
+  { \@@_date_compare_aux:w #1 -0-0- \q_mark #2 #3 -0-0- \q_stop }
+\cs_new:Npn \@@_date_compare_aux:w
+  #1 - #2 - #3 - #4 \q_mark #5 #6 - #7 - #8 - #9 \q_stop
+  {
+    \int_compare:nNnTF {#1} = {#6}
+      {
+        \int_compare:nNnTF {#2} = {#7}
+          { \int_compare:nNnTF {#3} #5 {#8} }
+          { \int_compare:nNnTF {#2} #5 {#7} }
+      }
+      { \int_compare:nNnTF {#1} #5 {#6} }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_not_yet_deprecated:nTF, \@@_minus_six_months:w}
+%   Receives a deprecation \meta{date} and runs the \texttt{true}
+%   (\texttt{false}) branch if the \pkg{expl3} date is earlier (later)
+%   than \meta{date}.  If \texttt{undo-recent-deprecations} is used we
+%   subtract $6$ months to the \pkg{expl3} date (equivalently add $6$
+%   months to the \meta{date}).  In addition, if the \pkg{expl3} date is
+%   between \meta{date} and \meta{date} plus $6$ months,
+%   \cs{l_@@_grace_period_bool} is set to \texttt{true}, otherwise
+%   \texttt{false}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_not_yet_deprecated:nTF #1
+  {
+    \bool_set_false:N \l_@@_grace_period_bool
+    \exp_args:No \@@_date_compare:nNnTF { \ExplLoaderFileDate } < {#1}
+      { \use_i:nn }
+      {
+        \exp_args:Nf \@@_date_compare:nNnTF
+          {
+            \exp_after:wN \@@_minus_six_months:w
+            \ExplLoaderFileDate -0-0- \q_stop
+          } < {#1}
+          {
+            \bool_set_true:N \l_@@_grace_period_bool
+            \bool_if:NTF \l at expl@undo at recent@deprecations at bool
+          }
+          { \use_ii:nn }
+      }
+  }
+\cs_new:Npn \@@_minus_six_months:w #1 - #2 - #3 - #4 \q_stop
+  {
+    \int_compare:nNnTF {#2} > 6
+      { #1 - \int_eval:n { #2 - 6 } - #3 }
+      { \int_eval:n { #1 - 1 } - \int_eval:n { #2 + 6 } - #3 }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Patching definitions to deprecate}
+%
+% \begin{quote}
+%   \cs{__kernel_patch_deprecation:nnNNpn} \Arg{date} \Arg{replacement}
+%   \meta{definition} \meta{function} \meta{parameters} \Arg{code}
+% \end{quote}
+% defines the \meta{function} to produce a warning and run its
+% \meta{code}, or to produce an error and not run any \meta{code},
+% depending on the \pkg{expl3} date.
+% \begin{itemize}
+% \item If the \pkg{expl3} date is less than the \meta{date} (plus
+%   $6$~months in case \texttt{undo-recent-deprecations} is used) then
+%   we define the \meta{function} to produce a warning and run its code.
+%   The warning is actually suppressed in two cases:
+%   \begin{itemize}
+%   \item if neither \texttt{undo-recent-deprecations} nor
+%     \texttt{enable-debug} are in effect we may be in an end-user's
+%     document so it is suppressed;
+%   \item if the command is expandable then we cannot produce a warning.
+%   \end{itemize}
+% \item Otherwise, we define the \meta{function} to produce an error.
+% \end{itemize}
+% In both cases we additionally make \cs{debug_on:n} |{deprecation}|
+% turn the \meta{function} into an \tn{outer} error, and
+% \cs{debug_off:n} |{deprecation}| restore whatever the behaviour was
+% without \cs{debug_on:n} |{deprecation}|.
+%
+% In later sections we use the \pkg{l3doc} key \texttt{deprecated} with
+% a date equal to that \meta{date} plus $6$~months, so that \pkg{l3doc}
+% will complain if we forget to remove the stale \meta{parameters} and
+% \Arg{code}.
+%
+% In the explanations below, \meta{definition} \meta{function}
+% \meta{parameters} \Arg{code} or assignments that only differ in the
+% scope of the \meta{definition} will be called \enquote{the standard
+% definition}.
+%
+% \begin{macro}
+%   {
+%     \__kernel_patch_deprecation:nnNNpn, \@@_patch_aux:nnNNnn,
+%     \@@_warn_once:nnNnn,
+%     \@@_patch_aux:Nn,
+%     \@@_just_error:nnNN
+%   }
+%   (The parameter text is grabbed using |#5#|.)  The arguments of
+%   \cs{__kernel_deprecation_code:nn} are run upon \cs{debug_on:n}
+%   |{deprecation}| and \cs{debug_off:n} |{deprecation}|, respectively.
+%   In both scenarios we the \meta{function} may be \tn{outer} so we
+%   undefine it with \cs{tex_let:D} before redefining it, with
+%   \cs{__kernel_deprecation_error:Nnn} or with some code added shortly.
+%
+%   Then check the date (taking into account
+%   \texttt{undo-recent-deprecations}) to see if the command should be
+%   deprecated right away (\texttt{false} branch of
+%   \cs{@@_not_yet_deprecated:nTF}), in which case
+%   \cs{@@_just_error:nnNN} makes \meta{function} into an error (not
+%   \tn{outer}), ignoring its \meta{parameters} and \meta{code}
+%   completely.
+%
+%   Otherwise distinguish cases where we should give a warning from
+%   those where we shouldn't: warnings can only happen for protected
+%   commands, and we only want them if either
+%   \texttt{undo-recent-deprecations} or \texttt{enable-debug} is in
+%   force, not for standard users.
+%    \begin{macrocode}
+\cs_new_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2#3#4#5#
+  { \@@_patch_aux:nnNNnn {#1} {#2} #3 #4 {#5} }
+\cs_new_protected:Npn \@@_patch_aux:nnNNnn #1#2#3#4#5#6
+  {
+    \__kernel_deprecation_code:nn
+      {
+        \tex_let:D #4 \scan_stop:
+        \__kernel_deprecation_error:Nnn #4 {#2} {#1}
+      }
+      { \tex_let:D #4 \scan_stop: }
+    \@@_not_yet_deprecated:nTF {#1}
+      {
+        \bool_if:nTF
+          {
+            \cs_if_eq_p:NN #3 \cs_new_protected:Npn &&
+            \__kernel_if_debug:TF
+              { \c_true_bool } { \l at expl@undo at recent@deprecations at bool }
+          }
+          { \@@_warn_once:nnNnn {#1} {#2} #4 {#5} {#6} }
+          { \@@_patch_aux:Nn #3 { #4 #5 {#6} } }
+      }
+      { \@@_just_error:nnNN {#1} {#2} #3 #4 }
+  }
+%    \end{macrocode}
+%   In case we want a warning, the \meta{function} is defined to produce
+%   such a warning without grabbing any argument, then redefine itself
+%   to the standard definition that the \meta{function} should have,
+%   with arguments, and call that definition.  The \texttt{x}-type
+%   expansion and \cs{exp_not:n} avoid needing to double the~|#|, which
+%   we could not do anyways.  We then deal with the code for
+%   \cs{debug_off:n} |{deprecation}|: presumably someone doing that does
+%   not need the warning so we simply do the standard definition.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_warn_once:nnNnn #1#2#3#4#5
+  {
+    \cs_new_protected:Npx #3
+      {
+        \__kernel_if_debug:TF
+          {
+            \exp_not:N \__kernel_msg_warning:nnxxx
+              { kernel } { deprecated-command }
+              {#1}
+              { \token_to_str:N #3 }
+              { \tl_to_str:n {#2} }
+          }
+          { }
+        \exp_not:n { \cs_gset_protected:Npn #3 #4 {#5} }
+        \exp_not:N #3
+      }
+    \__kernel_deprecation_code:nn { }
+      { \cs_set_protected:Npn #3 #4 {#5} }
+  }
+%    \end{macrocode}
+%   In case we want neither warning nor error, the \meta{function} is
+%   given its standard definition.  Here |#1| is \cs{cs_new:Npn} or
+%   \cs{cs_new_protected:Npn}) and |#2| is \meta{function}
+%   \meta{parameters} \Arg{code}, so |#1#2| performs the assignment.
+%   For \cs{debug_off:n} |{deprecation}| we want to use the same
+%   assignment but with a different scope, hence the \cs{cs_if_eq:NNTF}
+%   test.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_aux:Nn #1#2
+  {
+    #1 #2
+    \cs_if_eq:NNTF #1 \cs_new_protected:Npn
+      { \__kernel_deprecation_code:nn { } { \cs_set_protected:Npn #2 } }
+      { \__kernel_deprecation_code:nn { } { \cs_set:Npn #2 } }
+  }
+%    \end{macrocode}
+%   Finally, if we want an error we reuse the same \cs{@@_patch_aux:Nn}
+%   as the previous case.  Indeed, we want \cs{debug_off:n}
+%   |{deprecation}| to make the \meta{function} into an error, just like
+%   it is by default.  The error is expandable or not, and the last
+%   argument of the error message is empty or is \texttt{grace} to
+%   denote the case where we are in the $6$~month grace period, in which
+%   case the error message is more detailed.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_just_error:nnNN #1#2#3#4
+  {
+    \exp_args:NNx \@@_patch_aux:Nn #3
+      {
+        \exp_not:N #4
+        {
+          \cs_if_eq:NNTF #3 \cs_new_protected:Npn
+            { \exp_not:N \__kernel_msg_error:nnnnnn }
+            { \exp_not:N \__kernel_msg_expandable_error:nnnnnn }
+            { kernel } { deprecated-command }
+            {#1}
+            { \token_to_str:N #4 }
+            { \tl_to_str:n {#2} }
+            { \bool_if:NT \l_@@_grace_period_bool { grace } }
+        }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\__kernel_deprecation_error:Nnn}
 %   The \tn{outer} definition here ensures the command cannot appear
 %   in an argument.  Use this auxiliary on all commands that have been
@@ -85,112 +342,118 @@
           { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} }
       }
   }
-\__kernel_deprecation_error:Nnn \box_resize:cnn
-  { \box_resize_to_wd_and_ht_plus_dp:cnn } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \box_resize:Nnn
-  { \box_resize_to_wd_and_ht_plus_dp:Nnn } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \box_use_clear:c
-  { \box_use_drop:c } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \box_use_clear:N
-  { \box_use_drop:N } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \c_job_name_tl
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+\__kernel_msg_new:nnn { kernel } { deprecated-command }
+  {
+    '#2'~deprecated~on~#1.
+    \tl_if_empty:nF {#3} { ~Use~'#3'. }
+    \str_if_eq:nnT {#4} { grace }
+      {
+        \c_space_tl
+        For~6~months~after~that~date~one~can~restore~a~deprecated~
+        command~by~loading~the~expl3~package~with~the~option~
+        'undo-recent-deprecations'.
+      }
+  }
+%    \end{macrocode}
+%
+% \subsection{Removed functions}
+%
+% \begin{macro}{\@@_old_protected:Nnn, \@@_old:Nnn}
+%   Short-hands for old commands whose definition does not matter
+%   anymore, i.e., commands past the grace period.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_old_protected:Nnn #1#2#3
+  {
+    \__kernel_patch_deprecation:nnNNpn {#3} {#2}
+    \cs_new_protected:Npn #1 { }
+  }
+\cs_new_protected:Npn \@@_old:Nnn #1#2#3
+  {
+    \__kernel_patch_deprecation:nnNNpn {#3} {#2}
+    \cs_new:Npn #1 { }
+  }
+\@@_old:Nnn \c_job_name_tl
   { \c_sys_jobname_str } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \c_minus_one
-  { -1 } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \dim_case:nnn
+\@@_old:Nnn \dim_case:nnn
   { \dim_case:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \file_add_path:nN
-  { \file_get_full_name:nN } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \file_if_exist_input:nT
+\@@_old_protected:Nnn \file_if_exist_input:nT
   { \file_if_exist:nT and~ \file_input:n } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \file_if_exist_input:nTF
+\@@_old_protected:Nnn \file_if_exist_input:nTF
   { \file_if_exist:nT and~ \file_input:n } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \file_list:
-  { \file_log_list: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \file_path_include:n
-  { \seq_put_right:Nn \l_file_search_path_seq } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \file_path_remove:n
-  { \seq_remove_all:Nn \l_file_search_path_seq } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \g_file_current_name_tl
-  { \g_file_current_name_str } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \int_case:nnn
+\@@_old:Nnn \int_case:nnn
   { \int_case:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \int_from_binary:n
+\@@_old:Nnn \int_from_binary:n
   { \int_from_bin:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_from_hexadecimal:n
+\@@_old:Nnn \int_from_hexadecimal:n
   { \int_from_hex:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_from_octal:n
+\@@_old:Nnn \int_from_octal:n
   { \int_from_oct:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_to_binary:n
+\@@_old:Nnn \int_to_binary:n
   { \int_to_bin:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_to_hexadecimal:n
+\@@_old:Nnn \int_to_hexadecimal:n
   { \int_to_hex:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_to_octal:n
+\@@_old:Nnn \int_to_octal:n
   { \int_to_oct:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \ior_get_str:NN
+\@@_old_protected:Nnn \ior_get_str:NN
   { \ior_str_get:NN } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \ior_list_streams:
-  { \ior_show_list: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \ior_log_streams:
-  { \ior_log_list: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine_p:
+\@@_old:Nnn \luatex_if_engine_p:
   { \sys_if_engine_luatex_p: } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine:F
+\@@_old:Nnn \luatex_if_engine:F
   { \sys_if_engine_luatex:F } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine:T
+\@@_old:Nnn \luatex_if_engine:T
   { \sys_if_engine_luatex:T } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine:TF
+\@@_old:Nnn \luatex_if_engine:TF
   { \sys_if_engine_luatex:TF } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine_p:
+\@@_old:Nnn \pdftex_if_engine_p:
   { \sys_if_engine_pdftex_p: } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine:F
+\@@_old:Nnn \pdftex_if_engine:F
   { \sys_if_engine_pdftex:F } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine:T
+\@@_old:Nnn \pdftex_if_engine:T
   { \sys_if_engine_pdftex:T } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine:TF
+\@@_old:Nnn \pdftex_if_engine:TF
   { \sys_if_engine_pdftex:TF } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \prop_get:cn
+\@@_old:Nnn \prop_get:cn
   { \prop_item:cn } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \prop_get:Nn
+\@@_old:Nnn \prop_get:Nn
   { \prop_item:Nn } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \quark_if_recursion_tail_break:N
+\@@_old:Nnn \quark_if_recursion_tail_break:N
   { } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \quark_if_recursion_tail_break:n
+\@@_old:Nnn \quark_if_recursion_tail_break:n
   { } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \scan_align_safe_stop:
+\@@_old:Nnn \scan_align_safe_stop:
   { protected~commands } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \sort_ordered:
-  { \sort_return_same: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \sort_reversed:
-  { \sort_return_swapped: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \str_case:nnn
+\@@_old:Nnn \str_case:nnn
   { \str_case:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \str_case:onn
+\@@_old:Nnn \str_case:onn
   { \str_case:onF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \str_case_x:nnn
+\@@_old:Nnn \str_case_x:nnn
   { \str_case_e:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \tl_case:cnn
+\@@_old:Nnn \tl_case:cnn
   { \tl_case:cnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \tl_case:Nnn
+\@@_old:Nnn \tl_case:Nnn
   { \tl_case:NnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \tl_to_lowercase:n
+\@@_old_protected:Nnn \tl_to_lowercase:n
   { \tex_lowercase:D } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \tl_to_uppercase:n
+\@@_old_protected:Nnn \tl_to_uppercase:n
   { \tex_uppercase:D } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \token_new:Nn
-  { \cs_new_eq:NN } { 2018-12-29 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine_p:
+\@@_old:Nnn \xetex_if_engine_p:
   { \sys_if_engine_xetex_p: } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine:F
+\@@_old:Nnn \xetex_if_engine:F
   { \sys_if_engine_xetex:F } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine:T
+\@@_old:Nnn \xetex_if_engine:T
   { \sys_if_engine_xetex:T } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine:TF
+\@@_old:Nnn \xetex_if_engine:TF
   { \sys_if_engine_xetex:TF } { 2017-01-01 }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[deprecated = 2019-12-31]{\etex_beginL:D}
+% \subsection{Deprecated primitives}
+%
+% \begin{macro}[deprecated = 2020-07-01]{\etex_beginL:D}
 % \begin{macro}{\@@_primitive:NN, \@@_primitive:w}
 %   We renamed all primitives to \cs[no-index]{tex_\ldots{}:D} so all
 %   others are deprecated.  In \pkg{l3names}, \cs{__kernel_primitives:}
@@ -229,7 +492,7 @@
                 \@@_primitive:w { \cs_to_str:N #2 }
               }
           }
-          { 2019-12-31 }
+          { 2020-01-01 }
       }
     \__kernel_primitives:
   }
@@ -244,18 +507,563 @@
       {
         \tex_let:D #2 #1
         \cs_if_exist:cT { tex_ \cs_to_str:N #1 :D }
+          { \cs_set_eq:Nc #2 { tex_ \cs_to_str:N #1 :D } }
+      }
+    \__kernel_primitives:
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3box} functions}
+%
+% \begin{macro}[deprecated = 2019-07-01]
+%   {\box_resize:Nnn, \box_resize:cnn, \box_use_clear:N, \box_use_clear:c}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn
+  { 2019-01-01 } { \box_resize_to_wd_and_ht_plus_dp:Nnn }
+\cs_new_protected:Npn \box_resize:Nnn
+  { \box_resize_to_wd_and_ht_plus_dp:Nnn }
+\__kernel_patch_deprecation:nnNNpn
+  { 2019-01-01 } { \box_resize_to_wd_and_ht_plus_dp:cnn }
+\cs_new_protected:Npn \box_resize:cnn
+  { \box_resize_to_wd_and_ht_plus_dp:cnn }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \box_use_drop:N }
+\cs_new_protected:Npn \box_use_clear:N { \box_use_drop:N }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \box_use_drop:c }
+\cs_new_protected:Npn \box_use_clear:c { \box_use_drop:c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2021-07-01]
+%   {
+%     \box_set_eq_clear:NN, \box_set_eq_clear:cN,
+%     \box_set_eq_clear:Nc, \box_set_eq_clear:cc
+%   }
+% \begin{macro}[deprecated = 2021-07-01]
+%   {
+%     \box_gset_eq_clear:NN, \box_gset_eq_clear:cN,
+%     \box_gset_eq_clear:Nc, \box_gset_eq_clear:cc
+%   }
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \box_set_eq_drop:N }
+\cs_new_protected:Npn \box_set_eq_clear:NN #1#2
+  { \tex_setbox:D #1 \tex_box:D #2 }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \box_gset_eq_drop:N }
+\cs_new_protected:Npn \box_gset_eq_clear:NN #1#2
+  { \tex_global:D \tex_setbox:D #1 \tex_box:D #2 }
+\cs_generate_variant:Nn \box_set_eq_clear:NN  { c , Nc , cc }
+\cs_generate_variant:Nn \box_gset_eq_clear:NN { c , Nc , cc }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2021-07-01]{\hbox_unpack_clear:N, \hbox_unpack_clear:c}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \hbox_unpack_drop:N }
+\cs_new_protected:Npn \hbox_unpack_clear:N
+  { \hbox_unpack_drop:N }
+\cs_generate_variant:Nn \hbox_unpack_clear:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2021-07-01]{\vbox_unpack_clear:N, \vbox_unpack_clear:c}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \vbox_unpack_drop:N }
+\cs_new_protected:Npn \vbox_unpack_clear:N
+  { \vbox_unpack_drop:N }
+\cs_generate_variant:Nn \vbox_unpack_clear:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3file} functions}
+%
+%    \begin{macrocode}
+%<@@=deprecation>
+%    \end{macrocode}
+%
+% \begin{variable}[deprecated = 2019-07-01]{\g_file_current_name_tl}
+%   Contrarily to most other deprecated commands this is a token list so
+%   we have to resort to lower-level code.
+%
+%   so we need to put code by hand in two token lists.  We use
+%   \cs{tex_def:D} directly because \cs{g_file_current_name_tl} is made
+%   outer by \cs{debug_on:n} \texttt{\{deprecation\}}.
+%    \begin{macrocode}
+\__kernel_deprecation_code:nn
+  {
+    \tex_let:D \g_file_current_name_tl \scan_stop:
+    \__kernel_deprecation_error:Nnn \g_file_current_name_tl
+      { \g_file_curr_name_str } { 2019-01-01 }
+  }
+  {
+    \tex_let:D \g_file_current_name_tl \scan_stop:
+    \cs_set_nopar:Npn \g_file_current_name_tl { \g_file_curr_name_str }
+  }
+\@@_not_yet_deprecated:nTF { 2019-01-01 }
+  {
+    \tl_new:N \g_file_current_name_tl
+    \tl_gset:Nn \g_file_current_name_tl { \g_file_curr_name_str }
+  }
+  {
+    \cs_gset_nopar:Npn \g_file_current_name_tl
+      {
+        \__kernel_msg_expandable_error:nnnnn
+          { kernel } { deprecated-command }
+          { 2019-01-01 } { \g_file_current_name_tl } { \g_file_curr_name_str }
+      }
+  }
+%    \end{macrocode}
+% \end{variable}
+%
+%    \begin{macrocode}
+%<@@=file>
+%    \end{macrocode}
+%
+% \begin{macro}[deprecated = 2019-07-01]{\file_path_include:n, \file_path_remove:n}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn
+  { 2019-01-01 } { \seq_put_right:Nn \l_file_search_path_seq }
+\cs_new_protected:Npn \file_path_include:n #1
+  {
+    \__kernel_file_name_sanitize:nN {#1} \l_@@_full_name_str
+    \seq_if_in:NVF \l_file_search_path_seq \l_@@_full_name_str
+      { \seq_put_right:NV \l_file_search_path_seq \l_@@_full_name_str }
+  }
+\__kernel_patch_deprecation:nnNNpn
+  { 2019-01-01 } { \seq_remove_all:Nn \l_file_search_path_seq }
+\cs_new_protected:Npn \file_path_remove:n #1
+  {
+    \__kernel_file_name_sanitize:nN {#1} \l_@@_full_name_str
+    \seq_remove_all:NV \l_file_search_path_seq \l_@@_full_name_str
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2019-07-01]{\file_add_path:nN}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \file_get_full_name:nN }
+\cs_new_protected:Npn \file_add_path:nN #1#2
+  {
+    \file_get_full_name:nN {#1} #2
+    \str_if_empty:NT #2
+      { \tl_set:Nn #2 { \q_no_value } }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2019-07-01]{\file_list:}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \file_log_list: }
+\cs_new_protected:Npn \file_list:          { \file_log_list: }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[added = 2014-08-22, updated = 2015-08-01, deprecated = 2019-07-01]
+%   {\ior_list_streams:, \ior_log_streams:, \iow_list_streams:, \iow_log_streams:}
+%   These got a more consistent naming.
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \ior_show_list: }
+\cs_new_protected:Npn \ior_list_streams:   { \ior_show_list: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \ior_log_list: }
+\cs_new_protected:Npn \ior_log_streams:    { \ior_log_list: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \iow_show_list: }
+\cs_new_protected:Npn \iow_list_streams:   { \iow_show_list: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \iow_log_list: }
+\cs_new_protected:Npn \iow_log_streams:    { \iow_log_list: }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3int} functions}
+%
+%    \begin{macrocode}
+%<@@=deprecation>
+%    \end{macrocode}
+%
+% \begin{variable}[deprecated = 2019-07-01]{\c_minus_one, \c_@@_minus_one}
+%   In order to toggle definitions on and off locally we declare an
+%   internal constant integer and copy it into \cs{c_minus_one}.
+%    \begin{macrocode}
+\int_const:Nn \c_@@_minus_one { -1 }
+\__kernel_deprecation_code:nn
+  {
+    \tex_let:D \c_minus_one \scan_stop:
+    \__kernel_deprecation_error:Nnn \c_minus_one { -1 } { 2019-01-01 }
+  }
+  {
+    \tex_let:D \c_minus_one \scan_stop:
+    \cs_set_eq:NN \c_minus_one \c_@@_minus_one
+  }
+\@@_not_yet_deprecated:nTF { 2019-01-01 }
+  { \cs_new_eq:NN \c_minus_one \c_@@_minus_one }
+  {
+    \cs_gset_nopar:Npn \c_minus_one
+      {
+        \__kernel_msg_expandable_error:nnnnn
+          { kernel } { deprecated-command }
+          { 2019-01-01 } { \c_minus_one } { -1 }
+        \c_@@_minus_one
+      }
+  }
+%    \end{macrocode}
+% \end{variable}
+%
+%    \begin{macrocode}
+%<@@=int>
+%    \end{macrocode}
+%
+% \begin{variable}[deprecated = 2020-07-01]
+%   {
+%     \c_zero, \c_one, \c_two, \c_three, \c_four, \c_five, \c_six,
+%     \c_seven, \c_eight, \c_nine, \c_ten, \c_eleven, \c_twelve,
+%     \c_thirteen, \c_fourteen, \c_fifteen, \c_sixteen, \c_thirty_two,
+%     \c_one_hundred, \c_two_hundred_fifty_five,
+%     \c_two_hundred_fifty_six, \c_one_thousand, \c_ten_thousand,
+%   }
+% \begin{macro}{\@@_deprecated_constants:nn}
+%   Constants that are now deprecated.  By default define them with
+%   \cs{int_const:Nn}.  To deprecate them call for instance
+%   \cs{__kernel_deprecation_error:Nnn} \cs{c_zero} |{0}|
+%   |{2020-01-01}|.  To redefine them (locally), use
+%   \cs{@@_constdef:Nw}, with an \cs{exp_not:N} construction because the
+%   constants themselves are outer at that point.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_deprecated_constants:nn #1#2
+  {
+    #1 \c_zero                   {   0 } #2
+    #1 \c_one                    {   1 } #2
+    #1 \c_two                    {   2 } #2
+    #1 \c_three                  {   3 } #2
+    #1 \c_four                   {   4 } #2
+    #1 \c_five                   {   5 } #2
+    #1 \c_six                    {   6 } #2
+    #1 \c_seven                  {   7 } #2
+    #1 \c_eight                  {   8 } #2
+    #1 \c_nine                   {   9 } #2
+    #1 \c_ten                    {  10 } #2
+    #1 \c_eleven                 {  11 } #2
+    #1 \c_twelve                 {  12 } #2
+    #1 \c_thirteen               {  13 } #2
+    #1 \c_fourteen               {  14 } #2
+    #1 \c_fifteen                {  15 } #2
+    #1 \c_sixteen                {  16 } #2
+    #1 \c_thirty_two             {  32 } #2
+    #1 \c_one_hundred            { 100 } #2
+    #1 \c_two_hundred_fifty_five { 255 } #2
+    #1 \c_two_hundred_fifty_six  { 256 } #2
+    #1 \c_one_thousand         {  1000 } #2
+    #1 \c_ten_thousand         { 10000 } #2
+  }
+\@@_deprecated_constants:nn { \int_const:Nn } { }
+\__kernel_deprecation_code:nn
+  {
+    \@@_deprecated_constants:nn
+      { \exp_after:wN \__kernel_deprecation_error:Nnn \exp_not:N }
+      { { 2020-01-01 } }
+  }
+  {
+    \@@_deprecated_constants:nn
+      {
+        \exp_after:wN \use:nnn
+        \exp_after:wN \@@_constdef:Nw \exp_not:N
+      }
+      { \exp_stop_f: }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{variable}
+%
+% \begin{macro}[deprecated = 2020-07-01]{\@@_value:w}
+%   Made public.
+%    \begin{macrocode}
+\cs_new_eq:NN \@@_value:w \int_value:w
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3luatex} functions}
+%
+%    \begin{macrocode}
+%<@@=lua>
+%    \end{macrocode}
+%
+% \begin{macro}[EXP, deprecated = 2020-07-01]{\lua_now_x:n, \lua_escape_x:n}
+% \begin{macro}[deprecated = 2020-07-01]{\lua_shipout_x:n}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_now:e }
+\cs_new:Npn \lua_now_x:n #1 { \@@_now:n {#1} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_escape:e }
+\cs_new:Npn \lua_escape_x:n #1 { \@@_escape:n {#1} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_shipout_e:n }
+\cs_new_protected:Npn \lua_shipout_x:n #1 { \@@_shipout:n {#1} }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3msg} functions}
+%
+%    \begin{macrocode}
+%<@@=msg>
+%    \end{macrocode}
+%
+% \begin{macro}[deprecated = 2020-07-01]{\msg_log:n, \msg_term:n}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \iow_log:n }
+\cs_new_protected:Npn \msg_log:n #1
+  {
+    \iow_log:n { ................................................. }
+    \iow_wrap:nnnN { . ~ #1} { . ~ } { } \iow_log:n
+    \iow_log:n { ................................................. }
+  }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \iow_term:n }
+\cs_new_protected:Npn \msg_term:n #1
+  {
+    \iow_term:n { ************************************************* }
+    \iow_wrap:nnnN { * ~ #1} { * ~ } { } \iow_term:n
+    \iow_term:n { ************************************************* }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[deprecated = 2020-07-01]{\msg_interrupt:nnn}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { [Defined~error~message] }
+\cs_new_protected:Npn \msg_interrupt:nnn #1#2#3
+  {
+    \tl_if_empty:nTF {#3}
+      {
+        \@@_old_interrupt_wrap:nn { \\ \c_@@_no_info_text_tl }
+          {#1 \\\\ #2 \\\\ \c_@@_continue_text_tl }
+      }
+      {
+        \@@_old_interrupt_wrap:nn { \\ #3 }
+          {#1 \\\\ #2 \\\\ \c_@@_help_text_tl }
+      }
+  }
+\cs_new_protected:Npn \@@_old_interrupt_wrap:nn #1#2
+  {
+    \iow_wrap:nnnN {#1} { | ~ } { } \@@_old_interrupt_more_text:n
+    \iow_wrap:nnnN {#2} { ! ~ } { } \@@_old_interrupt_text:n
+  }
+\cs_new_protected:Npn \@@_old_interrupt_more_text:n #1
+  {
+    \exp_args:Nx \tex_errhelp:D
+      {
+        |'''''''''''''''''''''''''''''''''''''''''''''''
+        #1 \iow_newline:
+        |...............................................
+      }
+  }
+\group_begin:
+  \char_set_lccode:nn {`\{} {`\ }
+  \char_set_lccode:nn {`\}} {`\ }
+  \char_set_lccode:nn {`\&} {`\!}
+  \char_set_catcode_active:N \&
+\tex_lowercase:D
+  {
+    \group_end:
+    \cs_new_protected:Npn \@@_old_interrupt_text:n #1
+      {
+        \iow_term:x
           {
-            \exp_args:NNc \cs_set_eq:NN #2
-              { tex_ \cs_to_str:N #1 :D }
+            \iow_newline:
+            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+            \iow_newline:
+            !
           }
+        \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J }
+          {
+            \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 }
+              {
+                \group_begin:
+                  \cs_set_protected:Npn &
+                    {
+                      \tex_errmessage:D
+                        {
+                          #1
+                          \use_none:n
+                            { ............................................ }
+                        }
+                    }
+                  \exp_after:wN
+                \group_end:
+                &
+              }
+          }
       }
-    \__kernel_primitives:
   }
 %    \end{macrocode}
 % \end{macro}
+%
+% \subsection{Deprecated \pkg{l3prg} functions}
+%
+%    \begin{macrocode}
+%<@@=prg>
+%    \end{macrocode}
+%
+% \begin{macro}[deprecated = 2020-07-01]
+%   {
+%     \@@_break_point:Nn,
+%     \@@_break_point:,
+%     \@@_map_break:Nn,
+%     \@@_break:,
+%     \@@_break:n
+%   }
+%   Made public, but used by a few third-parties.  It's not possible to
+%   perfectly support a mixture of \cs{@@_map_break:Nn} and
+%   \cs{prg_map_break:Nn} because they use different delimiters.  The
+%   following code only breaks if someone tries to break from two
+%   \enquote{old-style} \cs{@@_map_break:Nn} \ldots{}
+%   \cs{@@_break_point:Nn} mappings in one go.  Basically, the
+%   \cs{@@_map_break:Nn} converts a single \cs{@@_break_point:Nn} to
+%   \cs{prg_break_point:Nn}, and that delimiter had better be the right
+%   one.  Then we call \cs{prg_map_break:Nn} which may end up breaking
+%   intermediate looks in the (unbraced) argument |#1|.  It is essential
+%   to define the |break_point| functions before the corresponding
+%   |break| functions: otherwise \cs{debug_on:n} |{deprecation}|
+%   \cs{debug_off:n} |{deprecation}| would break when trying to restore
+%   the definitions because they would involve deprecated commands whose
+%   definition has not yet been restored.
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break_point:Nn }
+\cs_new:Npn \@@_break_point:Nn { \prg_break_point:Nn }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break_point: }
+\cs_new:Npn \@@_break_point: { \prg_break_point: }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_map_break:Nn }
+\cs_new:Npn \@@_map_break:Nn #1 \@@_break_point:Nn
+  { \prg_map_break:Nn #1 \prg_break_point:Nn }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break: }
+\cs_new:Npn \@@_break: #1 \@@_break_point: { }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break:n }
+\cs_new:Npn \@@_break:n #1#2 \@@_break_point: {#1}
+%    \end{macrocode}
 % \end{macro}
 %
+% \subsection{Deprecated \pkg{l3sort} functions}
+%
+% \begin{macro}[deprecated = 2019-07-01]{\sort_ordered:, \sort_reversed:}
 %    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \sort_return_same: }
+\cs_new_protected:Npn \sort_ordered: { \sort_return_same: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \sort_return_swapped: }
+\cs_new_protected:Npn \sort_reversed: { \sort_return_swapped: }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3str} functions}
+%
+% \begin{macro}[EXP, deprecated = 2020-07-01, noTF]{\str_case_x:nn}
+% \begin{macro}[EXP, deprecated = 2020-07-01, pTF]{\str_if_eq_x:nn}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nn }
+\cs_new:Npn \str_case_x:nn { \str_case_e:nn }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nnT }
+\cs_new:Npn \str_case_x:nnT { \str_case_e:nnT }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nnF }
+\cs_new:Npn \str_case_x:nnF { \str_case_e:nnF }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nnTF }
+\cs_new:Npn \str_case_x:nnTF { \str_case_e:nnTF }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq_p:ee }
+\cs_new:Npn \str_if_eq_x_p:nn { \str_if_eq_p:ee }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq:eeT }
+\cs_new:Npn \str_if_eq_x:nnT { \str_if_eq:eeT }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq:eeF }
+\cs_new:Npn \str_if_eq_x:nnF { \str_if_eq:eeF }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq:eeTF }
+\cs_new:Npn \str_if_eq_x:nnTF { \str_if_eq:eeTF }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Deprecated \pkg{l3tl} functions}
+%
+%    \begin{macrocode}
+%<@@=tl>
+%    \end{macrocode}
+%
+% \begin{macro}[deprecated = 2021-07-01]
+%   {
+%     \tl_set_from_file:Nnn, \tl_set_from_file:cnn,
+%     \tl_gset_from_file:Nnn, \tl_gset_from_file:cnn,
+%     \tl_set_from_file_x:Nnn, \tl_set_from_file_x:cnn,
+%     \tl_gset_from_file_x:Nnn, \tl_gset_from_file_x:cnn
+%   }
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_set_from_file:Nnn #1#2#3
+  { \file_get:nnN {#3} {#2} #1 }
+\cs_generate_variant:Nn \tl_set_from_file:Nnn { c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_gset_from_file:Nnn #1#2#3
+  {
+    \group_begin:
+      \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
+      \tl_gset_eq:NN #1 \l_@@_internal_a_tl
+    \group_end:
+  }
+\cs_generate_variant:Nn \tl_gset_from_file:Nnn { c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_set_from_file_x:Nnn #1#2#3
+  {
+    \group_begin:
+      \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
+      #2 \scan_stop:
+      \tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl }
+    \exp_args:NNNo \group_end:
+    \tl_set:Nn #1 \l_@@_internal_a_tl
+  }
+\cs_generate_variant:Nn \tl_set_from_file_x:Nnn { c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_gset_from_file_x:Nnn #1#2#3
+  {
+    \group_begin:
+      \file_get:nnN {#3} {#2} \l_@@_internal_a_tl
+      #2 \scan_stop:
+      \tl_gset:Nx #1 { \l_@@_internal_a_tl }
+    \group_end:
+  }
+\cs_generate_variant:Nn \tl_gset_from_file_x:Nnn { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3tl-analysis} functions}
+%
+% \begin{macro}[deprecated = 2020-07-01]
+%   {\tl_show_analysis:N, \tl_show_analysis:n}
+%   Simple renames.
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \tl_analysis_show:N }
+\cs_new_protected:Npn \tl_show_analysis:N { \tl_analysis_show:N }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \tl_analysis_show:n }
+\cs_new_protected:Npn \tl_show_analysis:n { \tl_analysis_show:n }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated \pkg{l3token} functions}
+%
+% \begin{macro}[deprecated = 2019-07-01]{\token_new:Nn}
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \cs_new_eq:NN }
+\cs_new_protected:Npn \token_new:Nn #1#2 { \cs_new_eq:NN #1 #2 }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, deprecated = 2021-07-01]
+%   {
+%     \token_get_prefix_spec:N,
+%     \token_get_arg_spec:N,
+%     \token_get_replacement_spec:N
+%   }
+%    \begin{macrocode}
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \cs_prefix_spec:N }
+\cs_new:Npn \token_get_prefix_spec:N { \cs_prefix_spec:N }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \cs_argument_spec:N }
+\cs_new:Npn \token_get_arg_spec:N { \cs_argument_spec:N }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \cs_replacement_spec:N }
+\cs_new:Npn \token_get_replacement_spec:N { \cs_replacement_spec:N }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
 %</initex|package>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -79,7 +79,7 @@
 %
 % \title{The \cls{l3doc} class}
 % \author{\Team}
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 % \maketitle
 % \tableofcontents
 %
@@ -334,6 +334,17 @@
 %   class names, respectively.
 % \end{function}
 %
+% \begin{function}{\NB, \NOTE}
+%   \begin{syntax}
+%     \cs{NB} \marg{tag} \marg{comments}
+%     \verb|\begin{NOTE}| \marg{tag}
+%     \qquad\meta{comments}
+%     \verb|\end{NOTE}|
+%   \end{syntax}
+%   Make notes in the source that are not typeset by default. When the \verb|show-notes|
+%   class option is active, the comments are typeset in a detokenized and verbatim mode, respectively.
+% \end{function}
+%
 % \subsection{Describing functions in the documentation}
 %
 % \DescribeEnv{function}
@@ -694,6 +705,7 @@
 %     \g_@@_checkfunc_bool,
 %     \g_@@_checktest_bool,
 %     \g_@@_cs_break_bool,
+%     \g_@@_show_notes_bool,
 %     \g_@@_kernel_bool
 %   }
 %   Information about package options.
@@ -703,6 +715,7 @@
 \bool_new:N \g_@@_checktest_bool
 \bool_new:N \g_@@_kernel_bool
 \bool_new:N \g_@@_cs_break_bool
+\bool_new:N \g_@@_show_notes_bool
 \bool_gset_true:N \g_@@_cs_break_bool
 %    \end{macrocode}
 % \end{variable}
@@ -1430,6 +1443,13 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
+\DeclareOption { show-notes }
+  { \bool_gset_true:N  \g_@@_show_notes_bool }
+\DeclareOption { hide-notes }
+  { \bool_gset_false:N \g_@@_show_notes_bool }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \DeclareOption* { \PassOptionsToClass { \CurrentOption } { article } }
 \ExecuteOptions { full, kernel, nocheck, nochecktest, lm-default }
 \PassOptionsToClass { a4paper } { article }
@@ -1885,6 +1905,7 @@
 \NewDocumentCommand { \CodedocExplainEXP } { }
   {
     \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{expstar}{}}%
+    \write \@auxout { \def \string \Codedoc at expstar { } }
     \@@_typeset_exp:\ indicates~fully~expandable~functions,~which~
     can~be~used~within~an~\texttt{x}-type~argument~(in~plain~
     \TeX{}~terms,~inside~an~\cs{edef}),~as~well~as~within~an~
@@ -1893,6 +1914,7 @@
 \NewDocumentCommand { \CodedocExplainREXP } { }
   {
     \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{rexpstar}{}}%
+    \write \@auxout { \def \string \Codedoc at rexpstar { } }
     \@@_typeset_rexp:\ indicates~
     restricted~expandable~functions,~which~can~be~used~within~an~
     \texttt{x}-type~argument~but~cannot~be~fully~expanded~within~an~
@@ -1901,6 +1923,7 @@
 \NewDocumentCommand { \CodedocExplainTF } { }
   {
     \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{explTF}{}}%
+    \write \@auxout { \def \string \Codedoc at explTF { } }
     \@@_typeset_TF:\ indicates~conditional~(\texttt{if})~functions~
     whose~variants~with~\texttt{T},~\texttt{F}~and~\texttt{TF}~
     argument~specifiers~expect~different~
@@ -2062,18 +2085,30 @@
 %   to typeset conditionals and auxiliary functions.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_typeset_exp:
-  { \hyperlink{expstar} {$\star$} }
+  {
+    \cs_if_exist:NTF \Codedoc at expstar
+      { \hyperlink { expstar } }
+      { \mbox }
+    {$\star$}
+  }
 \cs_new_protected:Npn \@@_typeset_rexp:
-  { \hyperlink{rexpstar} {\ding{73}} } % hollow star
+  {
+    \cs_if_exist:NTF \Codedoc at rexpstar
+      { \hyperlink { rexpstar } }
+      { \mbox }
+    { \ding { 73 } } % hollow star
+  }
 \cs_new_protected:Npn \@@_typeset_TF:
   {
-    \hyperlink{explTF}
+    \cs_if_exist:NTF \Codedoc at explTF
+      { \hyperlink { explTF } }
+      { \mbox }
       {
         \color{black}
         \itshape TF
         \makebox[0pt][r]
           {
-            \color{red}
+            \cs_if_exist:NT \Codedoc at explTF { \color{red} }
             \underline { \phantom{\itshape TF} \kern-0.1em }
           }
       }
@@ -2409,7 +2444,7 @@
   {
     \@@_date_set:Nn #1 {#2}
     \exp_args:No \@@_date_compare:nNnT
-      {#1} > { \tex_year:D - \tex_month:D - \tex_day:D }
+      {#1} > { \c_sys_year_int - \c_sys_month_int - \c_sys_day_int }
       {
         \msg_error:nnxx { l3doc } { future-date }
           { \tl_to_str:N \l_@@_macro_argument_tl }
@@ -2430,7 +2465,7 @@
   {
     \@@_date_set:Nn \l_@@_tmpa_tl {#1}
     \exp_args:No \@@_date_compare:nNnT
-      { \l_@@_tmpa_tl } < { \tex_year:D - \tex_month:D - \tex_day:D }
+      { \l_@@_tmpa_tl } < { \c_sys_year_int - \c_sys_month_int - \c_sys_day_int }
       {
         \msg_error:nnxx { l3doc } { deprecated-function }
           { \tl_to_str:N \l_@@_macro_argument_tl }
@@ -2495,6 +2530,7 @@
 \cs_new_protected:Npn \@@_function_typeset_stop:
   {
     \par
+    \dim_set:Nn \prevdepth { \box_dp:N \l_@@_descr_coffin }
     \allowbreak
   }
 %    \end{macrocode}
@@ -3435,6 +3471,57 @@
 % \end{environment}
 % \end{environment}
 %
+% \subsubsection{NB and NOTE}
+%
+% These macros are intended for additional notes added to the source that are not typeset.
+%
+% \begin{macro}{\NB}
+% \NB{wspr}{this is what I think about this!}
+% \begin{verbatim}
+%   \NB{wspr}{this is what I think about this!}
+% \end{verbatim}
+%    \begin{macrocode}
+\bool_if:NTF \g_@@_show_notes_bool
+  {
+    \NewDocumentCommand\NB{mm}
+      {
+        (\emph{Note}\footnote{\ttfamily [#1]:~\detokenize{#2}})
+      }
+  }
+  {
+    \NewDocumentCommand\NB{mm}{}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{\NOTE}
+% \begin{NOTE}{wspr}
+%   this is what I #$%& think about this!
+% \end{NOTE}
+% \begin{verbatim}
+%   \begin{NOTE}{wspr}
+%     this is what I #$%& think about this!
+%   \end{NOTE}
+% \end{verbatim}
+%    \begin{macrocode}
+\bool_if:NTF \g_@@_show_notes_bool
+  {
+    \NewDocumentEnvironment{NOTE}{m}
+      {
+        \par\noindent (\emph{Note}~[\texttt{#1}]:\par
+        \verbatim
+      }
+      {
+        \endverbatim
+        \par\noindent \emph{Note~end})\par
+      }
+  }
+  {
+    \NewDocumentEnvironment{NOTE}{m}{\comment}{\endcomment}
+  }
+%    \end{macrocode}
+% \end{environment}
+%
 % \subsection{Documenting templates}
 %
 %    \begin{macrocode}
@@ -3742,7 +3829,7 @@
       \@@_replace_at_at:N \l_@@_tmpa_tl
 
       \tl_gset:Nn \g_@@_module_name_tl {#2}
-      \tl_put_right:Nn \l_@@_tmpa_tl { < @ @ = #2 > }
+      \tl_put_right:Nn \l_@@_tmpa_tl { < \text { \verbatim at font @ @ = #2 } > }
 
       \tl_set:Nn \l_@@_tmpb_tl {#3}
       \@@_detect_internals:N \l_@@_tmpb_tl

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -63,7 +63,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -556,23 +556,23 @@
 %<*package>
 \ProvidesExplFile
 %<*dvipdfmx>
-  {l3dvipdfmx.def}{2019-02-15}{}
+  {l3dvipdfmx.def}{2019-03-05}{}
   {L3 Experimental driver: dvipdfmx}
 %</dvipdfmx>
 %<*dvips>
-  {l3dvips.def}{2019-02-15}{}
+  {l3dvips.def}{2019-03-05}{}
   {L3 Experimental driver: dvips}
 %</dvips>
 %<*dvisvgm>
-  {l3dvisvgm.def}{2019-02-15}{}
+  {l3dvisvgm.def}{2019-03-05}{}
   {L3 Experimental driver: dvisvgm}
 %</dvisvgm>
 %<*pdfmode>
-  {l3pdfmode.def}{2019-02-15}{}
+  {l3pdfmode.def}{2019-03-05}{}
   {L3 Experimental driver: PDF mode}
 %</pdfmode>
 %<*xdvipdfmx>
-  {l3xdvipdfmx.def}{2019-02-15}{}
+  {l3xdvipdfmx.def}{2019-03-05}{}
   {L3 Experimental driver: xdvipdfmx}
 %</xdvipdfmx>
 %</package>

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -713,7 +713,7 @@
 %     \cs{exp_not:o} \Arg{tokens}
 %   \end{syntax}
 %   Expands the \meta{tokens} once, then prevents any further expansion
-%   in |x|-type arguments using \cs{exp_not:n}.
+%   in |x|-type or \texttt{e}-type arguments using \cs{exp_not:n}.
 % \end{function}
 %
 % \begin{function}[EXP]{\exp_not:V}
@@ -721,7 +721,7 @@
 %     \cs{exp_not:V} \meta{variable}
 %   \end{syntax}
 %   Recovers the content of the \meta{variable}, then prevents expansion
-%   of this material in |x|-type arguments using \cs{exp_not:n}.
+%   of this material in |x|-type or \texttt{e}-type arguments using \cs{exp_not:n}.
 % \end{function}
 %
 % \begin{function}[EXP]{\exp_not:v}
@@ -732,7 +732,7 @@
 %   converts this into a control sequence which should be a \meta{variable}
 %   name.
 %   The content of the \meta{variable} is recovered, and further
-%   expansion in |x|-type arguments is prevented using \cs{exp_not:n}.
+%   expansion in |x|-type or \texttt{e}-type arguments is prevented using \cs{exp_not:n}.
 %   \begin{texnote}
 %     Protected macros that appear in a \texttt{v}-type argument are
 %     expanded despite being protected; \cs{exp_not:n} also has no
@@ -759,7 +759,7 @@
 %   Expands \meta{tokens} fully until the first unexpandable token is
 %   found (if it is a space it is removed). Expansion then stops, and
 %   the result of the expansion (including any tokens which were not
-%   expanded) is protected from further expansion in |x|-type arguments
+%   expanded) is protected from further expansion in |x|-type or \texttt{e}-type arguments
 %   using \cs{exp_not:n}.
 % \end{function}
 %
@@ -1783,7 +1783,7 @@
   {
 %    \end{macrocode}
 %
-% \begin{macro}[EXP]{\@@_e:nn}
+% \begin{macro}[EXP]{\@@_e:nn, \@@_e_end:nn}
 %   Repeatedly expand tokens, keeping track of fully-expanded tokens in
 %   the second argument to \cs{@@_e:nn}; this function eventually
 %   calls \cs{@@_e_end:nn} to leave \cs{exp_end:} in the input
@@ -1790,6 +1790,11 @@
 %   stream, followed by the result of the expansion.  There are many
 %   special cases: spaces, brace groups, \tn{noexpand}, \tn{unexpanded},
 %   \tn{the}, \tn{primitive}.
+%   While we use brace tricks \cs{if_false:} |{| \cs{fi:}, the expansion
+%   of this function is always triggered by \cs{exp:w} so brace balance
+%   is eventually restored after that is hit with a single step of
+%   expansion.  Otherwise we could not nest \texttt{e}-type expansions
+%   within each other.
 %    \begin{macrocode}
     \cs_new:Npn \@@_e:nn #1
       {
@@ -1844,7 +1849,8 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[EXP]{\@@_e:N}
+% \begin{macro}[EXP]
+%   {\@@_e:N, \@@_e:Nnn, \@@_e_protected:Nnn, \@@_e_expandable:Nnn}
 %   For an \texttt{N}-type token, call \cs{@@_e:Nnn} with arguments the
 %   \meta{first token}, the remaining tokens to expand and what's
 %   already been expanded.  If the \meta{first token} is non-expandable,
@@ -1887,15 +1893,75 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[EXP]{\@@_e_primitive:Nnn}
-%   Quite rare.  Will be implemented later.
+% \begin{macro}[EXP]
+%   {
+%     \@@_e_primitive:Nnn,
+%     \@@_e_primitive_aux:NNw,
+%     \@@_e_primitive_aux:NNnn,
+%     \@@_e_primitive_other:NNnn,
+%     \@@_e_primitive_other_aux:nNNnn
+%   }
+%   We don't try hard to make sensible error recovery since the error
+%   recovery of \cs{tex_primitive:D} when followed by something else
+%   than a primitive depends on the engine.  The only valid case is when
+%   what follows is \texttt{N}-type.  Then distinguish special
+%   primitives \tn{unexpanded}, \tn{noexpand}, \tn{the}, \tn{primitive}
+%   from other primitives.  In the \enquote{other} case, the only
+%   reasonable way to check if the primitive that follows
+%   \cs{tex_primitive:D} is expandable is to expand and compare the
+%   before-expansion and after-expansion results.  If they coincide then
+%   probably the primitive is non-expandable and should be put in the
+%   output together with \cs{tex_primitive:D} (one can cook up contrived
+%   counter-examples where the true \tn{expanded} would have an infinite
+%   loop), and otherwise one should continue expanding.
 %    \begin{macrocode}
-    \cs_new:Npn \@@_e_primitive:Nnn #1
+    \cs_new:Npn \@@_e_primitive:Nnn #1#2
       {
-        \__kernel_msg_expandable_error:nnn { kernel } { e-type }
-          { \primitive not~implemented }
-        \@@_e:nn
+        \if_false: { \fi:
+          \tl_if_head_is_N_type:nTF {#2}
+            { \@@_e_primitive_aux:NNw #1 }
+            {
+              \__kernel_msg_expandable_error:nnn { kernel } { e-type }
+                { Missing~primitive~name }
+              \@@_e_primitive_aux:NNw #1 \c_empty_tl
+            }
+          #2
+        }
       }
+    \cs_new:Npn \@@_e_primitive_aux:NNw #1#2
+      {
+        \exp_after:wN \@@_e_primitive_aux:NNnn
+        \exp_after:wN #1
+        \exp_after:wN #2
+        \exp_after:wN { \if_false: } \fi:
+      }
+    \cs_new:Npn \@@_e_primitive_aux:NNnn #1#2
+      {
+        \exp_args:Nf \str_case_e:nnTF { \cs_to_str:N #2 }
+          {
+            { unexpanded } { \@@_e_unexpanded:Nnn \exp_not:n }
+            { noexpand } { \@@_e_noexpand:Nnn \exp_not:N }
+            { the } { \@@_e_the:Nnn \tex_the:D }
+            {
+              \sys_if_engine_xetex:T { pdf }
+              \sys_if_engine_luatex:T { pdf }
+              primitive
+            } { \@@_e_primitive:Nnn #1 }
+          }
+          { \@@_e_primitive_other:NNnn #1 #2 }
+      }
+    \cs_new:Npn \@@_e_primitive_other:NNnn #1#2#3
+      {
+        \exp_args:No \@@_e_primitive_other_aux:nNNnn
+          { #1 #2 #3 }
+          #1 #2 {#3}
+      }
+    \cs_new:Npn \@@_e_primitive_other_aux:nNNnn #1#2#3#4#5
+      {
+        \str_if_eq:nnTF {#1} { #2 #3 #4 }
+          { \@@_e:nn {#4} { #5 #2 #3 } }
+          { \@@_e:nn {#1} {#5} }
+      }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1937,10 +2003,10 @@
 %   braces), unless that \meta{token} is \cs{scan_stop:} or a space
 %   (recall that we don't implement the case of an implicit begin-group
 %   token).  An expandable \meta{token} is instead expanded, unless it
-%   is \tn{noexpand}.  That primitive can be followed by an expandable
-%   \texttt{N}-type token, to be removed, by a non-expandable one, kept
-%   (and later causing an error), by a space, removed by
-%   \texttt{f}-expansion, or by a brace group or nothing (later causing
+%   is \tn{noexpand}.  The latter primitive can be followed by an expandable
+%   \texttt{N}-type token (removed), by a non-expandable one (kept
+%   and later causing an error), by a space (removed by
+%   \texttt{f}-expansion), or by a brace group or nothing (later causing
 %   an error).
 %    \begin{macrocode}
     \cs_new:Npn \@@_e_unexpanded:Nnn #1 { \@@_e_unexpanded:nn }
@@ -2098,20 +2164,41 @@
         {
           #1
           \exp_after:wN \@@_e_the_toks:n
+          \exp_after:wN { \if_false: } \fi:
         }
-        { \exp_after:wN ; }
-        \exp_after:wN { \if_false: } \fi:
+        {
+          \exp_after:wN ;
+          \exp_after:wN { \if_false: } \fi: #1
+        }
       }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_e_if_toks_register:NTF}
-%   We need to detect both \tn{toks} registers like \tn{toks@} (in
-%   \LaTeXe{}) and parameters such as \tn{everypar}, as the result of
-%   unpacking the register should not expand further.  The list of
-%   parameters is finite so we just use a \cs{cs_if_exist:cTF} test to
-%   look up in a table.  Registers are found by
-%   \cs{token_if_toks_register:NTF} by inspecting the meaning.  We abuse
+% \begin{macro}[EXP]
+%   {
+%     \@@_e_the_XeTeXinterchartoks:,
+%     \@@_e_the_errhelp:,
+%     \@@_e_the_everycr:,
+%     \@@_e_the_everydisplay:,
+%     \@@_e_the_everyeof:,
+%     \@@_e_the_everyhbox:,
+%     \@@_e_the_everyjob:,
+%     \@@_e_the_everymath:,
+%     \@@_e_the_everypar:,
+%     \@@_e_the_everyvbox:,
+%     \@@_e_the_output:,
+%     \@@_e_the_pdfpageattr:,
+%     \@@_e_the_pdfpageresources:,
+%     \@@_e_the_pdfpagesattr:,
+%     \@@_e_the_pdfpkmode:
+%   }
+%   We need to detect both \tn{toks} registers like \tn{toks@} in
+%   \LaTeXe{} and parameters such as \tn{everypar}, as the result of
+%   unpacking the register should not expand further.  Registers are
+%   found by \cs{token_if_toks_register:NTF} by inspecting the meaning.
+%   The list of parameters is finite so we just use a
+%   \cs{cs_if_exist:cTF} test to look up in a table.  We abuse
 %   \cs{cs_to_str:N}'s ability to remove a leading escape character
 %   whatever it is.
 %    \begin{macrocode}
@@ -2145,6 +2232,7 @@
     \cs_new_eq:NN \@@_e_the_pdfpkmode: ?
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % We are done emulating \texttt{e}-type argument expansion when
 % \tn{expanded} is unavailable.

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -164,9 +164,10 @@
 %
 % \subsection{Reading from files}
 %
-% \begin{function}[added = 2012-06-24]{\ior_get:NN}
+% \begin{function}[noTF, added = 2012-06-24, updated = 2019-02-17]{\ior_get:NN}
 %   \begin{syntax}
 %     \cs{ior_get:NN} \meta{stream} \meta{token list variable}
+%     \cs{ior_get:NNTF} \meta{stream} \meta{token list variable} \meta{true code} \meta{false code}
 %   \end{syntax}
 %   Function that reads one or more lines (until an equal number of left
 %   and right braces are found) from the input \meta{stream} and stores
@@ -191,6 +192,8 @@
 %   \end{verbatim}
 %   Also notice that if multiple lines are read to match braces
 %   then the resulting token list can contain \cs{par} tokens.
+%   In the non-branching version, where the file is not found the \meta{tl var}
+%   is set to \cs{q_no_value}.
 %   \begin{texnote}
 %     This protected macro is a wrapper around the \TeX{} primitive
 %     \tn{read}.  Regardless of settings, \TeX{} replaces trailing space
@@ -203,9 +206,11 @@
 %   \end{texnote}
 % \end{function}
 %
-% \begin{function}[added = 2016-12-04]{\ior_str_get:NN}
+% \begin{function}[noTF, added = 2016-12-04, updated = 2019-02-17]
+%   {\ior_str_get:NN}
 %   \begin{syntax}
 %     \cs{ior_str_get:NN} \meta{stream} \meta{token list variable}
+%     \cs{ior_str_get:NNTF} \meta{stream} \meta{token list variable} \meta{true code} \meta{false code}
 %   \end{syntax}
 %   Function that reads one line from the input \meta{stream} and stores
 %   the result locally in the \meta{token list} variable. If the
@@ -223,6 +228,8 @@
 %   \end{verbatim}
 %   results in a token list |a b  c| with the letters |a|, |b|, and |c|
 %   having category code~12.
+%   In the non-branching version, where the file is not found the \meta{tl var}
+%   is set to \cs{q_no_value}.
 %   \begin{texnote}
 %     This protected macro is a wrapper around the \eTeX{} primitive
 %     \tn{readline}.  Regardless of settings, \TeX{} removes trailing
@@ -313,17 +320,17 @@
 %   \end{texnote}
 % \end{function}
 %
-%\begin{function}[updated = 2012-02-10, EXP, pTF]{\ior_if_eof:N}
-%  \begin{syntax}
-%    \cs{ior_if_eof_p:N} \meta{stream} \\
-%    \cs{ior_if_eof:NTF} \meta{stream} \Arg{true code} \Arg{false code}
-%  \end{syntax}
-%  Tests if the end of a \meta{stream} has been reached during a reading
-%  operation. The test also returns a \texttt{true} value if
-%  the \meta{stream} is not open.
-%\end{function}
+% \begin{function}[updated = 2012-02-10, EXP, pTF]{\ior_if_eof:N}
+%   \begin{syntax}
+%     \cs{ior_if_eof_p:N} \meta{stream} \\
+%     \cs{ior_if_eof:NTF} \meta{stream} \Arg{true code} \Arg{false code}
+%   \end{syntax}
+%   Tests if the end of a \meta{stream} has been reached during a reading
+%   operation. The test also returns a \texttt{true} value if
+%   the \meta{stream} is not open.
+% \end{function}
 %
-% \section{Writing to files}
+% \subsection{Writing to files}
 %
 % \begin{function}[updated = 2012-06-05]{\iow_now:Nn, \iow_now:Nx, \iow_now:cn, \iow_now:cx}
 %   \begin{syntax}
@@ -592,8 +599,7 @@
 %   \cs{l_file_search_path_seq}.
 % \end{function}
 %
-% \begin{function}[added = 2019-01-16]{\file_get:nnN}
-% \begin{function}[TF, added = 2019-01-16]{\file_get:nnN}
+% \begin{function}[noTF, added = 2019-01-16, updated = 2019-02-16]{\file_get:nnN}
 %   \begin{syntax}
 %     \cs{file_get:nnN} \Arg{filename} \Arg{setup} \meta{tl}
 %     \cs{file_get:nnNTF} \Arg{filename} \Arg{setup} \meta{tl} \Arg{true code} \Arg{false code}
@@ -601,23 +607,25 @@
 %   Defines \meta{tl} to the contents of \meta{filename}.
 %   Category codes may need to be set appropriately via the \meta{setup}
 %   argument.
-%   While \cs{file_get:nnN} produces an error if the file is not found,
-%   \cs{file_get:nnNTF} runs the \meta{true code} (after the assignment
-%   to \meta{tl}) if the file is found and \meta{false code} otherwise.
+%   The non-branching version sets the \meta{tl} to \cs{q_no_value} if the file is
+%   not found. The branching version runs the \meta{true code} after the
+%   assignment to \meta{tl} if the file is found, and \meta{false code}
+%   otherwise.
 % \end{function}
-% \end{function}
 %
-% \begin{function}[updated = 2017-06-26]
+% \begin{function}[noTF, updated = 2019-02-16]
 %   {\file_get_full_name:nN, \file_get_full_name:VN}
 %   \begin{syntax}
-%     \cs{file_get_full_name:nN} \Arg{file name} \meta{str var}
+%     \cs{file_get_full_name:nN} \Arg{file name} \meta{tl}
+%     \cs{file_get_full_name:nNTF} \Arg{file name} \meta{tl} \Arg{true code} \Arg{false code}
 %   \end{syntax}
 %   Searches for \meta{file name} in the path as detailed for
-%   \cs{file_if_exist:nTF}, and if found sets the \meta{str var} the
+%   \cs{file_if_exist:nTF}, and if found sets the \meta{tl var} the
 %   fully-qualified name of the file, \emph{i.e.}~the path and file name.
 %   This includes an extension |.tex| when the given \meta{file name}
 %   has no extension but the file found has that extension.
-%   If the file is not found then the \meta{str var} is empty.
+%   In the non-branching version, the \meta{tl var} will be set to
+%   \cs{q_no_value} in the case that the file does not exist.
 % \end{function}
 %
 % \begin{function}[added = 2017-06-23, updated = 2017-06-26]
@@ -782,10 +790,10 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{variable}{\l_@@_file_name_str}
+% \begin{variable}{\l_@@_file_name_tl}
 %   Data storage.
 %    \begin{macrocode}
-\str_new:N \l_@@_file_name_str
+\tl_new:N \l_@@_file_name_tl
 %    \end{macrocode}
 % \end{variable}
 %
@@ -797,13 +805,12 @@
 %    \begin{macrocode}
 \prg_new_protected_conditional:Npnn \ior_open:Nn #1#2 { T , F , TF }
   {
-    \file_get_full_name:nN {#2} \l_@@_file_name_str
-    \str_if_empty:NTF \l_@@_file_name_str
-      { \prg_return_false: }
+    \file_get_full_name:nNTF {#2} \l_@@_file_name_tl
       {
-        \__kernel_ior_open:No #1 \l_@@_file_name_str
+        \__kernel_ior_open:No #1 \l_@@_file_name_tl
         \prg_return_true:
       }
+      { \prg_return_false: }
   }
 \prg_generate_conditional_variant:Nnn \ior_open:Nn { c } { T , F , TF }
 %    \end{macrocode}
@@ -955,19 +962,35 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\ior_get:NN}
+% \begin{macro}{\ior_get:NN, \@@_get:NN}
+% \begin{macro}[TF]{\ior_get:NN}
 %   And here we read from files.
 %    \begin{macrocode}
 \cs_new_protected:Npn \ior_get:NN #1#2
+  { \ior_get:NNF #1 #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \@@_get:NN #1#2
   { \tex_read:D #1 to #2 }
+\prg_new_protected_conditional:Npnn \ior_get:NN #1#2 { T , F , TF }
+  {
+    \ior_if_eof:NTF #1
+      { \prg_return_false: }
+      {
+        \@@_get:NN #1 #2
+        \prg_return_true:
+      }
+  }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
-% \begin{macro}{\ior_str_get:NN}
+% \begin{macro}{\ior_str_get:NN, \@@_str_get:NN}
+% \begin{macro}[TF]{\ior_str_get:NN}
 %   Reading as strings is a more complicated wrapper, as we wish to
 %   remove the endline character and restore it afterwards.
 %    \begin{macrocode}
 \cs_new_protected:Npn \ior_str_get:NN #1#2
+  { \ior_str_get:NNF #1 #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \@@_str_get:NN #1#2
   {
     \exp_args:Nno \use:n
       {
@@ -976,8 +999,18 @@
         \int_set:Nn \tex_endlinechar:D
       }   { \int_use:N \tex_endlinechar:D }
   }
+\prg_new_protected_conditional:Npnn \ior_str_get:NN #1#2 { T , F , TF }
+  {
+    \ior_if_eof:NTF #1
+      { \prg_return_false: }
+      {
+        \@@_str_get:NN #1 #2
+        \prg_return_true:
+      }
+  }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}[EXP]{\ior_map_break:, \ior_map_break:n}
 %   Usual map breaking functions.
@@ -1001,9 +1034,9 @@
 %   stream has only one \enquote{current line}.
 %    \begin{macrocode}
 \cs_new_protected:Npn \ior_map_inline:Nn
-  { \@@_map_inline:NNn \ior_get:NN }
+  { \@@_map_inline:NNn \@@_get:NN }
 \cs_new_protected:Npn \ior_str_map_inline:Nn
-  { \@@_map_inline:NNn \ior_str_get:NN }
+  { \@@_map_inline:NNn \@@_str_get:NN }
 \cs_new_protected:Npn \@@_map_inline:NNn
   {
     \int_gincr:N \g__kernel_prg_map_int
@@ -1173,10 +1206,10 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{variable}{\l_@@_file_name_str}
+% \begin{variable}{\l_@@_file_name_tl}
 %  Data storage.
 %    \begin{macrocode}
-\str_new:N \l_@@_file_name_str
+\tl_new:N \l_@@_file_name_tl
 %    \end{macrocode}
 % \end{variable}
 %
@@ -1187,10 +1220,10 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \iow_open:Nn #1#2
   {
-    \__kernel_file_name_sanitize:nN {#2} \l_@@_file_name_str
+    \__kernel_file_name_sanitize:nN {#2} \l_@@_file_name_tl
     \iow_close:N #1
     \seq_gpop:NNTF \g_@@_streams_seq \l_@@_stream_tl
-      { \@@_open_stream:NV #1 \l_@@_file_name_str }
+      { \@@_open_stream:NV #1 \l_@@_file_name_tl }
 %<*initex>
       { \__kernel_msg_fatal:nn { kernel } { output-streams-exhausted } }
 %</initex>
@@ -1198,7 +1231,7 @@
       {
         \@@_new:N #1
         \tl_set:Nx \l_@@_stream_tl { \int_eval:n {#1} }
-        \@@_open_stream:NV #1 \l_@@_file_name_str
+        \@@_open_stream:NV #1 \l_@@_file_name_tl
       }
 %</package>
   }
@@ -1332,8 +1365,8 @@
 \cs_set_protected:Npn \iow_term:x { \iow_now:Nx \c_term_iow }
 \cs_new_protected:Npn \iow_term:n { \iow_now:Nn \c_term_iow }
 %    \end{macrocode}
-%\end{macro}
-%\end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \subsubsection{Special characters for writing}
 %
@@ -2092,11 +2125,11 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_base_name_str, \l_@@_full_name_str}
+% \begin{variable}{\l_@@_base_name_tl, \l_@@_full_name_tl}
 %   For storing the basename and full path whilst passing data internally.
 %    \begin{macrocode}
-\str_new:N \l_@@_base_name_str
-\str_new:N \l_@@_full_name_str
+\tl_new:N \l_@@_base_name_tl
+\tl_new:N \l_@@_full_name_tl
 %    \end{macrocode}
 % \end{variable}
 %
@@ -2144,8 +2177,6 @@
           \char_set_active_eq:NN ##1 \l_@@_internal_tl
         }
       \tl_set:Nx \l_@@_internal_tl {#1}
-      \tl_set:Nx \l_@@_internal_tl
-        { \tl_to_str:N \l_@@_internal_tl }
     \exp_args:NNNV \group_end:
     \str_set:Nn #2 \l_@@_internal_tl
   }
@@ -2190,19 +2221,18 @@
 \cs_new_protected:Npn \file_get:nnN #1#2#3
   {
     \file_get:nnNF {#1} {#2} #3
-      { \__kernel_file_missing:n {#1} }
+      { \tl_set:Nn #3 { \q_no_value } }
   }
 \prg_new_protected_conditional:Npnn \file_get:nnN #1#2#3 { T , F , TF }
   {
-    \file_get_full_name:nN {#1} \l_@@_full_name_str
-    \str_if_empty:NTF \l_@@_full_name_str
-      { \prg_return_false: }
+    \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
       {
         \exp_args:NV \@@_get_aux:nnN
-          \l_@@_full_name_str
+          \l_@@_full_name_tl
           {#2} #3
         \prg_return_true:
       }
+      { \prg_return_false: }
   }
 \cs_new_protected:Npn \@@_get_aux:nnN #1#2#3
   {
@@ -2229,6 +2259,7 @@
 % \end{macro}
 %
 % \begin{macro}{\file_get_full_name:nN, \file_get_full_name:VN}
+% \begin{macro}[TF]{\file_get_full_name:nN, \file_get_full_name:VN}
 % \begin{macro}{\@@_get_full_name_search:nN}
 %   The way to test if a file exists is to try to open it: if it does
 %   not exist then \TeX{} reports end-of-file. A search is made
@@ -2242,7 +2273,13 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \file_get_full_name:nN #1#2
   {
-    \__kernel_file_name_sanitize:nN {#1} \l_@@_base_name_str
+    \file_get_full_name:nNF {#1} #2
+      { \tl_set:Nn #2 { \q_no_value } }
+  }
+\cs_generate_variant:Nn \file_get_full_name:nN { V }
+\prg_new_protected_conditional:Npnn \file_get_full_name:nN #1#2 { T , F , TF }
+  {
+    \__kernel_file_name_sanitize:nN {#1} \l_@@_base_name_tl
     \@@_get_full_name_search:nN { } \use:n
     \seq_map_inline:Nn \l_file_search_path_seq
       { \@@_get_full_name_search:nN { ##1 / } \seq_map_break:n }
@@ -2253,35 +2290,43 @@
           { \@@_get_full_name_search:nN { ##1 } \tl_map_break:n }
       }
 %</package>
-    \str_clear:N \l_@@_full_name_str
+    \tl_set:Nn \l_@@_full_name_tl { \q_no_value }
     \prg_break_point:
-    \str_if_empty:NF \l_@@_full_name_str
+    \quark_if_no_value:NTF \l_@@_full_name_tl
       {
-        \exp_args:NV \file_parse_full_name:nNNN \l_@@_full_name_str
+        \ior_close:N \g_@@_internal_ior
+        \prg_return_false:
+      }
+      {
+        \exp_args:NV \file_parse_full_name:nNNN \l_@@_full_name_tl
           \l_@@_dir_str \l_@@_name_str \l_@@_ext_str
         \str_if_empty:NT \l_@@_ext_str
           {
             \__kernel_ior_open:No \g_@@_internal_ior
-              { \l_@@_full_name_str .tex }
+              { \l_@@_full_name_tl .tex }
             \ior_if_eof:NF \g_@@_internal_ior
-              { \str_put_right:Nn \l_@@_full_name_str { .tex } }
+              { \tl_put_right:Nn \l_@@_full_name_tl { .tex } }
           }
+        \ior_close:N \g_@@_internal_ior
+        \tl_set_eq:NN #2 \l_@@_full_name_tl
+        \prg_return_true:
       }
-    \str_set_eq:NN #2 \l_@@_full_name_str
-    \ior_close:N \g_@@_internal_ior
   }
-\cs_generate_variant:Nn \file_get_full_name:nN { V }
+\cs_generate_variant:Nn \file_get_full_name:nNT  { V }
+\cs_generate_variant:Nn \file_get_full_name:nNF  { V }
+\cs_generate_variant:Nn \file_get_full_name:nNTF { V }
 \cs_new_protected:Npn \@@_get_full_name_search:nN #1#2
   {
     \@@_name_quote:nN
-      { \tl_to_str:n {#1} \l_@@_base_name_str }
-      \l_@@_full_name_str
-    \__kernel_ior_open:No \g_@@_internal_ior \l_@@_full_name_str
+      { \tl_to_str:n {#1} \l_@@_base_name_tl }
+      \l_@@_full_name_tl
+    \__kernel_ior_open:No \g_@@_internal_ior \l_@@_full_name_tl
     \ior_if_eof:NF \g_@@_internal_ior { #2 { \prg_break: } }
   }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}[TF]{\file_if_exist:n}
 %   The test for the existence of a file is a wrapper around the function to
@@ -2291,10 +2336,9 @@
 %    \begin{macrocode}
 \prg_new_protected_conditional:Npnn \file_if_exist:n #1 { T , F , TF }
   {
-    \file_get_full_name:nN {#1} \l_@@_full_name_str
-    \str_if_empty:NTF \l_@@_full_name_str
+    \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
+      { \prg_return_true: }
       { \prg_return_false: }
-      { \prg_return_true: }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2304,9 +2348,9 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \__kernel_file_missing:n #1
   {
-    \__kernel_file_name_sanitize:nN {#1} \l_@@_base_name_str
+    \__kernel_file_name_sanitize:nN {#1} \l_@@_base_name_tl
     \__kernel_msg_error:nnx { kernel } { file-not-found }
-      { \l_@@_base_name_str }
+      { \l_@@_base_name_tl }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2323,10 +2367,9 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \file_input:n #1
   {
-    \file_get_full_name:nN {#1} \l_@@_full_name_str
-    \str_if_empty:NTF \l_@@_full_name_str
+    \file_get_full_name:nNTF {#1} \l_@@_full_name_tl
+      { \@@_input:V \l_@@_full_name_tl }
       { \__kernel_file_missing:n {#1} }
-      { \@@_input:V \l_@@_full_name_str }
   }
 \cs_new_protected:Npn \@@_input:n #1
   {
@@ -2491,6 +2534,75 @@
 %</package>
 %    \end{macrocode}
 %
+% \subsection{GetIfInfo}
+%
+% \begin{macro}{\GetIdInfo}
+% \begin{macro}{\@@_id_info_auxi:w, \@@_id_info_auxii:w, \@@_id_info_auxiii:w}
+%   As documented in \pkg{expl3.dtx} this function extracts file name
+%   etc from an \textsc{svn} \texttt{Id} line.  This used to be how we
+%   got version number and so on in all modules, so it had to be defined
+%   in \pkg{l3bootstrap}.  Now it's more convenient to define it after
+%   we have set up quite a lot of tools, and \pkg{l3file} seems the
+%   least unreasonable place for it.
+%
+%   The idea here is to extract out the information needed from a standard
+%   \textsc{svn} \texttt{Id} line, but to avoid a line that would get
+%   changed when the file is checked in. Hence the fact that none of the
+%   lines here include both a dollar sign and the \texttt{Id} keyword!
+%    \begin{macrocode}
+\cs_new_protected:Npn \GetIdInfo
+  {
+    \group_begin:
+    \char_set_catcode_space:n { 32 }
+    \exp_after:wN
+    \group_end:
+    \@@_id_info_auxi:w
+  }
+%    \end{macrocode}
+%   A first check for a completely empty \textsc{svn} field. If that is
+%   not the case, there is a second case when a file created using
+%   \texttt{svn cp} but has not been checked in. That leaves a special
+%   marker \texttt{-1} version, which has no further data. Dealing
+%   correctly with that is the reason for the space in the line to use
+%   \cs{@@_id_info_auxii:w}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_id_info_auxi:w $ #1 $ #2
+  {
+    \tl_set:Nn \ExplFileDescription {#2}
+    \str_if_eq:nnTF {#1} { Id }
+      {
+        \tl_set:Nn \ExplFileDate { 0000/00/00 }
+        \tl_set:Nn \ExplFileName { [unknown] }
+        \tl_set:Nn \ExplFileExtension { [unknown~extension] }
+        \tl_set:Nn \ExplFileVersion {-1}
+      }
+      { \@@_id_info_auxii:w #1 ~ \q_stop }
+  }
+%    \end{macrocode}
+%   Here, |#1| is |Id|, |#2| is the file name, |#3| is the extension,
+%   |#4| is the version, |#5| is the check in date and |#6| is the check
+%   in time and user, plus some trailing spaces. If |#4| is the marker
+%   |-1| value then |#5| and |#6| are empty.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_id_info_auxii:w
+    #1 ~ #2.#3 ~ #4 ~ #5 ~ #6 \q_stop
+  {
+    \tl_set:Nn \ExplFileName {#2}
+    \tl_set:Nn \ExplFileExtension {#3}
+    \tl_set:Nn \ExplFileVersion {#4}
+    \str_if_eq:nnTF {#4} {-1}
+      { \tl_set:Nn \ExplFileDate { 0000/00/00 } }
+      { \@@_id_info_auxiii:w #5 - 0 - 0 - \q_stop }
+  }
+%    \end{macrocode}
+%   Convert an \textsc{svn}-style date into a \LaTeX{}-style one.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_id_info_auxiii:w #1 - #2 - #3 - #4 \q_stop
+  { \tl_set:Nn \ExplFileDate { #1/#2/#3 } }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Messages}
 %
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3final.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3final.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3final.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 % \maketitle
 %
 % \begin{documentation}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -1156,7 +1156,7 @@
 %     \@@_small_int_test:NnnwNTF
 %   }
 %   Tests if the floating point argument is an integer or $\pm\infty$.
-%   If so, it is converted to an integer in the range $[-10^{8},10^{8}]$
+%   If so, it is clipped to an integer in the range $[-10^{8},10^{8}]$
 %   and fed as a braced argument to the \meta{true code}.
 %   Otherwise, the \meta{false code} is performed.
 %
@@ -1207,37 +1207,6 @@
 % \end{macro}
 % \end{macro}
 %
-% \subsection{\texttt{x}-like expansion expandably}
-%
-% \begin{macro}[EXP]{\@@_expand:n}
-% \begin{macro}[EXP]{\@@_expand_loop:nwnN}
-%   This expandable function behaves in a way somewhat similar to
-%   \cs{use:x}, but much less robust.  The argument is
-%   \texttt{f}-expanded, then the leading item (often a single character
-%   token) is moved to a storage area after \cs{s_@@_mark}, and
-%   \texttt{f}-expansion is applied again, repeating until the argument
-%   is empty.  The result built one piece at a time is then inserted in
-%   the input stream.  Note that spaces are ignored by this procedure,
-%   unless surrounded with braces.  Multiple tokens which do not need
-%   expansion can be inserted within braces.
-%    \begin{macrocode}
-\cs_new:Npn \@@_expand:n #1
-  {
-    \@@_expand_loop:nwnN { }
-      #1 \prg_do_nothing:
-      \s_@@_mark { } \@@_expand_loop:nwnN
-      \s_@@_mark { } \@@_use_i_until_s:nw ;
-  }
-\cs_new:Npn \@@_expand_loop:nwnN #1#2 \s_@@_mark #3 #4
-  {
-    \exp_after:wN #4 \exp:w \exp_end_continue_f:w
-    #2
-    \s_@@_mark { #3 #1 } #4
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
 % \subsection{Fast string comparison}
 %
 % \begin{macro}{\@@_str_if_eq:nn}
@@ -1247,10 +1216,9 @@
 %   No \pkg{l3sys} or \pkg{l3luatex} just yet so we have to define in terms of
 %   primitives.
 %    \begin{macrocode}
-\cs_new:Npn \@@_str_if_eq:nn #1#2 { \tex_strcmp:D {#1} {#2} }
-\sys_if_engine_luatex:T
+\sys_if_engine_luatex:TF
   {
-    \cs_set:Npn \@@_str_if_eq:nn #1#2
+    \cs_new:Npn \@@_str_if_eq:nn #1#2
       {
         \tex_directlua:D
           {
@@ -1262,6 +1230,7 @@
           }
       }
   }
+  { \cs_new_eq:NN \@@_str_if_eq:nn \tex_strcmp:D }
 %    \end{macrocode}
 % \end{macro}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -592,26 +592,19 @@
   {
     \tl_if_empty:nF {#1}
       {
-        \@@_expand:n
+        \exp_last_unbraced:Ne \use_ii:nn
           {
-            { \use_ii:nn }
             \@@_array_to_clist_loop:Nw #1 { ? \prg_break: } ;
             \prg_break_point:
           }
       }
   }
-\cs_new:Npx \@@_array_to_clist_loop:Nw #1#2;
+\cs_new:Npn \@@_array_to_clist_loop:Nw #1#2;
   {
-    \exp_not:N \use_none:n #1
-    \exp_not:N \exp_after:wN
-                 {
-    \exp_not:N     \exp_after:wN ,
-    \exp_not:N     \exp_after:wN \c_space_tl
-    \exp_not:N     \exp:w
-    \exp_not:N     \exp_end_continue_f:w
-    \exp_not:N     \@@_to_tl_dispatch:w #1 #2 ;
-                 }
-    \exp_not:N \@@_array_to_clist_loop:Nw
+    \use_none:n #1
+    , ~
+    \exp_not:f { \@@_to_tl_dispatch:w #1 #2 ; }
+    \@@_array_to_clist_loop:Nw
   }
 %    \end{macrocode}
 % \end{macro}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -64,6 +64,7 @@
 %   {
 %     \@@_parse_word_exp:N   ,
 %     \@@_parse_word_ln:N    ,
+%     \@@_parse_word_fact:N,
 %   }
 %   Unary functions.
 %    \begin{macrocode}
@@ -71,6 +72,8 @@
   { \@@_parse_unary_function:NNN \@@_exp_o:w ? }
 \cs_new:Npn \@@_parse_word_ln:N
   { \@@_parse_unary_function:NNN \@@_ln_o:w ? }
+\cs_new:Npn \@@_parse_word_fact:N
+  { \@@_parse_unary_function:NNN \@@_fact_o:w ? }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1247,7 +1250,125 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \subsection{Factorial}
+%
+% \begin{variable}{\c_@@_fact_max_arg_int}
+%   The maximum integer whose factorial fits in the exponent range is
+%   $3248$, as $3249!\sim 10^{10000.8}$
 %    \begin{macrocode}
+\int_const:Nn \c_@@_fact_max_arg_int { 3248 }
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\@@_fact_o:w}
+%   First detect $\pm 0$ and $+\infty$ and \texttt{nan}.  Then note that
+%   factorial of anything with a negative sign (except $-0$) is
+%   undefined.  Then call \cs{@@_small_int:wTF} to get an integer as the
+%   argument, and start a loop.  This is not the most efficient way of
+%   computing the factorial, but it works all right.  Of course we work
+%   with $24$ digits instead of~$16$.  It is easy to check that
+%   computing factorials with this precision is enough.
+%    \begin{macrocode}
+\cs_new:Npn \@@_fact_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+  {
+    \if_case:w #2 \exp_stop_f:
+      \@@_case_return_o:Nw \c_one_fp
+    \or:
+    \or:
+      \if_meaning:w 0 #3
+        \exp_after:wN \@@_case_return_same_o:w
+      \fi:
+    \or:
+      \@@_case_return_same_o:w
+    \fi:
+    \if_meaning:w 2 #3
+      \@@_case_use:nw { \@@_invalid_operation_o:fw { fact } }
+    \fi:
+    \@@_fact_pos_o:w
+    \s_@@ \@@_chk:w #2 #3 #4 ;
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fact_pos_o:w, \@@_fact_int_o:w}
+%   Then check the input is an integer, and call
+%   \cs{@@_facorial_int_o:n} with that \texttt{int} as an argument.  If
+%   it's too big the factorial overflows.  Otherwise call
+%   \cs{@@_sanitize:Nw} with a positive sign marker~|0| and an integer
+%   expression that will mop up any exponent in the calculation.
+%    \begin{macrocode}
+\cs_new:Npn \@@_fact_pos_o:w #1;
+  {
+    \@@_small_int:wTF #1;
+      { \@@_fact_int_o:n }
+      { \@@_invalid_operation_o:fw { fact } #1; }
+  }
+\cs_new:Npn \@@_fact_int_o:n #1
+  {
+    \if_int_compare:w #1 > \c_@@_fact_max_arg_int
+      \@@_case_return:nw
+        {
+          \exp_after:wN \exp_after:wN \exp_after:wN \@@_overflow:w
+          \exp_after:wN \c_inf_fp
+        }
+    \fi:
+    \exp_after:wN \@@_sanitize:Nw
+    \exp_after:wN 0
+    \int_value:w \@@_int_eval:w
+    \@@_fact_loop_o:w #1 . 4 , { 1 } { } { } { } { } { } ;
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_fact_loop_o:w}
+%   The loop receives an integer |#1| whose factorial we want to
+%   compute, which we progressively decrement, and the result so far as
+%   an extended-precision number |#2| in the form
+%   \meta{exponent}|,|\meta{mantissa}|;|.  The loop goes in steps of two
+%   because we compute |#1*#1-1| as an integer expression (it must fit
+%   since |#1| is at most $3248$), then multiply with the result so far.
+%   We don't need to fill in most of the mantissa with zeros because
+%   \cs{@@_ep_mul:wwwwn} first normalizes the extended precision number
+%   to avoid loss of precision.  When reaching a small enough number
+%   simply use a table of factorials less than $10^8$.  This limit is
+%   chosen because the normalization step cannot deal with larger
+%   integers.
+%    \begin{macrocode}
+\cs_new:Npn \@@_fact_loop_o:w #1 . #2 ;
+  {
+    \if_int_compare:w #1 < 12 \exp_stop_f:
+      \@@_fact_small_o:w #1
+    \fi:
+    \exp_after:wN \@@_ep_mul:wwwwn
+    \exp_after:wN 4 \exp_after:wN ,
+    \exp_after:wN { \int_value:w \@@_int_eval:w #1 * (#1 - 1) }
+    { } { } { } { } { } ;
+    #2 ;
+    {
+      \exp_after:wN \@@_fact_loop_o:w
+      \int_value:w \@@_int_eval:w #1 - 2 .
+    }
+  }
+\cs_new:Npn \@@_fact_small_o:w #1 \fi: #2 ; #3 ; #4
+  {
+    \fi:
+    \exp_after:wN \@@_ep_mul:wwwwn
+    \exp_after:wN 4 \exp_after:wN ,
+    \exp_after:wN
+      {
+        \int_value:w
+        \if_case:w #1 \exp_stop_f:
+        1 \or: 1 \or: 2 \or: 6 \or: 24 \or: 120 \or: 720 \or: 5040
+        \or: 40320 \or: 362880 \or: 3628800 \or: 39916800
+        \fi:
+      } { } { } { } { } { } ;
+    #3 ;
+    \@@_ep_to_float_o:wwN 0
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
 %</initex|package>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 % \maketitle
 %
 % \begin{documentation}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -49,7 +49,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -73,6 +73,7 @@
 %     $x\mathop{\&\&}y$, disjunction $x\mathop{\vert\vert}y$, ternary
 %     operator $x\mathop{?}y\mathop{:}z$.
 %   \item Exponentials: $\exp x$, $\ln x$, $x^y$.
+%   \item Integer factorial: $\operatorname{fact} x$.
 %   \item Trigonometry: $\sin x$, $\cos x$, $\tan x$, $\cot x$, $\sec
 %     x$, $\csc x$ expecting their arguments in radians, and
 %     $\operatorname{sind} x$, $\operatorname{cosd} x$,
@@ -1028,6 +1029,18 @@
 %   If the operand is a tuple, \enquote{invalid operation} occurs.
 % \end{function}
 %
+% \begin{function}[tested = m3fp-expo001]{fact}
+%   \begin{syntax}
+%     \cs{fp_eval:n} \{ |fact(| \meta{fpexpr} |)| \}
+%   \end{syntax}
+%   Computes the factorial of the \meta{fpexpr}.  If the \meta{fpexpr}
+%   is an integer between $-0$ and $3248$ included, the result is finite
+%   and correctly rounded.  Larger positive integers give $+\infty$ with
+%   \enquote{overflow}, while $|fact(|{+\infty}|)|=+\infty$ and
+%   $|fact(nan)|=|nan|$ with no exception.  All other inputs give \nan{}
+%   with the \enquote{invalid operation} exception.
+% \end{function}
+%
 % \begin{function}[tested = m3fp-expo001]{ln}
 %   \begin{syntax}
 %     \cs{fp_eval:n} \{ |ln(| \meta{fpexpr} |)| \}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -63,10 +63,30 @@
 %   \begin{syntax}
 %     \cs{int_eval:n} \Arg{integer expression}
 %   \end{syntax}
-%   Evaluates the \meta{integer expression}, expanding any
-%   integer and token list variables within the \meta{expression}
-%   to their content (without requiring \cs{int_use:N}/\cs{tl_use:N})
-%   and applying the standard mathematical rules. For example both
+%   Evaluates the \meta{integer expression} and leaves the result in the
+%   input stream as an integer denotation: for positive results an
+%   explicit sequence of decimal digits not starting with~\texttt{0},
+%   for negative results \texttt{-}~followed by such a sequence, and
+%   \texttt{0}~for zero.  The \meta{integer expression} should consist,
+%   after expansion, of \texttt{+}, \texttt{-}, \texttt{*}, \texttt{/},
+%   \texttt{(}, \texttt{)} and of course integer operands.  The result
+%   is calculated by applying standard mathematical rules with the
+%   following peculiarities:
+%   \begin{itemize}
+%   \item \texttt{/} denotes division rounded to the closest integer with
+%     ties rounded away from zero;
+%   \item there is an error and the overall expression evaluates to zero
+%     whenever the absolute value of any intermediate result exceeds
+%     $2^{31}-1$, except in the case of scaling operations
+%     $a$\texttt{*}$b$\texttt{/}$c$, for which $a$\texttt{*}$b$ may be
+%     arbitrarily large;
+%   \item parentheses may not appear after unary \texttt{+} or
+%     \texttt{-}, namely placing \texttt{+(} or \texttt{-(} at the start
+%     of an expression or after \texttt{+}, \texttt{-}, \texttt{*},
+%     \texttt{/} or~\texttt{(} leads to an error.
+%   \end{itemize}
+%   Each integer operand can be either an integer variable (with no need
+%   for \cs{int_use:N}) or an integer denotation.  For example both
 %   \begin{verbatim}
 %     \int_eval:n { 5 +  4 * 3 - ( 3 + 4 * 5 ) }
 %   \end{verbatim}
@@ -76,21 +96,27 @@
 %     \tl_set:Nn \l_my_tl { 5 }
 %     \int_new:N  \l_my_int
 %     \int_set:Nn \l_my_int { 4 }
-%    \int_eval:n { \l_my_tl +  \l_my_int * 3 - ( 3 + 4 * 5 ) }
+%     \int_eval:n { \l_my_tl +  \l_my_int * 3 - ( 3 + 4 * 5 ) }
 %   \end{verbatim}
-%   both evaluate to \( -6 \). The  \Arg{integer expression} may
-%   contain the operators \texttt{+}, \texttt{-}, \texttt{*} and
-%   \texttt{/}, along with parenthesis \texttt{(} and \texttt{)}.
-%   Any functions within the expressions should expand to an
-%   \meta{integer denotation}: a sequence of a sign and digits matching
-%   the regex |\-?[0-9]+|).
-%   After expansion \cs{int_eval:n} yields an  \meta{integer denotation}
-%   which is left in the input stream.
+%   evaluate to $-6$ because \cs[no-index]{l_my_tl} expands to the
+%   integer denotation~|5|.  As the \meta{integer expression} is fully
+%   expanded from left to right during evaluation, fully expandable and
+%   restricted-expandable functions can both be used, and \cs{exp_not:n}
+%   and its variants have no effect while \cs{exp_not:N} may incorrectly
+%   interrupt the expression.
 %   \begin{texnote}
 %     Exactly two expansions are needed to evaluate \cs{int_eval:n}.
 %     The result is \emph{not} an \meta{internal integer}, and therefore
 %     requires suitable termination if used in a \TeX{}-style integer
 %     assignment.
+%
+%     As all \TeX{} integers, integer operands can also be dimension or
+%     skip variables, converted to integers in~\texttt{sp}, or octal
+%     numbers given as \texttt{'} followed by digits other than
+%     \texttt{8} and \texttt{9}, or hexadecimal numbers given as
+%     |"| followed by digits or upper case letters from
+%     \texttt{A} to~\texttt{F}, or the character code of some character
+%     or one-character control sequence, given as \texttt{`}\meta{char}.
 %   \end{texnote}
 % \end{function}
 %
@@ -100,9 +126,12 @@
 %   \end{syntax}
 %   Evaluates the \meta{integer expression} as described for
 %   \cs{int_eval:n}. The end of the expression is the first token
-%   encountered that cannot form part of such an expression.
-%   If that token is \cs{scan_stop:} it is removed, otherwise not.
-%   Spaces do \emph{not} terminate the expression.
+%   encountered that cannot form part of such an expression.  If that
+%   token is \cs{scan_stop:} it is removed, otherwise not.  Spaces do
+%   \emph{not} terminate the expression.  However, spaces terminate
+%   explict integers, and this may terminate the expression: for
+%   instance, \cs{int_eval:w} \verb*|1 + 1 9| expands to \texttt{29}
+%   since the digit~\texttt{9} is not part of the expression.
 % \end{function}
 %
 % \begin{function}[EXP, updated = 2012-09-26]{\int_abs:n}
@@ -698,9 +727,13 @@
 %     \cs{int_to_roman:n} \Arg{integer expression}
 %   \end{syntax}
 %   Places the value of the \meta{integer expression} in the input
-%   stream as Roman numerals, either lower case (\cs{int_to_roman:n})
-%   or upper case (\cs{int_to_Roman:n}). The Roman numerals are letters
-%   with category code $11$ (letter).
+%   stream as Roman numerals, either lower case (\cs{int_to_roman:n}) or
+%   upper case (\cs{int_to_Roman:n}).  If the value is negative or zero,
+%   the output is empty.  The Roman numerals are letters with category
+%   code $11$ (letter).  The letters used are |mdclxvi|, repeated as
+%   needed: the notation with bars (such as $\bar{\mbox{v}}$ for $5000$)
+%   is \emph{not} used.  For instance \cs{int_to_roman:n} |{| 8249 |}|
+%   expands to |mmmmmmmmccxlix|.
 % \end{function}
 %
 % \section{Converting from other formats to integers}
@@ -2557,76 +2590,7 @@
 % \end{variable}
 % \end{variable}
 %
-% \subsection{Deprecated}
-%
-% \begin{variable}[deprecated = 2019-12-31]
-%   {
-%     \c_zero, \c_one, \c_two, \c_three, \c_four, \c_five, \c_six,
-%     \c_seven, \c_eight, \c_nine, \c_ten, \c_eleven, \c_twelve,
-%     \c_thirteen, \c_fourteen, \c_fifteen, \c_sixteen, \c_thirty_two,
-%     \c_one_hundred, \c_two_hundred_fifty_five,
-%     \c_two_hundred_fifty_six, \c_one_thousand, \c_ten_thousand,
-%   }
-% \begin{macro}{\@@_deprecated_constants:nn}
-%   Constants that are now deprecated.  By default define them with
-%   \cs{int_const:Nn}.  To deprecate them call for instance
-%   \cs{__kernel_deprecation_error:Nnn} \cs{c_zero} |{0}|
-%   |{2019-12-31}|.  To redefine them (locally), use
-%   \cs{@@_constdef:Nw}, with an \cs{exp_not:N} construction because the
-%   constants themselves are outer at that point.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_deprecated_constants:nn #1#2
-  {
-    #1 \c_zero                   {   0 } #2
-    #1 \c_one                    {   1 } #2
-    #1 \c_two                    {   2 } #2
-    #1 \c_three                  {   3 } #2
-    #1 \c_four                   {   4 } #2
-    #1 \c_five                   {   5 } #2
-    #1 \c_six                    {   6 } #2
-    #1 \c_seven                  {   7 } #2
-    #1 \c_eight                  {   8 } #2
-    #1 \c_nine                   {   9 } #2
-    #1 \c_ten                    {  10 } #2
-    #1 \c_eleven                 {  11 } #2
-    #1 \c_twelve                 {  12 } #2
-    #1 \c_thirteen               {  13 } #2
-    #1 \c_fourteen               {  14 } #2
-    #1 \c_fifteen                {  15 } #2
-    #1 \c_sixteen                {  16 } #2
-    #1 \c_thirty_two             {  32 } #2
-    #1 \c_one_hundred            { 100 } #2
-    #1 \c_two_hundred_fifty_five { 255 } #2
-    #1 \c_two_hundred_fifty_six  { 256 } #2
-    #1 \c_one_thousand         {  1000 } #2
-    #1 \c_ten_thousand         { 10000 } #2
-  }
-\@@_deprecated_constants:nn { \int_const:Nn } { }
-\__kernel_deprecation_code:nn
-  {
-    \@@_deprecated_constants:nn
-      { \__kernel_deprecation_error:Nnn } { { 2019-12-31 } }
-  }
-  {
-    \@@_deprecated_constants:nn
-      {
-        \exp_after:wN \use:nnn
-        \exp_after:wN \@@_constdef:Nw \exp_not:N
-      }
-      { \exp_stop_f: }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{variable}
-%
-% \begin{macro}[deprecated = 2019-12-31]{\@@_value:w}
-%   Made public.
-%    \begin{macrocode}
-\cs_new_eq:NN \@@_value:w \int_value:w
-%    \end{macrocode}
-% \end{macro}
-%
-%    \begin{macrocode}
 %</initex|package>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -404,14 +404,6 @@
 %   because that would interfere with the action of the conditional.
 % \end{function}
 %
-% \begin{function}{\__kernel_patch_deprecation:nnNNpn}
-%   \begin{syntax}
-%     \cs{__kernel_patch_deprecation:nnNNpn} \Arg{before} \Arg{after}
-%     \meta{definition} \meta{function}\meta{parameters} \Arg{type} \Arg{code}
-%   \end{syntax}
-%   Similar to \cs{__kernel_patch:nnNNpn} for deprecated functions.
-% \end{function}
-%
 % \begin{function}
 %   {\__kernel_patch_args:nNNpn, \__kernel_patch_conditional_args:nNNpnn}
 %   \begin{syntax}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -305,16 +305,16 @@
 %   Specifies that the \meta{key} path should inherit the keys listed
 %   as \meta{parents}. For example, after setting
 %   \begin{verbatim}
-%     \keys_define:n { foo } { test .code:n = \tl_show:n {#1} }
-%     \keys_define:n { } { bar .inherit:n = foo }
+%     \keys_define:nn { foo } { test .code:n = \tl_show:n {#1} }
+%     \keys_define:nn { } { bar .inherit:n = foo }
 %   \end{verbatim}
 %   setting
 %   \begin{verbatim}
-%     \keys_set:n { bar } { test = a }
+%     \keys_set:nn { bar } { test = a }
 %   \end{verbatim}
 %   will be equivalent to
 %   \begin{verbatim}
-%     \keys_set:n { foo } { test = a }
+%     \keys_set:nn { foo } { test = a }
 %   \end{verbatim}
 % \end{function}
 %
@@ -2478,14 +2478,10 @@
           \exp_after:wN { \l_keys_value_tl }
       }
       {
-        \bool_if:NTF \l_@@_only_known_bool
-          { \@@_store_unused: }
-          {
-            \cs_if_exist:cTF
-              { \c_@@_inherit_root_tl \@@_parent:o \l_keys_path_tl }
-              { \@@_execute_inherit: }
-              { \@@_execute_unknown: }
-          }
+        \cs_if_exist:cTF
+          { \c_@@_inherit_root_tl \@@_parent:o \l_keys_path_tl }
+          { \@@_execute_inherit: }
+          { \@@_execute_unknown: }
       }
   }
 %    \end{macrocode}
@@ -2512,16 +2508,20 @@
   }
 \cs_new_protected:Npn \@@_execute_unknown:
   {
-    \cs_if_exist:cTF
-      { \c_@@_code_root_tl \l_@@_module_tl / unknown }
+    \bool_if:NTF \l_@@_only_known_bool
+      { \@@_store_unused: }
       {
-        \cs:w \c_@@_code_root_tl \l_@@_module_tl / unknown
-          \exp_after:wN \cs_end: \exp_after:wN { \l_keys_value_tl }
+        \cs_if_exist:cTF
+          { \c_@@_code_root_tl \l_@@_module_tl / unknown }
+          {
+            \cs:w \c_@@_code_root_tl \l_@@_module_tl / unknown
+              \exp_after:wN \cs_end: \exp_after:wN { \l_keys_value_tl }
+          }
+          {
+            \__kernel_msg_error:nnxx { kernel } { key-unknown }
+             { \l_keys_path_tl } { \l_@@_module_tl }
+          }
       }
-      {
-        \__kernel_msg_error:nnxx { kernel } { key-unknown }
-         { \l_keys_path_tl } { \l_@@_module_tl }
-      }
   }
 \cs_new:Npn \@@_execute:nn #1#2
   {
@@ -2536,7 +2536,7 @@
 %   When there is no relative path, things here are easy: just save the key
 %   name and value. When we are working with a relative path, first we
 %   need to turn it into a string: that can't happen earlier as we need
-%   to store |\q_no_value|. Then, use a standard delimited approach to fish
+%   to store \cs{q_no_value}. Then, use a standard delimited approach to fish
 %   out the partial path.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_store_unused:
@@ -2706,7 +2706,7 @@
           {
             \exp_args:Nnf \msg_show_item_unbraced:nn { code }
               {
-                \exp_args:Nc \token_get_replacement_spec:N
+                \exp_args:Nc \cs_replacement_spec:N
                   {
                     \c_@@_code_root_tl
                     \@@_trim_spaces:n { #2 / #3 }

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -279,23 +279,7 @@
   }
 %    \end{macrocode}
 %
-% \subsection{Deprecated functions}
-%
-% \begin{macro}[EXP, deprecated = 2019-12-31]{\lua_now_x:n, \lua_escape_x:n}
-% \begin{macro}[deprecated = 2019-12-31]{\lua_shipout_x:n}
-%   For removal after 2019-12-31.
 %    \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \lua_now:e }
-\cs_new:Npn \lua_now_x:n #1 { \@@_now:n {#1} }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \lua_escape:e }
-\cs_new:Npn \lua_escape_x:n #1 { \@@_escape:n {#1} }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \lua_shipout_e:n }
-\cs_new_protected:Npn \lua_shipout_x:n #1 { \@@_shipout:n {#1} }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-%    \begin{macrocode}
 %</tex>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -1699,11 +1699,6 @@
     LaTeX~has~been~asked~to~use~a~control~sequence~'#1':\\
     this~has~not~been~defined~yet.
   }
-\__kernel_msg_new:nnn { kernel } { deprecated-command }
-  {
-    The~deprecated~command~'#2'~has~been~or~will~be~removed~on~#1.
-    \tl_if_empty:nF {#3} { ~Use~instead~'#3'. }
-  }
 \__kernel_msg_new:nnnn { kernel } { empty-search-pattern }
   { Empty~search~pattern. }
   {
@@ -1757,7 +1752,7 @@
     Only~expandable~tests~can~have~a~predicate~version.
   }
 \__kernel_msg_new:nnn { kernel } { randint-backward-range }
-  { Bounds~ordered~backwards~in~\int_rand:nn {#1}~{#2}. }
+  { Bounds~ordered~backwards~in~\iow_char:N\\int_rand:nn~{#1}~{#2}. }
 \__kernel_msg_new:nnnn { kernel } { conditional-form-unknown }
   { Conditional~form~'#1'~for~function~'#2'~unknown. }
   {
@@ -1923,7 +1918,7 @@
 \__kernel_msg_new:nnn { kernel } { misused-prop }
   { A~property~list~was~misused. }
 \__kernel_msg_new:nnn { kernel } { negative-replication }
-  { Negative~argument~for~\prg_replicate:nn. }
+  { Negative~argument~for~\iow_char:N\\prg_replicate:nn. }
 \__kernel_msg_new:nnn { kernel } { prop-keyval }
   { Missing/extra~'='~in~'#1'~(in~'..._keyval:Nn') }
 \__kernel_msg_new:nnn { kernel } { unknown-comparison }
@@ -2034,15 +2029,21 @@
 %   The command built from the csname
 %   \cs{c_@@_text_prefix_tl} |LaTeX / #1 / #2|
 %   takes four arguments and builds the error text, which is fed to
-%   \cs{@@_expandable_error:n}.
+%   \cs{@@_expandable_error:n} with appropriate expansion: just as for
+%   usual messages the arguments are first turned to strings, then the
+%   message is fully expanded.
 %    \begin{macrocode}
+\exp_args_generate:n { oooo }
 \cs_new:Npn \__kernel_msg_expandable_error:nnnnnn #1#2#3#4#5#6
   {
-    \exp_args:Nf \@@_expandable_error:n
+    \exp_args:Ne \@@_expandable_error:n
       {
-        \exp_args:NNc \exp_after:wN \exp_stop_f:
+        \exp_args:Nc \exp_args:Noooo
           { \c_@@_text_prefix_tl LaTeX / #1 / #2 }
-          {#3} {#4} {#5} {#6}
+          { \tl_to_str:n {#3} }
+          { \tl_to_str:n {#4} }
+          { \tl_to_str:n {#5} }
+          { \tl_to_str:n {#6} }
       }
   }
 \cs_new:Npn \__kernel_msg_expandable_error:nnnnn #1#2#3#4#5
@@ -2072,96 +2073,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[deprecated = 2019-12-31]{\msg_log:n, \msg_term:n}
 %    \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \iow_log:n }
-\cs_new_protected:Npn \msg_log:n #1
-  {
-    \iow_log:n { ................................................. }
-    \iow_wrap:nnnN { . ~ #1} { . ~ } { } \iow_log:n
-    \iow_log:n { ................................................. }
-  }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \iow_term:n }
-\cs_new_protected:Npn \msg_term:n #1
-  {
-    \iow_term:n { ************************************************* }
-    \iow_wrap:nnnN { * ~ #1} { * ~ } { } \iow_term:n
-    \iow_term:n { ************************************************* }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[deprecated = 2019-12-31]{\msg_interrupt:nnn}
-%    \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { [Defined~error~message] }
-\cs_new_protected:Npn \msg_interrupt:nnn #1#2#3
-  {
-    \tl_if_empty:nTF {#3}
-      {
-        \@@_old_interrupt_wrap:nn { \\ \c_@@_no_info_text_tl }
-          {#1 \\\\ #2 \\\\ \c_@@_continue_text_tl }
-      }
-      {
-        \@@_old_interrupt_wrap:nn { \\ #3 }
-          {#1 \\\\ #2 \\\\ \c_@@_help_text_tl }
-      }
-  }
-\cs_new_protected:Npn \@@_old_interrupt_wrap:nn #1#2
-  {
-    \iow_wrap:nnnN {#1} { | ~ } { } \@@_old_interrupt_more_text:n
-    \iow_wrap:nnnN {#2} { ! ~ } { } \@@_old_interrupt_text:n
-  }
-\cs_new_protected:Npn \@@_old_interrupt_more_text:n #1
-  {
-    \exp_args:Nx \tex_errhelp:D
-      {
-        |'''''''''''''''''''''''''''''''''''''''''''''''
-        #1 \iow_newline:
-        |...............................................
-      }
-  }
-\group_begin:
-  \char_set_lccode:nn {`\{} {`\ }
-  \char_set_lccode:nn {`\}} {`\ }
-  \char_set_lccode:nn {`\&} {`\!}
-  \char_set_catcode_active:N \&
-\tex_lowercase:D
-  {
-    \group_end:
-    \cs_new_protected:Npn \@@_old_interrupt_text:n #1
-      {
-        \iow_term:x
-          {
-            \iow_newline:
-            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-            \iow_newline:
-            !
-          }
-        \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J }
-          {
-            \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 }
-              {
-                \group_begin:
-                  \cs_set_protected:Npn &
-                    {
-                      \tex_errmessage:D
-                        {
-                          #1
-                          \use_none:n
-                            { ............................................ }
-                        }
-                    }
-                  \exp_after:wN
-                \group_end:
-                &
-              }
-          }
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-%    \begin{macrocode}
 %</initex|package>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -1616,48 +1616,7 @@
 % \end{macro}
 % \end{macro}
 %
-% \subsection{Deprecated functions}
-%
-% \begin{macro}[deprecated = 2019-12-31]{\@@_break_point:Nn}
-% \begin{macro}[deprecated = 2019-12-31]{\@@_break_point:}
-% \begin{macro}[deprecated = 2019-12-31]{\@@_map_break:Nn}
-% \begin{macro}[deprecated = 2019-12-31]{\@@_break:}
-% \begin{macro}[deprecated = 2019-12-31]{\@@_break:n}
-%   Made public, but used by a few third-parties.  It's not possible to
-%   perfectly support a mixture of \cs{@@_map_break:Nn} and
-%   \cs{prg_map_break:Nn} because they use different delimiters.  The
-%   following code only breaks if someone tries to break from two
-%   \enquote{old-style} \cs{@@_map_break:Nn} \ldots{}
-%   \cs{@@_break_point:Nn} mappings in one go.  Basically, the
-%   \cs{@@_map_break:Nn} converts a single \cs{@@_break_point:Nn} to
-%   \cs{prg_break_point:Nn}, and that delimiter had better be the right
-%   one.  Then we call \cs{prg_map_break:Nn} which may end up breaking
-%   intermediate looks in the (unbraced) argument |#1|.  It is essential
-%   to define the |break_point| functions before the corresponding
-%   |break| functions: otherwise \cs{debug_on:n} |{deprecation}|
-%   \cs{debug_off:n} |{deprecation}| would break when trying to restore
-%   the definitions because they would involve deprecated commands whose
-%   definition has not yet been restored.
 %    \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break_point:Nn }
-\cs_new:Npn \@@_break_point:Nn { \prg_break_point:Nn }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break_point: }
-\cs_new:Npn \@@_break_point: { \prg_break_point: }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_map_break:Nn }
-\cs_new:Npn \@@_map_break:Nn #1 \@@_break_point:Nn
-  { \prg_map_break:Nn #1 \prg_break_point:Nn }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break: }
-\cs_new:Npn \@@_break: #1 \@@_break_point: { }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break:n }
-\cs_new:Npn \@@_break:n #1#2 \@@_break_point: {#1}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%    \begin{macrocode}
 %</initex|package>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -216,6 +216,14 @@
 %   \end{texnote}
 % \end{function}
 %
+% \begin{function}[EXP]{\prop_count:N, \prop_count:c}
+%   \begin{syntax}
+%     \cs{prop_count:N} \meta{property list}
+%   \end{syntax}
+%   Leaves the number of key--value pairs in the \meta{property list} in
+%   the input stream as an \meta{integer denotation}.
+% \end{function}
+%
 % \section{Modifying property lists}
 %
 % \begin{function}[added = 2012-05-12]
@@ -872,6 +880,27 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}[EXP]{\prop_count:N, \prop_count:c}
+% \begin{macro}[EXP]{\@@_count:nn}
+%   Counting the key--value pairs in a property list is done using the
+%   same approach as for other count functions: turn each entry into a
+%   \texttt{+1} then use integer evaluation to actually do the
+%   mathematics.
+%    \begin{macrocode}
+\cs_new:Npn \prop_count:N #1
+  {
+    \int_eval:n
+      {
+        0
+        \prop_map_function:NN #1 \@@_count:nn
+      }
+  }
+\cs_new:Npn \@@_count:nn #1#2 { + 1 }
+\cs_generate_variant:Nn \prop_count:N { c }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \begin{macro}[TF, tested = m3prop004]
 %   {\prop_pop:NnN, \prop_pop:cnN, \prop_gpop:NnN, \prop_gpop:cnN}
 %   Popping an item from a property list, keeping track of whether

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -742,7 +742,7 @@
 %   ~~~~~~\meta{extra arguments}\\
 %   ~~|}|\\
 %   \cs{@@_loop:wNn}~\ldots{}~\meta{prepared tokens}\\
-%   ~~\meta{end-loop}~|{}|~|\q_stop|
+%   ~~\meta{end-loop}~|{}|~\cs{q_stop}
 % \end{quote}
 % In this example, which matches the structure of
 % \cs{@@_quick_split_i:NnnnnNn} and a few other functions below, the

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -791,6 +791,14 @@
 %   Displays the content of the \meta{str~var} on the terminal.
 % \end{function}
 %
+% \begin{function}[added = 2019-02-15]
+%   {\str_log:N, \str_log:c, \str_log:n}
+%   \begin{syntax}
+%     \cs{str_log:N} \meta{str~var}
+%   \end{syntax}
+%   Writes the content of the \meta{str~var} in the log file.
+% \end{function}
+%
 % \section{Constant token lists}
 %
 % \begin{variable}[added = 2015-09-19]
@@ -1942,39 +1950,18 @@
 % \subsection{Viewing strings}
 %
 % \begin{macro}{\str_show:n, \str_show:N, \str_show:c}
+% \begin{macro}{\str_log:n, \str_log:N, \str_log:c}
 %   Displays a string on the terminal.
 %    \begin{macrocode}
 \cs_new_eq:NN \str_show:n \tl_show:n
 \cs_new_eq:NN \str_show:N \tl_show:N
 \cs_generate_variant:Nn \str_show:N { c }
+\cs_new_eq:NN \str_log:n \tl_log:n
+\cs_new_eq:NN \str_log:N \tl_log:N
+\cs_generate_variant:Nn \str_log:N { c }
 %    \end{macrocode}
 % \end{macro}
-%
-% \subsection{Deprecated functions}
-%
-% \begin{macro}[EXP, deprecated = 2019-12-31, noTF]{\str_case_x:nn}
-% \begin{macro}[EXP, deprecated = 2019-12-31, pTF]{\str_if_eq_x:nn}
-%   For removal after 2019-12-31.
-%    \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nn }
-\cs_new:Npn \str_case_x:nn { \str_case_e:nn }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nnT }
-\cs_new:Npn \str_case_x:nnT { \str_case_e:nnT }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nnF }
-\cs_new:Npn \str_case_x:nnF { \str_case_e:nnF }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nnTF }
-\cs_new:Npn \str_case_x:nnTF { \str_case_e:nnTF }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq_p:ee }
-\cs_new:Npn \str_if_eq_x_p:nn { \str_if_eq_p:ee }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq:eeT }
-\cs_new:Npn \str_if_eq_x:nnT { \str_if_eq:eeT }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq:eeF }
-\cs_new:Npn \str_if_eq_x:nnF { \str_if_eq:eeF }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq:eeTF }
-\cs_new:Npn \str_if_eq_x:nnTF { \str_if_eq:eeTF }
-%    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 %    \begin{macrocode}
 %</initex|package>

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -1094,24 +1094,7 @@
   }
 %    \end{macrocode}
 %
-% \subsection{Deprecated functions}
-%
-% \begin{macro}[deprecated = 2019-12-31]
-%   {\tl_show_analysis:N, \tl_show_analysis:n}
-%   Simple renames.
 %    \begin{macrocode}
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 }
-  { \tl_analysis_show:N }
-\cs_new_protected:Npn \tl_show_analysis:N #1
-  { \tl_analysis_show:N #1 }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 }
-  { \tl_analysis_show:n }
-\cs_new_protected:Npn \tl_show_analysis:n #1
-  { \tl_analysis_show:n {#1} }
-%    \end{macrocode}
-% \end{macro}
-%
-%    \begin{macrocode}
 %</initex|package>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -700,6 +700,16 @@
 %   giving an \meta{integer denotation}.
 % \end{function}
 %
+% \begin{function}[EXP, added = 2019-02-25]{\tl_count_tokens:n}
+%   \begin{syntax}
+%     \cs{tl_count_tokens:n} \Arg{tokens}
+%   \end{syntax}
+%   Counts the number of \TeX{} tokens in the \meta{tokens} and leaves
+%   this information in the input stream. Every token, including spaces and
+%   braces, contributes one to the total; thus for instance, the token count of
+%   |a~{bc}| is $6$.
+% \end{function}
+%
 % \begin{function}[updated = 2012-01-08, EXP]
 %   {\tl_reverse:n, \tl_reverse:V, \tl_reverse:o}
 %   \begin{syntax}
@@ -822,7 +832,7 @@
 %   \begin{texnote}
 %     The result is returned within \cs{exp_not:n}, which means that the
 %     token list does not expand further when appearing in an
-%     \texttt{x}-type argument expansion.
+%     \texttt{x}-type or \texttt{e}-type argument expansion.
 %   \end{texnote}
 % \end{function}
 %
@@ -1149,7 +1159,7 @@
 %
 % \begin{variable}[added = 2017-11-14]{\c_novalue_tl}
 %   A marker for the absence of an argument. This constant |tl| can safely
-%   be typeset (\emph{cf.}~|\q_nil|), with the result being |-NoValue-|.
+%   be typeset (\emph{cf.}~\cs{q_nil}), with the result being |-NoValue-|.
 %   It is important to note that \cs{c_novalue_tl} is constructed such that it
 %   will \emph{not} match the simple text input |-NoValue-|, \emph{i.e.}
 %   that
@@ -1571,6 +1581,10 @@
 %
 %   The two \cs{if_false:} \ldots{} \cs{fi:} are there to prevent
 %   alignment tabs to cause a change of tabular cell while rescanning.
+%   We put the \enquote{opening} one after \cs{group_begin:} so that if
+%   one accidentally \texttt{f}-expands \cs{tl_set_rescan:Nnn} braces
+%   remain balanced.  This is essential in \texttt{e}-type arguments
+%   when \tn{expanded} is not available.
 %    \begin{macrocode}
 \cs_new_protected:Npn \tl_set_rescan:Nnn
   { \@@_set_rescan:NNnn \tl_set:No }
@@ -1584,8 +1598,8 @@
   }
 \cs_new_protected:Npn \@@_set_rescan:NNnn #1#2#3#4
   {
-    \if_false: { \fi:
     \group_begin:
+      \if_false: { \fi:
       \int_set_eq:NN \tex_tracingnesting:D \c_zero_int
       \exp_args:No \tex_everyeof:D { \c_@@_rescan_marker_tl }
       \int_compare:nNnT \tex_endlinechar:D = { 32 }
@@ -1804,7 +1818,7 @@
 %   \meta{pattern}~|#6| then we can use it as the \meta{delimiter}
 %   through \cs{@@_replace_auxii:nNNNnn} |{#1}|.  Otherwise, we end up
 %   calling \cs{@@_replace:NnNNNnn} repeatedly with the first two
-%   arguments |\q_mark| |{?}|, |\?| |{??}|, |\??| |{???}|, and so on,
+%   arguments \cs{q_mark} |{?}|, |\?| |{??}|, |\??| |{???}|, and so on,
 %   until |#6|~does not contain the control sequence~|#1|, which we take
 %   as our~\meta{A}.  The argument~|#2| only serves to collect~|?|
 %   characters for~|#1|.  Note that the order of the tests means that
@@ -2126,9 +2140,12 @@
 %   groups makes the test work also for empty arguments.
 %   The \cs{if_false:} constructions are a faster way to do
 %   \cs{group_align_safe_begin:} and \cs{group_align_safe_end:}.
+%   The \cs{scan_stop:} ensures that \texttt{f}-expanding
+%   \cs{tl_if_in:nn} does not lead to unbalanced braces.
 %    \begin{macrocode}
 \prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 { T  , F , TF }
   {
+    \scan_stop:
     \if_false: { \fi:
     \cs_set:Npn \@@_tmp:w ##1 #2 { }
     \tl_if_empty:oTF { \@@_tmp:w #1 {} {} #2 }
@@ -2427,6 +2444,36 @@
 % \end{macro}
 % \end{macro}
 %
+%
+% \begin{macro}[EXP]{\tl_count_tokens:n}
+% \begin{macro}[EXP]{\@@_act_count_normal:nN,
+%     \@@_act_count_group:nn, \@@_act_count_space:n}
+%   The token count is computed through an \cs{int_eval:n} construction.
+%   Each \texttt{1+} is output to the \emph{left}, into the integer
+%   expression, and the sum is ended by the \cs{exp_end:} inserted by
+%   \cs{@@_act_end:wn} (which is technically implemented as  \cs{c_zero_int}).
+%   Somewhat a hack!
+%    \begin{macrocode}
+\cs_new:Npn \tl_count_tokens:n #1
+  {
+    \int_eval:n
+      {
+        \@@_act:NNNnn
+          \@@_act_count_normal:nN
+          \@@_act_count_group:nn
+          \@@_act_count_space:n
+          { }
+          {#1}
+      }
+  }
+\cs_new:Npn \@@_act_count_normal:nN #1 #2 { 1 + }
+\cs_new:Npn \@@_act_count_space:n #1 { 1 + }
+\cs_new:Npn \@@_act_count_group:nn #1 #2
+  { 2 + \tl_count_tokens:n {#2} + }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \begin{macro}{\tl_reverse_items:n}
 % \begin{macro}{\@@_reverse_items:nwNwn}
 % \begin{macro}{\@@_reverse_items:wn}
@@ -2945,13 +2992,11 @@
 % \end{macro}
 %
 % \begin{macro}[EXP,pTF]{\tl_if_head_is_group:n}
-%   Pass the first token of |#1| through \cs{token_to_str:N},
-%   then check for the brace balance. The extra \texttt{?}
-%   caters for an empty argument.\footnote{Bruno: this could
-%     be made faster, but we don't: if we hope to ever have
-%     an e-type argument, we need all brace \enquote{tricks}
-%     to happen in one step of expansion, keeping the token
-%     list brace balanced at all times.}
+%   Pass the first token of |#1| through \cs{token_to_str:N}, then check
+%   for the brace balance.  The extra \texttt{?} caters for an empty
+%   argument.  This could be made faster, but we need all brace tricks
+%   to happen in one step of expansion, keeping the token list brace
+%   balanced at all times.
 %    \begin{macrocode}
 \prg_new_conditional:Npnn \tl_if_head_is_group:n #1 { p , T , F , TF }
   {

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -931,66 +931,6 @@
 %   (as appropriate to the result of the test).
 % \end{function}
 %
-% \section{Decomposing a macro definition}
-%
-% These functions decompose \TeX{} macros into their constituent
-% parts: if the \meta{token} passed is not a macro then no decomposition
-% can occur. In the latter case, all three functions leave \cs{scan_stop:}
-% in the input stream.
-%
-% \begin{function}[EXP]{\token_get_arg_spec:N}
-%   \begin{syntax}
-%     \cs{token_get_arg_spec:N} \meta{token}
-%   \end{syntax}
-%   If the \meta{token} is a macro, this function leaves
-%   the primitive \TeX{} argument specification in input stream as
-%   a string of tokens of category code $12$ (with spaces having category
-%   code $10$). Thus for example for a token \cs{next} defined by
-%   \begin{verbatim}
-%     \cs_set:Npn \next #1#2 { x #1 y #2 }
-%   \end{verbatim}
-%   leaves |#1#2| in the input stream. If the \meta{token} is
-%   not a macro then \cs{scan_stop:} is left in the input stream.
-%   \begin{texnote}
-%     If the arg~spec. contains the string |->|, then the |spec| function
-%     produces incorrect results.
-%   \end{texnote}
-% \end{function}
-%
-% \begin{function}[EXP]{\token_get_replacement_spec:N}
-%   \begin{syntax}
-%     \cs{token_get_replacement_spec:N} \meta{token}
-%   \end{syntax}
-%   If the \meta{token} is a macro, this function leaves
-%   the replacement text in input stream as
-%   a string of tokens of category code $12$ (with spaces having category
-%   code $10$). Thus for example for a token \cs{next} defined by
-%   \begin{verbatim}
-%     \cs_set:Npn \next #1#2 { x #1~y #2 }
-%   \end{verbatim}
-%   leaves \verb|x#1 y#2| in the input stream. If the \meta{token} is
-%   not a macro then \cs{scan_stop:} is left in the input stream.
-%   \begin{texnote}
-%     If the arg~spec. contains the string |->|, then the |spec| function
-%     produces incorrect results.
-%   \end{texnote}
-% \end{function}
-%
-% \begin{function}[EXP]{\token_get_prefix_spec:N}
-%   \begin{syntax}
-%     \cs{token_get_prefix_spec:N} \meta{token}
-%   \end{syntax}
-%   If the \meta{token} is a macro, this function leaves
-%   the \TeX{} prefixes applicable in input stream as
-%   a string of tokens of category code $12$ (with spaces having category
-%   code $10$). Thus for example for a token \cs{next} defined by
-%   \begin{verbatim}
-%     \cs_set:Npn \next #1#2 { x #1~y #2 }
-%   \end{verbatim}
-%   leaves |\long| in the input stream. If the \meta{token} is
-%   not a macro then \cs{scan_stop:} is left in the input stream
-% \end{function}
-%
 % \section{Description of all possible tokens}
 % \label{sec:l3token:all-tokens}
 %
@@ -2465,60 +2405,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{Decomposing a macro definition}
-%
-% \begin{macro}{\token_get_prefix_spec:N}
-% \begin{macro}{\token_get_arg_spec:N}
-% \begin{macro}{\token_get_replacement_spec:N}
-% \begin{macro}{\@@_get_prefix_arg_replacement:wN}
-%   We sometimes want to test if a
-%   control sequence can be expanded to reveal a hidden
-%   value. However, we cannot just expand the macro blindly as it may
-%   have arguments and none might be present. Therefore we define
-%   these functions to pick either the prefix(es), the argument
-%   specification, or the replacement text from a macro. All of this
-%   information is returned as characters with catcode~$12$. If the
-%   token in question isn't a macro, the token \cs{scan_stop:} is
-%   returned instead.
 %    \begin{macrocode}
-\exp_args:Nno \use:nn
-  { \cs_new:Npn \@@_get_prefix_arg_replacement:wN #1 }
-  { \tl_to_str:n { macro : } #2 -> #3 \q_stop #4 }
-  { #4 {#1} {#2} {#3} }
-\cs_new:Npn \token_get_prefix_spec:N #1
-  {
-    \token_if_macro:NTF #1
-      {
-        \exp_after:wN \@@_get_prefix_arg_replacement:wN
-          \token_to_meaning:N #1 \q_stop \use_i:nnn
-      }
-      { \scan_stop: }
-  }
-\cs_new:Npn \token_get_arg_spec:N #1
-  {
-    \token_if_macro:NTF #1
-      {
-        \exp_after:wN \@@_get_prefix_arg_replacement:wN
-          \token_to_meaning:N #1 \q_stop \use_ii:nnn
-      }
-      { \scan_stop: }
-  }
-\cs_new:Npn \token_get_replacement_spec:N #1
-  {
-    \token_if_macro:NTF #1
-      {
-        \exp_after:wN \@@_get_prefix_arg_replacement:wN
-          \token_to_meaning:N #1 \q_stop \use_iii:nnn
-      }
-      { \scan_stop: }
-  }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%    \begin{macrocode}
 %</initex|package>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2019-02-15}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,9 @@
 % \iffalse meta-comment
 %
-%% File: l3keys2e.dtx (C) Copyright 2009,2011-2018 The LaTeX3 Project
+%% File: l3keys2e.dtx
 %
+% Copyright (C) 2009,2011-2019 The LaTeX3 Project
+%
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
 % license or (at your option) any later version.  The latest version
@@ -60,7 +62,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2018-10-17}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -131,7 +133,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{l3keys2e}{2018-10-17}{}
+\ProvidesExplPackage{l3keys2e}{2019-03-05}{}
   {LaTeX2e option processing using LaTeX3 keys}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.ins	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.ins	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,9 @@
 \iffalse meta-comment
 
-File l3keys2e.ins Copyright (C) 2009,2011,2012,2016,2017 The LaTeX3 Project
+File: l3keys2e.ins
 
+Copyright (C) 2009,2011,2012,2016,2017,2019 The LaTeX3 Project
+
 It may be distributed and/or modified under the conditions of the
 LaTeX Project Public License (LPPL), either version 1.3c of this
 license or (at your option) any later version.  The latest version
@@ -9,7 +11,7 @@
 
    http://www.latex-project.org/lppl.txt
 
-This file is part of the "xpackage bundle" (The Work in LPPL)
+This file is part of the "l3packages bundle" (The Work in LPPL)
 and all files in that bundle must be distributed together.
 
 The released version of this bundle is available from CTAN.
@@ -21,7 +23,7 @@
 
 \preamble
 
-Copyright (C) 2009-2017 The LaTeX3 Project
+Copyright (C) 2009-2019 The LaTeX3 Project
 
 It may be distributed and/or modified under the conditions of
 the LaTeX Project Public License (LPPL), either version 1.3c of

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,9 @@
 % \iffalse meta-comment
 %
-%% File: xfp.dtx (C) Copyright 2017-2018 The LaTeX3 Project
+%% File: xfp.dtx
 %
+% Copyright (C) 2017-2019 The LaTeX3 Project
+%
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
 % license or (at your option) any later version.  The latest version
@@ -62,7 +64,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2018-10-17}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -93,6 +95,7 @@
 %     $x\mathop{\&\&}y$, disjunction $x\mathop{\vert\vert}y$, ternary
 %     operator $x\mathop{?}y\mathop{:}z$.
 %   \item Exponentials: $\exp x$, $\ln x$, $x^y$.
+%   \item Integer factorial: $\operatorname{fact} x$.
 %   \item Trigonometry: $\sin x$, $\cos x$, $\tan x$, $\cot x$, $\sec
 %     x$, $\csc x$ expecting their arguments in radians, and
 %     $\operatorname{sind} x$, $\operatorname{cosd} x$,
@@ -107,17 +110,20 @@
 %     $\operatorname{atand} x$, $\operatorname{acotd} x$,
 %     $\operatorname{asecd} x$, $\operatorname{acscd} x$ giving a result
 %     in degrees.
-%   \item Extrema: $\max(x,y,\ldots)$, $\min(x,y,\ldots)$,
+%   \item Extrema: $\max(x_{1},x_{2},\ldots)$, $\min(x_{1},x_{2},\ldots)$,
 %     $\operatorname{abs}(x)$.
-%   \item Rounding functions ($n=0$ by default, $t=\nan$ by default):
-%     $\operatorname{trunc}(x,n)$ rounds towards zero,
-%     $\operatorname{floor}(x,n)$ rounds towards~$-\infty$,
-%     $\operatorname{ceil}(x,n)$ rounds towards~$+\infty$,
-%     $\operatorname{round}(x,n,t)$ rounds to the closest value, with
+%   \item Rounding functions, controlled by two optional
+%     values,  $n$ (number of places, $0$ by default) and
+%       $t$ (behavior on a tie, $\nan$ by default):
+%     \begin{itemize}
+%     \item $\operatorname{trunc}(x,n)$ rounds towards zero,
+%     \item $\operatorname{floor}(x,n)$ rounds towards~$-\infty$,
+%     \item $\operatorname{ceil}(x,n)$ rounds towards~$+\infty$,
+%     \item $\operatorname{round}(x,n,t)$ rounds to the closest value, with
 %     ties rounded to an even value by default, towards zero if $t=0$,
 %     towards $+\infty$ if $t>0$ and towards $-\infty$ if $t<0$.
-%   \item Random numbers: $\mathop{rand}()$, $\mathop{randint}(m,n)$
-%     (not available in \XeTeX{}).
+%     \end{itemize}
+%   \item Random numbers: $\mathop{rand}()$, $\mathop{randint}(m,n)$.
 %   \item Constants: \texttt{pi}, \texttt{deg} (one degree in radians).
 %   \item Dimensions, automatically expressed in points, \emph{e.g.},
 %     \texttt{pc} is~$12$.
@@ -161,7 +167,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xfp}{2018-10-17}{}
+\ProvidesExplPackage{xfp}{2019-03-05}{}
   {L3 Floating point unit}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.ins	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.ins	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,9 @@
 \iffalse meta-comment
 
-File xfp.ins Copyright (C) 2017 The LaTeX3 Project
+File: xfp.ins
 
+Copyright (C) 2017,2019 The LaTeX3 Project
+
 It may be distributed and/or modified under the conditions of the
 LaTeX Project Public License (LPPL), either version 1.3c of this
 license or (at your option) any later version.  The latest version
@@ -21,7 +23,7 @@
 
 \preamble
 
-Copyright (C) 2017 The LaTeX3 Project
+Copyright (C) 2017-2019 The LaTeX3 Project
 
 It may be distributed and/or modified under the conditions of
 the LaTeX Project Public License (LPPL), either version 1.3c of

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,9 @@
 % \iffalse meta-comment
 %
-%% File: xfrac.dtx Copyright (C) 2004, 2008-2010 Morten Hoegholm
-%%                           (C) 2011,2012,2014-2018 The LaTeX3 Project
+%% File: xfrac.dtx
+% 
+% Copyright (C) 2004,2008-2010 Morten Hoegholm
+%           (C) 2011,2012,2014-2019 The LaTeX3 Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -63,7 +65,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2018-10-17}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -533,7 +535,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xfrac}{2018-10-17}{}
+\ProvidesExplPackage{xfrac}{2019-03-05}{}
   {L3 Experimental split-level fractions}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.ins	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.ins	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,8 +1,10 @@
 \iffalse meta-comment
 
-File xfrac.ins Copyright (C) 2004, 2008-2010 Morten Hoegholm
-                         (C) 2011,2012,2016,2017 The LaTeX3 Project
+File: xfrac.ins
 
+Copyright (C) 2004,2008-2010 Morten Hoegholm
+          (C) 2011,2012,2016,2017,2019 The LaTeX3 Project
+
 It may be distributed and/or modified under the conditions of the
 LaTeX Project Public License (LPPL), either version 1.3c of this
 license or (at your option) any later version.  The latest version
@@ -22,7 +24,7 @@
 
 \preamble
 
-Copyright (C) 2011-2017 The LaTeX3 Project
+Copyright (C) 2011-2019 The LaTeX3 Project
 
 It may be distributed and/or modified under the conditions of
 the LaTeX Project Public License (LPPL), either version 1.3c of

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,11 +1,11 @@
 % \iffalse meta-comment
 %
-%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley,
-%%                      David Carlisle
-%%                  (C) Copyright 2004-2008 Frank Mittelbach,
-%%                      The LaTeX3 Project
-%%                  (C) Copyright 2009-2018 The LaTeX3 Project
+%% File: xparse.dtx
 %
+% Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle
+%           (C) 2004-2008 Frank Mittelbach, The LaTeX3 Project
+%           (C) 2009-2019 The LaTeX3 Project
+%
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
 % license or (at your option) any later version.  The latest version
@@ -67,7 +67,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2018-10-17}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -85,18 +85,18 @@
 % At present, the functions in \pkg{xparse} which are regarded as
 % \enquote{stable} are:
 % \begin{itemize}
-%   \item \cs{NewDocumentCommand}
-%   \item \cs{RenewDocumentCommand}
-%   \item \cs{ProvideDocumentCommand}
-%   \item \cs{DeclareDocumentCommand}
-%   \item \cs{NewDocumentEnvironment}
-%   \item \cs{RenewDocumentEnvironment}
-%   \item \cs{ProvideDocumentEnvironment}
-%   \item \cs{DeclareDocumentEnvironment}
-%   \item \cs{NewExpandableDocumentCommand}
-%   \item \cs{RenewExpandableDocumentCommand}
-%   \item \cs{ProvideExpandableDocumentCommand}
-%   \item \cs{DeclareExpandableDocumentCommand}
+%   \item \cs{NewDocumentCommand}\\
+%     \cs{RenewDocumentCommand}\\
+%     \cs{ProvideDocumentCommand}\\
+%     \cs{DeclareDocumentCommand}
+%   \item \cs{NewDocumentEnvironment}\\
+%     \cs{RenewDocumentEnvironment}\\
+%     \cs{ProvideDocumentEnvironment}\\
+%     \cs{DeclareDocumentEnvironment}
+%   \item \cs{NewExpandableDocumentCommand}\\
+%     \cs{RenewExpandableDocumentCommand}\\
+%     \cs{ProvideExpandableDocumentCommand}\\
+%     \cs{DeclareExpandableDocumentCommand}
 %   \item \cs{IfNoValue(TF)}
 %   \item \cs{IfValue(TF)}
 %   \item \cs{IfBoolean(TF)}
@@ -105,7 +105,7 @@
 % try all of the commands provided here, but be aware that the
 % experimental ones may change or disappear.
 %
-% \subsection{Specifying arguments}
+% \section{Specifying arguments}
 %
 % Before introducing the functions used to create document commands,
 % the method for specifying arguments with \pkg{xparse} will be
@@ -126,27 +126,32 @@
 % are:
 % \begin{itemize}[font=\ttfamily]
 %   \item[m] A standard mandatory argument, which can either be a single
-%     token alone or multiple tokens surrounded by curly braces.
+%     token alone or multiple tokens surrounded by curly braces |{}|.
 %     Regardless of the input, the argument will be passed to the
-%     internal code surrounded by a brace pair. This is the \pkg{xparse}
+%     internal code without the outer braces. This is the \pkg{xparse}
 %     type specifier for a normal \TeX{} argument.
-%   \item[r] Reads a \enquote{required} delimited argument, where the
-%     delimiters are given as \meta{char1} and \meta{char2}:
-%     \texttt{r}\meta{char1}\meta{char2}. If the opening \meta{character}
-%     is missing, the default marker |-NoValue-| will be inserted after
-%     a suitable error.
-%   \item[R] As for \texttt{r}, this is a \enquote{required} delimited
-%     argument but has a user-definable recovery \meta{default}, given
-%     as \texttt{R}\meta{char1}\meta{char2}\marg{default}.
+%   \item[r] Given as \texttt{r}\meta{char1}\meta{char2}, this denotes a
+%     \enquote{required} delimited argument, where the delimiters are
+%     \meta{char1} and \meta{char2}. If the opening delimiter
+%     \meta{char1} is missing, the default marker |-NoValue-| will be
+%     inserted after a suitable error.
+%   \item[R] Given as \texttt{R}\meta{char1}\meta{char2}\marg{default},
+%     this is a \enquote{required} delimited argument as for~\texttt{r},
+%     but it has a user-definable recovery \meta{default} instead of
+%     |-NoValue-|.
 %   \item[v] Reads an argument \enquote{verbatim}, between the following
 %     character and its next occurrence, in a way similar to the argument
 %     of the \LaTeXe{} command \cs{verb}. Thus a \texttt{v}-type argument
-%     is read between two matching tokens, which cannot be any of |%|, |\|,
+%     is read between two identical characters, which cannot be any of |%|, |\|,
 %     |#|, |{|, |}| or \verb*| |.
 %     The verbatim argument can also be enclosed between braces, |{| and |}|.
 %     A command with a verbatim
-%     argument will not work when it appears within an argument of
+%     argument will produce an error when it appears within an argument of
 %     another function.
+%   \item[b] Only suitable in the argument specification of an
+%     environment, it denotes the body of the environment, between
+%     |\begin|\marg{environment} and |\end|\marg{environment}.  See
+%     Section~\ref{sec:body} for details.
 % \end{itemize}
 % The types which define optional arguments are:
 % \begin{itemize}[font=\ttfamily]
@@ -153,14 +158,14 @@
 %   \item[o] A standard \LaTeX{} optional argument, surrounded with square
 %     brackets, which will supply
 %     the special |-NoValue-| marker if not given (as described later).
-%   \item[d] An optional argument which is delimited by \meta{char1}
-%     and \meta{char2}, given as follows:
-%     \texttt{d}\meta{char1}\meta{char2}. As with \texttt{o}, if no
+%   \item[d] Given as \texttt{d}\meta{char1}\meta{char2}, an optional
+%     argument which is delimited by \meta{char1} and \meta{char2}.
+%     As with \texttt{o}, if no
 %     value is given the special marker |-NoValue-| is returned.
-%   \item[O] As for \texttt{o}, but returns \meta{default} if no
-%     value is given.  Should be given as \texttt{O}\marg{default}.
-%   \item[D] As for \texttt{d}, but returns \meta{default} if no
-%     value is given: \texttt{D}\meta{char1}\meta{char2}\marg{default}.
+%   \item[O] Given as \texttt{O}\marg{default}, is like \texttt{o}, but
+%     returns \meta{default} if no value is given.
+%   \item[D] Given as \texttt{D}\meta{char1}\meta{char2}\marg{default},
+%     it is as for \texttt{d}, but returns \meta{default} if no value is given.
 %     Internally, the \texttt{o}, \texttt{d} and \texttt{O} types are
 %     short-cuts to an appropriated-constructed \texttt{D} type argument.
 %   \item[s] An optional star, which will result in a value
@@ -169,9 +174,9 @@
 %   \item[t] An optional \meta{char}, which will result in a value
 %     \cs{BooleanTrue} if \meta{char} is present and \cs{BooleanFalse}
 %     otherwise. Given as \texttt{t}\meta{char}.
-%   \item[e] A set of optional \emph{embellishments}, each of which
-%     requires a \emph{value}: \texttt{e}\marg{chars}.  If an
-%     embellishment is not present, |-NoValue-| is returned.  Each
+%   \item[e] Given as \texttt{e}\marg{chars}, a set of optional
+%     \emph{embellishments}, each of which requires a \emph{value}.
+%     If an embellishment is not present, |-NoValue-| is returned.  Each
 %     embellishment gives one argument, ordered as for the list of
 %     \meta{chars} in the argument specification.  All \meta{chars}
 %     must be distinct.  \emph{This is an experimental type}.
@@ -217,7 +222,7 @@
 %   \NewDocumentCommand{\foobar}{o}{#1}
 %   \foobar[{[}]         % Allowed as the "[" is 'hidden'
 % \end{verbatim}
-% These braces will be stripped if they surround the \emph{entire} content
+% These braces will be stripped only if they surround the \emph{entire} content
 % of the optional argument
 % \begin{verbatim}
 %   \NewDocumentCommand{\foobaz}{o}{#1}
@@ -241,7 +246,7 @@
 % When an optional argument is followed by a mandatory argument with the
 % same delimiter, \pkg{xparse} issues a warning because the optional
 % argument could not be omitted by the user, thus becoming in effect
-% mandatory.  This applies to \texttt{o}, \texttt{d}, \texttt{O},
+% mandatory.  This can apply to \texttt{o}, \texttt{d}, \texttt{O},
 % \texttt{D}, \texttt{s}, \texttt{t}, \texttt{e}, and \texttt{E} type
 % arguments followed by \texttt{r} or \texttt{R}-type required
 % arguments, but also to \texttt{g} or \texttt{G} type arguments
@@ -313,10 +318,6 @@
 % (\texttt{r}-type) or user-specified default (for \texttt{R}-type) will be
 % inserted to allow error recovery.
 %
-% Users should note that support for required delimited arguments is somewhat
-% experimental. Feedback is therefore very welcome on the \texttt{LaTeX-L}
-% mailing list.
-%
 % \subsection{Verbatim arguments}
 %
 % Arguments of type~\texttt{v} are read in verbatim mode, which will
@@ -385,8 +386,108 @@
 % |-NoValue-| marker as a default for |_|. This allows mixing of explicit
 % defaults with testing for missing values.
 %
-% \subsection{Declaring commands and environments}
+% \subsection{Body of an environment}
+% \label{sec:body}
 %
+% While environments |\begin|\marg{environment} \dots{}
+%   |\end|\marg{environment} are typically used in cases where the code
+% implementing the \meta{environment} does not need to access the
+% contents of the environment (its \enquote{body}), it is sometimes
+% useful to have the body as a standard argument.
+%
+% This is achieved in \pkg{xparse} by ending the argument specification
+% with~\texttt{b}. The approach taken in \pkg{xparse} is
+% different from the earlier packages \pkg{environ} or \pkg{newenviron}:
+% the body of the environment is provided to the code part as a usual
+% argument |#1|, |#2| etc.\@, rather than stored in a macro such as
+% \cs[no-index]{BODY}.
+%
+% For instance
+% \begin{verbatim}
+%   \NewDocumentEnvironment { twice }
+%     { O{\ttfamily} +b }
+%     {#2#1#2} {}
+%   \begin{twice}[\itshape]
+%     Hello world!
+%   \end{twice}
+% \end{verbatim}
+% typesets \enquote{Hello world!{\itshape Hello world!}}.
+%
+% The prefix |+| is used to allow multiple paragraphs in the
+% environment's body.  Argument processors can also be applied to
+% \texttt{b}~arguments.
+%
+% By default, spaces are trimmed at both ends of the body: in the
+% example there would otherwise be spaces coming from the ends the lines
+% after |[\itshape]| and |world!|.  Putting the prefix |!| before
+% \texttt{b} suppresses space-trimming.
+%
+% When \texttt{b} is used in the argument specification,
+% the last argument of \cs{NewDocumentEnvironment}, which consists of
+% an \meta{end code} to insert at |\end|\marg{environment}, is
+% redundant since one can simply put that code at the end of the
+% \meta{start code}.  Nevertheless this (empty) \meta{end code} must be
+% provided.
+%
+% Environments that use this feature can be nested.
+%
+% Users should note that this feature is somewhat experimental. Feedback
+% is therefore very welcome on the \texttt{LaTeX-L} mailing list.
+%
+% \subsection{Starred environments}
+%
+% Many packages define environments with and without \texttt{*} in their
+% name, for instance \texttt{tabular} and \texttt{tabular*}.  At
+% present, \pkg{xparse} does not provide specific tools to define these:
+% one should simply define the two environment separately, for instance
+% \begin{verbatim}
+% \NewDocumentEnvironment { tabular } { o +m } {...} {...}
+% \NewDocumentEnvironment { tabular* } { m o +m } {...} {...}
+% \end{verbatim}
+% Of course the implementation of these two environments, denoted
+% \enquote{\texttt{...}} in this example, can rely on the same internal
+% commands.
+%
+% Note that this situation is different from the \texttt{s} argument
+% type: if the signature of an environment starts with~\texttt{s} then
+% the star is searched for after the argument of \cs{begin}.  For
+% instance, the following typesets \texttt{star}.
+% \begin{verbatim}
+% \NewDocumentEnvironment { envstar } { s }
+%   {\IfBooleanTF {#1} {star} {no star}} {}
+% \begin{envstar}*
+% \end{envstar}
+% \end{verbatim}
+%
+% \subsection{Backwards Compatibility}
+% \label{sec:backwards}
+%
+% One role of \pkg{xparse} is to describe existing \LaTeX{} interfaces,
+% including some that are rather unusual in \LaTeX{} (as opposed to
+% formats such as plain \TeX{}) such as delimited arguments.  As such,
+% the package defines some argument specifiers that should largely be
+% avoided nowadays as using them in packages leads to inconsistent user
+% interfaces.  The simplest syntax is often best, with argument
+% specifications such as |mmmm| or |ommmm|, namely an optional argument
+% followed by some standard mandatory ones.  The optional argument can
+% be made to support key--value syntax using tools from \pkg{l3keys}.
+%
+% The argument types that are not recommended any longer are:
+% \begin{itemize}[font=\ttfamily]
+%   \item[l] A mandatory argument which reads everything up to the first
+%     begin-group token: in standard \LaTeX{} this is a left brace.
+%   \item[u] Reads a mandatory argument \enquote{until} \meta{tokens} are encountered,
+%     where the desired \meta{tokens} are given as an argument to the
+%     specifier: \texttt{u}\marg{tokens}.
+%   \item[g] An optional argument given inside a pair of \TeX{} group
+%     tokens (in standard \LaTeX{}, |{| \ldots |}|), which returns
+%     |-NoValue-| if not present.
+%   \item[G] As for \texttt{g} but returns \meta{default} if no value
+%     is given: \texttt{G}\marg{default}.
+% \end{itemize}
+%
+% \section{Declaring commands and environments}
+%
 % With the concept of an argument specifier defined, it is now
 % possible to describe the methods available for creating both
 % functions and environments using \pkg{xparse}.
@@ -404,12 +505,13 @@
 %     \DeclareDocumentCommand
 %   }
 %   \begin{syntax}
-%     \cs{NewDocumentCommand} \meta{Function} \Arg{arg spec} \Arg{code}
+%     \cs{NewDocumentCommand} \meta{function} \Arg{arg spec} \Arg{code}
 %   \end{syntax}
 %   This family of commands are used to create a document-level
 %   \meta{function}. The argument specification for the function is
-%   given by \meta{arg spec},  and expanding
-%   to be replaced by the \meta{code}.
+%   given by \meta{arg spec}, and the function expands to the
+%   \meta{code} with |#1|, |#2|, etc.\ replaced by the arguments found
+%   by \pkg{xparse}.
 % \end{function}
 %
 %   As an example:
@@ -467,6 +569,8 @@
 %   The arguments will be given following \cs{begin}\Arg{environment}.
 % \end{function}
 %
+% \section{Other \pkg{xparse} commands}
+%
 % \subsection{Testing special values}
 %
 % Optional arguments created using \pkg{xparse} make use of dedicated
@@ -599,10 +703,10 @@
 %
 % \begin{function}[updated = 2012-02-12]{\SplitArgument}
 %   \begin{syntax}
-%     \cs{SplitArgument} \Arg{number} \Arg{token}
+%     \cs{SplitArgument} \Arg{number} \Arg{token(s)}
 %   \end{syntax}
 %   This processor splits the argument given at each occurrence of the
-%   \meta{token} up to a maximum of \meta{number} tokens (thus
+%   \meta{tokens} up to a maximum of \meta{number} tokens (thus
 %   dividing the input into $\text{\meta{number}} + 1$ parts).
 %   An error is given if too many \meta{tokens} are present in the
 %   input. The processed input is placed inside
@@ -615,9 +719,10 @@
 %       { > { \SplitArgument { 2 } { ; } } m }
 %       { \InternalFunctionOfThreeArguments #1 }
 %   \end{verbatim}
-%   Any category code $13$ (active) \meta{tokens} will be replaced
-%   before the split takes place. Spaces are trimmed at each end of each
-%   item parsed.
+%   If only a single character \meta{token} is used for the split, any
+%   category code $13$ (active) character matching the \meta{token} will
+%   be replaced before the split takes place.
+%   Spaces are trimmed at each end of each item parsed.
 % \end{function}
 %
 % \begin{function}{\SplitList}
@@ -633,9 +738,10 @@
 %       { > { \SplitList { ; } } m }
 %       { \MappingFunction #1 }
 %   \end{verbatim}
-%   If only a single \meta{token} is used for the split, any
-%   category code $13$ (active) \meta{token} will be replaced
-%   before the split takes place.
+%   If only a single character \meta{token} is used for the split, any
+%   category code $13$ (active) character matching the \meta{token} will
+%   be replaced before the split takes place.
+%   Spaces are trimmed at each end of each item parsed.
 % \end{function}
 %
 % \begin{function}[EXP]{\ProcessList}
@@ -713,7 +819,8 @@
 %   available:
 %   \begin{itemize}
 %     \item The last argument (if any are present) must be one of the
-%       mandatory types \texttt{m} or \texttt{r}.
+%       mandatory types \texttt{m}, \texttt{r}, \texttt{R}, \texttt{l}
+%       or~\texttt{u}.
 %     \item All short arguments appear before long arguments.
 %     \item The mandatory argument types \texttt{l} and \texttt{u} may
 %       not be used after optional arguments.
@@ -768,41 +875,14 @@
 % \DescribeOption{log-declarations}
 % The package recognises the load-time option \texttt{log-declarations},
 % which is a key--value option taking the value \texttt{true} and
-% \texttt{false}. By default, the option is set to \texttt{true}, meaning
-% that each command or environment declared is logged. By loading
+% \texttt{false}. By default, the option is set to \texttt{false}, meaning
+% that no command or environment declared is logged. By loading
 % \pkg{xparse} using
 % \begin{verbatim}
-%   \usepackage[log-declarations=false]{xparse}
+%   \usepackage[log-declarations=true]{xparse}
 % \end{verbatim}
-% this may be suppressed and no information messages are produced.
+% each new, declared or renewed command or environment is logged.
 %
-% \section{Backwards Compatibility}
-% \label{sec:backwards}
-%
-% One role of \pkg{xparse} is to describe existing \LaTeX{} interfaces,
-% including some that are rather unusual in \LaTeX{} (as opposed to
-% formats such as plain \TeX{}) such as delimited arguments.  As such,
-% the package defines some argument specifiers that should largely be
-% avoided nowadays as using them in packages leads to inconsistent user
-% interfaces.  The simplest syntax is often best, with argument
-% specifications such as |mmmm| or |ommmm|, namely an optional argument
-% followed by some standard mandatory ones.  The optional argument can
-% be made to support key--value syntax using tools from \pkg{l3keys}.
-%
-% The argument types that are not recommended any longer are:
-% \begin{itemize}[font=\ttfamily]
-%   \item[l] A mandatory argument which reads everything up to the first
-%     begin-group token: in standard \LaTeX{} this is a left brace.
-%   \item[u] Reads a mandatory argument \enquote{until} \meta{tokens} are encountered,
-%     where the desired \meta{tokens} are given as an argument to the
-%     specifier: \texttt{u}\marg{tokens}.
-%   \item[g] An optional argument given inside a pair of \TeX{} group
-%     tokens (in standard \LaTeX{}, |{| \ldots |}|), which returns
-%     |-NoValue-| if not present.
-%   \item[G] As for \texttt{g} but returns \meta{default} if no value
-%     is given: \texttt{G}\marg{default}.
-% \end{itemize}
-%
 % \end{documentation}
 %
 % \begin{implementation}
@@ -818,7 +898,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xparse}{2018-10-17}{}
+\ProvidesExplPackage{xparse}{2019-03-05}{}
   {L3 Experimental document command parser}
 %    \end{macrocode}
 %
@@ -883,11 +963,19 @@
 %   Generating environments uses the same mechanism as generating functions.
 %   However, full processing of arguments is always needed for environments,
 %   and so the function-generating code needs to know this.
+%   This variable is also used at run time to give correct error messages.
 %    \begin{macrocode}
 \bool_new:N \l_@@_environment_bool
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\l_@@_environment_str}
+%   Name of the environment, used at definition time and at run time.
+%    \begin{macrocode}
+\str_new:N \l_@@_environment_str
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{variable}{\l_@@_expandable_bool}
 %   Used to indicate if an expandable command is begin generated, as this
 %   affects both the acceptable argument types and how they are implemented.
@@ -987,15 +1075,6 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_mandatory_args_int}
-%   Holds the total number of mandatory arguments for a function, which is
-%   needed to tell whether further mandatory arguments follow an optional
-%   one.
-%    \begin{macrocode}
-\int_new:N \l_@@_mandatory_args_int
-%    \end{macrocode}
-% \end{variable}
-%
 % \begin{variable}{\l_@@_prefixed_bool}
 %   When preparing the signature of non-expandable commands, indicates
 %   that the current argument is affected by a processor or by |+|
@@ -1018,6 +1097,14 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\l_@@_saved_args_tl}
+%   Stores \cs{l_@@_args_tl} to deal with space-trimming of
+%   \texttt{b}-type arguments.
+%    \begin{macrocode}
+\tl_new:N \l_@@_saved_args_tl
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{variable}{\l_@@_signature_tl}
 %   Used when constructing the signature (code for argument grabbing) to
 %   hold what will become the implementation of the main function.
@@ -1064,7 +1151,7 @@
 % \begin{macro}{\@@_declare_cmd:Nnn, \@@_declare_expandable_cmd:Nnn}
 % \begin{macro}{\@@_declare_cmd_aux:Nnn}
 % \begin{macro}
-%   {\@@_declare_cmd_internal:Nnn, \@@_declare_cmd_internal:cnx}
+%   {\@@_declare_cmd_internal:Nnnn, \@@_declare_cmd_internal:cnxn}
 %   The main functions for creating commands set the appropriate flag then
 %   use the same internal code to do the definition.
 %    \begin{macrocode}
@@ -1082,7 +1169,7 @@
 %  The first stage is to log information, both for the user in the log and
 %  for programmatic use in a property list of all declared commands.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_declare_cmd_aux:Nnn #1#2
+\cs_new_protected:Npn \@@_declare_cmd_aux:Nnn #1#2#3
   {
     \cs_if_exist:NTF #1
       {
@@ -1101,22 +1188,26 @@
           { \token_to_str:N #1 } { \tl_to_str:n {#2} }
       }
     \bool_set_false:N \l_@@_environment_bool
-    \@@_declare_cmd_internal:Nnn #1 {#2}
+    \@@_declare_cmd_internal:Nnnn #1 {#2} {#3} { }
   }
 %    \end{macrocode}
+%   At definition time, the variable \cs{l_@@_fn_tl} is only used for error messages.
 %   The real business of defining a document command starts with setting up
 %   the appropriate name, then normalizing the argument specification to get rid of
-%   shorthands (this step also counts the number of mandatory arguments).
+%   shorthands.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_declare_cmd_internal:Nnn #1#2#3
+\cs_new_protected:Npn \@@_declare_cmd_internal:Nnnn #1#2#3#4
   {
     \tl_set:Nx \l_@@_function_tl { \cs_to_str:N #1 }
+    \tl_set:Nx \l_@@_fn_tl
+      { \exp_not:c { \l_@@_function_tl \c_space_tl } }
     \@@_normalize_arg_spec:n {#2}
     \exp_args:No \@@_prepare_signature:n \l_@@_arg_spec_tl
     \@@_declare_cmd_code:Nnn #1 {#2} {#3}
+    #4
     \@@_break_point:n {#2}
   }
-\cs_generate_variant:Nn \@@_declare_cmd_internal:Nnn { cnx }
+\cs_generate_variant:Nn \@@_declare_cmd_internal:Nnnn { cnx }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -1153,10 +1244,16 @@
       \cs_set_protected:Npn \l_@@_current_arg_int {#3}
     \cs_set_protected_nopar:Npx #1
       {
-        \@@_start:nNNnnn
-          { \exp_not:n {#2} }
-          \exp_not:c { \l_@@_function_tl \c_space_tl }
-          \exp_not:c { \l_@@_function_tl \c_space_tl code }
+        \bool_if:NTF \l_@@_environment_bool
+          {
+            \@@_start_env:nnnnn { \exp_not:n {#2} }
+              { \l_@@_environment_str }
+          }
+          {
+            \@@_start:nNNnnn { \exp_not:n {#2} }
+              \exp_not:c { \l_@@_function_tl \c_space_tl }
+              \exp_not:c { \l_@@_function_tl \c_space_tl code }
+          }
           { \exp_not:o \l_@@_signature_tl }
           {
             \bool_if:NT \l_@@_defaults_bool
@@ -1241,23 +1338,27 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_declare_env:nnnn #1#2
   {
+    \str_set:Nx \l_@@_environment_str {#1}
+    \str_set:Nx \l_@@_environment_str
+      { \tl_trim_spaces:o { \l_@@_environment_str } }
 %<*initex>
-    \cs_if_exist:cTF { environment~ #1 }
+    \cs_if_exist:cTF { environment~ \l_@@_environment_str }
 %</initex>
 %<*package>
-    \cs_if_exist:cTF {#1}
+    \cs_if_exist:cTF { \l_@@_environment_str }
 %</package>
       {
         \__kernel_msg_info:nnxx { xparse } { redefine-environment }
-          {#1} { \tl_to_str:n {#2} }
+          { \l_@@_environment_str } { \tl_to_str:n {#2} }
       }
       {
         \__kernel_msg_info:nnxx { xparse } { define-environment }
-          {#1} { \tl_to_str:n {#2} }
+          { \l_@@_environment_str } { \tl_to_str:n {#2} }
       }
     \bool_set_false:N \l_@@_expandable_bool
     \bool_set_true:N \l_@@_environment_bool
-    \@@_declare_env_internal:nnnn {#1} {#2}
+    \exp_args:NV \@@_declare_env_internal:nnnn
+      \l_@@_environment_str {#2}
   }
 %    \end{macrocode}
 %   Creating a document environment requires a few more steps than creating
@@ -1267,10 +1368,16 @@
 %   redefined to contain the appropriate information. To minimize the amount
 %   of expansion at point of use, the code here is expanded now as well as
 %   when used.
+%   The last argument of \cs{@@_declare_cmd_internal:Nnnn} is only run
+%   if the definition succeeded.  In package mode this ensures that the
+%   original definition of the environment is not changed if the
+%   definition fails for any reason.  This also avoids an error when
+%   defining the \verb*|end aux | function when the user asks for more
+%   than $9$ arguments.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_declare_env_internal:nnnn #1#2#3#4
   {
-    \@@_declare_cmd_internal:cnx { environment~ #1 } {#2}
+    \@@_declare_cmd_internal:cnxn { environment~ #1 } {#2}
       {
         \cs_set_nopar:Npx \exp_not:c { environment~ #1 ~end~aux }
           {
@@ -1279,15 +1386,17 @@
           }
         \exp_not:n {#3}
       }
-    \cs_set_nopar:cpx { environment~ #1 ~end }
-      { \exp_not:c { environment~ #1 ~end~aux } }
-    \cs_generate_from_arg_count:cNnn
-      { environment~ #1 ~end~aux~ } \cs_set:Npn
-      \l_@@_current_arg_int {#4}
+      {
+        \cs_set_nopar:cpx { environment~ #1 ~end }
+          { \exp_not:c { environment~ #1 ~end~aux } }
+        \cs_generate_from_arg_count:cNnn
+          { environment~ #1 ~end~aux~ } \cs_set:Npn
+          \l_@@_current_arg_int {#4}
 %<*package>
-    \cs_set_eq:cc {#1}       { environment~ #1 }
-    \cs_set_eq:cc { end #1 } { environment~ #1 ~end }
+        \cs_set_eq:cc {#1}       { environment~ #1 }
+        \cs_set_eq:cc { end #1 } { environment~ #1 ~end }
 %</package>
+      }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -1295,32 +1404,52 @@
 %
 % \subsection{Structure of \pkg{xparse} commands}
 %
-% \begin{macro}{\@@_start:nNNnnn}
-% \begin{macro}{\@@_start_aux:nNNnnn}
+% \begin{macro}{\@@_start_env:nnnnn, \@@_start:nNNnnn}
+%   For error messages that occur during run-time when getting arguments
+%   of environments it is necessary to keep track of the environment
+%   name.  We begin non-expandable commands with a token equal to
+%   \cs{scan_stop:}, whose name gives a reasonable error message if the
+%   command is used inside a csname and protects against
+%   \texttt{f}-expansion.  This is useless for environments since
+%   \cs{begin} is already not expandable.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_start_env:nnnnn #1#2
+  {
+    \str_set:Nn \l_@@_environment_str {#2}
+    \bool_set_true:N \l_@@_environment_bool
+    \@@_start_aux:ccnnnn
+      { environment~ \l_@@_environment_str \c_space_tl }
+      { environment~ \l_@@_environment_str \c_space_tl code }
+      {#1}
+  }
+\cs_new_protected:Npx \@@_start:nNNnnn #1#2#3
+  {
+    \exp_not:c { xparse~function~is~not~expandable }
+    \exp_not:n { \bool_set_false:N \l_@@_environment_bool }
+    \exp_not:N \@@_start_aux:NNnnnn
+    #2 #3 {#1}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_start_aux:NNnnnn, \@@_start_aux:ccnnnn}
 %   This sets up a few variables to minimize the boilerplate code
 %   included in all \pkg{xparse}-defined commands.  It then runs the
 %   grabbers~|#4|.  Again, the argument specification |#1| is only for
-%   diagnostics.  The control sequence equal to \cs{scan_stop:} protects
-%   against \texttt{f}-expansion and ensures errors are more reasonable
-%   when an \pkg{xparse} command is placed in a csname.
+%   diagnostics.
 %    \begin{macrocode}
-\cs_new_protected:Npx \@@_start:nNNnnn
+\cs_new_protected:Npn \@@_start_aux:NNnnnn #1#2#3#4#5#6
   {
-    \exp_not:c { xparse~function~is~not~expandable }
-    \exp_not:N \@@_start_aux:nNNnnn
-  }
-\cs_new_protected:Npn \@@_start_aux:nNNnnn #1#2#3#4#5#6
-  {
     \tl_clear:N \l_@@_args_tl
-    \tl_set:Nn \l_@@_fn_tl {#2}
-    \tl_set:Nn \l_@@_fn_code_tl {#3}
+    \tl_set:Nn \l_@@_fn_tl {#1}
+    \tl_set:Nn \l_@@_fn_code_tl {#2}
     \tl_set:Nn \l_@@_defaults_tl {#5}
     \tl_set:Nn \l_@@_process_all_tl {#6}
     #4 \@@_run_code:
   }
+\cs_generate_variant:Nn \@@_start_aux:NNnnnn { cc }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\@@_run_code:}
 %   After arguments are grabbed, this function is responsible for
@@ -1369,7 +1498,7 @@
 \cs_new_protected:Npn \@@_defaults_error:w \q_recursion_stop
   {
     \__kernel_msg_error:nnx { xparse } { loop-in-defaults }
-      { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
+      { \@@_environment_or_command: }
   }
 %    \end{macrocode}
 %   To construct \cs{@@_tmp:w}, first go through the arguments
@@ -1485,8 +1614,9 @@
     \@@_end_expandable_defaults:nnnNNn {#1} { } {#1} #2#3
       { } { } { } { } { } { } { } { } { } { }
       {
-        \__kernel_msg_expandable_error:nnn
-          { xparse } { loop-in-defaults } {#4}
+        \__kernel_msg_expandable_error:nnf
+          { xparse } { loop-in-defaults }
+          { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N #4 } }
         \use_iv:nnnn
       }
     \q_stop
@@ -1552,8 +1682,6 @@
 %     commands will be grabbed expandably and arguments of environments
 %     will not (because the list of arguments built by non-expandable
 %     grabbing is used to pass them to the end-environment code).
-%   \item Count mandatory arguments, used later to detect which optional
-%     arguments are trailing.
 % \end{itemize}
 % Further checks happen at the end of the loop:
 % \begin{itemize}
@@ -1572,7 +1700,6 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_normalize_arg_spec:n #1
   {
-    \int_zero:N \l_@@_mandatory_args_int
     \int_zero:N \l_@@_current_arg_int
     \tl_clear:N \l_@@_last_delimiters_tl
     \tl_clear:N \l_@@_arg_spec_tl
@@ -1587,7 +1714,7 @@
     \int_compare:nNnT \l_@@_current_arg_int > 9
       {
         \__kernel_msg_error:nnxx { xparse } { too-many-arguments }
-          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+          { \@@_environment_or_command: } { \tl_to_str:n {#1} }
         \@@_bad_def:wn
       }
     \bool_if:NT \l_@@_expandable_bool
@@ -1611,7 +1738,7 @@
     \cs_if_exist_use:cF { @@_normalize_type_ \tl_to_str:n {#1} :w }
       {
         \__kernel_msg_error:nnxx { xparse } { unknown-argument-type }
-          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+          { \@@_environment_or_command: } { \tl_to_str:n {#1} }
         \@@_bad_def:wn
       }
   }
@@ -1699,7 +1826,7 @@
     \bool_if:NT \l_@@_long_bool
       {
         \__kernel_msg_error:nnxx { xparse } { two-markers }
-          { \iow_char:N \\ \l_@@_function_tl } { + }
+          { \@@_environment_or_command: } { + }
         \@@_bad_def:wn
       }
     \bool_set_true:N \l_@@_long_bool
@@ -1712,7 +1839,7 @@
     \bool_if:NT \l_@@_obey_spaces_bool
       {
         \__kernel_msg_error:nnxx { xparse } { two-markers }
-          { \iow_char:N \\ \l_@@_function_tl } { ! }
+          { \@@_environment_or_command: } { ! }
         \@@_bad_def:wn
       }
     \bool_set_true:N \l_@@_obey_spaces_bool
@@ -1857,6 +1984,31 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\@@_normalize_type_b:w}
+%   This argument type is not allowed for commands.  This is only
+%   allowed at the end of the argument specification, hence we check
+%   that |#1| is the end.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_normalize_type_b:w #1
+  {
+    \bool_if:NF \l_@@_environment_bool
+      {
+        \__kernel_msg_error:nnxx
+          { xparse } { invalid-command-arg }
+          { \@@_environment_or_command: } { b }
+        \@@_bad_def:wn
+      }
+    \tl_clear:N \l_@@_last_delimiters_tl
+    \@@_add_arg_spec:n { b }
+    \quark_if_recursion_tail_stop:n {#1}
+    \__kernel_msg_error:nnxx { xparse } { arg-after-body }
+      { \@@_environment_or_command: }
+      { \tl_to_str:n {#1} }
+    \@@_bad_def:wn
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\@@_single_char_check:n}
 %   Checks that what should be single characters really are single
 %   characters (possibly surrounded by spaces).
@@ -1871,13 +2023,13 @@
           { \exp_args:No \tl_to_str:n { \use:nn #1 { } } }
           {
             \__kernel_msg_warning:nnxx { xparse } { not-single-char }
-              { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+              { \@@_environment_or_command: } { \tl_to_str:n {#1} }
           }
         \group_end:
       }
       {
         \__kernel_msg_error:nnxx { xparse } { not-single-char }
-          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+          { \@@_environment_or_command: } { \tl_to_str:n {#1} }
         \@@_bad_def:wn
       }
   }
@@ -1942,7 +2094,7 @@
 \cs_new_protected:Npn \@@_bad_arg_spec:wn #1 \@@_break_point:n #2
   {
     \__kernel_msg_error:nnxx { xparse } { bad-arg-spec }
-      { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#2} }
+      { \@@_environment_or_command: } { \tl_to_str:n {#2} }
   }
 \cs_new_protected:Npn \@@_bad_def:wn #1 \@@_break_point:n #2 { }
 %    \end{macrocode}
@@ -1990,10 +2142,9 @@
     \bool_if:NT \l_@@_some_obey_spaces_bool
       {
         \__kernel_msg_error:nnxx { xparse } { non-trailing-obey-spaces }
-          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+          { \@@_environment_or_command: } { \tl_to_str:n {#1} }
         \@@_bad_def:wn
       }
-    \int_incr:N \l_@@_mandatory_args_int
     \tl_clear:N \l_@@_last_delimiters_tl
     \@@_add_arg_spec:n {#1}
   }
@@ -2033,8 +2184,7 @@
 %
 %  For each known argument type there is an appropriate function to actually
 %  do the addition to the signature. These are separate for expandable and
-%  standard functions, as the approaches are different. Of course, if the type
-%  is not known at all then a fall-back is needed.
+%  standard functions, as the approaches are different.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_prepare_signature:N
   {
@@ -2098,7 +2248,7 @@
 %
 % \begin{macro}{\@@_add_type_>:w}
 %   When a processor is found, the processor code is stored.  It will be
-%   used by \cs{@@_args_process:} once arguments are all found. Here,
+%   used by \cs{@@_args_process:} once arguments are all found. Here too
 %   the loop calls \cs{@@_prepare_signature_bypass:N} rather than
 %   \cs{@@_prepare_signature:N} so that the flag is not reset.
 %    \begin{macrocode}
@@ -2113,6 +2263,18 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\@@_add_type_b:w}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_type_b:w
+  {
+    \@@_flush_m_args:
+    \@@_add_default:
+    \@@_add_grabber:N b
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\@@_add_type_D:w}
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_add_type_D:w #1#2#3
@@ -2119,7 +2281,7 @@
   {
     \@@_flush_m_args:
     \@@_add_default:n {#3}
-    \@@_add_grabber_optional:N D
+    \@@_add_grabber:N D
     \tl_put_right:Nn \l_@@_signature_tl { #1 #2 }
     \@@_prepare_signature:N
   }
@@ -2134,7 +2296,7 @@
   {
     \@@_flush_m_args:
     \@@_add_default_E:nn {#1} {#2}
-    \@@_add_grabber_optional:N E
+    \@@_add_grabber:N E
     \tl_put_right:Nn \l_@@_signature_tl { {#1} }
     \@@_prepare_signature:N
   }
@@ -2149,7 +2311,7 @@
   {
     \@@_flush_m_args:
     \@@_add_default:n {#1}
-    \@@_add_grabber_optional:N G
+    \@@_add_grabber:N G
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
@@ -2163,7 +2325,7 @@
   {
     \@@_flush_m_args:
     \@@_add_default:
-    \@@_add_grabber_mandatory:N l
+    \@@_add_grabber:N l
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
@@ -2181,7 +2343,7 @@
   {
     \@@_add_default:
     \bool_if:NTF \l_@@_prefixed_bool
-      { \@@_add_grabber_mandatory:N m }
+      { \@@_add_grabber:N m }
       { \int_incr:N \l_@@_m_args_int }
     \@@_prepare_signature:N
   }
@@ -2195,7 +2357,7 @@
   {
     \@@_flush_m_args:
     \@@_add_default:n {#3}
-    \@@_add_grabber_mandatory:N R
+    \@@_add_grabber:N R
     \tl_put_right:Nn \l_@@_signature_tl { #1 #2 }
     \@@_prepare_signature:N
   }
@@ -2210,7 +2372,7 @@
   {
     \@@_flush_m_args:
     \@@_add_default:
-    \@@_add_grabber_optional:N t
+    \@@_add_grabber:N t
     \tl_put_right:Nn \l_@@_signature_tl {#1}
     \@@_prepare_signature:N
   }
@@ -2225,7 +2387,7 @@
   {
     \@@_flush_m_args:
     \@@_add_default:
-    \@@_add_grabber_mandatory:N u
+    \@@_add_grabber:N u
     \tl_put_right:Nn \l_@@_signature_tl { {#1} }
     \@@_prepare_signature:N
   }
@@ -2241,7 +2403,7 @@
   {
     \@@_flush_m_args:
     \exp_args:No \@@_add_default:n \c_novalue_tl
-    \@@_add_grabber_mandatory:N v
+    \@@_add_grabber:N v
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
@@ -2251,9 +2413,7 @@
 %   As \texttt{m} arguments are simply counted, there is a need to add
 %   them to the token register in a block. As this function can only
 %   be called if something other than \texttt{m} turns up, the flag can
-%   be switched here. The total number of mandatory arguments which
-%   remain to be added to
-%   the signature is also decreased by the appropriate amount.
+%   be switched here.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_flush_m_args:
   {
@@ -2261,7 +2421,6 @@
       {
         \tl_put_right:Nx \l_@@_signature_tl
           { \exp_not:c { @@_grab_m_ \int_use:N \l_@@_m_args_int :w } }
-        \int_sub:Nn \l_@@_mandatory_args_int { \l_@@_m_args_int }
         \tl_put_right:Nx \l_@@_process_all_tl
           { \prg_replicate:nn { \l_@@_m_args_int } { { } } }
       }
@@ -2270,8 +2429,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_grabber_mandatory:N}
-% \begin{macro}{\@@_add_grabber_optional:N}
+% \begin{macro}{\@@_add_grabber:N}
 %   To keep the various checks needed in one place, adding the grabber
 %   to the signature is done here.  The only questions are whether the
 %   grabber should be long or not, and whether to obey spaces.  The
@@ -2279,13 +2437,8 @@
 %   trailing optional arguments.  In that case spaces will not be
 %   ignored when looking for that optional argument.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_grabber_mandatory:N #1
+\cs_new_protected:Npn \@@_add_grabber:N #1
   {
-    \@@_add_grabber_optional:N #1
-    \int_decr:N \l_@@_mandatory_args_int
-  }
-\cs_new_protected:Npn \@@_add_grabber_optional:N #1
-  {
     \tl_put_right:Nx \l_@@_signature_tl
       {
         \exp_not:c
@@ -2304,7 +2457,6 @@
   }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\@@_add_default:n, \@@_add_default:, \@@_add_default_E:nn}
 %   Store the default value of an argument, or rather code that gives
@@ -2593,6 +2745,60 @@
 % calls \cs{@@_add_arg:n}, responsible for calling processors and
 % grabbing further arguments.
 %
+% \begin{macro}
+%   {
+%     \@@_grab_b:w,
+%     \@@_grab_b_long:w,
+%     \@@_grab_b_obey_spaces:w,
+%     \@@_grab_b_long_obey_spaces:w,
+%     \@@_grab_b_aux:NNw,
+%     \@@_grab_b_end:Nw
+%   }
+%   This uses the well-tested code of \texttt{D}-type arguments,
+%   skipping the peeking step because the \texttt{b}-type argument is
+%   always present, and adding a cleanup stage at the end by hijacking
+%   the signature.  The clean-up consists of properly
+%   dealing with \cs{l_@@_args_tl} and also putting back the \cs{end}
+%   that served as an end-delimiter: this \cs{end} receives the
+%   environment name as its argument and is run normally.  The
+%   \texttt{D}-type code stores the argument found (body of the
+%   environment) as a brace group in \cs{l_@@_args_tl} and depending on
+%   the presence of a prefix~|!| we trim spaces or not before adding
+%   this braced argument into the saved \cs{l_@@_args_tl}.
+%   The strange \verb*|\begin | control sequence is there for display
+%     purposes only: it has to look like |\begin| in the terminal but
+%       not to delimited arguments.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_b:w
+  { \@@_grab_b_aux:NNw \cs_set_protected_nopar:Npn \tl_trim_spaces:n }
+\cs_new_protected:Npn \@@_grab_b_long:w
+  { \@@_grab_b_aux:NNw \cs_set_protected:Npn \tl_trim_spaces:n }
+\cs_new_protected:Npn \@@_grab_b_obey_spaces:w
+  { \@@_grab_b_aux:NNw \cs_set_protected_nopar:Npn \exp_not:n }
+\cs_new_protected:Npn \@@_grab_b_long_obey_spaces:w
+  { \@@_grab_b_aux:NNw \cs_set_protected:Npn \exp_not:n }
+\cs_new_protected:Npn \@@_grab_b_aux:NNw #1#2#3 \@@_run_code:
+  {
+    \@@_grab_D_aux:NNnN \begin \end {#3} #1
+    \tl_put_left:Nn \l_@@_signature_tl { \@@_grab_b_end:Nw #2 }
+    \tl_set_eq:NN \l_@@_saved_args_tl \l_@@_args_tl
+    \tl_clear:N \l_@@_args_tl
+    \exp_args:Nc \l_@@_fn_tl { begin ~ }
+  }
+\cs_new_protected:Npn \@@_grab_b_end:Nw #1#2 \@@_run_code:
+  {
+    \tl_set:Nx \l_@@_args_tl
+      {
+        \exp_not:V \l_@@_saved_args_tl
+        { \exp_after:wN #1 \l_@@_args_tl }
+      }
+    #2
+    \@@_run_code:
+    \end
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\@@_grab_D:w}
 % \begin{macro}{\@@_grab_D_long:w}
 % \begin{macro}{\@@_grab_D_obey_spaces:w}
@@ -3037,7 +3243,7 @@
       { \@@_grab_D_call:Nw #1 }
       {
         \__kernel_msg_error:nnxx { xparse } { missing-required }
-          { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
+          { \@@_environment_or_command: }
           { \token_to_str:N #1 }
         \@@_add_arg:o \c_novalue_tl
       }
@@ -3316,7 +3522,7 @@
       \peek_meaning_remove:NTF \char_generate:nn { \tex_endlinechar:D } { 6 }
       {
         \__kernel_msg_error:nnxxx { xparse } { verbatim-newline }
-          { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
+          { \@@_environment_or_command: }
           { \tl_to_str:N \l_@@_v_arg_tl }
           { \tl_to_str:n {#1} }
         \@@_add_arg:o \c_novalue_tl
@@ -3323,7 +3529,7 @@
       }
       {
         \__kernel_msg_error:nnxxx { xparse } { verbatim-tokenized }
-          { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
+          { \@@_environment_or_command: }
           { \tl_to_str:N \l_@@_v_arg_tl }
           { \tl_to_str:n {#1} }
         \@@_add_arg:o \c_novalue_tl
@@ -3673,8 +3879,10 @@
               \q_nil { } ##2 \ERROR \q_@@ \ERROR
           }
           {
-            \__kernel_msg_expandable_error:nnnn
-              { xparse } { missing-required } {##5} {##2}
+            \__kernel_msg_expandable_error:nnff
+              { xparse } { missing-required }
+              { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N ##5 } }
+              { \tl_to_str:n {##2} }
             ##4 {#1} \q_@@ ##5 ##6 {##7}
           }
       }
@@ -3709,8 +3917,10 @@
               ##6 \ERROR
           }
           {
-            \__kernel_msg_expandable_error:nnnn
-              { xparse } { missing-required } {##4} {##2}
+            \__kernel_msg_expandable_error:nnff
+              { xparse } { missing-required }
+              { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N ##4 } }
+              { \tl_to_str:n {##2} }
             ##3 {#1} \q_@@ ##4 ##5 {##6}
           }
       }
@@ -3891,35 +4101,38 @@
 % \subsection{Access to the argument specification}
 %
 % \begin{macro}{\@@_get_arg_spec_error:N, \@@_get_arg_spec_error:n}
+% \begin{macro}{\@@_get_arg_spec_error_aux:n}
 %   Provide an informative error when trying to get the argument
 %   specification of a non-\pkg{xparse} command or environment.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_get_arg_spec_error:N #1
   {
-    \cs_if_exist:NTF #1
-      {
-        \__kernel_msg_error:nnx { xparse } { non-xparse-command }
-          { \token_to_str:N #1 }
-      }
-      {
-        \__kernel_msg_error:nnx { xparse } { unknown-command }
-          { \token_to_str:N #1 }
-      }
+    \bool_set_false:N \l_@@_environment_bool
+    \tl_set:Nn \l_@@_fn_tl {#1}
+    \@@_get_arg_spec_error_aux:n { \cs_if_exist:NTF #1 }
   }
 \cs_new_protected:Npn \@@_get_arg_spec_error:n #1
   {
-    \cs_if_exist:cTF {#1}
+    \bool_set_true:N \l_@@_environment_bool
+    \str_set:Nx \l_@@_environment_str {#1}
+    \@@_get_arg_spec_error_aux:n
+      { \cs_if_exist:cTF { \l_@@_environment_str } }
+  }
+\cs_new_protected:Npn \@@_get_arg_spec_error_aux:n #1
+  {
+    #1
       {
-        \__kernel_msg_error:nnx { xparse } { non-xparse-environment }
-          { \tl_to_str:n {#1} }
+        \__kernel_msg_error:nnx { xparse } { non-xparse }
+          { \@@_environment_or_command: }
       }
       {
-        \__kernel_msg_error:nnx { xparse } { unknown-environment }
-          { \tl_to_str:n {#1} }
+        \__kernel_msg_error:nnx { xparse } { unknown }
+          { \@@_environment_or_command: }
       }
   }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\@@_get_arg_spec:NTF}
 %   If the command is not an \pkg{xparse} command, complain.  If it is,
@@ -4076,21 +4289,22 @@
 %   that its |arg_spec| is empty (this also excludes non-macros) and
 %   that its |replacement_spec| starts with either \cs{@@_start:nNNnnn}
 %   (non-expandable command) or \cs{@@_start_expandable:nNNNNn}
-%   (expandable command).
+%   (expandable command) or \cs{@@_start_env:nnnnn} (environment).
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_cmd_if_xparse:NTF #1
   {
     \exp_args:Nf \str_case_e:nnTF
       {
-        \exp_args:Nf \tl_if_empty:nT { \token_get_arg_spec:N #1 }
+        \exp_args:Nf \tl_if_empty:nT { \cs_argument_spec:N #1 }
           {
             \exp_last_unbraced:Nf \@@_cmd_if_xparse_aux:w
-              { \token_get_replacement_spec:N #1 } ~ \q_stop
+              { \cs_replacement_spec:N #1 } ~ \q_stop
           }
       }
       {
         { \token_to_str:N \@@_start:nNNnnn } { }
         { \token_to_str:N \@@_start_expandable:nNNNNn } { }
+        { \token_to_str:N \@@_start_env:nnnnn } { }
       }
   }
 \cs_new:Npn \@@_cmd_if_xparse_aux:w #1 ~ #2 \q_stop {#1}
@@ -4117,20 +4331,48 @@
 %
 % \subsection{Messages}
 %
-% Some messages intended as errors.
+% \begin{macro}{\@@_environment_or_command:}
+% \begin{variable}{\c_@@_ignore_def_tl}
+%   Two texts used in several messages.
 %    \begin{macrocode}
+\cs_new:Npn \@@_environment_or_command:
+  {
+    \bool_if:NTF \l_@@_environment_bool
+      { environment ~ ' \l_@@_environment_str ' }
+      {
+        command ~ '
+        \exp_args:Nf \tl_trim_spaces:n
+          { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
+        '
+      }
+  }
+\tl_const:Nn \c_@@_ignore_def_tl
+  { \\ \\ LaTeX~will~ignore~this~entire~definition. }
+%    \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% Some messages intended as errors when defining commands/environments.
+%    \begin{macrocode}
+\__kernel_msg_new:nnnn { xparse } { arg-after-body }
+  { In~the~definition~of~#1,~b~(body)~argument~must~be~last. }
+  {
+    The~'body'~argument~type~is~followed~by~'#2'~in~the~argument~
+    specification~of~the~#1.~This~is~not~allowed.
+    \c_@@_ignore_def_tl
+  }
 \__kernel_msg_new:nnnn { xparse } { bad-arg-spec }
-  { Bad~argument~specification~'#2'~for~command~'#1'. }
+  { Bad~argument~specification~'#2'~for~#1. }
   {
     The~argument~specification~provided~was~not~valid:~
-    one~or~more~mandatory~pieces~of~information~were~missing. \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    one~or~more~mandatory~pieces~of~information~were~missing.
+    \c_@@_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { command-already-defined }
   { Command~'#1'~already~defined! }
   {
     You~have~used~#2~
-    with~a~command~that~already~has~a~definition. \\
+    with~a~command~that~already~has~a~definition. \\ \\
     The~existing~definition~of~'#1'~will~not~be~altered.
   }
 \__kernel_msg_new:nnnn { xparse } { command-not-yet-defined }
@@ -4137,22 +4379,22 @@
   { Command ~'#1'~not~yet~defined! }
   {
     You~have~used~#2~
-    with~a~command~that~was~never~defined. \\
-    LaTeX~will~ignore~this~entire~definition.
+    with~a~command~that~was~never~defined.
+    \c_@@_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { environment-already-defined }
   { Environment~'#1'~already~defined! }
   {
     You~have~used~\NewDocumentEnvironment
-    with~an~environment~that~already~has~a~definition. \\
-    The~existing~definition~of~'#1'~will~be~overwritten.
+    with~an~environment~that~already~has~a~definition. \\ \\
+    The~existing~definition~of~'#1'~will~not~be~altered.
   }
 \__kernel_msg_new:nnnn { xparse } { environment-not-yet-defined }
   { Environment~'#1'~not~yet~defined! }
   {
     You~have~used~\RenewDocumentEnvironment
-    with~an~environment~that~was~never~defined. \\
-    LaTeX~will~ignore~this~entire~definition.
+    with~an~environment~that~was~never~defined.
+    \c_@@_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { expandable-ending-optional }
   {
@@ -4164,12 +4406,6 @@
     (or~no~arguments~at~all).~You~cannot~have~a~terminal~optional~
     argument~with~expandable~commands.
   }
-\__kernel_msg_new:nnnn { xparse } { if-boolean }
-  { Invalid~use~\iow_char:N\\IfBooleanTF~{#1} }
-  {
-    The~first~argument~of~\iow_char:N\\IfBoolean(TF/T/F)~must~be~
-    a~boolean~argument~obtained~from~parsing~'s'~or~'t'~arguments.
-  }
 \__kernel_msg_new:nnnn { xparse } { inconsistent-long }
   { Inconsistent~long~arguments~for~expandable~command~'#1'. }
   {
@@ -4176,13 +4412,20 @@
     The~arguments~for~an~expandable~command~must~not~involve~short~
     arguments~after~long~arguments.~You~have~tried~to~mix~the~two~types.
   }
+\__kernel_msg_new:nnnn { xparse } { invalid-command-arg }
+  { Argument~type~'#2'~not~available~for~#1. }
+  {
+    The~letter~'#2'~can~only~be~used~in~environment~argument~
+    specifications,~not~for~commands.
+    \\ \\
+    LaTeX~will~ignore~this~entire~definition.
+  }
 \__kernel_msg_new:nnnn { xparse } { invalid-expandable-argument-type }
   { Argument~type~'#2'~not~available~for~expandable~command~'#1'. }
   {
-    The~letter~'#2'~does~not~specify~an~argument~type~which~can~be~used~
+    The~letter~'#2'~specifies~an~argument~type~which~cannot~be~used~
     in~an~expandable~command.
-    \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    \c_@@_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { invalid-after-optional-expandably }
   {
@@ -4190,42 +4433,16 @@
     for~expandable~command~'#1'.
   }
   {
-    The~letter~'#2'~does~not~specify~an~argument~type~which~can~be~used~
+    The~letter~'#2'~specifies~an~argument~type~which~cannot~be~used~
     in~an~expandable~command~after~an~optional~argument.
-    \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    \c_@@_ignore_def_tl
   }
-\__kernel_msg_new:nnnn { xparse } { loop-in-defaults }
-  { Circular~dependency~in~defaults~of~'#1'. }
-  {
-    The~default~values~of~two~or~more~arguments~of~'#1'~depend~on~each~
-    other~in~a~way~that~cannot~be~resolved.
-  }
-\__kernel_msg_new:nnnn { xparse } { missing-required }
-  { Failed~to~find~required~argument~starting~with~'#2'~for~command~'#1'. }
-  {
-    The~current~command~'#1'~expects~an~argument~starting~with~'#2'.~
-    LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed.
-  }
 \__kernel_msg_new:nnnn { xparse } { non-trailing-obey-spaces }
-  { Prefix~'!'~used~before~mandatory~argument~'#2'~of~command~'#1'. }
+  { Prefix~'!'~used~before~mandatory~argument~'#2'~of~#1. }
   {
     The~prefix~'!'~can~only~apply~to~trailing~optional~arguments.
-    \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    \c_@@_ignore_def_tl
   }
-\__kernel_msg_new:nnnn { xparse } { non-xparse-command }
-  { Command~'#1'~not~defined~using~xparse. }
-  {
-    You~have~asked~for~the~argument~specification~for~a~command~'#1',~
-    but~this~is~not~a~command~defined~using~xparse.
-  }
-\__kernel_msg_new:nnnn { xparse } { non-xparse-environment }
-  { Environment~'#1'~not~defined~using~xparse. }
-  {
-    You~have~asked~for~the~argument~specification~for~an~environment~'#1',~
-    but~this~is~not~an~environment~defined~using~xparse.
-  }
 \__kernel_msg_new:nnnn { xparse } { not-definable }
   { First~argument~of~'#2'~must~be~a~command. }
   {
@@ -4232,8 +4449,7 @@
     The~first~argument~of~'#2'~should~be~the~document~command~that~will~
     be~defined.~The~provided~argument~'#1'~is~a~character.~Perhaps~a~
     backslash~is~missing?
-    \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    \c_@@_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { not-one-token }
   { First~argument~of~'#2'~must~be~a~command. }
@@ -4240,81 +4456,99 @@
   {
     The~first~argument~of~'#2'~should~be~the~document~command~that~will~
     be~defined.~The~provided~argument~'#1'~contains~more~than~one~
-    token.
-    \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    token.~Perhaps~a~backslash~is~missing?
+    \c_@@_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { not-single-char }
   {
-    Argument~delimiter~'#2'~for~the~command~'#1'~should~be~
+    Argument~delimiter~'#2'~for~the~#1~should~be~
     a~single~character.
   }
   {
     The~argument~specification~provided~was~not~valid:~in~a~place~
-    where~a~single~character~is~required,~LaTeX~found~'#2'. \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    where~a~single~character~is~required,~LaTeX~found~'#2'.
+    \c_@@_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { processor-in-expandable }
   { Argument~processor~'>{#2}'~cannot~be~used~for~the~expandable~command~'#1'. }
   {
     The~argument~specification~for~#1~contains~a~processor~function:~
-    this~is~only~supported~for~standard~robust~commands. \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    this~is~only~supported~for~standard~robust~commands.
+    \c_@@_ignore_def_tl
   }
-\__kernel_msg_new:nnnn { xparse } { split-excess-tokens }
-  { Too~many~'#1'~tokens~when~trying~to~split~argument. }
-  {
-    LaTeX~was~asked~to~split~the~input~'#3'~
-    at~each~occurrence~of~the~token~'#1',~up~to~a~maximum~of~#2~parts.~
-    There~were~too~many~'#1'~tokens.
-  }
 \__kernel_msg_new:nnnn { xparse } { too-many-arguments }
-  { Too~many~arguments~in~argument~specification~'#2'~of~command~'#1'. }
+  { Too~many~arguments~in~argument~specification~'#2'~of~#1. }
   {
     The~argument~specification~provided~has~more~than~9~arguments.~
-    This~cannot~be~implemented. \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    This~cannot~be~implemented.
+    \c_@@_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { two-markers }
-  { Two~'#2'~apply~to~the~same~argument~in~argument~specification~of~command~'#1'. }
+  { Two~'#2'~apply~to~the~same~argument~in~argument~specification~of~#1. }
   {
     The~argument~specification~provided~has~two~markers~'#2'~applying~
     to~the~same~argument;~these~are~redundant.
   }
 \__kernel_msg_new:nnnn { xparse } { unknown-argument-type }
-  { Unknown~argument~type~'#2'~for~the~command~'#1'. }
+  { Unknown~argument~type~'#2'~for~the~#1. }
   {
-    The~letter~'#2'~does~not~specify~a~known~argument~type.~
-    LaTeX~will~ignore~this~entire~definition.
+    The~letter~'#2'~does~not~specify~a~known~argument~type.
+    \c_@@_ignore_def_tl
   }
-\__kernel_msg_new:nnnn { xparse } { unknown-command }
-  { Unknown~document~command~'#1'. }
+%    \end{macrocode}
+%
+% Errors when using commands/environments.  The \texttt{if-boolean}
+% message is always used in expandable errors.  The
+% \texttt{loop-in-defaults} and \texttt{missing-required} messages can
+% be expandable or not expandable.
+%    \begin{macrocode}
+\__kernel_msg_new:nnn { xparse } { if-boolean }
+  { Invalid~use~\iow_char:N\\IfBooleanTF~{#1} }
+\__kernel_msg_new:nnnn { xparse } { loop-in-defaults }
+  { Defaults~of~#1~have~circular~dependency. }
   {
-    You~have~asked~for~the~argument~specification~for~a~command~'#1',~
-    but~it~is~not~defined.
+    The~default~values~of~two~or~more~arguments~of~the~#1~
+    depend~on~each~other~in~a~way~that~cannot~be~resolved.
   }
-\__kernel_msg_new:nnnn { xparse } { unknown-environment }
-  { Unknown~document~environment~'#1'. }
+\__kernel_msg_new:nnnn { xparse } { missing-required }
+  { Missing~required~argument~for~#1. }
   {
-    You~have~asked~for~the~argument~specification~for~an~environment~'#1',~
+    The~current~#1~expects~an~argument~starting~with~'#2'.~
+    LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed.
+  }
+\__kernel_msg_new:nnnn { xparse } { non-xparse }
+  { \str_upper_case:n #1~not~defined~using~xparse. }
+  {
+    You~have~asked~for~the~argument~specification~for~the~#1,~
+    but~this~was~not~defined~using~xparse.
+  }
+\__kernel_msg_new:nnnn { xparse } { split-excess-tokens }
+  { Too~many~'#1'~tokens~when~trying~to~split~argument. }
+  {
+    LaTeX~was~asked~to~split~the~input~'#3'~
+    at~each~occurrence~of~the~token~'#1',~up~to~a~maximum~of~#2~parts.~
+    There~were~too~many~'#1'~tokens.
+  }
+\__kernel_msg_new:nnnn { xparse } { unknown }
+  { Unknown~document~#1. }
+  {
+    You~have~asked~for~the~argument~specification~for~the~#1,~
     but~it~is~not~defined.
   }
 \__kernel_msg_new:nnnn { xparse } { verbatim-newline }
-  { Verbatim~argument~of~'#1'~ended~by~end~of~line. }
+  { Verbatim~argument~of~#1~ended~by~end~of~line. }
   {
-    The~verbatim~argument~of~'#1'~cannot~contain~more~than~one~line,~
+    The~verbatim~argument~of~the~#1~cannot~contain~more~than~one~line,~
     but~the~end~
-    of~the~current~line~has~been~reached.~You~have~probably~forgotten~the~
+    of~the~current~line~has~been~reached.~You~may~have~forgotten~the~
     closing~delimiter.
     \\ \\
     LaTeX~will~ignore~'#2'.
   }
 \__kernel_msg_new:nnnn { xparse } { verbatim-tokenized }
+  { The~verbatim~#1~cannot~be~used~inside~an~argument. }
   {
-    The~verbatim~command~'#1'~cannot~be~used~inside~an~argument.~
-  }
-  {
-    The~command~'#1'~takes~a~verbatim~argument.~
+    The~#1~takes~a~verbatim~argument.~
     It~may~not~appear~within~the~argument~of~another~function.~
     It~received~an~illegal~token \tl_if_empty:nF {#3} { ~'#3' } .
     \\ \\
@@ -4435,7 +4669,7 @@
     \cs_if_exist:cTF {#1}
       { \__kernel_msg_error:nnx { xparse } { environment-already-defined } {#1} }
       { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} }
-}
+  }
 \cs_new_protected:Npn \RenewDocumentEnvironment #1#2#3#4
   {
     \cs_if_exist:cTF {#1}
@@ -4456,7 +4690,10 @@
 % \begin{macro}{\RenewExpandableDocumentCommand}
 % \begin{macro}{\ProvideExpandableDocumentCommand}
 % \begin{macro}{\DeclareExpandableDocumentCommand}
-%   The expandable versions are essentially the same as the basic functions.
+%   The expandable versions are essentially the same as the basic
+%   functions.  The strange \cs{use:nnn} is there in case |#1| is
+%   surrounded with spaces, as can happen with usual document catcodes
+%   in \cs{RenewExpandableDocumentCommand} |{| |\!| |}| \ldots{}
 %    \begin{macrocode}
 \cs_new_protected:Npn \NewExpandableDocumentCommand #1#2#3
   {
@@ -4505,19 +4742,34 @@
 %
 % \begin{macro}{\IfBooleanT, \IfBooleanF, \IfBooleanTF}
 %   The logical \meta{true} and \meta{false} statements are just the
-%   normal \cs{c_true_bool} and \cs{c_false_bool}, so testing for them is
-%   done with the \cs{bool_if:NTF} functions from \textsf{l3prg}.
+%   normal \cs{c_true_bool} and \cs{c_false_bool} so \cs{bool_if:NTF} is
+%   almost enough.  However, this code-level function blows up badly
+%   when passed invalid input.  We want \cs{IfBooleanTF} to accept a
+%   single (non-space) token equal to \cs{c_true_bool} or
+%   \cs{c_false_bool}, possibly surrounded by spaces.  If the input is
+%   blank or multiple items, jump to the error and pick the false
+%   branch.  If the input, ignoring spaces (we do this by omitting
+%   braces in the \cs{tl_if_single_token:nF} test), is not a single
+%   token then jump to the error as well.  It is then safe to compare
+%   the token to the two booleans, picking the appropriate branch.  If
+%   neither matches, we jump to the error as well.
 %    \begin{macrocode}
 \cs_new:Npn \IfBooleanTF #1
   {
-    \bool_lazy_and:nnTF
-      { \tl_if_single_p:n {#1} }
-      { \tl_if_single_token_p:n #1 }
-      { \bool_if:NTF #1 }
-      {
-        \__kernel_msg_error:nnn { xparse } { if-boolean } {#1}
-        \use_ii:nn
-      }
+    \tl_if_single:nF {#1}
+      { \prg_break:n { \use:n } }
+    \tl_if_single_token:nF #1
+      { \prg_break:n { \use:n } }
+    \token_if_eq_meaning:NNT #1 \c_true_bool
+      { \prg_break:n { \use_ii:nnn } }
+    \token_if_eq_meaning:NNT #1 \c_false_bool
+      { \prg_break:n { \use_iii:nnn } }
+    \prg_break:n { \use:n }
+    \prg_break_point:
+    {
+      \__kernel_msg_expandable_error:nnn { xparse } { if-boolean } {#1}
+      \use_ii:nn
+    }
   }
 \cs_new:Npn \IfBooleanT #1#2 { \IfBooleanTF {#1} {#2} { } }
 \cs_new:Npn \IfBooleanF #1 { \IfBooleanTF {#1} { } }

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,9 @@
 \iffalse meta-comment
 
-File xparse.ins Copyright (C) 2000-2012,2016,2017 The LaTeX3 Project
+File: xparse.ins
 
+Copyright (C) 2000-2012,2016,2017,2019 The LaTeX3 Project
+
 It may be distributed and/or modified under the conditions of the
 LaTeX Project Public License (LPPL), either version 1.3c of this
 license or (at your option) any later version.  The latest version
@@ -21,7 +23,7 @@
 
 \preamble
 
-Copyright (C) 2009-2017 The LaTeX3 Project
+Copyright (C) 2009-2019 The LaTeX3 Project
 
 It may be distributed and/or modified under the conditions of
 the LaTeX Project Public License (LPPL), either version 1.3c of

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,11 +1,11 @@
 % \iffalse meta-comment
 %
-%% File: xtemplate.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley,
-%%                         David Carlisle
-%%                     (C) Copyright 2004-2010 Frank Mittelbach,
-%%                         The LaTeX3 Project
-%%                     (C) Copyright 2011-2018 The LaTeX3 Project
+%% File: xtemplate.dtx
 %
+% Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle
+%           (C) 2004-2010 Frank Mittelbach, The LaTeX3 Project
+%           (C) 2011-2019 The LaTeX3 Project
+%
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
 % license or (at your option) any later version.  The latest version
@@ -63,7 +63,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2018-10-17}
+% \date{Released 2019-03-05}
 %
 % \maketitle
 %
@@ -682,7 +682,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xtemplate}{2018-10-17}{}
+\ProvidesExplPackage{xtemplate}{2019-03-05}{}
   {L3 Experimental prototype document functions}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.ins	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.ins	2019-03-05 22:35:14 UTC (rev 50246)
@@ -1,7 +1,9 @@
 \iffalse meta-comment
 
-File xtemplate.ins Copyright (C) 2000-2012,2016,2017 The LaTeX3 Project
+File: xtemplate.ins
 
+Copyright (C) 2000-2012,2016,2017,2019 The LaTeX3 Project
+
 It may be distributed and/or modified under the conditions of the
 LaTeX Project Public License (LPPL), either version 1.3c of this
 license or (at your option) any later version.  The latest version
@@ -32,7 +34,7 @@
 
 \preamble
 
-Copyright (C) 2011-2017 The LaTeX3 Project
+Copyright (C) 2011-2019 The LaTeX3 Project
 
 It may be distributed and/or modified under the conditions of
 the LaTeX Project Public License (LPPL), either version 1.3c of

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3benchmark/l3benchmark.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3benchmark.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3benchmark}{2019-01-28}{}
+\ProvidesExplPackage{l3benchmark}{2019-03-05}{}
   {L3 Experimental benchmarking}
 \sys_if_engine_luatex:TF
   {

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3cctab/l3cctab.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3cctab/l3cctab.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3cctab/l3cctab.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3cctab.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3cctab}{2019-01-28}{}
+\ProvidesExplPackage{l3cctab}{2019-03-05}{}
   {L3 Experimental category code tables}
 \int_new:N  \g__cctab_allocate_int
 \int_gset:Nn \g__cctab_allocate_int { -1 }

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3color/l3color.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3color/l3color.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3color/l3color.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3color.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3color}{2019-01-28}{}
+\ProvidesExplPackage{l3color}{2019-03-05}{}
   {L3 Experimental color support}
 \tl_new:N \l__color_tmp_tl
 \prg_new_conditional:Npnn \__color_if_defined:n #1 { T, F, TF }

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3draw/l3draw.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -6,6 +6,7 @@
 %%
 %% l3draw.dtx  (with options: `package')
 %% l3draw-boxes.dtx  (with options: `package')
+%% l3draw-layers.dtx  (with options: `package')
 %% l3draw-paths.dtx  (with options: `package')
 %% l3draw-points.dtx  (with options: `package')
 %% l3draw-scopes.dtx  (with options: `package')
@@ -27,7 +28,7 @@
 %% 
 %% File: l3draw.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3draw}{2019-01-28}{}
+\ProvidesExplPackage{l3draw}{2019-03-05}{}
   {L3 Experimental core drawing support}
 \RequirePackage { l3color }
 %% File: l3draw-boxes.dtx
@@ -90,6 +91,101 @@
         { \box_ht:N \l__draw_tmp_box }
     \group_end:
   }
+%% File: l3draw-layers.dtx
+\cs_new_protected:Npn \draw_layer_new:n #1
+  {
+    \str_if_eq:nnTF {#1} { main }
+      { \msg_error:nnn { draw } { main-reserved } }
+      {
+        \box_new:c { g__draw_layer_ #1 _box }
+        \box_new:c { l__draw_layer_ #1 _box }
+      }
+  }
+\tl_new:N \l__draw_layer_tl
+\tl_set:Nn \l__draw_layer_tl { main }
+\bool_new:N \l__draw_layer_close_bool
+\clist_new:N \l_draw_layers_clist
+\clist_set:Nn \l_draw_layers_clist { main }
+\clist_new:N \g__draw_layers_clist
+\cs_new_protected:Npn \draw_layer_begin:n #1
+  {
+    \group_begin:
+      \box_if_exist:cTF { g__draw_layer_ #1 _box }
+        {
+          \str_if_eq:VnTF \l__draw_layer_tl {#1}
+            { \bool_set_false:N \l__draw_layer_close_bool }
+            {
+              \bool_set_true:N \l__draw_layer_close_bool
+              \tl_set:Nn \l__draw_layer_tl {#1}
+              \box_gset_wd:cn { g__draw_layer_ #1 _box } { 0pt }
+              \hbox_gset:cw { g__draw_layer_ #1 _box }
+                \box_use_drop:c { g__draw_layer_ #1 _box }
+                \group_begin:
+            }
+          \draw_linewidth:n { \l_draw_default_linewidth_dim }
+        }
+        {
+          \str_if_eq:nnTF {#1} { main }
+            { \msg_error:nnn { draw } { unknown-layer } {#1} }
+            { \msg_error:nnn { draw } { main-layer } }
+        }
+  }
+\cs_new_protected:Npn \draw_layer_end:
+  {
+      \bool_if:NT \l__draw_layer_close_bool
+        {
+            \group_end:
+          \hbox_gset_end:
+        }
+    \group_end:
+  }
+\cs_new_protected:Npn \__draw_layers_insert:
+  {
+    \clist_map_inline:Nn \l_draw_layers_clist
+      {
+        \str_if_eq:nnTF {##1} { main }
+          {
+            \box_set_wd:Nn \l__draw_layer_main_box { 0pt }
+            \box_use_drop:N \l__draw_layer_main_box
+          }
+          {
+            \driver_draw_scope_begin:
+            \box_gset_wd:cn { g__draw_layer_ ##1 _box } { 0pt }
+            \box_use_drop:c { g__draw_layer_ ##1 _box }
+            \driver_draw_scope_end:
+          }
+      }
+  }
+\cs_new_protected:Npn \__draw_layers_save:
+  {
+    \clist_map_inline:Nn \l_draw_layers_clist
+      {
+        \str_if_eq:nnF {##1} { main }
+          {
+            \box_set_eq:cc { l__draw_layer_ ##1 _box }
+              { g__draw_layer_ ##1 _box }
+          }
+      }
+  }
+\cs_new_protected:Npn \__draw_layers_restore:
+  {
+    \clist_map_inline:Nn \l_draw_layers_clist
+      {
+        \str_if_eq:nnF {##1} { main }
+          {
+            \box_gset_eq:cc { g__draw_layer_ ##1 _box }
+              { l__draw_layer_ ##1 _box }
+          }
+      }
+  }
+\msg_new:nnnn { draw } { main-layer }
+  { Material~cannot~be~added~to~'main'~layer. }
+  { The~main~layer~may~only~be~accessed~at~the~top~level. }
+\msg_new:nnn { draw } { main-reserved }
+  { The~'main'~layer~is~reserved. }
+\msg_new:nnnn { draw } { unknown-layer }
+  { Layer~'#1'~has~not~been~created. }
+  { You~have~tried~to~use~layer~'#1',~but~it~was~never~set~up. }
 %% File: l3draw-paths.dtx
 \tl_new:N \l__draw_path_tmp_tl
 \fp_new:N \l__draw_path_tmpa_fp
@@ -183,15 +279,12 @@
   }
 \cs_new_protected:Npn \draw_path_curveto:nnn #1#2#3
   {
-    \__draw_point_process:nnn
+    \__draw_point_process:nnnn
       {
-        \__draw_point_process:nn
-          {
-            \__draw_path_mark_corner:
-            \__draw_path_curveto:nnnnnn
-          }
-          { \draw_point_transform:n {#1} }
+        \__draw_path_mark_corner:
+        \__draw_path_curveto:nnnnnn
       }
+      { \draw_point_transform:n {#1} }
       { \draw_point_transform:n {#2} }
       { \draw_point_transform:n {#3} }
   }
@@ -214,16 +307,12 @@
   { \__draw_point_process:nn { \__draw_path_lineto:nn } {#1} }
 \cs_new_protected:Npn \draw_path_canvas_curveto:nnn #1#2#3
   {
-    \__draw_point_process:nnn
+    \__draw_point_process:nnnn
       {
-        \__draw_point_process:nn
-          {
-            \__draw_path_mark_corner:
-            \__draw_path_curveto:nnnnnn
-          }
-          {#1}
+        \__draw_path_mark_corner:
+        \__draw_path_curveto:nnnnnn
       }
-      {#2} {#3}
+      {#1} {#2} {#3}
   }
 \cs_new_protected:Npn \draw_path_curveto:nn #1#2
   {
@@ -353,14 +442,11 @@
         \__draw_point_transform_noshift:n
           { \draw_point_polar:nnn { #1 #4 90 } {#7} {#8} }
       }
-    \__draw_point_process:nn
+    \__draw_point_process:nnn
+      { \__draw_path_arc_auxiv:nnnn }
       {
-        \__draw_point_process:nn
-          { \__draw_path_arc_auxiv:nnnn }
-          {
-            \draw_point_transform:n
-              { \draw_point_polar:nnn {#1} {#5} {#6} }
-          }
+        \draw_point_transform:n
+          { \draw_point_polar:nnn {#1} {#5} {#6} }
       }
       {
         \draw_point_transform:n
@@ -417,12 +503,9 @@
   }
 \cs_new_protected:Npn \draw_path_ellipse:nnn #1#2#3
   {
-    \__draw_point_process:nnn
-      {
-        \__draw_point_process:nn
-          { \__draw_path_ellipse:nnnnnn }
-          { \draw_point_transform:n {#1} }
-      }
+    \__draw_point_process:nnnn
+      { \__draw_path_ellipse:nnnnnn }
+      { \draw_point_transform:n {#1} }
       { \__draw_point_transform_noshift:n {#2} }
       { \__draw_point_transform_noshift:n {#3} }
   }
@@ -706,18 +789,17 @@
 %% File: l3draw-points.dtx
 \cs_new:Npn \__draw_point_process:nn #1#2
   {
-    \__draw_point_process_auxi:fn
+    \exp_args:Nf \__draw_point_process_auxi:nn
       { \__draw_point_to_dim:n {#2} }
       {#1}
   }
 \cs_new:Npn \__draw_point_process_auxi:nn #1#2
   { \__draw_point_process_auxii:nw {#2} #1 \q_stop }
-\cs_generate_variant:Nn \__draw_point_process_auxi:nn { f }
 \cs_new:Npn \__draw_point_process_auxii:nw #1 #2 , #3 \q_stop
   { #1 {#2} {#3} }
 \cs_new:Npn \__draw_point_process:nnn #1#2#3
   {
-    \__draw_point_process_auxiii:ffn
+    \exp_args:Nff \__draw_point_process_auxiii:nnn
       { \__draw_point_to_dim:n {#2} }
       { \__draw_point_to_dim:n {#3} }
       {#1}
@@ -724,9 +806,38 @@
   }
 \cs_new:Npn \__draw_point_process_auxiii:nnn #1#2#3
   { \__draw_point_process_auxiv:nw {#3} #1 \q_mark #2 \q_stop }
-\cs_generate_variant:Nn \__draw_point_process_auxiii:nnn { ff }
 \cs_new:Npn \__draw_point_process_auxiv:nw #1 #2 , #3 \q_mark #4 , #5 \q_stop
   { #1 {#2} {#3} {#4} {#5} }
+\cs_new:Npn \__draw_point_process:nnnn #1#2#3#4
+  {
+    \exp_args:Nfff \__draw_point_process_auxv:nnnn
+      { \__draw_point_to_dim:n {#2} }
+      { \__draw_point_to_dim:n {#3} }
+      { \__draw_point_to_dim:n {#4} }
+      {#1}
+  }
+\cs_new:Npn \__draw_point_process_auxv:nnnn #1#2#3#4
+  { \__draw_point_process_auxvi:nw {#4} #1 \q_mark #2 \q_mark #3 \q_stop }
+\cs_new:Npn \__draw_point_process_auxvi:nw
+  #1 #2 , #3 \q_mark #4 , #5 \q_mark #6 , #7 \q_stop
+  { #1 {#2} {#3} {#4} {#5} {#6} {#7} }
+\cs_new:Npn \__draw_point_process:nnnnn #1#2#3#4#5
+  {
+    \exp_args:Nffff \__draw_point_process_auxvii:nnnnn
+      { \__draw_point_to_dim:n {#2} }
+      { \__draw_point_to_dim:n {#3} }
+      { \__draw_point_to_dim:n {#4} }
+      { \__draw_point_to_dim:n {#5} }
+      {#1}
+  }
+\cs_new:Npn \__draw_point_process_auxvii:nnnnn #1#2#3#4#5
+  {
+    \__draw_point_process_auxviii:nw
+      {#5} #1 \q_mark #2 \q_mark #3 \q_mark #4 \q_stop
+  }
+\cs_new:Npn \__draw_point_process_auxviii:nw
+  #1 #2 , #3 \q_mark #4 , #5 \q_mark #6 , #7 \q_mark #8 , #9 \q_stop
+  { #1 {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9} }
 \cs_new:Npn \__draw_point_to_dim:n #1
   { \__draw_point_to_dim_aux:f { \fp_eval:n {#1} } }
 \cs_new:Npn \__draw_point_to_dim_aux:n #1
@@ -749,12 +860,9 @@
   }
 \cs_new:Npn \draw_point_intersect_lines:nnnn #1#2#3#4
   {
-    \__draw_point_process:nnn
-      {
-        \__draw_point_process:nnn
-          { \__draw_point_intersect_lines:nnnnnnnn } {#3} {#4}
-      }
-      {#1} {#2}
+    \__draw_point_process:nnnnn
+      { \__draw_point_intersect_lines:nnnnnnnn }
+      {#1} {#2} {#3} {#4}
   }
 \cs_new:Npn \__draw_point_intersect_lines:nnnnnnnn #1#2#3#4#5#6#7#8
   {
@@ -866,18 +974,14 @@
 \cs_generate_variant:Nn \__draw_point_interpolate_distance:nnnnn { f }
 \cs_new:Npn \draw_point_interpolate_arcaxes:nnnnnn #1#2#3#4#5#6
   {
-    \__draw_point_process:nnn
-      {
-        \__draw_point_process:nn
-          { \__draw_point_interpolate_arcaxes_auxi:nnnnnnnnn {#1} {#5} {#6} }
-          {#4}
-      }
-      {#2} {#3}
+    \__draw_point_process:nnnn
+      { \__draw_point_interpolate_arcaxes_auxi:nnnnnnnnn {#1} {#5} {#6} }
+      {#2} {#3} {#4}
   }
 \cs_new:Npn \__draw_point_interpolate_arcaxes_auxi:nnnnnnnnn #1#2#3#4#5#6#7#8#9
   {
     \__draw_point_interpolate_arcaxes_auxii:fnnnnnnnn
-      { \fp_eval:n {#1} } {#2} {#3} {#6} {#7} {#8} {#9} {#4} {#5}
+      { \fp_eval:n {#1} } {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9}
   }
 \cs_new:Npn \__draw_point_interpolate_arcaxes_auxii:nnnnnnnnn #1#2#3#4#5#6#7#8#9
   {
@@ -902,19 +1006,15 @@
 \cs_generate_variant:Nn \__draw_point_interpolate_arcaxes_auxiv:nnnnnnnn { ff }
 \cs_new:Npn \draw_point_interpolate_curve:nnnnnn #1#2#3#4#5
   {
-    \__draw_point_process:nnn
-      {
-        \__draw_point_process:nnn
-          { \__draw_point_interpolate_curve_auxi:nnnnnnnnn {#1} }
-          {#4} {#5}
-      }
-      {#2} {#3}
+    \__draw_point_process:nnnnn
+      { \__draw_point_interpolate_curve_auxi:nnnnnnnnn {#1} }
+      {#2} {#3} {#4} {#5}
   }
 \cs_new:Npn \__draw_point_interpolate_curve_auxi:nnnnnnnnn #1#2#3#4#5#6#7#8#9
   {
     \__draw_point_interpolate_curve_auxii:fnnnnnnnn
       { \fp_eval:n {#1} }
-      {#6} {#7} {#8} {#9} {#2} {#3} {#4} {#5}
+      {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9}
   }
 \cs_new:Npn \__draw_point_interpolate_curve_auxii:nnnnnnnnn
   #1#2#3#4#5#6#7#8#9
@@ -1095,6 +1195,7 @@
 \dim_new:N \g__draw_ymin_dim
 \bool_new:N \l_draw_bb_update_bool
 \box_new:N \l__draw_main_box
+\box_new:N \l__draw_layer_main_box
 \int_new:N \g__draw_id_int
 \cs_new_protected:Npn \__draw_reset_bb:
   {
@@ -1122,9 +1223,13 @@
         \draw_join_miter:
         \draw_miterlimit:n { 10 }
         \draw_dash_pattern:nn { } { 0cm }
+        \hbox_set:Nw \l__draw_layer_main_box
   }
 \cs_new_protected:Npn \draw_end:
   {
+          \exp_args:NNNV \hbox_set_end:
+          \clist_set:Nn \l_draw_layers_clist \l_draw_layers_clist
+          \__draw_layers_insert:
         \driver_draw_end:
       \hbox_set_end:
       \dim_compare:nNnT \g__draw_xmin_dim = \c_max_dim
@@ -1193,9 +1298,11 @@
     \draw_path_scope_begin:
     \draw_transform_matrix_reset:
     \draw_transform_shift_reset:
+    \__draw_layers_save:
   }
 \cs_new_protected:Npn \draw_suspend_end:
   {
+    \__draw_layers_restore:
     \draw_path_scope_end:
     \__draw_scope_bb_end:
   }
@@ -1603,7 +1710,7 @@
   }
 \draw_transform_matrix_reset:
 \draw_transform_shift_reset:
-\cs_new_protected:Npn \draw_transform_matrix:nnnn #1#2#3#4
+\cs_new_protected:Npn \draw_transform_matrix_absolute:nnnn #1#2#3#4
   {
     \fp_set:Nn \l__draw_matrix_a_fp {#1}
     \fp_set:Nn \l__draw_matrix_b_fp {#2}
@@ -1619,21 +1726,21 @@
       { \bool_set_false:N \l__draw_matrix_active_bool }
       { \bool_set_true:N \l__draw_matrix_active_bool }
   }
-\cs_new_protected:Npn \draw_transform_shift:n #1
+\cs_new_protected:Npn \draw_transform_shift_absolute:n #1
   {
     \__draw_point_process:nn
-      { \__draw_transform_shift:nn } {#1}
+      { \__draw_transform_shift_absolute:nn } {#1}
   }
-\cs_new_protected:Npn \__draw_transform_shift:nn #1#2
+\cs_new_protected:Npn \__draw_transform_shift_absolute:nn #1#2
   {
     \dim_set:Nn \l__draw_xshift_dim {#1}
     \dim_set:Nn \l__draw_yshift_dim {#2}
   }
-\cs_new_protected:Npn \draw_transform_matrix_concat:nnnn #1#2#3#4
+\cs_new_protected:Npn \draw_transform_matrix:nnnn #1#2#3#4
   {
     \use:x
       {
-        \__draw_transform_concat:nnnn
+        \__draw_transform:nnnn
           { \fp_eval:n {#1} }
           { \fp_eval:n {#2} }
           { \fp_eval:n {#3} }
@@ -1640,11 +1747,11 @@
           { \fp_eval:n {#4} }
       }
   }
-\cs_new_protected:Npn \__draw_transform_concat:nnnn #1#2#3#4
+\cs_new_protected:Npn \__draw_transform:nnnn #1#2#3#4
   {
     \use:x
       {
-        \draw_transform_matrix:nnnn
+        \draw_transform_matrix_absolute:nnnn
           { #1 * \l__draw_matrix_a_fp + #2 * \l__draw_matrix_c_fp }
           { #1 * \l__draw_matrix_b_fp + #2 * \l__draw_matrix_d_fp }
           { #3 * \l__draw_matrix_a_fp + #4 * \l__draw_matrix_c_fp }
@@ -1651,12 +1758,12 @@
           { #3 * \l__draw_matrix_b_fp + #4 * \l__draw_matrix_d_fp }
         }
   }
-\cs_new_protected:Npn \draw_transform_shift_concat:n #1
+\cs_new_protected:Npn \draw_transform_shift:n #1
   {
     \__draw_point_process:nn
-      { \__draw_transform_shift_concat:nn } {#1}
+      { \__draw_transform_shift:nn } {#1}
   }
-\cs_new_protected:Npn \__draw_transform_shift_concat:nn #1#2
+\cs_new_protected:Npn \__draw_transform_shift:nn #1#2
   {
     \dim_set:Nn \l__draw_xshift_dim { \l__draw_xshift_dim + #1 }
     \dim_set:Nn \l__draw_yshift_dim { \l__draw_yshift_dim + #2 }
@@ -1709,28 +1816,28 @@
   {
     \use:x
       {
-        \draw_transform_matrix:nnnn
+        \draw_transform_matrix_absolute:nnnn
           { #3 - #1 }
           { #4 - #2 }
           { #5 - #1 }
           { #6 - #2 }
-        \draw_transform_shift:n { #1 , #2 }
+        \draw_transform_shift_absolute:n { #1 , #2 }
       }
   }
 \cs_new_protected:Npn \draw_transform_scale:n #1
-  { \draw_transform_matrix_concat:nnnn { #1 } { 0 } { 0 } { #1 } }
+  { \draw_transform_matrix:nnnn { #1 } { 0 } { 0 } { #1 } }
 \cs_new_protected:Npn \draw_transform_xscale:n #1
-  { \draw_transform_matrix_concat:nnnn { #1 } { 0 } { 0 } { 1 } }
+  { \draw_transform_matrix:nnnn { #1 } { 0 } { 0 } { 1 } }
 \cs_new_protected:Npn \draw_transform_yscale:n #1
-  { \draw_transform_matrix_concat:nnnn { 1 } { 0 } { 0 } { #1 } }
+  { \draw_transform_matrix:nnnn { 1 } { 0 } { 0 } { #1 } }
 \cs_new_protected:Npn \draw_transform_xshift:n #1
-  { \draw_transform_shift_concat:n { #1 , 0 } }
+  { \draw_transform_shift:n { #1 , 0pt } }
 \cs_new_protected:Npn \draw_transform_yshift:n #1
-  { \draw_transform_shift_concat:n { 0 , #1 } }
+  { \draw_transform_shift:n { 0pt , #1 } }
 \cs_new_protected:Npn \draw_transform_xslant:n #1
-  { \draw_transform_matrix_concat:nnnn { 1 } { 0 } { #1 } { 1 } }
+  { \draw_transform_matrix:nnnn { 1 } { 0 } { #1 } { 1 } }
 \cs_new_protected:Npn \draw_transform_yslant:n #1
-  { \draw_transform_matrix_concat:nnnn { 1 } { #1 } { 0 } { 1 } }
+  { \draw_transform_matrix:nnnn { 1 } { #1 } { 0 } { 1 } }
 \cs_new_protected:Npn \draw_transform_rotate:n #1
   { \__draw_transform_rotate:f { \fp_eval:n {#1} } }
 \cs_new_protected:Npn \__draw_transform_rotate:n #1
@@ -1741,7 +1848,7 @@
   }
 \cs_generate_variant:Nn \__draw_transform_rotate:n { f }
 \cs_new_protected:Npn \__draw_transform_rotate:nn #1#2
-  { \draw_transform_matrix_concat:nnnn {#1} {#2} { -#2 } { #1 } }
+  { \draw_transform_matrix:nnnn {#1} {#2} { -#2 } { #1 } }
 \cs_generate_variant:Nn \__draw_transform_rotate:nn { ff }
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-convert.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-convert.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-convert.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3str-convert.dtx Copyright (C) 2013-2019 The LaTeX3 Project
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3str-convert}{2019-01-28}{}
+\ProvidesExplPackage{l3str-convert}{2019-03-05}{}
   {L3 Experimental string encoding conversions}
 \cs_if_exist:NF \use_ii_i:nn
   { \cs_new:Npn \use_ii_i:nn #1#2 { #2 #1 } }

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3str-format.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3str-format.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3str-format}{2019-01-28}{}
+\ProvidesExplPackage{l3str-format}{2019-03-05}{}
   {L3 Experimental string formatting}
 \cs_generate_variant:Nn \use:nn { nf }
 \cs_generate_variant:Nn \use:nnn { fnf }

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3sys-shell/l3sys-shell.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3sys-shell.dtx
 \RequirePackage{expl3}
-\ProvidesExplPackage{l3sys-shell}{2019-01-28}{}
+\ProvidesExplPackage{l3sys-shell}{2019-03-05}{}
   {L3 Experimental system shell functions}
 \cs_new:Npn \__sys_path_to_win:n #1
   {

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/xcoffins/xcoffins.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: xcoffins.dtx
 \RequirePackage{xparse}
-\ProvidesExplPackage{xcoffins}{2019-01-28}{}
+\ProvidesExplPackage{xcoffins}{2019-03-05}{}
   {L3 Experimental design level coffins}
 \keys_define:nn { coffin }
   {

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{l3galley}{2019-01-28}{}
+\ProvidesExplPackage{l3galley}{2019-03-05}{}
   {L3 Experimental galley code}
 \int_new:N \l__galley_tmp_int
 \seq_new:N \g__galley_tmpa_seq

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/xgalley.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: xgalley.dtx
 \RequirePackage{xparse}
-\ProvidesExplPackage{xgalley}{2019-01-28}{}
+\ProvidesExplPackage{xgalley}{2019-03-05}{}
   {L3 Experimental galley}
 \RequirePackage{xparse,xtemplate,l3galley}
 \clist_new:N \l__galley_tmpa_clist

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex	2019-03-05 22:35:14 UTC (rev 50246)
@@ -63,7 +63,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2019-02-15}%
+\def\ExplFileDate{2019-03-05}%
 \begingroup
   \def\next{\endgroup}%
   \expandafter\ifx\csname PackageError\endcsname\relax
@@ -122,65 +122,6 @@
   }%
 %% File: l3bootstrap.dtx
 \begingroup
-  \csname protected\endcsname\gdef\GetIdInfo
-    {%
-      \begingroup
-        \catcode 32 = 10 %
-        \GetIdInfoAuxI
-    }%
-  \csname protected\endcsname\gdef\GetIdInfoAuxI$#1$#2%
-    {%
-      \def\tempa{#1}%
-      \def\tempb{Id}%
-      \ifx\tempa\tempb
-        \def\tempa
-          {%
-            \endgroup
-            \def\ExplFileDate{0000/00/00}%
-            \def\ExplFileDescription{#2}%
-            \def\ExplFileName{[unknown]}%
-            \def\ExplFileExtension{[unknown extension]}%
-            \def\ExplFileVersion{-1}%
-          }%
-      \else
-        \def\tempa
-          {%
-            \endgroup
-            \def\ExplFileDescription{#2}%
-            \GetIdInfoAuxII$#1 $%
-          }%
-      \fi
-      \tempa
-    }%
-  \csname protected\endcsname\gdef\GetIdInfoAuxII$#1 #2.#3 #4 #5 #6$%
-    {%
-      \def\ExplFileName{#2}%
-      \def\ExplFileExtension{#3}%
-      \def\ExplFileVersion{#4}%
-      \begingroup
-        \def\tempa{#4}%
-        \def\tempb{-1}%
-        \ifx\tempa\tempb
-          \def\tempa
-            {%
-              \endgroup
-              \def\ExplFileDate{0000/00/00}%
-            }%
-        \else
-          \def\tempa
-            {%
-              \endgroup
-              \GetIdInfoAuxIII$#5$%
-            }%
-        \fi
-        \tempa
-    }%
-  \csname protected\endcsname\gdef\GetIdInfoAuxIII$#1-#2-#3$%
-    {%
-      \def\ExplFileDate{#1/#2/#3}%
-    }%
-\endgroup
-\begingroup
   \expandafter\ifx\csname directlua\endcsname\relax
   \else
     \directlua{%
@@ -2491,61 +2432,6 @@
   }
 \__kernel_if_debug:TF
   {
-    \cs_set_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2#3#4#5#
-      {
-        \if_meaning:w \cs_new_protected:Npn #3
-          \exp_after:wN \use_i:nn
-        \else:
-          \if_meaning:w \cs_new:Npn #3
-            \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nn
-          \else:
-            \__kernel_msg_error:nnx { kernel } { debug-unpatchable }
-              { \token_to_str:N #3 ~(for~deprecation) }
-            \exp_after:wN \exp_after:wN \exp_after:wN \use_none:nn
-          \fi:
-        \fi:
-        { \__debug_deprecation_aux:nnNnn {#1} {#2} #4 {#5} }
-        { \__debug_deprecation_expandable:nnNnn {#1} {#2} #4 {#5} }
-      }
-    \cs_set_protected:Npn \__debug_deprecation_aux:nnNnn #1#2#3#4#5
-      {
-        \tl_gput_right:Nn \g__debug_deprecation_on_tl
-          {
-            \tex_let:D #3 \scan_stop:
-            \__kernel_deprecation_error:Nnn #3 {#2} {#1}
-          }
-        \tl_gput_right:Nn \g__debug_deprecation_off_tl
-          {
-            \tex_let:D #3 \scan_stop:
-            \cs_set_protected:Npn #3 #4 {#5}
-          }
-        \cs_new_protected:Npx #3
-          {
-            \exp_not:N \__kernel_msg_warning:nnxxx
-              { kernel } { deprecated-command }
-              {#1} { \token_to_str:N #3 } { \tl_to_str:n {#2} }
-            \exp_not:n { \cs_gset_protected:Npn #3 #4 {#5} }
-            \exp_not:N #3
-          }
-      }
-    \cs_set_protected:Npn \__debug_deprecation_expandable:nnNnn #1#2#3#4#5
-      {
-        \tl_gput_right:Nn \g__debug_deprecation_on_tl
-          {
-            \tex_let:D #3 \scan_stop:
-            \__kernel_deprecation_error:Nnn #3 {#2} {#1}
-          }
-        \tl_gput_right:Nn \g__debug_deprecation_off_tl
-          {
-            \tex_let:D #3 \scan_stop:
-            \cs_set:Npn #3 #4 {#5}
-          }
-        \cs_new:Npn #3 #4 {#5}
-      }
-  }
-  { \cs_set_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2 { } }
-\__kernel_if_debug:TF
-  {
     \cs_set_protected:Npn \__kernel_patch:nnNNpn #1#2#3#4#5#
       { \__debug_patch_aux:nnnn {#1} {#2} { #3 #4 #5 } }
     \cs_set_protected:Npn \__kernel_patch_conditional:nNNpnn #1#2#3#4#
@@ -3208,6 +3094,39 @@
     \group_end:
     #1 { \token_to_str:N #2 = \cs_meaning:N #2 }
   }
+\use:x
+  {
+    \exp_not:n { \cs_new:Npn \__kernel_prefix_arg_replacement:wN #1 }
+    \tl_to_str:n { macro : } \exp_not:n { #2 -> #3 \q_stop #4 }
+  }
+  { #4 {#1} {#2} {#3} }
+\cs_new:Npn \cs_prefix_spec:N #1
+  {
+    \token_if_macro:NTF #1
+      {
+        \exp_after:wN \__kernel_prefix_arg_replacement:wN
+          \token_to_meaning:N #1 \q_stop \use_i:nnn
+      }
+      { \scan_stop: }
+  }
+\cs_new:Npn \cs_argument_spec:N #1
+  {
+    \token_if_macro:NTF #1
+      {
+        \exp_after:wN \__kernel_prefix_arg_replacement:wN
+          \token_to_meaning:N #1 \q_stop \use_ii:nnn
+      }
+      { \scan_stop: }
+  }
+\cs_new:Npn \cs_replacement_spec:N #1
+  {
+    \token_if_macro:NTF #1
+      {
+        \exp_after:wN \__kernel_prefix_arg_replacement:wN
+          \token_to_meaning:N #1 \q_stop \use_iii:nnn
+      }
+      { \scan_stop: }
+  }
 \cs_new:Npn \prg_do_nothing: { }
 \cs_new_eq:NN \prg_break_point:Nn \use_ii:nn
 \cs_new:Npn \prg_map_break:Nn #1#2#3 \prg_break_point:Nn #4#5
@@ -3658,12 +3577,53 @@
       { \__exp_e:nn {#2} { #3 #1 } }
     \cs_new:Npn \__exp_e_expandable:Nnn #1#2
       { \exp_args:No \__exp_e:nn { #1 #2 } }
-    \cs_new:Npn \__exp_e_primitive:Nnn #1
+    \cs_new:Npn \__exp_e_primitive:Nnn #1#2
       {
-        \__kernel_msg_expandable_error:nnn { kernel } { e-type }
-          { \primitive not~implemented }
-        \__exp_e:nn
+        \if_false: { \fi:
+          \tl_if_head_is_N_type:nTF {#2}
+            { \__exp_e_primitive_aux:NNw #1 }
+            {
+              \__kernel_msg_expandable_error:nnn { kernel } { e-type }
+                { Missing~primitive~name }
+              \__exp_e_primitive_aux:NNw #1 \c_empty_tl
+            }
+          #2
+        }
       }
+    \cs_new:Npn \__exp_e_primitive_aux:NNw #1#2
+      {
+        \exp_after:wN \__exp_e_primitive_aux:NNnn
+        \exp_after:wN #1
+        \exp_after:wN #2
+        \exp_after:wN { \if_false: } \fi:
+      }
+    \cs_new:Npn \__exp_e_primitive_aux:NNnn #1#2
+      {
+        \exp_args:Nf \str_case_e:nnTF { \cs_to_str:N #2 }
+          {
+            { unexpanded } { \__exp_e_unexpanded:Nnn \exp_not:n }
+            { noexpand } { \__exp_e_noexpand:Nnn \exp_not:N }
+            { the } { \__exp_e_the:Nnn \tex_the:D }
+            {
+              \sys_if_engine_xetex:T { pdf }
+              \sys_if_engine_luatex:T { pdf }
+              primitive
+            } { \__exp_e_primitive:Nnn #1 }
+          }
+          { \__exp_e_primitive_other:NNnn #1 #2 }
+      }
+    \cs_new:Npn \__exp_e_primitive_other:NNnn #1#2#3
+      {
+        \exp_args:No \__exp_e_primitive_other_aux:nNNnn
+          { #1 #2 #3 }
+          #1 #2 {#3}
+      }
+    \cs_new:Npn \__exp_e_primitive_other_aux:nNNnn #1#2#3#4#5
+      {
+        \str_if_eq:nnTF {#1} { #2 #3 #4 }
+          { \__exp_e:nn {#4} { #5 #2 #3 } }
+          { \__exp_e:nn {#1} {#5} }
+      }
     \cs_new:Npn \__exp_e_noexpand:Nnn #1#2
       {
         \tl_if_head_is_N_type:nTF {#2}
@@ -3791,9 +3751,12 @@
         {
           #1
           \exp_after:wN \__exp_e_the_toks:n
+          \exp_after:wN { \if_false: } \fi:
         }
-        { \exp_after:wN ; }
-        \exp_after:wN { \if_false: } \fi:
+        {
+          \exp_after:wN ;
+          \exp_after:wN { \if_false: } \fi: #1
+        }
       }
     \prg_new_conditional:Npnn \__exp_e_if_toks_register:N #1 { TF }
       {
@@ -4306,8 +4269,8 @@
   }
 \cs_new_protected:Npn \__tl_set_rescan:NNnn #1#2#3#4
   {
-    \if_false: { \fi:
     \group_begin:
+      \if_false: { \fi:
       \int_set_eq:NN \tex_tracingnesting:D \c_zero_int
       \exp_args:No \tex_everyeof:D { \c__tl_rescan_marker_tl }
       \int_compare:nNnT \tex_endlinechar:D = { 32 }
@@ -4538,6 +4501,7 @@
   { c } { T , F , TF }
 \prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 { T  , F , TF }
   {
+    \scan_stop:
     \if_false: { \fi:
     \cs_set:Npn \__tl_tmp:w ##1 #2 { }
     \tl_if_empty:oTF { \__tl_tmp:w #1 {} {} #2 }
@@ -4681,6 +4645,22 @@
 \cs_new:Npn \__tl_count:n #1 { + 1 }
 \cs_generate_variant:Nn \tl_count:n { V , o }
 \cs_generate_variant:Nn \tl_count:N { c }
+\cs_new:Npn \tl_count_tokens:n #1
+  {
+    \int_eval:n
+      {
+        \__tl_act:NNNnn
+          \__tl_act_count_normal:nN
+          \__tl_act_count_group:nn
+          \__tl_act_count_space:n
+          { }
+          {#1}
+      }
+  }
+\cs_new:Npn \__tl_act_count_normal:nN #1 #2 { 1 + }
+\cs_new:Npn \__tl_act_count_space:n #1 { 1 + }
+\cs_new:Npn \__tl_act_count_group:nn #1 #2
+  { 2 + \tl_count_tokens:n {#2} + }
 \cs_new:Npn \tl_reverse_items:n #1
   {
     \__tl_reverse_items:nwNwn #1 ?
@@ -5754,22 +5734,9 @@
 \cs_new_eq:NN \str_show:n \tl_show:n
 \cs_new_eq:NN \str_show:N \tl_show:N
 \cs_generate_variant:Nn \str_show:N { c }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nn }
-\cs_new:Npn \str_case_x:nn { \str_case_e:nn }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nnT }
-\cs_new:Npn \str_case_x:nnT { \str_case_e:nnT }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nnF }
-\cs_new:Npn \str_case_x:nnF { \str_case_e:nnF }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_case_e:nnTF }
-\cs_new:Npn \str_case_x:nnTF { \str_case_e:nnTF }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq_p:ee }
-\cs_new:Npn \str_if_eq_x_p:nn { \str_if_eq_p:ee }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq:eeT }
-\cs_new:Npn \str_if_eq_x:nnT { \str_if_eq:eeT }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq:eeF }
-\cs_new:Npn \str_if_eq_x:nnF { \str_if_eq:eeF }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \str_if_eq:eeTF }
-\cs_new:Npn \str_if_eq_x:nnTF { \str_if_eq:eeTF }
+\cs_new_eq:NN \str_log:n \tl_log:n
+\cs_new_eq:NN \str_log:N \tl_log:N
+\cs_generate_variant:Nn \str_log:N { c }
 %% File: l3quark.dtx
 \__kernel_patch:nnNNpn { \__kernel_chk_var_scope:NN q #1 } { }
 \cs_new_protected:Npn \quark_new:N #1
@@ -7311,47 +7278,6 @@
 \int_new:N \l_tmpb_int
 \int_new:N \g_tmpa_int
 \int_new:N \g_tmpb_int
-\cs_new_protected:Npn \__int_deprecated_constants:nn #1#2
-  {
-    #1 \c_zero                   {   0 } #2
-    #1 \c_one                    {   1 } #2
-    #1 \c_two                    {   2 } #2
-    #1 \c_three                  {   3 } #2
-    #1 \c_four                   {   4 } #2
-    #1 \c_five                   {   5 } #2
-    #1 \c_six                    {   6 } #2
-    #1 \c_seven                  {   7 } #2
-    #1 \c_eight                  {   8 } #2
-    #1 \c_nine                   {   9 } #2
-    #1 \c_ten                    {  10 } #2
-    #1 \c_eleven                 {  11 } #2
-    #1 \c_twelve                 {  12 } #2
-    #1 \c_thirteen               {  13 } #2
-    #1 \c_fourteen               {  14 } #2
-    #1 \c_fifteen                {  15 } #2
-    #1 \c_sixteen                {  16 } #2
-    #1 \c_thirty_two             {  32 } #2
-    #1 \c_one_hundred            { 100 } #2
-    #1 \c_two_hundred_fifty_five { 255 } #2
-    #1 \c_two_hundred_fifty_six  { 256 } #2
-    #1 \c_one_thousand         {  1000 } #2
-    #1 \c_ten_thousand         { 10000 } #2
-  }
-\__int_deprecated_constants:nn { \int_const:Nn } { }
-\__kernel_deprecation_code:nn
-  {
-    \__int_deprecated_constants:nn
-      { \__kernel_deprecation_error:Nnn } { { 2019-12-31 } }
-  }
-  {
-    \__int_deprecated_constants:nn
-      {
-        \exp_after:wN \use:nnn
-        \exp_after:wN \__int_constdef:Nw \exp_not:N
-      }
-      { \exp_stop_f: }
-  }
-\cs_new_eq:NN \__int_value:w \int_value:w
 %% File: l3flag.dtx
 \cs_new_protected:Npn \flag_new:n #1
   {
@@ -7717,17 +7643,6 @@
 \cs_new:Npn \group_align_safe_end:
   { \if_int_compare:w `{ = \c_zero_int } \fi: }
 \int_new:N \g__kernel_prg_map_int
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break_point:Nn }
-\cs_new:Npn \__prg_break_point:Nn { \prg_break_point:Nn }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break_point: }
-\cs_new:Npn \__prg_break_point: { \prg_break_point: }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_map_break:Nn }
-\cs_new:Npn \__prg_map_break:Nn #1 \__prg_break_point:Nn
-  { \prg_map_break:Nn #1 \prg_break_point:Nn }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break: }
-\cs_new:Npn \__prg_break: #1 \__prg_break_point: { }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \prg_break:n }
-\cs_new:Npn \__prg_break:n #1#2 \__prg_break_point: {#1}
 %% File: l3sys.dtx
 \str_const:Nx \c_sys_jobname_str { \tex_jobname:D }
 \int_const:Nn \c_sys_minute_int
@@ -9027,37 +8942,6 @@
           { \exp_not:c { peek_#1:NF } ##1 {##2} }
       }
   }
-\exp_args:Nno \use:nn
-  { \cs_new:Npn \__peek_get_prefix_arg_replacement:wN #1 }
-  { \tl_to_str:n { macro : } #2 -> #3 \q_stop #4 }
-  { #4 {#1} {#2} {#3} }
-\cs_new:Npn \token_get_prefix_spec:N #1
-  {
-    \token_if_macro:NTF #1
-      {
-        \exp_after:wN \__peek_get_prefix_arg_replacement:wN
-          \token_to_meaning:N #1 \q_stop \use_i:nnn
-      }
-      { \scan_stop: }
-  }
-\cs_new:Npn \token_get_arg_spec:N #1
-  {
-    \token_if_macro:NTF #1
-      {
-        \exp_after:wN \__peek_get_prefix_arg_replacement:wN
-          \token_to_meaning:N #1 \q_stop \use_ii:nnn
-      }
-      { \scan_stop: }
-  }
-\cs_new:Npn \token_get_replacement_spec:N #1
-  {
-    \token_if_macro:NTF #1
-      {
-        \exp_after:wN \__peek_get_prefix_arg_replacement:wN
-          \token_to_meaning:N #1 \q_stop \use_iii:nnn
-      }
-      { \scan_stop: }
-  }
 %% File: l3prop.dtx
 \scan_new:N \s__prop
 \cs_new:Npn \__prop_pair:wn #1 \s__prop #2
@@ -9216,6 +9100,16 @@
       { \__prop_item_Nn:nwwn {#1} }
   }
 \cs_generate_variant:Nn \prop_item:Nn { c }
+\cs_new:Npn \prop_count:N #1
+  {
+    \int_eval:n
+      {
+        0
+        \prop_map_function:NN #1 \__prop_count:nn
+      }
+  }
+\cs_new:Npn \__prop_count:nn #1#2 { + 1 }
+\cs_generate_variant:Nn \prop_count:N { c }
 \prg_new_protected_conditional:Npnn \prop_pop:NnN #1#2#3 { T , F , TF }
   {
     \__prop_split:NnTF #1 {#2}
@@ -10001,11 +9895,6 @@
     LaTeX~has~been~asked~to~use~a~control~sequence~'#1':\\
     this~has~not~been~defined~yet.
   }
-\__kernel_msg_new:nnn { kernel } { deprecated-command }
-  {
-    The~deprecated~command~'#2'~has~been~or~will~be~removed~on~#1.
-    \tl_if_empty:nF {#3} { ~Use~instead~'#3'. }
-  }
 \__kernel_msg_new:nnnn { kernel } { empty-search-pattern }
   { Empty~search~pattern. }
   {
@@ -10059,7 +9948,7 @@
     Only~expandable~tests~can~have~a~predicate~version.
   }
 \__kernel_msg_new:nnn { kernel } { randint-backward-range }
-  { Bounds~ordered~backwards~in~\int_rand:nn {#1}~{#2}. }
+  { Bounds~ordered~backwards~in~\iow_char:N\\int_rand:nn~{#1}~{#2}. }
 \__kernel_msg_new:nnnn { kernel } { conditional-form-unknown }
   { Conditional~form~'#1'~for~function~'#2'~unknown. }
   {
@@ -10200,7 +10089,7 @@
 \__kernel_msg_new:nnn { kernel } { misused-prop }
   { A~property~list~was~misused. }
 \__kernel_msg_new:nnn { kernel } { negative-replication }
-  { Negative~argument~for~\prg_replicate:nn. }
+  { Negative~argument~for~\iow_char:N\\prg_replicate:nn. }
 \__kernel_msg_new:nnn { kernel } { prop-keyval }
   { Missing/extra~'='~in~'#1'~(in~'..._keyval:Nn') }
 \__kernel_msg_new:nnn { kernel } { unknown-comparison }
@@ -10263,13 +10152,17 @@
 \exp_args:Ncx \__msg_tmp:w { LaTeX3~error: }
   { \char_generate:nn { `\  } { 7 } }
 \group_end:
+\exp_args_generate:n { oooo }
 \cs_new:Npn \__kernel_msg_expandable_error:nnnnnn #1#2#3#4#5#6
   {
-    \exp_args:Nf \__msg_expandable_error:n
+    \exp_args:Ne \__msg_expandable_error:n
       {
-        \exp_args:NNc \exp_after:wN \exp_stop_f:
+        \exp_args:Nc \exp_args:Noooo
           { \c__msg_text_prefix_tl LaTeX / #1 / #2 }
-          {#3} {#4} {#5} {#6}
+          { \tl_to_str:n {#3} }
+          { \tl_to_str:n {#4} }
+          { \tl_to_str:n {#5} }
+          { \tl_to_str:n {#6} }
       }
   }
 \cs_new:Npn \__kernel_msg_expandable_error:nnnnn #1#2#3#4#5
@@ -10296,85 +10189,6 @@
 \cs_generate_variant:Nn \__kernel_msg_expandable_error:nnnnn { nnfff }
 \cs_generate_variant:Nn \__kernel_msg_expandable_error:nnnn { nnff }
 \cs_generate_variant:Nn \__kernel_msg_expandable_error:nnn { nnf }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \iow_log:n }
-\cs_new_protected:Npn \msg_log:n #1
-  {
-    \iow_log:n { ................................................. }
-    \iow_wrap:nnnN { . ~ #1} { . ~ } { } \iow_log:n
-    \iow_log:n { ................................................. }
-  }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \iow_term:n }
-\cs_new_protected:Npn \msg_term:n #1
-  {
-    \iow_term:n { ************************************************* }
-    \iow_wrap:nnnN { * ~ #1} { * ~ } { } \iow_term:n
-    \iow_term:n { ************************************************* }
-  }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { [Defined~error~message] }
-\cs_new_protected:Npn \msg_interrupt:nnn #1#2#3
-  {
-    \tl_if_empty:nTF {#3}
-      {
-        \__msg_old_interrupt_wrap:nn { \\ \c__msg_no_info_text_tl }
-          {#1 \\\\ #2 \\\\ \c__msg_continue_text_tl }
-      }
-      {
-        \__msg_old_interrupt_wrap:nn { \\ #3 }
-          {#1 \\\\ #2 \\\\ \c__msg_help_text_tl }
-      }
-  }
-\cs_new_protected:Npn \__msg_old_interrupt_wrap:nn #1#2
-  {
-    \iow_wrap:nnnN {#1} { | ~ } { } \__msg_old_interrupt_more_text:n
-    \iow_wrap:nnnN {#2} { ! ~ } { } \__msg_old_interrupt_text:n
-  }
-\cs_new_protected:Npn \__msg_old_interrupt_more_text:n #1
-  {
-    \exp_args:Nx \tex_errhelp:D
-      {
-        |'''''''''''''''''''''''''''''''''''''''''''''''
-        #1 \iow_newline:
-        |...............................................
-      }
-  }
-\group_begin:
-  \char_set_lccode:nn {`\{} {`\ }
-  \char_set_lccode:nn {`\}} {`\ }
-  \char_set_lccode:nn {`\&} {`\!}
-  \char_set_catcode_active:N \&
-\tex_lowercase:D
-  {
-    \group_end:
-    \cs_new_protected:Npn \__msg_old_interrupt_text:n #1
-      {
-        \iow_term:x
-          {
-            \iow_newline:
-            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-            \iow_newline:
-            !
-          }
-        \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J }
-          {
-            \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 }
-              {
-                \group_begin:
-                  \cs_set_protected:Npn &
-                    {
-                      \tex_errmessage:D
-                        {
-                          #1
-                          \use_none:n
-                            { ............................................ }
-                        }
-                    }
-                  \exp_after:wN
-                \group_end:
-                &
-              }
-          }
-      }
-  }
 %% File: l3file.dtx
 \tl_new:N  \l__ior_internal_tl
 \int_const:Nn \c_term_ior { 16 }
@@ -10401,16 +10215,15 @@
 \cs_new_protected:Npn \ior_open:Nn #1#2
   { \ior_open:NnF #1 {#2} { \__kernel_file_missing:n {#2} } }
 \cs_generate_variant:Nn \ior_open:Nn { c }
-\str_new:N \l__ior_file_name_str
+\tl_new:N \l__ior_file_name_tl
 \prg_new_protected_conditional:Npnn \ior_open:Nn #1#2 { T , F , TF }
   {
-    \file_get_full_name:nN {#2} \l__ior_file_name_str
-    \str_if_empty:NTF \l__ior_file_name_str
-      { \prg_return_false: }
+    \file_get_full_name:nNTF {#2} \l__ior_file_name_tl
       {
-        \__kernel_ior_open:No #1 \l__ior_file_name_str
+        \__kernel_ior_open:No #1 \l__ior_file_name_tl
         \prg_return_true:
       }
+      { \prg_return_false: }
   }
 \prg_generate_conditional_variant:Nnn \ior_open:Nn { c } { T , F , TF }
 \exp_args:NNf \cs_new_protected:Npn \__ior_new:N
@@ -10484,8 +10297,21 @@
       { \prg_return_true: }
   }
 \cs_new_protected:Npn \ior_get:NN #1#2
+  { \ior_get:NNF #1 #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \__ior_get:NN #1#2
   { \tex_read:D #1 to #2 }
+\prg_new_protected_conditional:Npnn \ior_get:NN #1#2 { T , F , TF }
+  {
+    \ior_if_eof:NTF #1
+      { \prg_return_false: }
+      {
+        \__ior_get:NN #1 #2
+        \prg_return_true:
+      }
+  }
 \cs_new_protected:Npn \ior_str_get:NN #1#2
+  { \ior_str_get:NNF #1 #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \__ior_str_get:NN #1#2
   {
     \exp_args:Nno \use:n
       {
@@ -10494,14 +10320,23 @@
         \int_set:Nn \tex_endlinechar:D
       }   { \int_use:N \tex_endlinechar:D }
   }
+\prg_new_protected_conditional:Npnn \ior_str_get:NN #1#2 { T , F , TF }
+  {
+    \ior_if_eof:NTF #1
+      { \prg_return_false: }
+      {
+        \__ior_str_get:NN #1 #2
+        \prg_return_true:
+      }
+  }
 \cs_new:Npn \ior_map_break:
   { \prg_map_break:Nn \ior_map_break: { } }
 \cs_new:Npn \ior_map_break:n
   { \prg_map_break:Nn \ior_map_break: }
 \cs_new_protected:Npn \ior_map_inline:Nn
-  { \__ior_map_inline:NNn \ior_get:NN }
+  { \__ior_map_inline:NNn \__ior_get:NN }
 \cs_new_protected:Npn \ior_str_map_inline:Nn
-  { \__ior_map_inline:NNn \ior_str_get:NN }
+  { \__ior_map_inline:NNn \__ior_str_get:NN }
 \cs_new_protected:Npn \__ior_map_inline:NNn
   {
     \int_gincr:N \g__kernel_prg_map_int
@@ -10573,17 +10408,17 @@
 \iow_new:N \g_tmpb_iow
 \exp_args:NNf \cs_new_protected:Npn \__iow_new:N
   { \exp_args:NNc \exp_after:wN \exp_stop_f: { newwrite } }
-\str_new:N \l__iow_file_name_str
+\tl_new:N \l__iow_file_name_tl
 \cs_new_protected:Npn \iow_open:Nn #1#2
   {
-    \__kernel_file_name_sanitize:nN {#2} \l__iow_file_name_str
+    \__kernel_file_name_sanitize:nN {#2} \l__iow_file_name_tl
     \iow_close:N #1
     \seq_gpop:NNTF \g__iow_streams_seq \l__iow_stream_tl
-      { \__iow_open_stream:NV #1 \l__iow_file_name_str }
+      { \__iow_open_stream:NV #1 \l__iow_file_name_tl }
       {
         \__iow_new:N #1
         \tl_set:Nx \l__iow_stream_tl { \int_eval:n {#1} }
-        \__iow_open_stream:NV #1 \l__iow_file_name_str
+        \__iow_open_stream:NV #1 \l__iow_file_name_tl
       }
   }
 \cs_generate_variant:Nn \iow_open:Nn { c }
@@ -11003,8 +10838,8 @@
     { \exp_after:wN \__file_tmp:w \@currnamestack }
 \group_end:
 \seq_new:N \g__file_record_seq
-\str_new:N \l__file_base_name_str
-\str_new:N \l__file_full_name_str
+\tl_new:N \l__file_base_name_tl
+\tl_new:N \l__file_full_name_tl
 \str_new:N \l__file_dir_str
 \str_new:N \l__file_ext_str
 \str_new:N \l__file_name_str
@@ -11019,8 +10854,6 @@
           \char_set_active_eq:NN ##1 \l__file_internal_tl
         }
       \tl_set:Nx \l__file_internal_tl {#1}
-      \tl_set:Nx \l__file_internal_tl
-        { \tl_to_str:N \l__file_internal_tl }
     \exp_args:NNNV \group_end:
     \str_set:Nn #2 \l__file_internal_tl
   }
@@ -11043,19 +10876,18 @@
 \cs_new_protected:Npn \file_get:nnN #1#2#3
   {
     \file_get:nnNF {#1} {#2} #3
-      { \__kernel_file_missing:n {#1} }
+      { \tl_set:Nn #3 { \q_no_value } }
   }
 \prg_new_protected_conditional:Npnn \file_get:nnN #1#2#3 { T , F , TF }
   {
-    \file_get_full_name:nN {#1} \l__file_full_name_str
-    \str_if_empty:NTF \l__file_full_name_str
-      { \prg_return_false: }
+    \file_get_full_name:nNTF {#1} \l__file_full_name_tl
       {
         \exp_args:NV \__file_get_aux:nnN
-          \l__file_full_name_str
+          \l__file_full_name_tl
           {#2} #3
         \prg_return_true:
       }
+      { \prg_return_false: }
   }
 \cs_new_protected:Npn \__file_get_aux:nnN #1#2#3
   {
@@ -11079,7 +10911,13 @@
   }
 \cs_new_protected:Npn \file_get_full_name:nN #1#2
   {
-    \__kernel_file_name_sanitize:nN {#1} \l__file_base_name_str
+    \file_get_full_name:nNF {#1} #2
+      { \tl_set:Nn #2 { \q_no_value } }
+  }
+\cs_generate_variant:Nn \file_get_full_name:nN { V }
+\prg_new_protected_conditional:Npnn \file_get_full_name:nN #1#2 { T , F , TF }
+  {
+    \__kernel_file_name_sanitize:nN {#1} \l__file_base_name_tl
     \__file_get_full_name_search:nN { } \use:n
     \seq_map_inline:Nn \l_file_search_path_seq
       { \__file_get_full_name_search:nN { ##1 / } \seq_map_break:n }
@@ -11088,51 +10926,56 @@
         \tl_map_inline:Nn \input at path
           { \__file_get_full_name_search:nN { ##1 } \tl_map_break:n }
       }
-    \str_clear:N \l__file_full_name_str
+    \tl_set:Nn \l__file_full_name_tl { \q_no_value }
     \prg_break_point:
-    \str_if_empty:NF \l__file_full_name_str
+    \quark_if_no_value:NTF \l__file_full_name_tl
       {
-        \exp_args:NV \file_parse_full_name:nNNN \l__file_full_name_str
+        \ior_close:N \g__file_internal_ior
+        \prg_return_false:
+      }
+      {
+        \exp_args:NV \file_parse_full_name:nNNN \l__file_full_name_tl
           \l__file_dir_str \l__file_name_str \l__file_ext_str
         \str_if_empty:NT \l__file_ext_str
           {
             \__kernel_ior_open:No \g__file_internal_ior
-              { \l__file_full_name_str .tex }
+              { \l__file_full_name_tl .tex }
             \ior_if_eof:NF \g__file_internal_ior
-              { \str_put_right:Nn \l__file_full_name_str { .tex } }
+              { \tl_put_right:Nn \l__file_full_name_tl { .tex } }
           }
+        \ior_close:N \g__file_internal_ior
+        \tl_set_eq:NN #2 \l__file_full_name_tl
+        \prg_return_true:
       }
-    \str_set_eq:NN #2 \l__file_full_name_str
-    \ior_close:N \g__file_internal_ior
   }
-\cs_generate_variant:Nn \file_get_full_name:nN { V }
+\cs_generate_variant:Nn \file_get_full_name:nNT  { V }
+\cs_generate_variant:Nn \file_get_full_name:nNF  { V }
+\cs_generate_variant:Nn \file_get_full_name:nNTF { V }
 \cs_new_protected:Npn \__file_get_full_name_search:nN #1#2
   {
     \__file_name_quote:nN
-      { \tl_to_str:n {#1} \l__file_base_name_str }
-      \l__file_full_name_str
-    \__kernel_ior_open:No \g__file_internal_ior \l__file_full_name_str
+      { \tl_to_str:n {#1} \l__file_base_name_tl }
+      \l__file_full_name_tl
+    \__kernel_ior_open:No \g__file_internal_ior \l__file_full_name_tl
     \ior_if_eof:NF \g__file_internal_ior { #2 { \prg_break: } }
   }
 \prg_new_protected_conditional:Npnn \file_if_exist:n #1 { T , F , TF }
   {
-    \file_get_full_name:nN {#1} \l__file_full_name_str
-    \str_if_empty:NTF \l__file_full_name_str
+    \file_get_full_name:nNTF {#1} \l__file_full_name_tl
+      { \prg_return_true: }
       { \prg_return_false: }
-      { \prg_return_true: }
   }
 \cs_new_protected:Npn \__kernel_file_missing:n #1
   {
-    \__kernel_file_name_sanitize:nN {#1} \l__file_base_name_str
+    \__kernel_file_name_sanitize:nN {#1} \l__file_base_name_tl
     \__kernel_msg_error:nnx { kernel } { file-not-found }
-      { \l__file_base_name_str }
+      { \l__file_base_name_tl }
   }
 \cs_new_protected:Npn \file_input:n #1
   {
-    \file_get_full_name:nN {#1} \l__file_full_name_str
-    \str_if_empty:NTF \l__file_full_name_str
+    \file_get_full_name:nNTF {#1} \l__file_full_name_tl
+      { \__file_input:V \l__file_full_name_tl }
       { \__kernel_file_missing:n {#1} }
-      { \__file_input:V \l__file_full_name_str }
   }
 \cs_new_protected:Npn \__file_input:n #1
   {
@@ -11236,6 +11079,38 @@
       \g__file_record_seq
       \l__file_tmp_seq
   }
+\cs_new_protected:Npn \GetIdInfo
+  {
+    \group_begin:
+    \char_set_catcode_space:n { 32 }
+    \exp_after:wN
+    \group_end:
+    \__file_id_info_auxi:w
+  }
+\cs_new_protected:Npn \__file_id_info_auxi:w $ #1 $ #2
+  {
+    \tl_set:Nn \ExplFileDescription {#2}
+    \str_if_eq:nnTF {#1} { Id }
+      {
+        \tl_set:Nn \ExplFileDate { 0000/00/00 }
+        \tl_set:Nn \ExplFileName { [unknown] }
+        \tl_set:Nn \ExplFileExtension { [unknown~extension] }
+        \tl_set:Nn \ExplFileVersion {-1}
+      }
+      { \__file_id_info_auxii:w #1 ~ \q_stop }
+  }
+\cs_new_protected:Npn \__file_id_info_auxii:w
+    #1 ~ #2.#3 ~ #4 ~ #5 ~ #6 \q_stop
+  {
+    \tl_set:Nn \ExplFileName {#2}
+    \tl_set:Nn \ExplFileExtension {#3}
+    \tl_set:Nn \ExplFileVersion {#4}
+    \str_if_eq:nnTF {#4} {-1}
+      { \tl_set:Nn \ExplFileDate { 0000/00/00 } }
+      { \__file_id_info_auxiii:w #5 - 0 - 0 - \q_stop }
+  }
+\cs_new_protected:Npn \__file_id_info_auxiii:w #1 - #2 - #3 - #4 \q_stop
+  { \tl_set:Nn \ExplFileDate { #1/#2/#3 } }
 \__kernel_msg_new:nnnn { kernel } { file-not-found }
   { File~'#1'~not~found. }
   {
@@ -12779,14 +12654,10 @@
           \exp_after:wN { \l_keys_value_tl }
       }
       {
-        \bool_if:NTF \l__keys_only_known_bool
-          { \__keys_store_unused: }
-          {
-            \cs_if_exist:cTF
-              { \c__keys_inherit_root_tl \__keys_parent:o \l_keys_path_tl }
-              { \__keys_execute_inherit: }
-              { \__keys_execute_unknown: }
-          }
+        \cs_if_exist:cTF
+          { \c__keys_inherit_root_tl \__keys_parent:o \l_keys_path_tl }
+          { \__keys_execute_inherit: }
+          { \__keys_execute_unknown: }
       }
   }
 \cs_new_protected:Npn \__keys_execute_inherit:
@@ -12808,16 +12679,20 @@
   }
 \cs_new_protected:Npn \__keys_execute_unknown:
   {
-    \cs_if_exist:cTF
-      { \c__keys_code_root_tl \l__keys_module_tl / unknown }
+    \bool_if:NTF \l__keys_only_known_bool
+      { \__keys_store_unused: }
       {
-        \cs:w \c__keys_code_root_tl \l__keys_module_tl / unknown
-          \exp_after:wN \cs_end: \exp_after:wN { \l_keys_value_tl }
+        \cs_if_exist:cTF
+          { \c__keys_code_root_tl \l__keys_module_tl / unknown }
+          {
+            \cs:w \c__keys_code_root_tl \l__keys_module_tl / unknown
+              \exp_after:wN \cs_end: \exp_after:wN { \l_keys_value_tl }
+          }
+          {
+            \__kernel_msg_error:nnxx { kernel } { key-unknown }
+             { \l_keys_path_tl } { \l__keys_module_tl }
+          }
       }
-      {
-        \__kernel_msg_error:nnxx { kernel } { key-unknown }
-         { \l_keys_path_tl } { \l__keys_module_tl }
-      }
   }
 \cs_new:Npn \__keys_execute:nn #1#2
   {
@@ -12946,7 +12821,7 @@
           {
             \exp_args:Nnf \msg_show_item_unbraced:nn { code }
               {
-                \exp_args:Nc \token_get_replacement_spec:N
+                \exp_args:Nc \cs_replacement_spec:N
                   {
                     \c__keys_code_root_tl
                     \__keys_trim_spaces:n { #2 / #3 }
@@ -13595,23 +13470,9 @@
       \exp_after:wN \use_ii:nn
     \fi:
   }
-\cs_new:Npn \__fp_expand:n #1
+\sys_if_engine_luatex:TF
   {
-    \__fp_expand_loop:nwnN { }
-      #1 \prg_do_nothing:
-      \s__fp_mark { } \__fp_expand_loop:nwnN
-      \s__fp_mark { } \__fp_use_i_until_s:nw ;
-  }
-\cs_new:Npn \__fp_expand_loop:nwnN #1#2 \s__fp_mark #3 #4
-  {
-    \exp_after:wN #4 \exp:w \exp_end_continue_f:w
-    #2
-    \s__fp_mark { #3 #1 } #4
-  }
-\cs_new:Npn \__fp_str_if_eq:nn #1#2 { \tex_strcmp:D {#1} {#2} }
-\sys_if_engine_luatex:T
-  {
-    \cs_set:Npn \__fp_str_if_eq:nn #1#2
+    \cs_new:Npn \__fp_str_if_eq:nn #1#2
       {
         \tex_directlua:D
           {
@@ -13623,6 +13484,7 @@
           }
       }
   }
+  { \cs_new_eq:NN \__fp_str_if_eq:nn \tex_strcmp:D }
 \cs_new:Npn \__fp_func_to_name:N #1
   {
     \exp_last_unbraced:Nf
@@ -17152,6 +17014,8 @@
   { \__fp_parse_unary_function:NNN \__fp_exp_o:w ? }
 \cs_new:Npn \__fp_parse_word_ln:N
   { \__fp_parse_unary_function:NNN \__fp_ln_o:w ? }
+\cs_new:Npn \__fp_parse_word_fact:N
+  { \__fp_parse_unary_function:NNN \__fp_fact_o:w ? }
 \tl_const:Nn \c__fp_ln_i_fixed_tl   { {0000}{0000}{0000}{0000}{0000}{0000};}
 \tl_const:Nn \c__fp_ln_ii_fixed_tl  { {6931}{4718}{0559}{9453}{0941}{7232};}
 \tl_const:Nn \c__fp_ln_iii_fixed_tl {{10986}{1228}{8668}{1096}{9139}{5245};}
@@ -17820,6 +17684,76 @@
       1
     \fi:
   }
+\int_const:Nn \c__fp_fact_max_arg_int { 3248 }
+\cs_new:Npn \__fp_fact_o:w #1 \s__fp \__fp_chk:w #2#3#4; @
+  {
+    \if_case:w #2 \exp_stop_f:
+      \__fp_case_return_o:Nw \c_one_fp
+    \or:
+    \or:
+      \if_meaning:w 0 #3
+        \exp_after:wN \__fp_case_return_same_o:w
+      \fi:
+    \or:
+      \__fp_case_return_same_o:w
+    \fi:
+    \if_meaning:w 2 #3
+      \__fp_case_use:nw { \__fp_invalid_operation_o:fw { fact } }
+    \fi:
+    \__fp_fact_pos_o:w
+    \s__fp \__fp_chk:w #2 #3 #4 ;
+  }
+\cs_new:Npn \__fp_fact_pos_o:w #1;
+  {
+    \__fp_small_int:wTF #1;
+      { \__fp_fact_int_o:n }
+      { \__fp_invalid_operation_o:fw { fact } #1; }
+  }
+\cs_new:Npn \__fp_fact_int_o:n #1
+  {
+    \if_int_compare:w #1 > \c__fp_fact_max_arg_int
+      \__fp_case_return:nw
+        {
+          \exp_after:wN \exp_after:wN \exp_after:wN \__fp_overflow:w
+          \exp_after:wN \c_inf_fp
+        }
+    \fi:
+    \exp_after:wN \__fp_sanitize:Nw
+    \exp_after:wN 0
+    \int_value:w \__fp_int_eval:w
+    \__fp_fact_loop_o:w #1 . 4 , { 1 } { } { } { } { } { } ;
+  }
+\cs_new:Npn \__fp_fact_loop_o:w #1 . #2 ;
+  {
+    \if_int_compare:w #1 < 12 \exp_stop_f:
+      \__fp_fact_small_o:w #1
+    \fi:
+    \exp_after:wN \__fp_ep_mul:wwwwn
+    \exp_after:wN 4 \exp_after:wN ,
+    \exp_after:wN { \int_value:w \__fp_int_eval:w #1 * (#1 - 1) }
+    { } { } { } { } { } ;
+    #2 ;
+    {
+      \exp_after:wN \__fp_fact_loop_o:w
+      \int_value:w \__fp_int_eval:w #1 - 2 .
+    }
+  }
+\cs_new:Npn \__fp_fact_small_o:w #1 \fi: #2 ; #3 ; #4
+  {
+    \fi:
+    \exp_after:wN \__fp_ep_mul:wwwwn
+    \exp_after:wN 4 \exp_after:wN ,
+    \exp_after:wN
+      {
+        \int_value:w
+        \if_case:w #1 \exp_stop_f:
+        1 \or: 1 \or: 2 \or: 6 \or: 24 \or: 120 \or: 720 \or: 5040
+        \or: 40320 \or: 362880 \or: 3628800 \or: 39916800
+        \fi:
+      } { } { } { } { } { } ;
+    #3 ;
+    \__fp_ep_to_float_o:wwN 0
+  }
 %% File: l3fp-trig.dtx
 \tl_map_inline:nn
   {
@@ -18987,26 +18921,19 @@
   {
     \tl_if_empty:nF {#1}
       {
-        \__fp_expand:n
+        \exp_last_unbraced:Ne \use_ii:nn
           {
-            { \use_ii:nn }
             \__fp_array_to_clist_loop:Nw #1 { ? \prg_break: } ;
             \prg_break_point:
           }
       }
   }
-\cs_new:Npx \__fp_array_to_clist_loop:Nw #1#2;
+\cs_new:Npn \__fp_array_to_clist_loop:Nw #1#2;
   {
-    \exp_not:N \use_none:n #1
-    \exp_not:N \exp_after:wN
-                 {
-    \exp_not:N     \exp_after:wN ,
-    \exp_not:N     \exp_after:wN \c_space_tl
-    \exp_not:N     \exp:w
-    \exp_not:N     \exp_end_continue_f:w
-    \exp_not:N     \__fp_to_tl_dispatch:w #1 #2 ;
-                 }
-    \exp_not:N \__fp_array_to_clist_loop:Nw
+    \use_none:n #1
+    , ~
+    \exp_not:f { \__fp_to_tl_dispatch:w #1 #2 ; }
+    \__fp_array_to_clist_loop:Nw
   }
 %% File: l3fp-random.dtx
 \cs_new:Npn \__fp_parse_word_rand:N
@@ -20314,14 +20241,6 @@
       { is~empty }
       { contains~the~tokens: #2 }
   }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 }
-  { \tl_analysis_show:N }
-\cs_new_protected:Npn \tl_show_analysis:N #1
-  { \tl_analysis_show:N #1 }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 }
-  { \tl_analysis_show:n }
-\cs_new_protected:Npn \tl_show_analysis:n #1
-  { \tl_analysis_show:n {#1} }
 %% File: l3regex.dtx
 \cs_new_eq:NN \__regex_int_eval:w \tex_numexpr:D
 \cs_new_protected:Npn \__regex_standard_escapechar:
@@ -24300,22 +24219,6 @@
           }
       }
   }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \box_set_eq_drop:N }
-\cs_new_protected:Npn \box_set_eq_clear:NN #1#2
-  { \tex_setbox:D #1 \tex_box:D #2 }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \box_gset_eq_drop:N }
-\cs_new_protected:Npn \box_gset_eq_clear:NN #1#2
-  { \tex_global:D \tex_setbox:D #1 \tex_box:D #2 }
-\cs_generate_variant:Nn \box_set_eq_clear:NN  { c , Nc , cc }
-\cs_generate_variant:Nn \box_gset_eq_clear:NN { c , Nc , cc }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \hbox_unpack_drop:N }
-\cs_new_protected:Npn \hbox_unpack_clear:N
-  { \hbox_unpack_drop:N }
-\cs_generate_variant:Nn \hbox_unpack_clear:N { c }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \vbox_unpack_drop:N }
-\cs_new_protected:Npn \vbox_unpack_clear:N
-  { \vbox_unpack_drop:N }
-\cs_generate_variant:Nn \vbox_unpack_clear:N { c }
 %% File: l3color-base.dtx
 \cs_new_eq:NN \color_group_begin: \group_begin:
 \cs_new_eq:NN \color_group_end:   \group_end:
@@ -24863,6 +24766,283 @@
           }
       }
   }
+\fp_new:N \l__coffin_sin_fp
+\fp_new:N \l__coffin_cos_fp
+\prop_new:N \l__coffin_bounding_prop
+\prop_new:N \l__coffin_corners_prop
+\prop_new:N \l__coffin_poles_prop
+\dim_new:N \l__coffin_bounding_shift_dim
+\dim_new:N \l__coffin_left_corner_dim
+\dim_new:N \l__coffin_right_corner_dim
+\dim_new:N \l__coffin_bottom_corner_dim
+\dim_new:N \l__coffin_top_corner_dim
+\cs_new_protected:Npn \coffin_rotate:Nn #1#2
+  { \__coffin_rotate:NnNNN #1 {#2} \box_rotate:Nn \prop_set_eq:cN \hbox_set:Nn }
+\cs_generate_variant:Nn \coffin_rotate:Nn { c }
+\cs_new_protected:Npn \coffin_grotate:Nn #1#2
+  { \__coffin_rotate:NnNNN #1 {#2} \box_grotate:Nn \prop_gset_eq:cN \hbox_gset:Nn }
+\cs_generate_variant:Nn \coffin_grotate:Nn { c }
+\cs_new_protected:Npn \__coffin_rotate:NnNNN #1#2#3#4#5
+  {
+    \fp_set:Nn \l__coffin_sin_fp { sind ( #2 ) }
+    \fp_set:Nn \l__coffin_cos_fp { cosd ( #2 ) }
+    \prop_set_eq:Nc \l__coffin_corners_prop
+      { coffin ~ \__coffin_to_value:N #1 ~ corners }
+    \prop_set_eq:Nc \l__coffin_poles_prop
+      { coffin ~ \__coffin_to_value:N #1 ~ poles }
+    \prop_map_inline:Nn \l__coffin_corners_prop
+      { \__coffin_rotate_corner:Nnnn #1 {##1} ##2 }
+    \prop_map_inline:Nn \l__coffin_poles_prop
+      { \__coffin_rotate_pole:Nnnnnn #1 {##1} ##2 }
+    \__coffin_set_bounding:N #1
+    \prop_map_inline:Nn \l__coffin_bounding_prop
+      { \__coffin_rotate_bounding:nnn {##1} ##2 }
+    \__coffin_find_corner_maxima:N #1
+    \__coffin_find_bounding_shift:
+    #3 #1 {#2}
+    \hbox_set:Nn \l__coffin_internal_box
+      {
+        \tex_kern:D
+          \dim_eval:n
+            { \l__coffin_bounding_shift_dim - \l__coffin_left_corner_dim }
+          \exp_stop_f:
+        \box_move_down:nn { \l__coffin_bottom_corner_dim }
+          { \box_use:N #1 }
+      }
+    \box_set_ht:Nn \l__coffin_internal_box
+      { \l__coffin_top_corner_dim - \l__coffin_bottom_corner_dim }
+    \box_set_dp:Nn \l__coffin_internal_box { 0pt }
+    \box_set_wd:Nn \l__coffin_internal_box
+      { \l__coffin_right_corner_dim - \l__coffin_left_corner_dim }
+    #5 #1 { \box_use_drop:N \l__coffin_internal_box }
+    \prop_map_inline:Nn \l__coffin_corners_prop
+      { \__coffin_shift_corner:Nnnn #1 {##1} ##2 }
+    \prop_map_inline:Nn \l__coffin_poles_prop
+      { \__coffin_shift_pole:Nnnnnn #1 {##1} ##2 }
+    #4 { coffin ~ \__coffin_to_value:N #1 ~ corners }
+      \l__coffin_corners_prop
+    #4 { coffin ~ \__coffin_to_value:N #1 ~ poles }
+      \l__coffin_poles_prop
+  }
+\cs_new_protected:Npn \__coffin_set_bounding:N #1
+  {
+    \prop_put:Nnx \l__coffin_bounding_prop { tl }
+      { { 0pt } { \dim_eval:n { \box_ht:N #1 } } }
+    \prop_put:Nnx \l__coffin_bounding_prop { tr }
+      {
+        { \dim_eval:n { \box_wd:N #1 } }
+        { \dim_eval:n { \box_ht:N #1 } }
+      }
+    \dim_set:Nn \l__coffin_internal_dim { -\box_dp:N #1 }
+    \prop_put:Nnx \l__coffin_bounding_prop { bl }
+      { { 0pt } { \dim_use:N \l__coffin_internal_dim } }
+    \prop_put:Nnx \l__coffin_bounding_prop { br }
+      {
+        { \dim_eval:n { \box_wd:N #1 } }
+        { \dim_use:N \l__coffin_internal_dim }
+      }
+  }
+\cs_new_protected:Npn \__coffin_rotate_bounding:nnn #1#2#3
+  {
+    \__coffin_rotate_vector:nnNN {#2} {#3} \l__coffin_x_dim \l__coffin_y_dim
+    \prop_put:Nnx \l__coffin_bounding_prop {#1}
+      { { \dim_use:N \l__coffin_x_dim } { \dim_use:N \l__coffin_y_dim } }
+  }
+\cs_new_protected:Npn \__coffin_rotate_corner:Nnnn #1#2#3#4
+  {
+    \__coffin_rotate_vector:nnNN {#3} {#4} \l__coffin_x_dim \l__coffin_y_dim
+    \prop_put:Nnx \l__coffin_corners_prop {#2}
+      { { \dim_use:N \l__coffin_x_dim } { \dim_use:N \l__coffin_y_dim } }
+  }
+\cs_new_protected:Npn \__coffin_rotate_pole:Nnnnnn #1#2#3#4#5#6
+  {
+    \__coffin_rotate_vector:nnNN {#3} {#4} \l__coffin_x_dim \l__coffin_y_dim
+    \__coffin_rotate_vector:nnNN {#5} {#6}
+      \l__coffin_x_prime_dim \l__coffin_y_prime_dim
+    \prop_put:Nnx \l__coffin_poles_prop {#2}
+      {
+        { \dim_use:N \l__coffin_x_dim } { \dim_use:N \l__coffin_y_dim }
+        { \dim_use:N \l__coffin_x_prime_dim }
+        { \dim_use:N \l__coffin_y_prime_dim }
+      }
+  }
+\cs_new_protected:Npn \__coffin_rotate_vector:nnNN #1#2#3#4
+  {
+    \dim_set:Nn #3
+      {
+        \fp_to_dim:n
+          {
+              \dim_to_fp:n {#1} * \l__coffin_cos_fp
+            - \dim_to_fp:n {#2} * \l__coffin_sin_fp
+          }
+      }
+    \dim_set:Nn #4
+      {
+        \fp_to_dim:n
+          {
+              \dim_to_fp:n {#1} * \l__coffin_sin_fp
+            + \dim_to_fp:n {#2} * \l__coffin_cos_fp
+          }
+      }
+  }
+\cs_new_protected:Npn \__coffin_find_corner_maxima:N #1
+  {
+    \dim_set:Nn \l__coffin_top_corner_dim   { -\c_max_dim }
+    \dim_set:Nn \l__coffin_right_corner_dim { -\c_max_dim }
+    \dim_set:Nn \l__coffin_bottom_corner_dim { \c_max_dim }
+    \dim_set:Nn \l__coffin_left_corner_dim   { \c_max_dim }
+    \prop_map_inline:Nn \l__coffin_corners_prop
+      { \__coffin_find_corner_maxima_aux:nn ##2 }
+  }
+\cs_new_protected:Npn \__coffin_find_corner_maxima_aux:nn #1#2
+  {
+    \dim_set:Nn \l__coffin_left_corner_dim
+     { \dim_min:nn { \l__coffin_left_corner_dim } {#1} }
+    \dim_set:Nn \l__coffin_right_corner_dim
+     { \dim_max:nn { \l__coffin_right_corner_dim } {#1} }
+    \dim_set:Nn \l__coffin_bottom_corner_dim
+     { \dim_min:nn { \l__coffin_bottom_corner_dim } {#2} }
+    \dim_set:Nn \l__coffin_top_corner_dim
+     { \dim_max:nn { \l__coffin_top_corner_dim } {#2} }
+  }
+\cs_new_protected:Npn \__coffin_find_bounding_shift:
+  {
+    \dim_set:Nn \l__coffin_bounding_shift_dim { \c_max_dim }
+    \prop_map_inline:Nn \l__coffin_bounding_prop
+      { \__coffin_find_bounding_shift_aux:nn ##2 }
+  }
+\cs_new_protected:Npn \__coffin_find_bounding_shift_aux:nn #1#2
+  {
+    \dim_set:Nn \l__coffin_bounding_shift_dim
+      { \dim_min:nn { \l__coffin_bounding_shift_dim } {#1} }
+  }
+\cs_new_protected:Npn \__coffin_shift_corner:Nnnn #1#2#3#4
+  {
+    \prop_put:Nnx \l__coffin_corners_prop {#2}
+      {
+        { \dim_eval:n { #3 - \l__coffin_left_corner_dim } }
+        { \dim_eval:n { #4 - \l__coffin_bottom_corner_dim } }
+      }
+  }
+\cs_new_protected:Npn \__coffin_shift_pole:Nnnnnn #1#2#3#4#5#6
+  {
+    \prop_put:Nnx \l__coffin_poles_prop {#2}
+      {
+        { \dim_eval:n { #3 - \l__coffin_left_corner_dim } }
+        { \dim_eval:n { #4 - \l__coffin_bottom_corner_dim } }
+        {#5} {#6}
+      }
+  }
+\fp_new:N \l__coffin_scale_x_fp
+\fp_new:N \l__coffin_scale_y_fp
+\dim_new:N \l__coffin_scaled_total_height_dim
+\dim_new:N \l__coffin_scaled_width_dim
+\cs_new_protected:Npn \coffin_resize:Nnn #1#2#3
+  {
+    \__coffin_resize:NnnNN #1 {#2} {#3}
+      \box_resize_to_wd_and_ht_plus_dp:Nnn
+      \prop_set_eq:cN
+  }
+\cs_generate_variant:Nn \coffin_resize:Nnn { c }
+\cs_new_protected:Npn \coffin_gresize:Nnn #1#2#3
+  {
+    \__coffin_resize:NnnNN #1 {#2} {#3}
+      \box_gresize_to_wd_and_ht_plus_dp:Nnn
+      \prop_gset_eq:cN
+  }
+\cs_generate_variant:Nn \coffin_gresize:Nnn { c }
+\cs_new_protected:Npn \__coffin_resize:NnnNN #1#2#3#4#5
+  {
+    \fp_set:Nn \l__coffin_scale_x_fp
+      { \dim_to_fp:n {#2} / \dim_to_fp:n { \coffin_wd:N #1 } }
+    \fp_set:Nn \l__coffin_scale_y_fp
+      {
+          \dim_to_fp:n {#3}
+        / \dim_to_fp:n { \coffin_ht:N #1 + \coffin_dp:N #1 }
+      }
+    #4 #1 {#2} {#3}
+    \__coffin_resize_common:NnnN #1 {#2} {#3} #5
+  }
+\cs_new_protected:Npn \__coffin_resize_common:NnnN #1#2#3#4
+  {
+    \prop_set_eq:Nc \l__coffin_corners_prop
+      { coffin ~ \__coffin_to_value:N #1 ~ corners }
+    \prop_set_eq:Nc \l__coffin_poles_prop
+      { coffin ~ \__coffin_to_value:N #1 ~ poles }
+    \prop_map_inline:Nn \l__coffin_corners_prop
+      { \__coffin_scale_corner:Nnnn #1 {##1} ##2 }
+    \prop_map_inline:Nn \l__coffin_poles_prop
+      { \__coffin_scale_pole:Nnnnnn #1 {##1} ##2 }
+    \fp_compare:nNnT \l__coffin_scale_x_fp < \c_zero_fp
+      {
+        \prop_map_inline:Nn \l__coffin_corners_prop
+          { \__coffin_x_shift_corner:Nnnn #1 {##1} ##2 }
+        \prop_map_inline:Nn \l__coffin_poles_prop
+          { \__coffin_x_shift_pole:Nnnnnn #1 {##1} ##2 }
+      }
+    #4 { coffin ~ \__coffin_to_value:N #1 ~ corners }
+      \l__coffin_corners_prop
+    #4 { coffin ~ \__coffin_to_value:N #1 ~ poles }
+      \l__coffin_poles_prop
+  }
+\cs_new_protected:Npn \coffin_scale:Nnn #1#2#3
+  { \__coffin_scale:NnnNN #1 {#2} {#3} \box_scale:Nnn \prop_set_eq:cN }
+\cs_generate_variant:Nn \coffin_scale:Nnn { c }
+\cs_new_protected:Npn \coffin_gscale:Nnn #1#2#3
+  { \__coffin_scale:NnnNN #1 {#2} {#3} \box_gscale:Nnn \prop_gset_eq:cN }
+\cs_generate_variant:Nn \coffin_gscale:Nnn { c }
+\cs_new_protected:Npn \__coffin_scale:NnnNN #1#2#3#4#5
+  {
+    \fp_set:Nn \l__coffin_scale_x_fp {#2}
+    \fp_set:Nn \l__coffin_scale_y_fp {#3}
+    #4 #1 { \l__coffin_scale_x_fp } { \l__coffin_scale_y_fp }
+    \dim_set:Nn \l__coffin_internal_dim
+      { \coffin_ht:N #1 + \coffin_dp:N #1 }
+    \dim_set:Nn \l__coffin_scaled_total_height_dim
+      { \fp_abs:n { \l__coffin_scale_y_fp } \l__coffin_internal_dim }
+    \dim_set:Nn \l__coffin_scaled_width_dim
+      { -\fp_abs:n { \l__coffin_scale_x_fp  } \coffin_wd:N #1 }
+    \__coffin_resize_common:NnnN #1
+      { \l__coffin_scaled_width_dim } { \l__coffin_scaled_total_height_dim }
+      #5
+  }
+\cs_new_protected:Npn \__coffin_scale_vector:nnNN #1#2#3#4
+  {
+    \dim_set:Nn #3
+      { \fp_to_dim:n { \dim_to_fp:n {#1} * \l__coffin_scale_x_fp } }
+    \dim_set:Nn #4
+      { \fp_to_dim:n { \dim_to_fp:n {#2} * \l__coffin_scale_y_fp } }
+  }
+\cs_new_protected:Npn \__coffin_scale_corner:Nnnn #1#2#3#4
+  {
+    \__coffin_scale_vector:nnNN {#3} {#4} \l__coffin_x_dim \l__coffin_y_dim
+    \prop_put:Nnx \l__coffin_corners_prop {#2}
+      { { \dim_use:N \l__coffin_x_dim } { \dim_use:N \l__coffin_y_dim } }
+  }
+\cs_new_protected:Npn \__coffin_scale_pole:Nnnnnn #1#2#3#4#5#6
+  {
+    \__coffin_scale_vector:nnNN {#3} {#4} \l__coffin_x_dim \l__coffin_y_dim
+    \prop_put:Nnx \l__coffin_poles_prop {#2}
+      {
+        { \dim_use:N \l__coffin_x_dim } { \dim_use:N \l__coffin_y_dim }
+        {#5} {#6}
+      }
+  }
+\cs_new_protected:Npn \__coffin_x_shift_corner:Nnnn #1#2#3#4
+  {
+    \prop_put:Nnx \l__coffin_corners_prop {#2}
+      {
+        { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
+      }
+  }
+\cs_new_protected:Npn \__coffin_x_shift_pole:Nnnnnn #1#2#3#4#5#6
+  {
+    \prop_put:Nnx \l__coffin_poles_prop {#2}
+      {
+        { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
+        {#5} {#6}
+      }
+  }
 \cs_new_protected:Npn \coffin_join:NnnNnnnn #1#2#3#4#5#6#7#8
   {
     \__coffin_join:NnnNnnnnN #1 {#2} {#3} #4 {#5} {#6} {#7} {#8}
@@ -25104,11 +25284,13 @@
 \prop_new:N \l__coffin_display_poles_prop
 \tl_new:N  \l__coffin_display_font_tl
 \tl_set:Nn \l__coffin_display_font_tl { \sffamily \tiny }
+\cs_new_protected:Npn \__coffin_color:n #1
+  { \cs_if_exist:NT \color { \color {#1} } }
 \cs_new_protected:Npn \coffin_mark_handle:Nnnn #1#2#3#4
   {
     \hcoffin_set:Nn \l__coffin_display_pole_coffin
       {
-        \color {#4}
+        \__coffin_color:n {#4}
         \rule { 1pt } { 1pt }
       }
     \__coffin_attach_mark:NnnNnnnn #1 {#2} {#3}
@@ -25115,7 +25297,7 @@
       \l__coffin_display_pole_coffin { hc } { vc } { 0pt } { 0pt }
     \hcoffin_set:Nn \l__coffin_display_coord_coffin
       {
-        \color {#4}
+        \__coffin_color:n {#4}
         \l__coffin_display_font_tl
         ( \tl_to_str:n { #2 , #3 } )
       }
@@ -25153,7 +25335,7 @@
   {
     \hcoffin_set:Nn \l__coffin_display_pole_coffin
       {
-        \color {#2}
+        \__coffin_color:n {#2}
         \rule { 1pt } { 1pt }
       }
     \prop_set_eq:Nc \l__coffin_display_poles_prop
@@ -25188,7 +25370,7 @@
               { 0pt } { 0pt }
             \hcoffin_set:Nn \l__coffin_display_coord_coffin
               {
-                \color {#6}
+                \__coffin_color:n {#6}
                 \l__coffin_display_font_tl
                 ( \tl_to_str:n { #1 , ##1 } )
               }
@@ -25338,12 +25520,6 @@
     The~feature~you~are~using~is~only~available~
     with~the~LuaTeX~engine.~LaTeX3~ignored~'#1'.
   }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \lua_now:e }
-\cs_new:Npn \lua_now_x:n #1 { \__lua_now:n {#1} }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \lua_escape:e }
-\cs_new:Npn \lua_escape_x:n #1 { \__lua_escape:n {#1} }
-\__kernel_patch_deprecation:nnNNpn { 2019-12-31 } { \lua_shipout_e:n }
-\cs_new_protected:Npn \lua_shipout_x:n #1 { \__lua_shipout:n {#1} }
 %% File: l3unicode.dtx
 \ior_new:N \g__char_data_ior
 \bool_lazy_or:nnTF { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: }
@@ -25599,323 +25775,66 @@
       }
     #6 #1 \l__box_internal_box
   }
-\fp_new:N \l__coffin_sin_fp
-\fp_new:N \l__coffin_cos_fp
-\prop_new:N \l__coffin_bounding_prop
-\prop_new:N \l__coffin_corners_prop
-\prop_new:N \l__coffin_poles_prop
-\dim_new:N \l__coffin_bounding_shift_dim
-\dim_new:N \l__coffin_left_corner_dim
-\dim_new:N \l__coffin_right_corner_dim
-\dim_new:N \l__coffin_bottom_corner_dim
-\dim_new:N \l__coffin_top_corner_dim
-\cs_new_protected:Npn \coffin_rotate:Nn #1#2
-  { \__coffin_rotate:NnNN #1 {#2} \box_rotate:Nn \prop_set_eq:cN }
-\cs_new_protected:Npn \coffin_grotate:Nn #1#2
-  { \__coffin_rotate:NnNN #1 {#2} \box_grotate:Nn \prop_gset_eq:cN }
-\cs_new_protected:Npn \__coffin_rotate:NnNN #1#2#3#4
-  {
-    \fp_set:Nn \l__coffin_sin_fp { sind ( #2 ) }
-    \fp_set:Nn \l__coffin_cos_fp { cosd ( #2 ) }
-    \prop_set_eq:Nc \l__coffin_corners_prop
-      { coffin ~ \__coffin_to_value:N #1 ~ corners }
-    \prop_set_eq:Nc \l__coffin_poles_prop
-      { coffin ~ \__coffin_to_value:N #1 ~ poles }
-    \prop_map_inline:Nn \l__coffin_corners_prop
-      { \__coffin_rotate_corner:Nnnn #1 {##1} ##2 }
-    \prop_map_inline:Nn \l__coffin_poles_prop
-      { \__coffin_rotate_pole:Nnnnnn #1 {##1} ##2 }
-    \__coffin_set_bounding:N #1
-    \prop_map_inline:Nn \l__coffin_bounding_prop
-      { \__coffin_rotate_bounding:nnn {##1} ##2 }
-    \__coffin_find_corner_maxima:N #1
-    \__coffin_find_bounding_shift:
-    #3 #1 {#2}
-    \hbox_set:Nn \l__coffin_internal_box
-      {
-        \tex_kern:D
-          \dim_eval:n
-            { \l__coffin_bounding_shift_dim - \l__coffin_left_corner_dim }
-          \exp_stop_f:
-        \box_move_down:nn { \l__coffin_bottom_corner_dim }
-          { \box_use:N #1 }
-      }
-    \box_set_ht:Nn \l__coffin_internal_box
-      { \l__coffin_top_corner_dim - \l__coffin_bottom_corner_dim }
-    \box_set_dp:Nn \l__coffin_internal_box { 0 pt }
-    \box_set_wd:Nn \l__coffin_internal_box
-      { \l__coffin_right_corner_dim - \l__coffin_left_corner_dim }
-    \hbox_set:Nn #1 { \box_use_drop:N \l__coffin_internal_box }
-    \prop_map_inline:Nn \l__coffin_corners_prop
-      { \__coffin_shift_corner:Nnnn #1 {##1} ##2 }
-    \prop_map_inline:Nn \l__coffin_poles_prop
-      { \__coffin_shift_pole:Nnnnnn #1 {##1} ##2 }
-    #4 { coffin ~ \__coffin_to_value:N #1 ~ corners }
-      \l__coffin_corners_prop
-    #4 { coffin ~ \__coffin_to_value:N #1 ~ poles }
-      \l__coffin_poles_prop
-  }
-\cs_generate_variant:Nn \coffin_rotate:Nn { c }
-\cs_new_protected:Npn \__coffin_set_bounding:N #1
-  {
-    \prop_put:Nnx \l__coffin_bounding_prop { tl }
-      { { 0 pt } { \dim_eval:n { \box_ht:N #1 } } }
-    \prop_put:Nnx \l__coffin_bounding_prop { tr }
-      {
-        { \dim_eval:n { \box_wd:N #1 } }
-        { \dim_eval:n { \box_ht:N #1 } }
-      }
-    \dim_set:Nn \l__coffin_internal_dim { -\box_dp:N #1 }
-    \prop_put:Nnx \l__coffin_bounding_prop { bl }
-      { { 0 pt } { \dim_use:N \l__coffin_internal_dim } }
-    \prop_put:Nnx \l__coffin_bounding_prop { br }
-      {
-        { \dim_eval:n { \box_wd:N #1 } }
-        { \dim_use:N \l__coffin_internal_dim }
-      }
-  }
-\cs_new_protected:Npn \__coffin_rotate_bounding:nnn #1#2#3
-  {
-    \__coffin_rotate_vector:nnNN {#2} {#3} \l__coffin_x_dim \l__coffin_y_dim
-    \prop_put:Nnx \l__coffin_bounding_prop {#1}
-      { { \dim_use:N \l__coffin_x_dim } { \dim_use:N \l__coffin_y_dim } }
-  }
-\cs_new_protected:Npn \__coffin_rotate_corner:Nnnn #1#2#3#4
-  {
-    \__coffin_rotate_vector:nnNN {#3} {#4} \l__coffin_x_dim \l__coffin_y_dim
-    \prop_put:Nnx \l__coffin_corners_prop {#2}
-      { { \dim_use:N \l__coffin_x_dim } { \dim_use:N \l__coffin_y_dim } }
-  }
-\cs_new_protected:Npn \__coffin_rotate_pole:Nnnnnn #1#2#3#4#5#6
-  {
-    \__coffin_rotate_vector:nnNN {#3} {#4} \l__coffin_x_dim \l__coffin_y_dim
-    \__coffin_rotate_vector:nnNN {#5} {#6}
-      \l__coffin_x_prime_dim \l__coffin_y_prime_dim
-    \prop_put:Nnx \l__coffin_poles_prop {#2}
-      {
-        { \dim_use:N \l__coffin_x_dim } { \dim_use:N \l__coffin_y_dim }
-        { \dim_use:N \l__coffin_x_prime_dim }
-        { \dim_use:N \l__coffin_y_prime_dim }
-      }
-  }
-\cs_new_protected:Npn \__coffin_rotate_vector:nnNN #1#2#3#4
-  {
-    \dim_set:Nn #3
-      {
-        \fp_to_dim:n
-          {
-              \dim_to_fp:n {#1} * \l__coffin_cos_fp
-            - \dim_to_fp:n {#2} * \l__coffin_sin_fp
-          }
-      }
-    \dim_set:Nn #4
-      {
-        \fp_to_dim:n
-          {
-              \dim_to_fp:n {#1} * \l__coffin_sin_fp
-            + \dim_to_fp:n {#2} * \l__coffin_cos_fp
-          }
-      }
-  }
-\cs_new_protected:Npn \__coffin_find_corner_maxima:N #1
-  {
-    \dim_set:Nn \l__coffin_top_corner_dim   { -\c_max_dim }
-    \dim_set:Nn \l__coffin_right_corner_dim { -\c_max_dim }
-    \dim_set:Nn \l__coffin_bottom_corner_dim { \c_max_dim }
-    \dim_set:Nn \l__coffin_left_corner_dim   { \c_max_dim }
-    \prop_map_inline:Nn \l__coffin_corners_prop
-      { \__coffin_find_corner_maxima_aux:nn ##2 }
-  }
-\cs_new_protected:Npn \__coffin_find_corner_maxima_aux:nn #1#2
-  {
-    \dim_set:Nn \l__coffin_left_corner_dim
-     { \dim_min:nn { \l__coffin_left_corner_dim } {#1} }
-    \dim_set:Nn \l__coffin_right_corner_dim
-     { \dim_max:nn { \l__coffin_right_corner_dim } {#1} }
-    \dim_set:Nn \l__coffin_bottom_corner_dim
-     { \dim_min:nn { \l__coffin_bottom_corner_dim } {#2} }
-    \dim_set:Nn \l__coffin_top_corner_dim
-     { \dim_max:nn { \l__coffin_top_corner_dim } {#2} }
-  }
-\cs_new_protected:Npn \__coffin_find_bounding_shift:
-  {
-    \dim_set:Nn \l__coffin_bounding_shift_dim { \c_max_dim }
-    \prop_map_inline:Nn \l__coffin_bounding_prop
-      { \__coffin_find_bounding_shift_aux:nn ##2 }
-  }
-\cs_new_protected:Npn \__coffin_find_bounding_shift_aux:nn #1#2
-  {
-    \dim_set:Nn \l__coffin_bounding_shift_dim
-      { \dim_min:nn { \l__coffin_bounding_shift_dim } {#1} }
-  }
-\cs_new_protected:Npn \__coffin_shift_corner:Nnnn #1#2#3#4
-  {
-    \prop_put:Nnx \l__coffin_corners_prop {#2}
-      {
-        { \dim_eval:n { #3 - \l__coffin_left_corner_dim } }
-        { \dim_eval:n { #4 - \l__coffin_bottom_corner_dim } }
-      }
-  }
-\cs_new_protected:Npn \__coffin_shift_pole:Nnnnnn #1#2#3#4#5#6
-  {
-    \prop_put:Nnx \l__coffin_poles_prop {#2}
-      {
-        { \dim_eval:n { #3 - \l__coffin_left_corner_dim } }
-        { \dim_eval:n { #4 - \l__coffin_bottom_corner_dim } }
-        {#5} {#6}
-      }
-  }
-\fp_new:N \l__coffin_scale_x_fp
-\fp_new:N \l__coffin_scale_y_fp
-\dim_new:N \l__coffin_scaled_total_height_dim
-\dim_new:N \l__coffin_scaled_width_dim
-\cs_new_protected:Npn \coffin_resize:Nnn #1#2#3
-  {
-    \__coffin_resize:NnnNN #1 {#2} {#3}
-      \box_resize_to_wd_and_ht_plus_dp:Nnn
-      \prop_set_eq:cN
-  }
-\cs_generate_variant:Nn \coffin_resize:Nnn { c }
-\cs_new_protected:Npn \coffin_gresize:Nnn #1#2#3
-  {
-    \__coffin_resize:NnnNN #1 {#2} {#3}
-      \box_gresize_to_wd_and_ht_plus_dp:Nnn
-      \prop_gset_eq:cN
-  }
-\cs_generate_variant:Nn \coffin_gresize:Nnn { c }
-\cs_new_protected:Npn \__coffin_resize:NnnNN #1#2#3#4#5
-  {
-    \fp_set:Nn \l__coffin_scale_x_fp
-      { \dim_to_fp:n {#2} / \dim_to_fp:n { \coffin_wd:N #1 } }
-    \fp_set:Nn \l__coffin_scale_y_fp
-      {
-          \dim_to_fp:n {#3}
-        / \dim_to_fp:n { \coffin_ht:N #1 + \coffin_dp:N #1 }
-      }
-    #4 #1 {#2} {#3}
-    \__coffin_resize_common:NnnN #1 {#2} {#3} #5
-  }
-\cs_new_protected:Npn \__coffin_resize_common:NnnN #1#2#3#4
-  {
-    \prop_set_eq:Nc \l__coffin_corners_prop
-      { coffin ~ \__coffin_to_value:N #1 ~ corners }
-    \prop_set_eq:Nc \l__coffin_poles_prop
-      { coffin ~ \__coffin_to_value:N #1 ~ poles }
-    \prop_map_inline:Nn \l__coffin_corners_prop
-      { \__coffin_scale_corner:Nnnn #1 {##1} ##2 }
-    \prop_map_inline:Nn \l__coffin_poles_prop
-      { \__coffin_scale_pole:Nnnnnn #1 {##1} ##2 }
-    \fp_compare:nNnT \l__coffin_scale_x_fp < \c_zero_fp
-      {
-        \prop_map_inline:Nn \l__coffin_corners_prop
-          { \__coffin_x_shift_corner:Nnnn #1 {##1} ##2 }
-        \prop_map_inline:Nn \l__coffin_poles_prop
-          { \__coffin_x_shift_pole:Nnnnnn #1 {##1} ##2 }
-      }
-    #4 { coffin ~ \__coffin_to_value:N #1 ~ corners }
-      \l__coffin_corners_prop
-    #4 { coffin ~ \__coffin_to_value:N #1 ~ poles }
-      \l__coffin_poles_prop
-  }
-\cs_new_protected:Npn \coffin_scale:Nnn #1#2#3
-  { \__coffin_scale:NnnNN #1 {#2} {#3} \box_scale:Nnn \prop_set_eq:cN }
-\cs_generate_variant:Nn \coffin_scale:Nnn { c }
-\cs_new_protected:Npn \coffin_gscale:Nnn #1#2#3
-  { \__coffin_scale:NnnNN #1 {#2} {#3} \box_gscale:Nnn \prop_gset_eq:cN }
-\cs_generate_variant:Nn \coffin_gscale:Nnn { c }
-\cs_new_protected:Npn \__coffin_scale:NnnNN #1#2#3#4#5
-  {
-    \fp_set:Nn \l__coffin_scale_x_fp {#2}
-    \fp_set:Nn \l__coffin_scale_y_fp {#3}
-    #4 #1 { \l__coffin_scale_x_fp } { \l__coffin_scale_y_fp }
-    \dim_set:Nn \l__coffin_internal_dim
-      { \coffin_ht:N #1 + \coffin_dp:N #1 }
-    \dim_set:Nn \l__coffin_scaled_total_height_dim
-      { \fp_abs:n { \l__coffin_scale_y_fp } \l__coffin_internal_dim }
-    \dim_set:Nn \l__coffin_scaled_width_dim
-      { -\fp_abs:n { \l__coffin_scale_x_fp  } \coffin_wd:N #1 }
-    \__coffin_resize_common:NnnN #1
-      { \l__coffin_scaled_width_dim } { \l__coffin_scaled_total_height_dim }
-      #5
-  }
-\cs_new_protected:Npn \__coffin_scale_vector:nnNN #1#2#3#4
-  {
-    \dim_set:Nn #3
-      { \fp_to_dim:n { \dim_to_fp:n {#1} * \l__coffin_scale_x_fp } }
-    \dim_set:Nn #4
-      { \fp_to_dim:n { \dim_to_fp:n {#2} * \l__coffin_scale_y_fp } }
-  }
-\cs_new_protected:Npn \__coffin_scale_corner:Nnnn #1#2#3#4
-  {
-    \__coffin_scale_vector:nnNN {#3} {#4} \l__coffin_x_dim \l__coffin_y_dim
-    \prop_put:Nnx \l__coffin_corners_prop {#2}
-      { { \dim_use:N \l__coffin_x_dim } { \dim_use:N \l__coffin_y_dim } }
-  }
-\cs_new_protected:Npn \__coffin_scale_pole:Nnnnnn #1#2#3#4#5#6
-  {
-    \__coffin_scale_vector:nnNN {#3} {#4} \l__coffin_x_dim \l__coffin_y_dim
-    \prop_put:Nnx \l__coffin_poles_prop {#2}
-      {
-        { \dim_use:N \l__coffin_x_dim } { \dim_use:N \l__coffin_y_dim }
-        {#5} {#6}
-      }
-  }
-\cs_new_protected:Npn \__coffin_x_shift_corner:Nnnn #1#2#3#4
-  {
-    \prop_put:Nnx \l__coffin_corners_prop {#2}
-      {
-        { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
-      }
-  }
-\cs_new_protected:Npn \__coffin_x_shift_pole:Nnnnnn #1#2#3#4#5#6
-  {
-    \prop_put:Nnx \l__coffin_poles_prop {#2}
-      {
-        { \dim_eval:n { #3 + \box_wd:N #1 } } {#4}
-        {#5} {#6}
-      }
-  }
 \cs_new:Npn \fp_sign:n #1
   { \fp_to_decimal:n { sign \__fp_parse:n {#1} } }
 \cs_new_protected:Npn \file_get_mdfive_hash:nN #1#2
+  { \file_get_mdfive_hash:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \file_get_size:nN #1#2
+  { \file_get_size:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\cs_new_protected:Npn \file_get_timestamp:nN #1#2
+  { \file_get_timestamp:nNF {#1} #2 { \tl_set:Nn #2 { \q_no_value } } }
+\prg_new_protected_conditional:Npnn \file_get_mdfive_hash:nN #1#2 { T , F , TF }
   { \__file_get_details:nnN {#1} { mdfivesum } {#2} }
-\cs_new_protected:Npn \file_get_size:nN #1#2
+\prg_new_protected_conditional:Npnn \file_get_size:nN #1#2 { T , F , TF }
   { \__file_get_details:nnN {#1} { size } {#2} }
-\cs_new_protected:Npn \file_get_timestamp:nN #1#2
+\prg_new_protected_conditional:Npnn \file_get_timestamp:nN #1#2 { T , F , TF }
   { \__file_get_details:nnN {#1} { moddate } {#2} }
 \cs_new_protected:Npn \__file_get_details:nnN #1#2#3
   {
-    \file_get_full_name:nN {#1} \l__file_full_name_str
-    \str_set:Nx #3
+    \file_get_full_name:nNTF {#1} \l__file_full_name_tl
       {
-        \use:c { tex_file #2 :D } \exp_after:wN
-          { \l__file_full_name_str }
+        \tl_set:Nx #3
+          {
+            \use:c { tex_file #2 :D } \exp_after:wN
+              { \l__file_full_name_tl }
+          }
+        \prg_return_true:
       }
+      { \prg_return_false: }
   }
 \sys_if_engine_luatex:TF
   {
     \cs_set_protected:Npn \__file_get_details:nnN #1#2#3
       {
-        \file_get_full_name:nN {#1} \l__file_full_name_str
-        \str_set:Nx #3
+        \file_get_full_name:nNTF {#1} \l__file_full_name_tl
           {
-            \lua_now:e
+            \tl_set:Nx #3
               {
-                l3kernel.file#2
-                  ( " \lua_escape:e { \l__file_full_name_str } " )
+                \lua_now:e
+                  {
+                    l3kernel.file#2
+                      ( " \lua_escape:e { \l__file_full_name_tl } " )
+                  }
               }
+            \prg_return_true:
           }
-       }
+          { \prg_return_false: }
+      }
   }
   {
-    \cs_set_protected:Npn \file_get_mdfive_hash:nN #1#2
+    \prg_set_protected_conditional:Npnn \file_get_mdfive_hash:nN #1#2
+      { T , F ,  TF }
       {
-        \file_get_full_name:nN {#1} \l__file_full_name_str
-        \tl_set:Nx #2
+        \file_get_full_name:nNTF {#1} \l__file_full_name_tl
           {
-            \tex_mdfivesum:D file \exp_after:wN
-              { \l__file_full_name_str }
+            \tl_set:Nx #2
+              {
+                \tex_mdfivesum:D file \exp_after:wN
+                  { \l__file_full_name_tl }
+              }
+            \prg_return_true:
           }
+          { \prg_return_false: }
       }
     \cs_if_exist:NF \tex_filesize:D
       {
@@ -25925,6 +25844,7 @@
             \__kernel_msg_error:nnx
               { kernel } { primitive-not-available }
               { \exp_not:c { (pdf)file #2 } }
+            \prg_return_false:
           }
       }
   }
@@ -25936,16 +25856,14 @@
   }
 \cs_new_protected:Npn \file_if_exist_input:n #1
   {
-    \file_get_full_name:nN {#1} \l__file_full_name_str
-    \str_if_empty:NF \l__file_full_name_str
-      { \__file_input:V \l__file_full_name_str }
+    \file_get_full_name:nNT {#1} \l__file_full_name_tl
+      { \__file_input:V \l__file_full_name_tl }
   }
 \cs_new_protected:Npn \file_if_exist_input:nF #1#2
   {
-    \file_get_full_name:nN {#1} \l__file_full_name_str
-    \str_if_empty:NTF \l__file_full_name_str
+    \file_get_full_name:nNTF {#1} \l__file_full_name_tl
+      { \__file_input:V \l__file_full_name_tl }
       {#2}
-      { \__file_input:V \l__file_full_name_str }
   }
 \cs_new_protected:Npn \file_input_stop: { \tex_endinput:D }
 \__kernel_patch:nnNNpn { \__flag_chk_exist:n {#1} } { }
@@ -25974,10 +25892,14 @@
   }
 \cs_new:Npn \msg_expandable_error:nnnnnn #1#2#3#4#5#6
   {
-    \exp_args:Nf \__msg_expandable_error_module:nn
+    \exp_args:Ne \__msg_expandable_error_module:nn
       {
-        \exp_args:Nf \tl_to_str:n
-          { \use:c { \c__msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+        \exp_args:Nc \exp_args:Noooo
+          { \c__msg_text_prefix_tl #1 / #2 }
+          { \tl_to_str:n {#3} }
+          { \tl_to_str:n {#4} }
+          { \tl_to_str:n {#5} }
+          { \tl_to_str:n {#6} }
       }
       {#1}
   }
@@ -26035,16 +25957,6 @@
 \cs_new_protected:Npn \bool_gset_inverse:N #1
   { \bool_if:NTF #1 { \bool_gset_false:N } { \bool_gset_true:N } #1 }
 \cs_generate_variant:Nn \bool_gset_inverse:N { c }
-\cs_new:Npn \prop_count:N #1
-  {
-    \int_eval:n
-      {
-        0
-        \prop_map_function:NN #1 \__prop_count:nn
-      }
-  }
-\cs_new:Npn \__prop_count:nn #1#2 { + 1 }
-\cs_generate_variant:Nn \prop_count:N { c }
 \cs_new:Npn \prop_map_tokens:Nn #1#2
   {
     \exp_last_unbraced:Nno
@@ -26244,19 +26156,6 @@
       \fi:
     \fi:
   }
-\cs_new:Npn \skip_split_finite_else_action:nnNN #1#2#3#4
-  {
-    \skip_if_finite:nTF {#1}
-      {
-        #3 = \tex_gluestretch:D #1 \scan_stop:
-        #4 = \tex_glueshrink:D  #1 \scan_stop:
-      }
-      {
-        #3 = \c_zero_skip
-        #4 = \c_zero_skip
-        #2
-      }
-  }
 \str_const:Nx \c_sys_engine_version_str
   {
     \str_case:on \c_sys_engine_str
@@ -26347,7 +26246,7 @@
 \cs_new_protected:Npn \sys_shell_get:nnN #1#2#3
   {
     \sys_shell_get:nnNF {#1} {#2} #3
-      { \tl_clear:N #3 }
+      { \tl_set:Nn #3 { \q_no_value } }
   }
 \prg_new_protected_conditional:Npnn \sys_shell_get:nnN #1#2#3 { T , F , TF }
   {
@@ -26364,8 +26263,8 @@
         \prg_return_false:
       }
       {
-        \if_false: { \fi:
         \group_begin:
+          \if_false: { \fi:
           \int_set_eq:NN \tex_tracingnesting:D \c_zero_int
           \exp_args:No \tex_everyeof:D { \c__sys_marker_tl }
           #2 \scan_stop:
@@ -26458,80 +26357,6 @@
       \prg_return_false:
     \fi:
   }
-\cs_new:Npn \tl_reverse_tokens:n #1
-  {
-    \__kernel_exp_not:w \exp_after:wN
-      {
-        \exp:w
-        \__tl_act:NNNnn
-          \__tl_reverse_normal:nN
-          \__tl_reverse_group:nn
-          \__tl_reverse_space:n
-          { }
-          {#1}
-      }
-  }
-\cs_new:Npn \__tl_reverse_group:nn #1
-  {
-    \__tl_act_group_recurse:Nnn
-      \__tl_act_reverse_output:n
-      { \tl_reverse_tokens:n }
-  }
-\cs_new:Npn \__tl_act_group_recurse:Nnn #1#2#3
-  {
-    \exp_args:Nf #1
-      { \exp_after:wN \exp_after:wN \exp_after:wN { #2 {#3} } }
-  }
-\cs_new:Npn \tl_count_tokens:n #1
-  {
-    \int_eval:n
-      {
-        \__tl_act:NNNnn
-          \__tl_act_count_normal:nN
-          \__tl_act_count_group:nn
-          \__tl_act_count_space:n
-          { }
-          {#1}
-      }
-  }
-\cs_new:Npn \__tl_act_count_normal:nN #1 #2 { 1 + }
-\cs_new:Npn \__tl_act_count_space:n #1 { 1 + }
-\cs_new:Npn \__tl_act_count_group:nn #1 #2
-  { 2 + \tl_count_tokens:n {#2} + }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_set_from_file:Nnn #1#2#3
-  { \file_get:nnN {#3} {#2} #1 }
-\cs_generate_variant:Nn \tl_set_from_file:Nnn { c }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_gset_from_file:Nnn #1#2#3
-  {
-    \group_begin:
-      \file_get:nnN {#3} {#2} \l__tl_internal_a_tl
-      \tl_gset_eq:NN #1 \l__tl_internal_a_tl
-    \group_end:
-  }
-\cs_generate_variant:Nn \tl_gset_from_file:Nnn { c }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_set_from_file_x:Nnn #1#2#3
-  {
-    \group_begin:
-      \file_get:nnN {#3} {#2} \l__tl_internal_a_tl
-      #2 \scan_stop:
-      \tl_set:Nx \l__tl_internal_a_tl { \l__tl_internal_a_tl }
-    \exp_args:NNNo \group_end:
-    \tl_set:Nn #1 \l__tl_internal_a_tl
-  }
-\cs_generate_variant:Nn \tl_set_from_file_x:Nnn { c }
-\__kernel_patch_deprecation:nnNNpn { 2020-12-31 } { \file_get:nnN }
-\cs_new_protected:Npn \tl_gset_from_file_x:Nnn #1#2#3
-  {
-    \group_begin:
-      \file_get:nnN {#3} {#2} \l__tl_internal_a_tl
-      #2 \scan_stop:
-      \tl_gset:Nx #1 { \l__tl_internal_a_tl }
-    \group_end:
-  }
-\cs_generate_variant:Nn \tl_gset_from_file_x:Nnn { c }
 \cs_new:Npn \char_lower_case:N #1
   { \__char_change_case:nNN { lower } \char_value_lccode:n #1 }
 \cs_new:Npn \char_upper_case:N #1
@@ -27774,6 +27599,110 @@
     \exp_after:wN \__peek_true_remove:w
   }
 %% File: l3deprecation.dtx
+\bool_new:N \l__deprecation_grace_period_bool
+\cs_new:Npn \__deprecation_date_compare:nNnTF #1#2#3
+  { \__deprecation_date_compare_aux:w #1 -0-0- \q_mark #2 #3 -0-0- \q_stop }
+\cs_new:Npn \__deprecation_date_compare_aux:w
+  #1 - #2 - #3 - #4 \q_mark #5 #6 - #7 - #8 - #9 \q_stop
+  {
+    \int_compare:nNnTF {#1} = {#6}
+      {
+        \int_compare:nNnTF {#2} = {#7}
+          { \int_compare:nNnTF {#3} #5 {#8} }
+          { \int_compare:nNnTF {#2} #5 {#7} }
+      }
+      { \int_compare:nNnTF {#1} #5 {#6} }
+  }
+\cs_new_protected:Npn \__deprecation_not_yet_deprecated:nTF #1
+  {
+    \bool_set_false:N \l__deprecation_grace_period_bool
+    \exp_args:No \__deprecation_date_compare:nNnTF { \ExplLoaderFileDate } < {#1}
+      { \use_i:nn }
+      {
+        \exp_args:Nf \__deprecation_date_compare:nNnTF
+          {
+            \exp_after:wN \__deprecation_minus_six_months:w
+            \ExplLoaderFileDate -0-0- \q_stop
+          } < {#1}
+          {
+            \bool_set_true:N \l__deprecation_grace_period_bool
+            \bool_if:NTF \l at expl@undo at recent@deprecations at bool
+          }
+          { \use_ii:nn }
+      }
+  }
+\cs_new:Npn \__deprecation_minus_six_months:w #1 - #2 - #3 - #4 \q_stop
+  {
+    \int_compare:nNnTF {#2} > 6
+      { #1 - \int_eval:n { #2 - 6 } - #3 }
+      { \int_eval:n { #1 - 1 } - \int_eval:n { #2 + 6 } - #3 }
+  }
+\cs_new_protected:Npn \__kernel_patch_deprecation:nnNNpn #1#2#3#4#5#
+  { \__deprecation_patch_aux:nnNNnn {#1} {#2} #3 #4 {#5} }
+\cs_new_protected:Npn \__deprecation_patch_aux:nnNNnn #1#2#3#4#5#6
+  {
+    \__kernel_deprecation_code:nn
+      {
+        \tex_let:D #4 \scan_stop:
+        \__kernel_deprecation_error:Nnn #4 {#2} {#1}
+      }
+      { \tex_let:D #4 \scan_stop: }
+    \__deprecation_not_yet_deprecated:nTF {#1}
+      {
+        \bool_if:nTF
+          {
+            \cs_if_eq_p:NN #3 \cs_new_protected:Npn &&
+            \__kernel_if_debug:TF
+              { \c_true_bool } { \l at expl@undo at recent@deprecations at bool }
+          }
+          { \__deprecation_warn_once:nnNnn {#1} {#2} #4 {#5} {#6} }
+          { \__deprecation_patch_aux:Nn #3 { #4 #5 {#6} } }
+      }
+      { \__deprecation_just_error:nnNN {#1} {#2} #3 #4 }
+  }
+\cs_new_protected:Npn \__deprecation_warn_once:nnNnn #1#2#3#4#5
+  {
+    \cs_new_protected:Npx #3
+      {
+        \__kernel_if_debug:TF
+          {
+            \exp_not:N \__kernel_msg_warning:nnxxx
+              { kernel } { deprecated-command }
+              {#1}
+              { \token_to_str:N #3 }
+              { \tl_to_str:n {#2} }
+          }
+          { }
+        \exp_not:n { \cs_gset_protected:Npn #3 #4 {#5} }
+        \exp_not:N #3
+      }
+    \__kernel_deprecation_code:nn { }
+      { \cs_set_protected:Npn #3 #4 {#5} }
+  }
+\cs_new_protected:Npn \__deprecation_patch_aux:Nn #1#2
+  {
+    #1 #2
+    \cs_if_eq:NNTF #1 \cs_new_protected:Npn
+      { \__kernel_deprecation_code:nn { } { \cs_set_protected:Npn #2 } }
+      { \__kernel_deprecation_code:nn { } { \cs_set:Npn #2 } }
+  }
+\cs_new_protected:Npn \__deprecation_just_error:nnNN #1#2#3#4
+  {
+    \exp_args:NNx \__deprecation_patch_aux:Nn #3
+      {
+        \exp_not:N #4
+        {
+          \cs_if_eq:NNTF #3 \cs_new_protected:Npn
+            { \exp_not:N \__kernel_msg_error:nnnnnn }
+            { \exp_not:N \__kernel_msg_expandable_error:nnnnnn }
+            { kernel } { deprecated-command }
+            {#1}
+            { \token_to_str:N #4 }
+            { \tl_to_str:n {#2} }
+            { \bool_if:NT \l__deprecation_grace_period_bool { grace } }
+        }
+      }
+  }
 \cs_new_protected:Npn \__kernel_deprecation_error:Nnn #1#2#3
   {
     \tex_protected:D \tex_outer:D \tex_edef:D #1
@@ -27786,107 +27715,99 @@
           { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} }
       }
   }
-\__kernel_deprecation_error:Nnn \box_resize:cnn
-  { \box_resize_to_wd_and_ht_plus_dp:cnn } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \box_resize:Nnn
-  { \box_resize_to_wd_and_ht_plus_dp:Nnn } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \box_use_clear:c
-  { \box_use_drop:c } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \box_use_clear:N
-  { \box_use_drop:N } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \c_job_name_tl
+\__kernel_msg_new:nnn { kernel } { deprecated-command }
+  {
+    '#2'~deprecated~on~#1.
+    \tl_if_empty:nF {#3} { ~Use~'#3'. }
+    \str_if_eq:nnT {#4} { grace }
+      {
+        \c_space_tl
+        For~6~months~after~that~date~one~can~restore~a~deprecated~
+        command~by~loading~the~expl3~package~with~the~option~
+        'undo-recent-deprecations'.
+      }
+  }
+\cs_new_protected:Npn \__deprecation_old_protected:Nnn #1#2#3
+  {
+    \__kernel_patch_deprecation:nnNNpn {#3} {#2}
+    \cs_new_protected:Npn #1 { }
+  }
+\cs_new_protected:Npn \__deprecation_old:Nnn #1#2#3
+  {
+    \__kernel_patch_deprecation:nnNNpn {#3} {#2}
+    \cs_new:Npn #1 { }
+  }
+\__deprecation_old:Nnn \c_job_name_tl
   { \c_sys_jobname_str } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \c_minus_one
-  { -1 } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \dim_case:nnn
+\__deprecation_old:Nnn \dim_case:nnn
   { \dim_case:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \file_add_path:nN
-  { \file_get_full_name:nN } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \file_if_exist_input:nT
+\__deprecation_old_protected:Nnn \file_if_exist_input:nT
   { \file_if_exist:nT and~ \file_input:n } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \file_if_exist_input:nTF
+\__deprecation_old_protected:Nnn \file_if_exist_input:nTF
   { \file_if_exist:nT and~ \file_input:n } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \file_list:
-  { \file_log_list: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \file_path_include:n
-  { \seq_put_right:Nn \l_file_search_path_seq } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \file_path_remove:n
-  { \seq_remove_all:Nn \l_file_search_path_seq } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \g_file_current_name_tl
-  { \g_file_current_name_str } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \int_case:nnn
+\__deprecation_old:Nnn \int_case:nnn
   { \int_case:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \int_from_binary:n
+\__deprecation_old:Nnn \int_from_binary:n
   { \int_from_bin:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_from_hexadecimal:n
+\__deprecation_old:Nnn \int_from_hexadecimal:n
   { \int_from_hex:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_from_octal:n
+\__deprecation_old:Nnn \int_from_octal:n
   { \int_from_oct:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_to_binary:n
+\__deprecation_old:Nnn \int_to_binary:n
   { \int_to_bin:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_to_hexadecimal:n
+\__deprecation_old:Nnn \int_to_hexadecimal:n
   { \int_to_hex:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \int_to_octal:n
+\__deprecation_old:Nnn \int_to_octal:n
   { \int_to_oct:n } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \ior_get_str:NN
+\__deprecation_old_protected:Nnn \ior_get_str:NN
   { \ior_str_get:NN } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \ior_list_streams:
-  { \ior_show_list: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \ior_log_streams:
-  { \ior_log_list: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine_p:
+\__deprecation_old:Nnn \luatex_if_engine_p:
   { \sys_if_engine_luatex_p: } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine:F
+\__deprecation_old:Nnn \luatex_if_engine:F
   { \sys_if_engine_luatex:F } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine:T
+\__deprecation_old:Nnn \luatex_if_engine:T
   { \sys_if_engine_luatex:T } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \luatex_if_engine:TF
+\__deprecation_old:Nnn \luatex_if_engine:TF
   { \sys_if_engine_luatex:TF } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine_p:
+\__deprecation_old:Nnn \pdftex_if_engine_p:
   { \sys_if_engine_pdftex_p: } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine:F
+\__deprecation_old:Nnn \pdftex_if_engine:F
   { \sys_if_engine_pdftex:F } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine:T
+\__deprecation_old:Nnn \pdftex_if_engine:T
   { \sys_if_engine_pdftex:T } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \pdftex_if_engine:TF
+\__deprecation_old:Nnn \pdftex_if_engine:TF
   { \sys_if_engine_pdftex:TF } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \prop_get:cn
+\__deprecation_old:Nnn \prop_get:cn
   { \prop_item:cn } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \prop_get:Nn
+\__deprecation_old:Nnn \prop_get:Nn
   { \prop_item:Nn } { 2016-01-05 }
-\__kernel_deprecation_error:Nnn \quark_if_recursion_tail_break:N
+\__deprecation_old:Nnn \quark_if_recursion_tail_break:N
   { } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \quark_if_recursion_tail_break:n
+\__deprecation_old:Nnn \quark_if_recursion_tail_break:n
   { } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \scan_align_safe_stop:
+\__deprecation_old:Nnn \scan_align_safe_stop:
   { protected~commands } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \sort_ordered:
-  { \sort_return_same: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \sort_reversed:
-  { \sort_return_swapped: } { 2018-12-27 }
-\__kernel_deprecation_error:Nnn \str_case:nnn
+\__deprecation_old:Nnn \str_case:nnn
   { \str_case:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \str_case:onn
+\__deprecation_old:Nnn \str_case:onn
   { \str_case:onF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \str_case_x:nnn
+\__deprecation_old:Nnn \str_case_x:nnn
   { \str_case_e:nnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \tl_case:cnn
+\__deprecation_old:Nnn \tl_case:cnn
   { \tl_case:cnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \tl_case:Nnn
+\__deprecation_old:Nnn \tl_case:Nnn
   { \tl_case:NnF } { 2015-07-14 }
-\__kernel_deprecation_error:Nnn \tl_to_lowercase:n
+\__deprecation_old_protected:Nnn \tl_to_lowercase:n
   { \tex_lowercase:D } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \tl_to_uppercase:n
+\__deprecation_old_protected:Nnn \tl_to_uppercase:n
   { \tex_uppercase:D } { 2018-03-05 }
-\__kernel_deprecation_error:Nnn \token_new:Nn
-  { \cs_new_eq:NN } { 2018-12-29 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine_p:
+\__deprecation_old:Nnn \xetex_if_engine_p:
   { \sys_if_engine_xetex_p: } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine:F
+\__deprecation_old:Nnn \xetex_if_engine:F
   { \sys_if_engine_xetex:F } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine:T
+\__deprecation_old:Nnn \xetex_if_engine:T
   { \sys_if_engine_xetex:T } { 2017-01-01 }
-\__kernel_deprecation_error:Nnn \xetex_if_engine:TF
+\__deprecation_old:Nnn \xetex_if_engine:TF
   { \sys_if_engine_xetex:TF } { 2017-01-01 }
 \cs_new_protected:Npn \__deprecation_primitive:NN #1#2 { }
 \exp_last_unbraced:NNNNo
@@ -27913,7 +27834,7 @@
                 \__deprecation_primitive:w { \cs_to_str:N #2 }
               }
           }
-          { 2019-12-31 }
+          { 2020-01-01 }
       }
     \__kernel_primitives:
   }
@@ -27928,13 +27849,318 @@
       {
         \tex_let:D #2 #1
         \cs_if_exist:cT { tex_ \cs_to_str:N #1 :D }
+          { \cs_set_eq:Nc #2 { tex_ \cs_to_str:N #1 :D } }
+      }
+    \__kernel_primitives:
+  }
+\__kernel_patch_deprecation:nnNNpn
+  { 2019-01-01 } { \box_resize_to_wd_and_ht_plus_dp:Nnn }
+\cs_new_protected:Npn \box_resize:Nnn
+  { \box_resize_to_wd_and_ht_plus_dp:Nnn }
+\__kernel_patch_deprecation:nnNNpn
+  { 2019-01-01 } { \box_resize_to_wd_and_ht_plus_dp:cnn }
+\cs_new_protected:Npn \box_resize:cnn
+  { \box_resize_to_wd_and_ht_plus_dp:cnn }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \box_use_drop:N }
+\cs_new_protected:Npn \box_use_clear:N { \box_use_drop:N }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \box_use_drop:c }
+\cs_new_protected:Npn \box_use_clear:c { \box_use_drop:c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \box_set_eq_drop:N }
+\cs_new_protected:Npn \box_set_eq_clear:NN #1#2
+  { \tex_setbox:D #1 \tex_box:D #2 }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \box_gset_eq_drop:N }
+\cs_new_protected:Npn \box_gset_eq_clear:NN #1#2
+  { \tex_global:D \tex_setbox:D #1 \tex_box:D #2 }
+\cs_generate_variant:Nn \box_set_eq_clear:NN  { c , Nc , cc }
+\cs_generate_variant:Nn \box_gset_eq_clear:NN { c , Nc , cc }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \hbox_unpack_drop:N }
+\cs_new_protected:Npn \hbox_unpack_clear:N
+  { \hbox_unpack_drop:N }
+\cs_generate_variant:Nn \hbox_unpack_clear:N { c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \vbox_unpack_drop:N }
+\cs_new_protected:Npn \vbox_unpack_clear:N
+  { \vbox_unpack_drop:N }
+\cs_generate_variant:Nn \vbox_unpack_clear:N { c }
+\__kernel_deprecation_code:nn
+  {
+    \tex_let:D \g_file_current_name_tl \scan_stop:
+    \__kernel_deprecation_error:Nnn \g_file_current_name_tl
+      { \g_file_curr_name_str } { 2019-01-01 }
+  }
+  {
+    \tex_let:D \g_file_current_name_tl \scan_stop:
+    \cs_set_nopar:Npn \g_file_current_name_tl { \g_file_curr_name_str }
+  }
+\__deprecation_not_yet_deprecated:nTF { 2019-01-01 }
+  {
+    \tl_new:N \g_file_current_name_tl
+    \tl_gset:Nn \g_file_current_name_tl { \g_file_curr_name_str }
+  }
+  {
+    \cs_gset_nopar:Npn \g_file_current_name_tl
+      {
+        \__kernel_msg_expandable_error:nnnnn
+          { kernel } { deprecated-command }
+          { 2019-01-01 } { \g_file_current_name_tl } { \g_file_curr_name_str }
+      }
+  }
+\__kernel_patch_deprecation:nnNNpn
+  { 2019-01-01 } { \seq_put_right:Nn \l_file_search_path_seq }
+\cs_new_protected:Npn \file_path_include:n #1
+  {
+    \__kernel_file_name_sanitize:nN {#1} \l__file_full_name_str
+    \seq_if_in:NVF \l_file_search_path_seq \l__file_full_name_str
+      { \seq_put_right:NV \l_file_search_path_seq \l__file_full_name_str }
+  }
+\__kernel_patch_deprecation:nnNNpn
+  { 2019-01-01 } { \seq_remove_all:Nn \l_file_search_path_seq }
+\cs_new_protected:Npn \file_path_remove:n #1
+  {
+    \__kernel_file_name_sanitize:nN {#1} \l__file_full_name_str
+    \seq_remove_all:NV \l_file_search_path_seq \l__file_full_name_str
+  }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \file_get_full_name:nN }
+\cs_new_protected:Npn \file_add_path:nN #1#2
+  {
+    \file_get_full_name:nN {#1} #2
+    \str_if_empty:NT #2
+      { \tl_set:Nn #2 { \q_no_value } }
+  }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \file_log_list: }
+\cs_new_protected:Npn \file_list:          { \file_log_list: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \ior_show_list: }
+\cs_new_protected:Npn \ior_list_streams:   { \ior_show_list: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \ior_log_list: }
+\cs_new_protected:Npn \ior_log_streams:    { \ior_log_list: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \iow_show_list: }
+\cs_new_protected:Npn \iow_list_streams:   { \iow_show_list: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \iow_log_list: }
+\cs_new_protected:Npn \iow_log_streams:    { \iow_log_list: }
+\int_const:Nn \c__deprecation_minus_one { -1 }
+\__kernel_deprecation_code:nn
+  {
+    \tex_let:D \c_minus_one \scan_stop:
+    \__kernel_deprecation_error:Nnn \c_minus_one { -1 } { 2019-01-01 }
+  }
+  {
+    \tex_let:D \c_minus_one \scan_stop:
+    \cs_set_eq:NN \c_minus_one \c__deprecation_minus_one
+  }
+\__deprecation_not_yet_deprecated:nTF { 2019-01-01 }
+  { \cs_new_eq:NN \c_minus_one \c__deprecation_minus_one }
+  {
+    \cs_gset_nopar:Npn \c_minus_one
+      {
+        \__kernel_msg_expandable_error:nnnnn
+          { kernel } { deprecated-command }
+          { 2019-01-01 } { \c_minus_one } { -1 }
+        \c__deprecation_minus_one
+      }
+  }
+\cs_new_protected:Npn \__int_deprecated_constants:nn #1#2
+  {
+    #1 \c_zero                   {   0 } #2
+    #1 \c_one                    {   1 } #2
+    #1 \c_two                    {   2 } #2
+    #1 \c_three                  {   3 } #2
+    #1 \c_four                   {   4 } #2
+    #1 \c_five                   {   5 } #2
+    #1 \c_six                    {   6 } #2
+    #1 \c_seven                  {   7 } #2
+    #1 \c_eight                  {   8 } #2
+    #1 \c_nine                   {   9 } #2
+    #1 \c_ten                    {  10 } #2
+    #1 \c_eleven                 {  11 } #2
+    #1 \c_twelve                 {  12 } #2
+    #1 \c_thirteen               {  13 } #2
+    #1 \c_fourteen               {  14 } #2
+    #1 \c_fifteen                {  15 } #2
+    #1 \c_sixteen                {  16 } #2
+    #1 \c_thirty_two             {  32 } #2
+    #1 \c_one_hundred            { 100 } #2
+    #1 \c_two_hundred_fifty_five { 255 } #2
+    #1 \c_two_hundred_fifty_six  { 256 } #2
+    #1 \c_one_thousand         {  1000 } #2
+    #1 \c_ten_thousand         { 10000 } #2
+  }
+\__int_deprecated_constants:nn { \int_const:Nn } { }
+\__kernel_deprecation_code:nn
+  {
+    \__int_deprecated_constants:nn
+      { \exp_after:wN \__kernel_deprecation_error:Nnn \exp_not:N }
+      { { 2020-01-01 } }
+  }
+  {
+    \__int_deprecated_constants:nn
+      {
+        \exp_after:wN \use:nnn
+        \exp_after:wN \__int_constdef:Nw \exp_not:N
+      }
+      { \exp_stop_f: }
+  }
+\cs_new_eq:NN \__int_value:w \int_value:w
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_now:e }
+\cs_new:Npn \lua_now_x:n #1 { \__lua_now:n {#1} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_escape:e }
+\cs_new:Npn \lua_escape_x:n #1 { \__lua_escape:n {#1} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \lua_shipout_e:n }
+\cs_new_protected:Npn \lua_shipout_x:n #1 { \__lua_shipout:n {#1} }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \iow_log:n }
+\cs_new_protected:Npn \msg_log:n #1
+  {
+    \iow_log:n { ................................................. }
+    \iow_wrap:nnnN { . ~ #1} { . ~ } { } \iow_log:n
+    \iow_log:n { ................................................. }
+  }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \iow_term:n }
+\cs_new_protected:Npn \msg_term:n #1
+  {
+    \iow_term:n { ************************************************* }
+    \iow_wrap:nnnN { * ~ #1} { * ~ } { } \iow_term:n
+    \iow_term:n { ************************************************* }
+  }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { [Defined~error~message] }
+\cs_new_protected:Npn \msg_interrupt:nnn #1#2#3
+  {
+    \tl_if_empty:nTF {#3}
+      {
+        \__msg_old_interrupt_wrap:nn { \\ \c__msg_no_info_text_tl }
+          {#1 \\\\ #2 \\\\ \c__msg_continue_text_tl }
+      }
+      {
+        \__msg_old_interrupt_wrap:nn { \\ #3 }
+          {#1 \\\\ #2 \\\\ \c__msg_help_text_tl }
+      }
+  }
+\cs_new_protected:Npn \__msg_old_interrupt_wrap:nn #1#2
+  {
+    \iow_wrap:nnnN {#1} { | ~ } { } \__msg_old_interrupt_more_text:n
+    \iow_wrap:nnnN {#2} { ! ~ } { } \__msg_old_interrupt_text:n
+  }
+\cs_new_protected:Npn \__msg_old_interrupt_more_text:n #1
+  {
+    \exp_args:Nx \tex_errhelp:D
+      {
+        |'''''''''''''''''''''''''''''''''''''''''''''''
+        #1 \iow_newline:
+        |...............................................
+      }
+  }
+\group_begin:
+  \char_set_lccode:nn {`\{} {`\ }
+  \char_set_lccode:nn {`\}} {`\ }
+  \char_set_lccode:nn {`\&} {`\!}
+  \char_set_catcode_active:N \&
+\tex_lowercase:D
+  {
+    \group_end:
+    \cs_new_protected:Npn \__msg_old_interrupt_text:n #1
+      {
+        \iow_term:x
           {
-            \exp_args:NNc \cs_set_eq:NN #2
-              { tex_ \cs_to_str:N #1 :D }
+            \iow_newline:
+            !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+            \iow_newline:
+            !
           }
+        \__kernel_iow_with:Nnn \tex_newlinechar:D { `\^^J }
+          {
+            \__kernel_iow_with:Nnn \tex_errorcontextlines:D { -1 }
+              {
+                \group_begin:
+                  \cs_set_protected:Npn &
+                    {
+                      \tex_errmessage:D
+                        {
+                          #1
+                          \use_none:n
+                            { ............................................ }
+                        }
+                    }
+                  \exp_after:wN
+                \group_end:
+                &
+              }
+          }
       }
-    \__kernel_primitives:
   }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break_point:Nn }
+\cs_new:Npn \__prg_break_point:Nn { \prg_break_point:Nn }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break_point: }
+\cs_new:Npn \__prg_break_point: { \prg_break_point: }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_map_break:Nn }
+\cs_new:Npn \__prg_map_break:Nn #1 \__prg_break_point:Nn
+  { \prg_map_break:Nn #1 \prg_break_point:Nn }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break: }
+\cs_new:Npn \__prg_break: #1 \__prg_break_point: { }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \prg_break:n }
+\cs_new:Npn \__prg_break:n #1#2 \__prg_break_point: {#1}
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \sort_return_same: }
+\cs_new_protected:Npn \sort_ordered: { \sort_return_same: }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \sort_return_swapped: }
+\cs_new_protected:Npn \sort_reversed: { \sort_return_swapped: }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nn }
+\cs_new:Npn \str_case_x:nn { \str_case_e:nn }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nnT }
+\cs_new:Npn \str_case_x:nnT { \str_case_e:nnT }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nnF }
+\cs_new:Npn \str_case_x:nnF { \str_case_e:nnF }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_case_e:nnTF }
+\cs_new:Npn \str_case_x:nnTF { \str_case_e:nnTF }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq_p:ee }
+\cs_new:Npn \str_if_eq_x_p:nn { \str_if_eq_p:ee }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq:eeT }
+\cs_new:Npn \str_if_eq_x:nnT { \str_if_eq:eeT }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq:eeF }
+\cs_new:Npn \str_if_eq_x:nnF { \str_if_eq:eeF }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \str_if_eq:eeTF }
+\cs_new:Npn \str_if_eq_x:nnTF { \str_if_eq:eeTF }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_set_from_file:Nnn #1#2#3
+  { \file_get:nnN {#3} {#2} #1 }
+\cs_generate_variant:Nn \tl_set_from_file:Nnn { c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_gset_from_file:Nnn #1#2#3
+  {
+    \group_begin:
+      \file_get:nnN {#3} {#2} \l__tl_internal_a_tl
+      \tl_gset_eq:NN #1 \l__tl_internal_a_tl
+    \group_end:
+  }
+\cs_generate_variant:Nn \tl_gset_from_file:Nnn { c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_set_from_file_x:Nnn #1#2#3
+  {
+    \group_begin:
+      \file_get:nnN {#3} {#2} \l__tl_internal_a_tl
+      #2 \scan_stop:
+      \tl_set:Nx \l__tl_internal_a_tl { \l__tl_internal_a_tl }
+    \exp_args:NNNo \group_end:
+    \tl_set:Nn #1 \l__tl_internal_a_tl
+  }
+\cs_generate_variant:Nn \tl_set_from_file_x:Nnn { c }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \file_get:nnN }
+\cs_new_protected:Npn \tl_gset_from_file_x:Nnn #1#2#3
+  {
+    \group_begin:
+      \file_get:nnN {#3} {#2} \l__tl_internal_a_tl
+      #2 \scan_stop:
+      \tl_gset:Nx #1 { \l__tl_internal_a_tl }
+    \group_end:
+  }
+\cs_generate_variant:Nn \tl_gset_from_file_x:Nnn { c }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \tl_analysis_show:N }
+\cs_new_protected:Npn \tl_show_analysis:N { \tl_analysis_show:N }
+\__kernel_patch_deprecation:nnNNpn { 2020-01-01 } { \tl_analysis_show:n }
+\cs_new_protected:Npn \tl_show_analysis:n { \tl_analysis_show:n }
+\__kernel_patch_deprecation:nnNNpn { 2019-01-01 } { \cs_new_eq:NN }
+\cs_new_protected:Npn \token_new:Nn #1#2 { \cs_new_eq:NN #1 #2 }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \cs_prefix_spec:N }
+\cs_new:Npn \token_get_prefix_spec:N { \cs_prefix_spec:N }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \cs_argument_spec:N }
+\cs_new:Npn \token_get_arg_spec:N { \cs_argument_spec:N }
+\__kernel_patch_deprecation:nnNNpn { 2021-01-01 } { \cs_replacement_spec:N }
+\cs_new:Npn \token_get_replacement_spec:N { \cs_replacement_spec:N }
 %% 
 %%
 %% End of file `expl3-code.tex'.

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex	2019-03-05 22:35:14 UTC (rev 50246)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2019-02-15}%
+\def\ExplFileDate{2019-03-05}%
 \let\ExplLoaderFileDate\ExplFileDate
 \begingroup
   \def\tempa{LaTeX2e}%
@@ -57,6 +57,7 @@
       \noexpand\undefined
   }%
 \catcode64=11 %
+\chardef \l at expl@undo at recent@deprecations at bool = 0 %
 \chardef \l at expl@check at declarations@bool = 0 %
 \chardef \l at expl@log at functions@bool = 0 %
 \chardef \l at expl@enable at debug@bool = 0 %

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2019-02-15}%
+\def\ExplFileDate{2019-03-05}%
 \let\ExplLoaderFileDate\ExplFileDate
 \ProvidesPackage{expl3}
   [%
@@ -34,6 +34,8 @@
     \newcommand*#2{}%
     \chardef #2=0 %
   }%
+\expl at create@bool at option
+  {undo-recent-deprecations}\l at expl@undo at recent@deprecations at bool
 \expl at create@bool at option{check-declarations}\l at expl@check at declarations@bool
 \expl at create@bool at option{log-functions}\l at expl@log at functions@bool
 \expl at create@bool at option{enable-debug}\l at expl@enable at debug@bool
@@ -78,11 +80,6 @@
 \expandafter\ifx\csname tex\string _let:D\endcsname\relax
   \expandafter\endinput
 \fi
-\AtBeginDocument
-  {
-    \cs_if_exist:NF \color
-      { \DeclareRobustCommand \color [2] [ ] { } }
-  }
 \__kernel_msg_new:nnnn { expl } { wrong-driver }
   { Driver~request~inconsistent~with~engine:~using~'#2'~driver. }
   {
@@ -212,6 +209,7 @@
   }
 \keys_define:nn { expl }
   {
+    undo-recent-deprecations .bool_set:N = \l at expl@undo at recent@deprecations at bool,
     check-declarations .bool_set:N = \l at expl@check at declarations@bool,
     log-functions      .bool_set:N = \l at expl@log at functions@bool
   }

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls	2019-03-05 22:35:14 UTC (rev 50246)
@@ -58,6 +58,7 @@
 \bool_new:N \g__codedoc_checktest_bool
 \bool_new:N \g__codedoc_kernel_bool
 \bool_new:N \g__codedoc_cs_break_bool
+\bool_new:N \g__codedoc_show_notes_bool
 \bool_gset_true:N \g__codedoc_cs_break_bool
 \tl_new:N \l__codedoc_tmpa_tl
 \tl_new:N \l__codedoc_tmpb_tl
@@ -424,6 +425,10 @@
   { \bool_gset_false:N \g__codedoc_cs_break_bool }
 \DeclareOption { cs-break-nohyphen }
   { \PassOptionsToPackage{nohyphen}{underscore} }
+\DeclareOption { show-notes }
+  { \bool_gset_true:N  \g__codedoc_show_notes_bool }
+\DeclareOption { hide-notes }
+  { \bool_gset_false:N \g__codedoc_show_notes_bool }
 \DeclareOption* { \PassOptionsToClass { \CurrentOption } { article } }
 \ExecuteOptions { full, kernel, nocheck, nochecktest, lm-default }
 \PassOptionsToClass { a4paper } { article }
@@ -650,6 +655,7 @@
 \NewDocumentCommand { \CodedocExplainEXP } { }
   {
     \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{expstar}{}}%
+    \write \@auxout { \def \string \Codedoc at expstar { } }
     \__codedoc_typeset_exp:\ indicates~fully~expandable~functions,~which~
     can~be~used~within~an~\texttt{x}-type~argument~(in~plain~
     \TeX{}~terms,~inside~an~\cs{edef}),~as~well~as~within~an~
@@ -658,6 +664,7 @@
 \NewDocumentCommand { \CodedocExplainREXP } { }
   {
     \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{rexpstar}{}}%
+    \write \@auxout { \def \string \Codedoc at rexpstar { } }
     \__codedoc_typeset_rexp:\ indicates~
     restricted~expandable~functions,~which~can~be~used~within~an~
     \texttt{x}-type~argument~but~cannot~be~fully~expanded~within~an~
@@ -666,6 +673,7 @@
 \NewDocumentCommand { \CodedocExplainTF } { }
   {
     \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{explTF}{}}%
+    \write \@auxout { \def \string \Codedoc at explTF { } }
     \__codedoc_typeset_TF:\ indicates~conditional~(\texttt{if})~functions~
     whose~variants~with~\texttt{T},~\texttt{F}~and~\texttt{TF}~
     argument~specifiers~expect~different~
@@ -765,18 +773,30 @@
     \ensuremath \rangle
   }
 \cs_new_protected:Npn \__codedoc_typeset_exp:
-  { \hyperlink{expstar} {$\star$} }
+  {
+    \cs_if_exist:NTF \Codedoc at expstar
+      { \hyperlink { expstar } }
+      { \mbox }
+    {$\star$}
+  }
 \cs_new_protected:Npn \__codedoc_typeset_rexp:
-  { \hyperlink{rexpstar} {\ding{73}} } % hollow star
+  {
+    \cs_if_exist:NTF \Codedoc at rexpstar
+      { \hyperlink { rexpstar } }
+      { \mbox }
+    { \ding { 73 } } % hollow star
+  }
 \cs_new_protected:Npn \__codedoc_typeset_TF:
   {
-    \hyperlink{explTF}
+    \cs_if_exist:NTF \Codedoc at explTF
+      { \hyperlink { explTF } }
+      { \mbox }
       {
         \color{black}
         \itshape TF
         \makebox[0pt][r]
           {
-            \color{red}
+            \cs_if_exist:NT \Codedoc at explTF { \color{red} }
             \underline { \phantom{\itshape TF} \kern-0.1em }
           }
       }
@@ -997,7 +1017,7 @@
   {
     \__codedoc_date_set:Nn #1 {#2}
     \exp_args:No \__codedoc_date_compare:nNnT
-      {#1} > { \tex_year:D - \tex_month:D - \tex_day:D }
+      {#1} > { \c_sys_year_int - \c_sys_month_int - \c_sys_day_int }
       {
         \msg_error:nnxx { l3doc } { future-date }
           { \tl_to_str:N \l__codedoc_macro_argument_tl }
@@ -1008,7 +1028,7 @@
   {
     \__codedoc_date_set:Nn \l__codedoc_tmpa_tl {#1}
     \exp_args:No \__codedoc_date_compare:nNnT
-      { \l__codedoc_tmpa_tl } < { \tex_year:D - \tex_month:D - \tex_day:D }
+      { \l__codedoc_tmpa_tl } < { \c_sys_year_int - \c_sys_month_int - \c_sys_day_int }
       {
         \msg_error:nnxx { l3doc } { deprecated-function }
           { \tl_to_str:N \l__codedoc_macro_argument_tl }
@@ -1042,6 +1062,7 @@
 \cs_new_protected:Npn \__codedoc_function_typeset_stop:
   {
     \par
+    \dim_set:Nn \prevdepth { \box_dp:N \l__codedoc_descr_coffin }
     \allowbreak
   }
 \cs_new_protected:Npn \__codedoc_function_init:
@@ -1670,6 +1691,31 @@
   }{
       \par\end{trivlist}
   }
+\bool_if:NTF \g__codedoc_show_notes_bool
+  {
+    \NewDocumentCommand\NB{mm}
+      {
+        (\emph{Note}\footnote{\ttfamily [#1]:~\detokenize{#2}})
+      }
+  }
+  {
+    \NewDocumentCommand\NB{mm}{}
+  }
+\bool_if:NTF \g__codedoc_show_notes_bool
+  {
+    \NewDocumentEnvironment{NOTE}{m}
+      {
+        \par\noindent (\emph{Note}~[\texttt{#1}]:\par
+        \verbatim
+      }
+      {
+        \endverbatim
+        \par\noindent \emph{Note~end})\par
+      }
+  }
+  {
+    \NewDocumentEnvironment{NOTE}{m}{\comment}{\endcomment}
+  }
 \newenvironment{TemplateInterfaceDescription}[1]
   {
     \subsection{The~object~type~`#1'}
@@ -1891,7 +1937,7 @@
       \__codedoc_replace_at_at:N \l__codedoc_tmpa_tl
 
       \tl_gset:Nn \g__codedoc_module_name_tl {#2}
-      \tl_put_right:Nn \l__codedoc_tmpa_tl { < @ @ = #2 > }
+      \tl_put_right:Nn \l__codedoc_tmpa_tl { < \text { \verbatim at font @ @ = #2 } > }
 
       \tl_set:Nn \l__codedoc_tmpb_tl {#3}
       \__codedoc_detect_internals:N \l__codedoc_tmpb_tl

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvipdfmx.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvipdfmx.def	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvipdfmx.def	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3drivers.dtx
 \ProvidesExplFile
-  {l3dvipdfmx.def}{2019-02-15}{}
+  {l3dvipdfmx.def}{2019-03-05}{}
   {L3 Experimental driver: dvipdfmx}
 \cs_new_eq:NN \__driver_literal:e \tex_special:D
 \cs_new_protected:Npn \__driver_literal:n #1

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvips.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvips.def	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvips.def	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3drivers.dtx
 \ProvidesExplFile
-  {l3dvips.def}{2019-02-15}{}
+  {l3dvips.def}{2019-03-05}{}
   {L3 Experimental driver: dvips}
 \cs_new_eq:NN \__driver_literal:e \tex_special:D
 \cs_new_protected:Npn \__driver_literal:n #1

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvisvgm.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvisvgm.def	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3dvisvgm.def	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3drivers.dtx
 \ProvidesExplFile
-  {l3dvisvgm.def}{2019-02-15}{}
+  {l3dvisvgm.def}{2019-03-05}{}
   {L3 Experimental driver: dvisvgm}
 \cs_new_eq:NN \__driver_literal:e \tex_special:D
 \cs_new_protected:Npn \__driver_literal:n #1

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3pdfmode.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3pdfmode.def	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3pdfmode.def	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3drivers.dtx
 \ProvidesExplFile
-  {l3pdfmode.def}{2019-02-15}{}
+  {l3pdfmode.def}{2019-03-05}{}
   {L3 Experimental driver: PDF mode}
 \cs_new_eq:NN \__driver_literal:e \tex_special:D
 \cs_new_protected:Npn \__driver_literal:n #1

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3xdvipdfmx.def	2019-03-05 22:35:14 UTC (rev 50246)
@@ -20,7 +20,7 @@
 %% 
 %% File: l3drivers.dtx
 \ProvidesExplFile
-  {l3xdvipdfmx.def}{2019-02-15}{}
+  {l3xdvipdfmx.def}{2019-03-05}{}
   {L3 Experimental driver: xdvipdfmx}
 \cs_new_eq:NN \__driver_literal:e \tex_special:D
 \cs_new_protected:Npn \__driver_literal:n #1

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -6,7 +6,7 @@
 %%
 %% l3keys2e.dtx  (with options: `package')
 %% 
-%% Copyright (C) 2009-2017 The LaTeX3 Project
+%% Copyright (C) 2009-2019 The LaTeX3 Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -18,7 +18,7 @@
 %% This file is part of the "l3packages bundle" (The Work in LPPL)
 %% and all files in that bundle must be distributed together.
 %% 
-%% File: l3keys2e.dtx (C) Copyright 2009,2011-2018 The LaTeX3 Project
+%% File: l3keys2e.dtx
 \RequirePackage{expl3}[2018/02/21]
 \@ifpackagelater{expl3}{2018/02/21}
   {}
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{l3keys2e}{2018-10-17}{}
+\ProvidesExplPackage{l3keys2e}{2019-03-05}{}
   {LaTeX2e option processing using LaTeX3 keys}
 \cs_generate_variant:Nn \clist_put_right:Nn { Nv }
 \cs_generate_variant:Nn \keys_if_exist:nnT  { nx }

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -6,7 +6,7 @@
 %%
 %% xfp.dtx  (with options: `package')
 %% 
-%% Copyright (C) 2017 The LaTeX3 Project
+%% Copyright (C) 2017-2019 The LaTeX3 Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -18,7 +18,7 @@
 %% This file is part of the "l3packages bundle" (The Work in LPPL)
 %% and all files in that bundle must be distributed together.
 %% 
-%% File: xfp.dtx (C) Copyright 2017-2018 The LaTeX3 Project
+%% File: xfp.dtx
 \RequirePackage{expl3}[2018/02/21]
 \@ifpackagelater{expl3}{2018/02/21}
   {}
@@ -33,7 +33,7 @@
     \endinput
   }
 \RequirePackage{xparse}
-\ProvidesExplPackage{xfp}{2018-10-17}{}
+\ProvidesExplPackage{xfp}{2019-03-05}{}
   {L3 Floating point unit}
 \NewExpandableDocumentCommand \fpeval { m } { \fp_eval:n {#1} }
 \NewExpandableDocumentCommand \inteval { m } { \int_eval:n {#1} }

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -6,7 +6,7 @@
 %%
 %% xfrac.dtx  (with options: `package')
 %% 
-%% Copyright (C) 2011-2017 The LaTeX3 Project
+%% Copyright (C) 2011-2019 The LaTeX3 Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -18,8 +18,7 @@
 %% This file is part of the "l3packages bundle" (The Work in LPPL)
 %% and all files in that bundle must be distributed together.
 %% 
-%% File: xfrac.dtx Copyright (C) 2004, 2008-2010 Morten Hoegholm
-%%                           (C) 2011,2012,2014-2018 The LaTeX3 Project
+%% File: xfrac.dtx
 \RequirePackage{expl3}[2018/02/21]
 \@ifpackagelater{expl3}{2018/02/21}
   {}
@@ -34,7 +33,7 @@
     \endinput
   }
 \RequirePackage{amstext,graphicx,l3keys2e,textcomp,xparse,xtemplate}
-\ProvidesExplPackage{xfrac}{2018-10-17}{}
+\ProvidesExplPackage{xfrac}{2019-03-05}{}
   {L3 Experimental split-level fractions}
 \keys_define:nn { xfrac }
   {

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -6,7 +6,7 @@
 %%
 %% xparse.dtx  (with options: `package')
 %% 
-%% Copyright (C) 2009-2017 The LaTeX3 Project
+%% Copyright (C) 2009-2019 The LaTeX3 Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -18,11 +18,7 @@
 %% This file is part of the "l3packages bundle" (The Work in LPPL)
 %% and all files in that bundle must be distributed together.
 %% 
-%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley,
-%%                      David Carlisle
-%%                  (C) Copyright 2004-2008 Frank Mittelbach,
-%%                      The LaTeX3 Project
-%%                  (C) Copyright 2009-2018 The LaTeX3 Project
+%% File: xparse.dtx
 \RequirePackage{expl3}[2018-04-12]
 \@ifpackagelater{expl3}{2018-04-12}
   {}
@@ -36,7 +32,7 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{xparse}{2018-10-17}{}
+\ProvidesExplPackage{xparse}{2019-03-05}{}
   {L3 Experimental document command parser}
 \tl_new:N \l__xparse_arg_spec_tl
 \tl_new:N \l__xparse_args_tl
@@ -46,6 +42,7 @@
 \bool_new:N \l__xparse_defaults_bool
 \tl_new:N \l__xparse_defaults_tl
 \bool_new:N \l__xparse_environment_bool
+\str_new:N \l__xparse_environment_str
 \bool_new:N \l__xparse_expandable_bool
 \tl_new:N \l__xparse_expandable_aux_name_tl
 \tl_set:Nn \l__xparse_expandable_aux_name_tl
@@ -62,11 +59,11 @@
 \tl_new:N \l__xparse_last_delimiters_tl
 \bool_new:N \l__xparse_long_bool
 \int_new:N \l__xparse_m_args_int
-\int_new:N \l__xparse_mandatory_args_int
 \bool_new:N \l__xparse_prefixed_bool
 \tl_new:N \l__xparse_process_all_tl
 \tl_new:N \l__xparse_process_one_tl
 \bool_new:N \l__xparse_process_some_bool
+\tl_new:N \l__xparse_saved_args_tl
 \tl_new:N \l__xparse_signature_tl
 \bool_new:N \l__xparse_some_obey_spaces_bool
 \bool_new:N \l__xparse_some_long_bool
@@ -85,7 +82,7 @@
     \bool_set_true:N \l__xparse_expandable_bool
     \__xparse_declare_cmd_aux:Nnn
   }
-\cs_new_protected:Npn \__xparse_declare_cmd_aux:Nnn #1#2
+\cs_new_protected:Npn \__xparse_declare_cmd_aux:Nnn #1#2#3
   {
     \cs_if_exist:NTF #1
       {
@@ -104,17 +101,20 @@
           { \token_to_str:N #1 } { \tl_to_str:n {#2} }
       }
     \bool_set_false:N \l__xparse_environment_bool
-    \__xparse_declare_cmd_internal:Nnn #1 {#2}
+    \__xparse_declare_cmd_internal:Nnnn #1 {#2} {#3} { }
   }
-\cs_new_protected:Npn \__xparse_declare_cmd_internal:Nnn #1#2#3
+\cs_new_protected:Npn \__xparse_declare_cmd_internal:Nnnn #1#2#3#4
   {
     \tl_set:Nx \l__xparse_function_tl { \cs_to_str:N #1 }
+    \tl_set:Nx \l__xparse_fn_tl
+      { \exp_not:c { \l__xparse_function_tl \c_space_tl } }
     \__xparse_normalize_arg_spec:n {#2}
     \exp_args:No \__xparse_prepare_signature:n \l__xparse_arg_spec_tl
     \__xparse_declare_cmd_code:Nnn #1 {#2} {#3}
+    #4
     \__xparse_break_point:n {#2}
   }
-\cs_generate_variant:Nn \__xparse_declare_cmd_internal:Nnn { cnx }
+\cs_generate_variant:Nn \__xparse_declare_cmd_internal:Nnnn { cnx }
 \cs_new_eq:NN \__xparse_break_point:n \use_none:n
 \cs_new_protected:Npn \__xparse_declare_cmd_code:Nnn
   {
@@ -129,10 +129,16 @@
       \cs_set_protected:Npn \l__xparse_current_arg_int {#3}
     \cs_set_protected_nopar:Npx #1
       {
-        \__xparse_start:nNNnnn
-          { \exp_not:n {#2} }
-          \exp_not:c { \l__xparse_function_tl \c_space_tl }
-          \exp_not:c { \l__xparse_function_tl \c_space_tl code }
+        \bool_if:NTF \l__xparse_environment_bool
+          {
+            \__xparse_start_env:nnnnn { \exp_not:n {#2} }
+              { \l__xparse_environment_str }
+          }
+          {
+            \__xparse_start:nNNnnn { \exp_not:n {#2} }
+              \exp_not:c { \l__xparse_function_tl \c_space_tl }
+              \exp_not:c { \l__xparse_function_tl \c_space_tl code }
+          }
           { \exp_not:o \l__xparse_signature_tl }
           {
             \bool_if:NT \l__xparse_defaults_bool
@@ -192,22 +198,26 @@
   }
 \cs_new_protected:Npn \__xparse_declare_env:nnnn #1#2
   {
-    \cs_if_exist:cTF {#1}
+    \str_set:Nx \l__xparse_environment_str {#1}
+    \str_set:Nx \l__xparse_environment_str
+      { \tl_trim_spaces:o { \l__xparse_environment_str } }
+    \cs_if_exist:cTF { \l__xparse_environment_str }
       {
         \__kernel_msg_info:nnxx { xparse } { redefine-environment }
-          {#1} { \tl_to_str:n {#2} }
+          { \l__xparse_environment_str } { \tl_to_str:n {#2} }
       }
       {
         \__kernel_msg_info:nnxx { xparse } { define-environment }
-          {#1} { \tl_to_str:n {#2} }
+          { \l__xparse_environment_str } { \tl_to_str:n {#2} }
       }
     \bool_set_false:N \l__xparse_expandable_bool
     \bool_set_true:N \l__xparse_environment_bool
-    \__xparse_declare_env_internal:nnnn {#1} {#2}
+    \exp_args:NV \__xparse_declare_env_internal:nnnn
+      \l__xparse_environment_str {#2}
   }
 \cs_new_protected:Npn \__xparse_declare_env_internal:nnnn #1#2#3#4
   {
-    \__xparse_declare_cmd_internal:cnx { environment~ #1 } {#2}
+    \__xparse_declare_cmd_internal:cnxn { environment~ #1 } {#2}
       {
         \cs_set_nopar:Npx \exp_not:c { environment~ #1 ~end~aux }
           {
@@ -216,28 +226,42 @@
           }
         \exp_not:n {#3}
       }
-    \cs_set_nopar:cpx { environment~ #1 ~end }
-      { \exp_not:c { environment~ #1 ~end~aux } }
-    \cs_generate_from_arg_count:cNnn
-      { environment~ #1 ~end~aux~ } \cs_set:Npn
-      \l__xparse_current_arg_int {#4}
-    \cs_set_eq:cc {#1}       { environment~ #1 }
-    \cs_set_eq:cc { end #1 } { environment~ #1 ~end }
+      {
+        \cs_set_nopar:cpx { environment~ #1 ~end }
+          { \exp_not:c { environment~ #1 ~end~aux } }
+        \cs_generate_from_arg_count:cNnn
+          { environment~ #1 ~end~aux~ } \cs_set:Npn
+          \l__xparse_current_arg_int {#4}
+        \cs_set_eq:cc {#1}       { environment~ #1 }
+        \cs_set_eq:cc { end #1 } { environment~ #1 ~end }
+      }
   }
-\cs_new_protected:Npx \__xparse_start:nNNnnn
+\cs_new_protected:Npn \__xparse_start_env:nnnnn #1#2
   {
+    \str_set:Nn \l__xparse_environment_str {#2}
+    \bool_set_true:N \l__xparse_environment_bool
+    \__xparse_start_aux:ccnnnn
+      { environment~ \l__xparse_environment_str \c_space_tl }
+      { environment~ \l__xparse_environment_str \c_space_tl code }
+      {#1}
+  }
+\cs_new_protected:Npx \__xparse_start:nNNnnn #1#2#3
+  {
     \exp_not:c { xparse~function~is~not~expandable }
-    \exp_not:N \__xparse_start_aux:nNNnnn
+    \exp_not:n { \bool_set_false:N \l__xparse_environment_bool }
+    \exp_not:N \__xparse_start_aux:NNnnnn
+    #2 #3 {#1}
   }
-\cs_new_protected:Npn \__xparse_start_aux:nNNnnn #1#2#3#4#5#6
+\cs_new_protected:Npn \__xparse_start_aux:NNnnnn #1#2#3#4#5#6
   {
     \tl_clear:N \l__xparse_args_tl
-    \tl_set:Nn \l__xparse_fn_tl {#2}
-    \tl_set:Nn \l__xparse_fn_code_tl {#3}
+    \tl_set:Nn \l__xparse_fn_tl {#1}
+    \tl_set:Nn \l__xparse_fn_code_tl {#2}
     \tl_set:Nn \l__xparse_defaults_tl {#5}
     \tl_set:Nn \l__xparse_process_all_tl {#6}
     #4 \__xparse_run_code:
   }
+\cs_generate_variant:Nn \__xparse_start_aux:NNnnnn { cc }
 \cs_new_protected:Npn \__xparse_run_code:
   {
     \tl_if_empty:NF \l__xparse_defaults_tl { \__xparse_defaults: }
@@ -266,7 +290,7 @@
 \cs_new_protected:Npn \__xparse_defaults_error:w \q_recursion_stop
   {
     \__kernel_msg_error:nnx { xparse } { loop-in-defaults }
-      { \exp_after:wN \token_to_str:N \l__xparse_fn_tl }
+      { \__xparse_environment_or_command: }
   }
 \cs_new_protected:Npn \__xparse_defaults_def:
   {
@@ -329,8 +353,9 @@
     \__xparse_end_expandable_defaults:nnnNNn {#1} { } {#1} #2#3
       { } { } { } { } { } { } { } { } { } { }
       {
-        \__kernel_msg_expandable_error:nnn
-          { xparse } { loop-in-defaults } {#4}
+        \__kernel_msg_expandable_error:nnf
+          { xparse } { loop-in-defaults }
+          { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N #4 } }
         \use_iv:nnnn
       }
     \q_stop
@@ -358,7 +383,6 @@
   { #2 \__xparse_end_expandable_defaults:nnnNNn { #3 {#1} } }
 \cs_new_protected:Npn \__xparse_normalize_arg_spec:n #1
   {
-    \int_zero:N \l__xparse_mandatory_args_int
     \int_zero:N \l__xparse_current_arg_int
     \tl_clear:N \l__xparse_last_delimiters_tl
     \tl_clear:N \l__xparse_arg_spec_tl
@@ -373,7 +397,7 @@
     \int_compare:nNnT \l__xparse_current_arg_int > 9
       {
         \__kernel_msg_error:nnxx { xparse } { too-many-arguments }
-          { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+          { \__xparse_environment_or_command: } { \tl_to_str:n {#1} }
         \__xparse_bad_def:wn
       }
     \bool_if:NT \l__xparse_expandable_bool
@@ -397,7 +421,7 @@
     \cs_if_exist_use:cF { __xparse_normalize_type_ \tl_to_str:n {#1} :w }
       {
         \__kernel_msg_error:nnxx { xparse } { unknown-argument-type }
-          { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+          { \__xparse_environment_or_command: } { \tl_to_str:n {#1} }
         \__xparse_bad_def:wn
       }
   }
@@ -448,7 +472,7 @@
     \bool_if:NT \l__xparse_long_bool
       {
         \__kernel_msg_error:nnxx { xparse } { two-markers }
-          { \iow_char:N \\ \l__xparse_function_tl } { + }
+          { \__xparse_environment_or_command: } { + }
         \__xparse_bad_def:wn
       }
     \bool_set_true:N \l__xparse_long_bool
@@ -461,7 +485,7 @@
     \bool_if:NT \l__xparse_obey_spaces_bool
       {
         \__kernel_msg_error:nnxx { xparse } { two-markers }
-          { \iow_char:N \\ \l__xparse_function_tl } { ! }
+          { \__xparse_environment_or_command: } { ! }
         \__xparse_bad_def:wn
       }
     \bool_set_true:N \l__xparse_obey_spaces_bool
@@ -559,6 +583,23 @@
     \__xparse_add_arg_spec_mandatory:n { v }
     \__xparse_normalize_arg_spec_loop:n
   }
+\cs_new_protected:Npn \__xparse_normalize_type_b:w #1
+  {
+    \bool_if:NF \l__xparse_environment_bool
+      {
+        \__kernel_msg_error:nnxx
+          { xparse } { invalid-command-arg }
+          { \__xparse_environment_or_command: } { b }
+        \__xparse_bad_def:wn
+      }
+    \tl_clear:N \l__xparse_last_delimiters_tl
+    \__xparse_add_arg_spec:n { b }
+    \quark_if_recursion_tail_stop:n {#1}
+    \__kernel_msg_error:nnxx { xparse } { arg-after-body }
+      { \__xparse_environment_or_command: }
+      { \tl_to_str:n {#1} }
+    \__xparse_bad_def:wn
+  }
 \cs_new_protected:Npn \__xparse_single_char_check:n #1
   {
     \tl_trim_spaces_apply:nN {#1} \tl_if_single_token:nTF
@@ -569,13 +610,13 @@
           { \exp_args:No \tl_to_str:n { \use:nn #1 { } } }
           {
             \__kernel_msg_warning:nnxx { xparse } { not-single-char }
-              { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+              { \__xparse_environment_or_command: } { \tl_to_str:n {#1} }
           }
         \group_end:
       }
       {
         \__kernel_msg_error:nnxx { xparse } { not-single-char }
-          { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+          { \__xparse_environment_or_command: } { \tl_to_str:n {#1} }
         \__xparse_bad_def:wn
       }
   }
@@ -617,7 +658,7 @@
 \cs_new_protected:Npn \__xparse_bad_arg_spec:wn #1 \__xparse_break_point:n #2
   {
     \__kernel_msg_error:nnxx { xparse } { bad-arg-spec }
-      { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#2} }
+      { \__xparse_environment_or_command: } { \tl_to_str:n {#2} }
   }
 \cs_new_protected:Npn \__xparse_bad_def:wn #1 \__xparse_break_point:n #2 { }
 \cs_new_protected:Npn \__xparse_add_arg_spec:n #1
@@ -651,10 +692,9 @@
     \bool_if:NT \l__xparse_some_obey_spaces_bool
       {
         \__kernel_msg_error:nnxx { xparse } { non-trailing-obey-spaces }
-          { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+          { \__xparse_environment_or_command: } { \tl_to_str:n {#1} }
         \__xparse_bad_def:wn
       }
-    \int_incr:N \l__xparse_mandatory_args_int
     \tl_clear:N \l__xparse_last_delimiters_tl
     \__xparse_add_arg_spec:n {#1}
   }
@@ -710,11 +750,18 @@
     \tl_put_left:Nn \l__xparse_process_one_tl { {#1} }
     \__xparse_prepare_signature_bypass:N
   }
+\cs_new_protected:Npn \__xparse_add_type_b:w
+  {
+    \__xparse_flush_m_args:
+    \__xparse_add_default:
+    \__xparse_add_grabber:N b
+    \__xparse_prepare_signature:N
+  }
 \cs_new_protected:Npn \__xparse_add_type_D:w #1#2#3
   {
     \__xparse_flush_m_args:
     \__xparse_add_default:n {#3}
-    \__xparse_add_grabber_optional:N D
+    \__xparse_add_grabber:N D
     \tl_put_right:Nn \l__xparse_signature_tl { #1 #2 }
     \__xparse_prepare_signature:N
   }
@@ -722,7 +769,7 @@
   {
     \__xparse_flush_m_args:
     \__xparse_add_default_E:nn {#1} {#2}
-    \__xparse_add_grabber_optional:N E
+    \__xparse_add_grabber:N E
     \tl_put_right:Nn \l__xparse_signature_tl { {#1} }
     \__xparse_prepare_signature:N
   }
@@ -730,7 +777,7 @@
   {
     \__xparse_flush_m_args:
     \__xparse_add_default:n {#1}
-    \__xparse_add_grabber_optional:N G
+    \__xparse_add_grabber:N G
     \__xparse_prepare_signature:N
   }
 \cs_new_protected:Npn \__xparse_add_type_l:w
@@ -737,7 +784,7 @@
   {
     \__xparse_flush_m_args:
     \__xparse_add_default:
-    \__xparse_add_grabber_mandatory:N l
+    \__xparse_add_grabber:N l
     \__xparse_prepare_signature:N
   }
 \cs_new_protected:Npn \__xparse_add_type_m:w
@@ -744,7 +791,7 @@
   {
     \__xparse_add_default:
     \bool_if:NTF \l__xparse_prefixed_bool
-      { \__xparse_add_grabber_mandatory:N m }
+      { \__xparse_add_grabber:N m }
       { \int_incr:N \l__xparse_m_args_int }
     \__xparse_prepare_signature:N
   }
@@ -752,7 +799,7 @@
   {
     \__xparse_flush_m_args:
     \__xparse_add_default:n {#3}
-    \__xparse_add_grabber_mandatory:N R
+    \__xparse_add_grabber:N R
     \tl_put_right:Nn \l__xparse_signature_tl { #1 #2 }
     \__xparse_prepare_signature:N
   }
@@ -760,7 +807,7 @@
   {
     \__xparse_flush_m_args:
     \__xparse_add_default:
-    \__xparse_add_grabber_optional:N t
+    \__xparse_add_grabber:N t
     \tl_put_right:Nn \l__xparse_signature_tl {#1}
     \__xparse_prepare_signature:N
   }
@@ -768,7 +815,7 @@
   {
     \__xparse_flush_m_args:
     \__xparse_add_default:
-    \__xparse_add_grabber_mandatory:N u
+    \__xparse_add_grabber:N u
     \tl_put_right:Nn \l__xparse_signature_tl { {#1} }
     \__xparse_prepare_signature:N
   }
@@ -776,7 +823,7 @@
   {
     \__xparse_flush_m_args:
     \exp_args:No \__xparse_add_default:n \c_novalue_tl
-    \__xparse_add_grabber_mandatory:N v
+    \__xparse_add_grabber:N v
     \__xparse_prepare_signature:N
   }
 \cs_new_protected:Npn \__xparse_flush_m_args:
@@ -785,19 +832,13 @@
       {
         \tl_put_right:Nx \l__xparse_signature_tl
           { \exp_not:c { __xparse_grab_m_ \int_use:N \l__xparse_m_args_int :w } }
-        \int_sub:Nn \l__xparse_mandatory_args_int { \l__xparse_m_args_int }
         \tl_put_right:Nx \l__xparse_process_all_tl
           { \prg_replicate:nn { \l__xparse_m_args_int } { { } } }
       }
     \int_zero:N \l__xparse_m_args_int
   }
-\cs_new_protected:Npn \__xparse_add_grabber_mandatory:N #1
+\cs_new_protected:Npn \__xparse_add_grabber:N #1
   {
-    \__xparse_add_grabber_optional:N #1
-    \int_decr:N \l__xparse_mandatory_args_int
-  }
-\cs_new_protected:Npn \__xparse_add_grabber_optional:N #1
-  {
     \tl_put_right:Nx \l__xparse_signature_tl
       {
         \exp_not:c
@@ -967,6 +1008,33 @@
     \cs_set_eq:NN #1 \__xparse_tmp:w
     \tl_set:Nn #2 {#1}
   }
+\cs_new_protected:Npn \__xparse_grab_b:w
+  { \__xparse_grab_b_aux:NNw \cs_set_protected_nopar:Npn \tl_trim_spaces:n }
+\cs_new_protected:Npn \__xparse_grab_b_long:w
+  { \__xparse_grab_b_aux:NNw \cs_set_protected:Npn \tl_trim_spaces:n }
+\cs_new_protected:Npn \__xparse_grab_b_obey_spaces:w
+  { \__xparse_grab_b_aux:NNw \cs_set_protected_nopar:Npn \exp_not:n }
+\cs_new_protected:Npn \__xparse_grab_b_long_obey_spaces:w
+  { \__xparse_grab_b_aux:NNw \cs_set_protected:Npn \exp_not:n }
+\cs_new_protected:Npn \__xparse_grab_b_aux:NNw #1#2#3 \__xparse_run_code:
+  {
+    \__xparse_grab_D_aux:NNnN \begin \end {#3} #1
+    \tl_put_left:Nn \l__xparse_signature_tl { \__xparse_grab_b_end:Nw #2 }
+    \tl_set_eq:NN \l__xparse_saved_args_tl \l__xparse_args_tl
+    \tl_clear:N \l__xparse_args_tl
+    \exp_args:Nc \l__xparse_fn_tl { begin ~ }
+  }
+\cs_new_protected:Npn \__xparse_grab_b_end:Nw #1#2 \__xparse_run_code:
+  {
+    \tl_set:Nx \l__xparse_args_tl
+      {
+        \exp_not:V \l__xparse_saved_args_tl
+        { \exp_after:wN #1 \l__xparse_args_tl }
+      }
+    #2
+    \__xparse_run_code:
+    \end
+  }
 \cs_new_protected:Npn \__xparse_grab_D:w #1#2#3 \__xparse_run_code:
   {
     \__xparse_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected_nopar:Npn
@@ -1244,7 +1312,7 @@
       { \__xparse_grab_D_call:Nw #1 }
       {
         \__kernel_msg_error:nnxx { xparse } { missing-required }
-          { \exp_after:wN \token_to_str:N \l__xparse_fn_tl }
+          { \__xparse_environment_or_command: }
           { \token_to_str:N #1 }
         \__xparse_add_arg:o \c_novalue_tl
       }
@@ -1401,7 +1469,7 @@
       \peek_meaning_remove:NTF \char_generate:nn { \tex_endlinechar:D } { 6 }
       {
         \__kernel_msg_error:nnxxx { xparse } { verbatim-newline }
-          { \exp_after:wN \token_to_str:N \l__xparse_fn_tl }
+          { \__xparse_environment_or_command: }
           { \tl_to_str:N \l__xparse_v_arg_tl }
           { \tl_to_str:n {#1} }
         \__xparse_add_arg:o \c_novalue_tl
@@ -1408,7 +1476,7 @@
       }
       {
         \__kernel_msg_error:nnxxx { xparse } { verbatim-tokenized }
-          { \exp_after:wN \token_to_str:N \l__xparse_fn_tl }
+          { \__xparse_environment_or_command: }
           { \tl_to_str:N \l__xparse_v_arg_tl }
           { \tl_to_str:n {#1} }
         \__xparse_add_arg:o \c_novalue_tl
@@ -1577,8 +1645,10 @@
               \q_nil { } ##2 \ERROR \q__xparse \ERROR
           }
           {
-            \__kernel_msg_expandable_error:nnnn
-              { xparse } { missing-required } {##5} {##2}
+            \__kernel_msg_expandable_error:nnff
+              { xparse } { missing-required }
+              { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N ##5 } }
+              { \tl_to_str:n {##2} }
             ##4 {#1} \q__xparse ##5 ##6 {##7}
           }
       }
@@ -1603,8 +1673,10 @@
               ##6 \ERROR
           }
           {
-            \__kernel_msg_expandable_error:nnnn
-              { xparse } { missing-required } {##4} {##2}
+            \__kernel_msg_expandable_error:nnff
+              { xparse } { missing-required }
+              { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N ##4 } }
+              { \tl_to_str:n {##2} }
             ##3 {#1} \q__xparse ##4 ##5 {##6}
           }
       }
@@ -1709,26 +1781,27 @@
   { \tl_set:Nx \ProcessedArgument { \tl_trim_spaces:n {#1} } }
 \cs_new_protected:Npn \__xparse_get_arg_spec_error:N #1
   {
-    \cs_if_exist:NTF #1
-      {
-        \__kernel_msg_error:nnx { xparse } { non-xparse-command }
-          { \token_to_str:N #1 }
-      }
-      {
-        \__kernel_msg_error:nnx { xparse } { unknown-command }
-          { \token_to_str:N #1 }
-      }
+    \bool_set_false:N \l__xparse_environment_bool
+    \tl_set:Nn \l__xparse_fn_tl {#1}
+    \__xparse_get_arg_spec_error_aux:n { \cs_if_exist:NTF #1 }
   }
 \cs_new_protected:Npn \__xparse_get_arg_spec_error:n #1
   {
-    \cs_if_exist:cTF {#1}
+    \bool_set_true:N \l__xparse_environment_bool
+    \str_set:Nx \l__xparse_environment_str {#1}
+    \__xparse_get_arg_spec_error_aux:n
+      { \cs_if_exist:cTF { \l__xparse_environment_str } }
+  }
+\cs_new_protected:Npn \__xparse_get_arg_spec_error_aux:n #1
+  {
+    #1
       {
-        \__kernel_msg_error:nnx { xparse } { non-xparse-environment }
-          { \tl_to_str:n {#1} }
+        \__kernel_msg_error:nnx { xparse } { non-xparse }
+          { \__xparse_environment_or_command: }
       }
       {
-        \__kernel_msg_error:nnx { xparse } { unknown-environment }
-          { \tl_to_str:n {#1} }
+        \__kernel_msg_error:nnx { xparse } { unknown }
+          { \__xparse_environment_or_command: }
       }
   }
 \cs_new_protected:Npn \__xparse_get_arg_spec:NTF #1#2#3
@@ -1828,15 +1901,16 @@
   {
     \exp_args:Nf \str_case_e:nnTF
       {
-        \exp_args:Nf \tl_if_empty:nT { \token_get_arg_spec:N #1 }
+        \exp_args:Nf \tl_if_empty:nT { \cs_argument_spec:N #1 }
           {
             \exp_last_unbraced:Nf \__xparse_cmd_if_xparse_aux:w
-              { \token_get_replacement_spec:N #1 } ~ \q_stop
+              { \cs_replacement_spec:N #1 } ~ \q_stop
           }
       }
       {
         { \token_to_str:N \__xparse_start:nNNnnn } { }
         { \token_to_str:N \__xparse_start_expandable:nNNNNn } { }
+        { \token_to_str:N \__xparse_start_env:nnnnn } { }
       }
   }
 \cs_new:Npn \__xparse_cmd_if_xparse_aux:w #1 ~ #2 \q_stop {#1}
@@ -1850,18 +1924,38 @@
       { \__xparse_peek_nonspace_aux:nNNTF { #1 ~ } #2 #3 {#4} {#5} }
       { #2 #3 { #4 } { #5 #1 } }
   }
+\cs_new:Npn \__xparse_environment_or_command:
+  {
+    \bool_if:NTF \l__xparse_environment_bool
+      { environment ~ ' \l__xparse_environment_str ' }
+      {
+        command ~ '
+        \exp_args:Nf \tl_trim_spaces:n
+          { \exp_after:wN \token_to_str:N \l__xparse_fn_tl }
+        '
+      }
+  }
+\tl_const:Nn \c__xparse_ignore_def_tl
+  { \\ \\ LaTeX~will~ignore~this~entire~definition. }
+\__kernel_msg_new:nnnn { xparse } { arg-after-body }
+  { In~the~definition~of~#1,~b~(body)~argument~must~be~last. }
+  {
+    The~'body'~argument~type~is~followed~by~'#2'~in~the~argument~
+    specification~of~the~#1.~This~is~not~allowed.
+    \c__xparse_ignore_def_tl
+  }
 \__kernel_msg_new:nnnn { xparse } { bad-arg-spec }
-  { Bad~argument~specification~'#2'~for~command~'#1'. }
+  { Bad~argument~specification~'#2'~for~#1. }
   {
     The~argument~specification~provided~was~not~valid:~
-    one~or~more~mandatory~pieces~of~information~were~missing. \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    one~or~more~mandatory~pieces~of~information~were~missing.
+    \c__xparse_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { command-already-defined }
   { Command~'#1'~already~defined! }
   {
     You~have~used~#2~
-    with~a~command~that~already~has~a~definition. \\
+    with~a~command~that~already~has~a~definition. \\ \\
     The~existing~definition~of~'#1'~will~not~be~altered.
   }
 \__kernel_msg_new:nnnn { xparse } { command-not-yet-defined }
@@ -1868,22 +1962,22 @@
   { Command ~'#1'~not~yet~defined! }
   {
     You~have~used~#2~
-    with~a~command~that~was~never~defined. \\
-    LaTeX~will~ignore~this~entire~definition.
+    with~a~command~that~was~never~defined.
+    \c__xparse_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { environment-already-defined }
   { Environment~'#1'~already~defined! }
   {
     You~have~used~\NewDocumentEnvironment
-    with~an~environment~that~already~has~a~definition. \\
-    The~existing~definition~of~'#1'~will~be~overwritten.
+    with~an~environment~that~already~has~a~definition. \\ \\
+    The~existing~definition~of~'#1'~will~not~be~altered.
   }
 \__kernel_msg_new:nnnn { xparse } { environment-not-yet-defined }
   { Environment~'#1'~not~yet~defined! }
   {
     You~have~used~\RenewDocumentEnvironment
-    with~an~environment~that~was~never~defined. \\
-    LaTeX~will~ignore~this~entire~definition.
+    with~an~environment~that~was~never~defined.
+    \c__xparse_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { expandable-ending-optional }
   {
@@ -1895,12 +1989,6 @@
     (or~no~arguments~at~all).~You~cannot~have~a~terminal~optional~
     argument~with~expandable~commands.
   }
-\__kernel_msg_new:nnnn { xparse } { if-boolean }
-  { Invalid~use~\iow_char:N\\IfBooleanTF~{#1} }
-  {
-    The~first~argument~of~\iow_char:N\\IfBoolean(TF/T/F)~must~be~
-    a~boolean~argument~obtained~from~parsing~'s'~or~'t'~arguments.
-  }
 \__kernel_msg_new:nnnn { xparse } { inconsistent-long }
   { Inconsistent~long~arguments~for~expandable~command~'#1'. }
   {
@@ -1907,13 +1995,20 @@
     The~arguments~for~an~expandable~command~must~not~involve~short~
     arguments~after~long~arguments.~You~have~tried~to~mix~the~two~types.
   }
+\__kernel_msg_new:nnnn { xparse } { invalid-command-arg }
+  { Argument~type~'#2'~not~available~for~#1. }
+  {
+    The~letter~'#2'~can~only~be~used~in~environment~argument~
+    specifications,~not~for~commands.
+    \\ \\
+    LaTeX~will~ignore~this~entire~definition.
+  }
 \__kernel_msg_new:nnnn { xparse } { invalid-expandable-argument-type }
   { Argument~type~'#2'~not~available~for~expandable~command~'#1'. }
   {
-    The~letter~'#2'~does~not~specify~an~argument~type~which~can~be~used~
+    The~letter~'#2'~specifies~an~argument~type~which~cannot~be~used~
     in~an~expandable~command.
-    \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    \c__xparse_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { invalid-after-optional-expandably }
   {
@@ -1921,42 +2016,16 @@
     for~expandable~command~'#1'.
   }
   {
-    The~letter~'#2'~does~not~specify~an~argument~type~which~can~be~used~
+    The~letter~'#2'~specifies~an~argument~type~which~cannot~be~used~
     in~an~expandable~command~after~an~optional~argument.
-    \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    \c__xparse_ignore_def_tl
   }
-\__kernel_msg_new:nnnn { xparse } { loop-in-defaults }
-  { Circular~dependency~in~defaults~of~'#1'. }
-  {
-    The~default~values~of~two~or~more~arguments~of~'#1'~depend~on~each~
-    other~in~a~way~that~cannot~be~resolved.
-  }
-\__kernel_msg_new:nnnn { xparse } { missing-required }
-  { Failed~to~find~required~argument~starting~with~'#2'~for~command~'#1'. }
-  {
-    The~current~command~'#1'~expects~an~argument~starting~with~'#2'.~
-    LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed.
-  }
 \__kernel_msg_new:nnnn { xparse } { non-trailing-obey-spaces }
-  { Prefix~'!'~used~before~mandatory~argument~'#2'~of~command~'#1'. }
+  { Prefix~'!'~used~before~mandatory~argument~'#2'~of~#1. }
   {
     The~prefix~'!'~can~only~apply~to~trailing~optional~arguments.
-    \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    \c__xparse_ignore_def_tl
   }
-\__kernel_msg_new:nnnn { xparse } { non-xparse-command }
-  { Command~'#1'~not~defined~using~xparse. }
-  {
-    You~have~asked~for~the~argument~specification~for~a~command~'#1',~
-    but~this~is~not~a~command~defined~using~xparse.
-  }
-\__kernel_msg_new:nnnn { xparse } { non-xparse-environment }
-  { Environment~'#1'~not~defined~using~xparse. }
-  {
-    You~have~asked~for~the~argument~specification~for~an~environment~'#1',~
-    but~this~is~not~an~environment~defined~using~xparse.
-  }
 \__kernel_msg_new:nnnn { xparse } { not-definable }
   { First~argument~of~'#2'~must~be~a~command. }
   {
@@ -1963,8 +2032,7 @@
     The~first~argument~of~'#2'~should~be~the~document~command~that~will~
     be~defined.~The~provided~argument~'#1'~is~a~character.~Perhaps~a~
     backslash~is~missing?
-    \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    \c__xparse_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { not-one-token }
   { First~argument~of~'#2'~must~be~a~command. }
@@ -1971,81 +2039,92 @@
   {
     The~first~argument~of~'#2'~should~be~the~document~command~that~will~
     be~defined.~The~provided~argument~'#1'~contains~more~than~one~
-    token.
-    \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    token.~Perhaps~a~backslash~is~missing?
+    \c__xparse_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { not-single-char }
   {
-    Argument~delimiter~'#2'~for~the~command~'#1'~should~be~
+    Argument~delimiter~'#2'~for~the~#1~should~be~
     a~single~character.
   }
   {
     The~argument~specification~provided~was~not~valid:~in~a~place~
-    where~a~single~character~is~required,~LaTeX~found~'#2'. \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    where~a~single~character~is~required,~LaTeX~found~'#2'.
+    \c__xparse_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { processor-in-expandable }
   { Argument~processor~'>{#2}'~cannot~be~used~for~the~expandable~command~'#1'. }
   {
     The~argument~specification~for~#1~contains~a~processor~function:~
-    this~is~only~supported~for~standard~robust~commands. \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    this~is~only~supported~for~standard~robust~commands.
+    \c__xparse_ignore_def_tl
   }
-\__kernel_msg_new:nnnn { xparse } { split-excess-tokens }
-  { Too~many~'#1'~tokens~when~trying~to~split~argument. }
-  {
-    LaTeX~was~asked~to~split~the~input~'#3'~
-    at~each~occurrence~of~the~token~'#1',~up~to~a~maximum~of~#2~parts.~
-    There~were~too~many~'#1'~tokens.
-  }
 \__kernel_msg_new:nnnn { xparse } { too-many-arguments }
-  { Too~many~arguments~in~argument~specification~'#2'~of~command~'#1'. }
+  { Too~many~arguments~in~argument~specification~'#2'~of~#1. }
   {
     The~argument~specification~provided~has~more~than~9~arguments.~
-    This~cannot~be~implemented. \\ \\
-    LaTeX~will~ignore~this~entire~definition.
+    This~cannot~be~implemented.
+    \c__xparse_ignore_def_tl
   }
 \__kernel_msg_new:nnnn { xparse } { two-markers }
-  { Two~'#2'~apply~to~the~same~argument~in~argument~specification~of~command~'#1'. }
+  { Two~'#2'~apply~to~the~same~argument~in~argument~specification~of~#1. }
   {
     The~argument~specification~provided~has~two~markers~'#2'~applying~
     to~the~same~argument;~these~are~redundant.
   }
 \__kernel_msg_new:nnnn { xparse } { unknown-argument-type }
-  { Unknown~argument~type~'#2'~for~the~command~'#1'. }
+  { Unknown~argument~type~'#2'~for~the~#1. }
   {
-    The~letter~'#2'~does~not~specify~a~known~argument~type.~
-    LaTeX~will~ignore~this~entire~definition.
+    The~letter~'#2'~does~not~specify~a~known~argument~type.
+    \c__xparse_ignore_def_tl
   }
-\__kernel_msg_new:nnnn { xparse } { unknown-command }
-  { Unknown~document~command~'#1'. }
+\__kernel_msg_new:nnn { xparse } { if-boolean }
+  { Invalid~use~\iow_char:N\\IfBooleanTF~{#1} }
+\__kernel_msg_new:nnnn { xparse } { loop-in-defaults }
+  { Defaults~of~#1~have~circular~dependency. }
   {
-    You~have~asked~for~the~argument~specification~for~a~command~'#1',~
-    but~it~is~not~defined.
+    The~default~values~of~two~or~more~arguments~of~the~#1~
+    depend~on~each~other~in~a~way~that~cannot~be~resolved.
   }
-\__kernel_msg_new:nnnn { xparse } { unknown-environment }
-  { Unknown~document~environment~'#1'. }
+\__kernel_msg_new:nnnn { xparse } { missing-required }
+  { Missing~required~argument~for~#1. }
   {
-    You~have~asked~for~the~argument~specification~for~an~environment~'#1',~
+    The~current~#1~expects~an~argument~starting~with~'#2'.~
+    LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed.
+  }
+\__kernel_msg_new:nnnn { xparse } { non-xparse }
+  { \str_upper_case:n #1~not~defined~using~xparse. }
+  {
+    You~have~asked~for~the~argument~specification~for~the~#1,~
+    but~this~was~not~defined~using~xparse.
+  }
+\__kernel_msg_new:nnnn { xparse } { split-excess-tokens }
+  { Too~many~'#1'~tokens~when~trying~to~split~argument. }
+  {
+    LaTeX~was~asked~to~split~the~input~'#3'~
+    at~each~occurrence~of~the~token~'#1',~up~to~a~maximum~of~#2~parts.~
+    There~were~too~many~'#1'~tokens.
+  }
+\__kernel_msg_new:nnnn { xparse } { unknown }
+  { Unknown~document~#1. }
+  {
+    You~have~asked~for~the~argument~specification~for~the~#1,~
     but~it~is~not~defined.
   }
 \__kernel_msg_new:nnnn { xparse } { verbatim-newline }
-  { Verbatim~argument~of~'#1'~ended~by~end~of~line. }
+  { Verbatim~argument~of~#1~ended~by~end~of~line. }
   {
-    The~verbatim~argument~of~'#1'~cannot~contain~more~than~one~line,~
+    The~verbatim~argument~of~the~#1~cannot~contain~more~than~one~line,~
     but~the~end~
-    of~the~current~line~has~been~reached.~You~have~probably~forgotten~the~
+    of~the~current~line~has~been~reached.~You~may~have~forgotten~the~
     closing~delimiter.
     \\ \\
     LaTeX~will~ignore~'#2'.
   }
 \__kernel_msg_new:nnnn { xparse } { verbatim-tokenized }
+  { The~verbatim~#1~cannot~be~used~inside~an~argument. }
   {
-    The~verbatim~command~'#1'~cannot~be~used~inside~an~argument.~
-  }
-  {
-    The~command~'#1'~takes~a~verbatim~argument.~
+    The~#1~takes~a~verbatim~argument.~
     It~may~not~appear~within~the~argument~of~another~function.~
     It~received~an~illegal~token \tl_if_empty:nF {#3} { ~'#3' } .
     \\ \\
@@ -2126,7 +2205,7 @@
     \cs_if_exist:cTF {#1}
       { \__kernel_msg_error:nnx { xparse } { environment-already-defined } {#1} }
       { \__xparse_declare_env:nnnn {#1} {#2} {#3} {#4} }
-}
+  }
 \cs_new_protected:Npn \RenewDocumentEnvironment #1#2#3#4
   {
     \cs_if_exist:cTF {#1}
@@ -2178,14 +2257,20 @@
   }
 \cs_new:Npn \IfBooleanTF #1
   {
-    \bool_lazy_and:nnTF
-      { \tl_if_single_p:n {#1} }
-      { \tl_if_single_token_p:n #1 }
-      { \bool_if:NTF #1 }
-      {
-        \__kernel_msg_error:nnn { xparse } { if-boolean } {#1}
-        \use_ii:nn
-      }
+    \tl_if_single:nF {#1}
+      { \prg_break:n { \use:n } }
+    \tl_if_single_token:nF #1
+      { \prg_break:n { \use:n } }
+    \token_if_eq_meaning:NNT #1 \c_true_bool
+      { \prg_break:n { \use_ii:nnn } }
+    \token_if_eq_meaning:NNT #1 \c_false_bool
+      { \prg_break:n { \use_iii:nnn } }
+    \prg_break:n { \use:n }
+    \prg_break_point:
+    {
+      \__kernel_msg_expandable_error:nnn { xparse } { if-boolean } {#1}
+      \use_ii:nn
+    }
   }
 \cs_new:Npn \IfBooleanT #1#2 { \IfBooleanTF {#1} {#2} { } }
 \cs_new:Npn \IfBooleanF #1 { \IfBooleanTF {#1} { } }

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty	2019-03-05 22:33:41 UTC (rev 50245)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty	2019-03-05 22:35:14 UTC (rev 50246)
@@ -6,7 +6,7 @@
 %%
 %% xtemplate.dtx  (with options: `package')
 %% 
-%% Copyright (C) 2011-2017 The LaTeX3 Project
+%% Copyright (C) 2011-2019 The LaTeX3 Project
 %% 
 %% It may be distributed and/or modified under the conditions of
 %% the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -18,11 +18,7 @@
 %% This file is part of the "l3packages bundle" (The Work in LPPL)
 %% and all files in that bundle must be distributed together.
 %% 
-%% File: xtemplate.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley,
-%%                         David Carlisle
-%%                     (C) Copyright 2004-2010 Frank Mittelbach,
-%%                         The LaTeX3 Project
-%%                     (C) Copyright 2011-2018 The LaTeX3 Project
+%% File: xtemplate.dtx
 \RequirePackage{expl3}[2018/02/21]
 \@ifpackagelater{expl3}{2018/02/21}
   {}
@@ -36,7 +32,7 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{xtemplate}{2018-10-17}{}
+\ProvidesExplPackage{xtemplate}{2019-03-05}{}
   {L3 Experimental prototype document functions}
 \tl_const:Nn \c__xtemplate_code_root_tl      { template~code~>~ }
 \tl_const:Nn \c__xtemplate_defaults_root_tl  { template~defaults~>~ }



More information about the tex-live-commits mailing list