texlive[43183] Master/texmf-dist: l3 (10feb17)

commits+karl at tug.org commits+karl at tug.org
Sat Feb 11 00:29:11 CET 2017


Revision: 43183
          http://tug.org/svn/texlive?view=revision&revision=43183
Author:   karl
Date:     2017-02-11 00:29:10 +0100 (Sat, 11 Feb 2017)
Log Message:
-----------
l3 (10feb17)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/l3experimental/README.md
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3flag.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3regex.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/l3str/l3tl-analysis.pdf
    trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3tl-build.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/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/l3docstrip.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
    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/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/l3str/l3flag.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-build.dtx
    trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3oldmodules.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3flag.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex-trace.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3tl-build.sty
    trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.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/l3basics.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3bootstrap.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3box.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3candidates.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3color.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3file.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3int.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3names.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3sort.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3str.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3token.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.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

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3experimental/README.md	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/doc/latex/l3experimental/README.md	2017-02-10 23:29:10 UTC (rev 43183)
@@ -1,7 +1,7 @@
 Experimental LaTeX3 Concepts
 ============================
 
-Release 2017/02/07 (r6846)
+Release 2017/02/10 (r6878)
 
 Overview
 --------

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

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3regex.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/l3str/l3tl-analysis.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3experimental/l3str/l3tl-build.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/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/README.md	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/README.md	2017-02-10 23:29:10 UTC (rev 43183)
@@ -1,7 +1,7 @@
 LaTeX3 Programming Conventions
 ==============================
 
-Release 2017/02/07 (r6846)
+Release 2017/02/10 (r6878)
 
 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/l3docstrip.pdf
===================================================================
(Binary files differ)

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

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

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

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3packages/README.md	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/doc/latex/l3packages/README.md	2017-02-10 23:29:10 UTC (rev 43183)
@@ -1,7 +1,7 @@
 LaTeX3 High-Level Concepts
 ==========================
 
-Release 2017/02/07 (r6846)
+Release 2017/02/10 (r6878)
 
 Overview
 --------

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/l3keys2e/l3keys2e.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/l3str/l3flag.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3flag.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3flag.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -23,8 +23,8 @@
 %<*driver|package>
 % The version of expl3 required is tested as early as possible, as
 % some really old versions do not define \ProvidesExplPackage.
-\RequirePackage{expl3}[2017/02/07]
-%<package>\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+%<package>\@ifpackagelater{expl3}{2017/02/10}
 %<package>  {}
 %<package>  {%
 %<package>    \PackageError{l3flag}{Support package l3kernel too old}
@@ -36,7 +36,7 @@
 %<package>      }%
 %<package>    \endinput
 %<package>  }
-\GetIdInfo$Id: l3flag.dtx 6846 2017-02-07 07:04:19Z joseph $
+\GetIdInfo$Id: l3flag.dtx 6878 2017-02-10 07:40:59Z joseph $
   {L3 Experimental flags}
 %</driver|package>
 %<*driver>

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -23,8 +23,8 @@
 %<*driver|package>
 % The version of expl3 required is tested as early as possible, as
 % some really old versions do not define \ProvidesExplPackage.
-\RequirePackage{expl3}[2017/02/07]
-%<package>\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+%<package>\@ifpackagelater{expl3}{2017/02/10}
 %<package>  {}
 %<package>  {%
 %<package>    \PackageError{l3regex}{Support package l3kernel too old}
@@ -36,7 +36,7 @@
 %<package>      }%
 %<package>    \endinput
 %<package>  }
-\GetIdInfo$Id: l3regex.dtx 6846 2017-02-07 07:04:19Z joseph $
+\GetIdInfo$Id: l3regex.dtx 6878 2017-02-10 07:40:59Z joseph $
   {L3 Experimental regular expressions}
 %</driver|package>
 %<*driver>

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-build.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-build.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-build.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -23,8 +23,8 @@
 %<*driver|package>
 % The version of expl3 required is tested as early as possible, as
 % some really old versions do not define \ProvidesExplPackage.
-\RequirePackage{expl3}[2017/02/07]
-%<package>\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+%<package>\@ifpackagelater{expl3}{2017/02/10}
 %<package>  {}
 %<package>  {%
 %<package>    \PackageError{l3tl-build}{Support package l3kernel too old}
@@ -36,7 +36,7 @@
 %<package>      }%
 %<package>    \endinput
 %<package>  }
-\GetIdInfo$Id: l3tl-build.dtx 6846 2017-02-07 07:04:19Z joseph $
+\GetIdInfo$Id: l3tl-build.dtx 6878 2017-02-10 07:40:59Z joseph $
   {L3 Experimental token list construction}
 %</driver|package>
 %<*driver>

Modified: trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -24,8 +24,8 @@
 %<*driver|package>
 % The version of expl3 required is tested as early as possible, as
 % some really old versions do not define \ProvidesExplPackage.
-\RequirePackage{expl3}[2017/02/07]
-%<package>\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+%<package>\@ifpackagelater{expl3}{2017/02/10}
 %<package>  {}
 %<package>  {%
 %<package>    \PackageError{l3galley}{Support package l3kernel too old}
@@ -37,7 +37,7 @@
 %<package>      }%
 %<package>    \endinput
 %<package>  }
-\GetIdInfo$Id: l3galley.dtx 6846 2017-02-07 07:04:19Z joseph $
+\GetIdInfo$Id: l3galley.dtx 6878 2017-02-10 07:40:59Z joseph $
   {L3 Experimental galley code}
 %</driver|package>
 %<*driver>

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -23,8 +23,8 @@
 %<*driver|generic|package>
 \def\ExplFileName{expl3}%
 \def\ExplFileDescription{L3 programming layer}%
-\def\ExplFileDate{2017/02/07}%
-\def\ExplFileVersion{6846}%
+\def\ExplFileDate{2017/02/10}%
+\def\ExplFileVersion{6878}%
 %</driver|generic|package>
 %<*driver>
 \documentclass[full]{l3doc}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -62,7 +62,7 @@
 %
 %<*driver|class>
 \RequirePackage{expl3,xparse,calc}
-\GetIdInfo$Id: l3doc.dtx 6839 2017-02-06 18:52:08Z bruno $
+\GetIdInfo$Id: l3doc.dtx 6847 2017-02-07 15:05:44Z bruno $
           {L3 Experimental documentation class}
 %</driver|class>
 %
@@ -2159,7 +2159,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_deprecated_on:n #1
   {
-    \@@_date_compare:nNnT {#1} < { \tex_year:D / \tex_month:D / \tex_day:D }
+    \@@_date_compare:nNnT {#1} < { \tex_year:D - \tex_month:D - \tex_day:D }
       {
         \msg_error:nnxx { l3doc } { deprecated-function }
           { \tl_to_str:N \l_@@_macro_argument_tl } {#1}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: l3fp-parse.dtx Copyright (C) 2011-2016 The LaTeX3 Project
+%% File: l3fp-parse.dtx Copyright (C) 2011-2017 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
@@ -22,7 +22,7 @@
 %
 %<*driver>
 \documentclass[full]{l3doc}
-\GetIdInfo$Id: l3fp-parse.dtx 6805 2016-12-28 22:15:52Z joseph $
+\GetIdInfo$Id: l3fp-parse.dtx 6877 2017-02-10 03:59:09Z bruno $
   {L3 Floating-point expression parsing}
 \begin{document}
   \DocInput{\jobname.dtx}
@@ -836,11 +836,14 @@
 %     \@@_parse_one_register_auxii:wwwNw,
 %     \@@_parse_one_register_int:www,
 %     \@@_parse_one_register_mu:www,
-%     \@@_parse_one_register_dim:ww
+%     \@@_parse_one_register_dim:ww,
+%     \@@_parse_one_register_wd:w,
+%     \@@_parse_one_register_wd:Nw,
 %   }
 %   This is called whenever~|#2| is a control sequence other than
-%   \cs{scan_stop:} in meaning.  We assume that it is a register, but
-%   carefully unpacking it with \cs{tex_the:D} within braces.  First, we
+%   \cs{scan_stop:} in meaning.  We special-case \tn{wd}, \tn{ht}, \tn{dp}
+%   (see later) and otherwise assume that it is a register, but
+%   carefully unpack it with \cs{tex_the:D} within braces.  First, we
 %   find the exponent following~|#2|.  Then we unpack~|#2| with
 %   \cs{tex_the:D}, and the \texttt{auxii} auxiliary distinguishes
 %   integer registers from dimensions/skips from muskips, according to
@@ -859,6 +862,9 @@
     \exp_after:wN \@@_parse_infix_after_operand:NwN
     \exp_after:wN #1
     \exp:w \exp_end_continue_f:w
+      \if_meaning:w \box_wd:N #2 \@@_parse_one_register_wd:w \fi:
+      \if_meaning:w \box_ht:N #2 \@@_parse_one_register_wd:w \fi:
+      \if_meaning:w \box_dp:N #2 \@@_parse_one_register_wd:w \fi:
       \exp_after:wN \@@_parse_one_register_aux:Nw
       \exp_after:wN #2
       \__int_value:w
@@ -896,6 +902,27 @@
     \__int_value:w \__dim_eval:w #1 pt ;
   }
 %    \end{macrocode}
+%   The \tn{wd}, \tn{dp}, \tn{ht} primitives expect an integer argument.
+%   We abuse the exponent parser to find the integer argument: simply
+%   include the exponent marker~|e|.  Once that \enquote{exponent} is
+%   found, use \cs{tex_the:D} to find the box dimension and then copy
+%   what we did for dimensions.
+%    \begin{macrocode}
+\cs_new:Npn \@@_parse_one_register_wd:w
+    #1#2 \exp_after:wN #3#4 \@@_parse_expand:w
+  {
+    #1
+    \exp_after:wN \@@_parse_one_register_wd:Nw
+    #4 \@@_parse_expand:w e
+  }
+\cs_new:Npn \@@_parse_one_register_wd:Nw #1#2 ;
+  {
+    \exp_after:wN \@@_from_dim_test:ww
+    \exp_after:wN 0 \exp_after:wN ,
+    \__int_value:w \__dim_eval:w
+      \exp_after:wN \use:n \exp_after:wN { \tex_the:D #1 #2 } ;
+  }
+%    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}[aux, EXP]{\@@_parse_one_digit:NN}
@@ -1584,7 +1611,7 @@
 % \begin{macro}[aux, rEXP]
 %   {\@@_parse_exponent:N, \@@_parse_exponent_aux:N}
 %   This function should be called within an \cs{__int_value:w}
-%   expansion (or within an integer expression.  It leaves digits of the
+%   expansion (or within an integer expression).  It leaves digits of the
 %   exponent behind it in the input stream, and terminates the expansion
 %   with a semicolon.  If there is no~|e|, leave an exponent of~$0$.  If
 %   there is an~|e|, expand the next token to run some tests on it.  The

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3oldmodules.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3oldmodules.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3oldmodules.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -21,7 +21,7 @@
 % for those people who are interested.
 %
 %<*driver|oldmodules>
-\def\ExplFileDate{2014/09/06}
+\def\ExplFileDate{2017/02/10}
 %</driver|oldmodules>
 %<*driver>
 \documentclass[full]{l3doc}
@@ -44,7 +44,7 @@
 %
 %
 % \date{Released \ExplFileDate}
-
+%
 % \maketitle
 %
 % \section{Introduction}
@@ -127,18 +127,22 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
-\typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+%<!l3sort>\typeout{** After showing you an error message you can hit <return> we will continue}
+%<!l3sort>\typeout{** for now by loading expl3 for you. However, the old packages will be}
+%<!l3sort>\typeout{** removed entirely at the end of 2017.}
+%<l3sort>\typeout{** The old packages will be removed entirely at the end of 2018.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+%<!l3sort>\PackageError
+%<l3sort>\PackageWarning
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+%<!l3sort>  \@ehc
 %    \end{macrocode}
 %    Finally load \texttt{expl3} so that the user can continue for now.
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -24,7 +24,7 @@
 \documentclass[full]{l3doc}
 %</driver>
 %<*driver|package>
-\GetIdInfo$Id: l3sort.dtx 6842 2017-02-06 21:51:22Z joseph $
+\GetIdInfo$Id: l3sort.dtx 6847 2017-02-07 15:05:44Z bruno $
   {L3 Sorting functions}
 %</driver|package>
 %<*driver>
@@ -1083,7 +1083,7 @@
 %
 % \subsection{Deprecated functions}
 %
-% \begin{macro}[deprecated = 2017-02-06]{\sort_ordered:, \sort_reversed:}
+% \begin{macro}[deprecated = 2018-12-31]{\sort_ordered:, \sort_reversed:}
 %   These functions were renamed for consistency.
 %    \begin{macrocode}
 \cs_new_eq:NN \sort_ordered: \sort_return_same:

Modified: trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -23,8 +23,8 @@
 %<*driver|package>
 % The version of expl3 required is tested as early as possible, as
 % some really old versions do not define \ProvidesExplPackage.
-\RequirePackage{expl3}[2017/02/07]
-%<package>\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+%<package>\@ifpackagelater{expl3}{2017/02/10}
 %<package>  {}
 %<package>  {%
 %<package>    \PackageError{l3keys2e}{Support package l3kernel too old}
@@ -38,8 +38,8 @@
 %<package>  }
 \def\ExplFileName{l3keys2e}
 \def\ExplFileDescription{LaTeX2e option processing using LaTeX3 keys}
-\def\ExplFileDate{2017/02/07}
-\def\ExplFileVersion{6846}
+\def\ExplFileDate{2017/02/10}
+\def\ExplFileVersion{6878}
 %</driver|package>
 %<*driver>
 \documentclass[full]{l3doc}

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -24,8 +24,8 @@
 %<*driver|package>
 % The version of expl3 required is tested as early as possible, as
 % some really old versions do not define \ProvidesExplPackage.
-\RequirePackage{expl3}[2017/02/07]
-%<package>\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+%<package>\@ifpackagelater{expl3}{2017/02/10}
 %<package>  {}
 %<package>  {%
 %<package>    \PackageError{xfrac}{Support package l3kernel too old}
@@ -40,8 +40,8 @@
 \RequirePackage{amstext,graphicx,l3keys2e,textcomp,xparse,xtemplate}
 \def\ExplFileName{xfrac}
 \def\ExplFileDescription{L3 Experimental split-level fractions}
-\def\ExplFileDate{2017/02/07}
-\def\ExplFileVersion{6846}
+\def\ExplFileDate{2017/02/10}
+\def\ExplFileVersion{6878}
 %</driver|package>
 %<*driver>
 \documentclass[full]{l3doc}

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -4,7 +4,7 @@
 %%                      David Carlisle
 %%                  (C) Copyright 2004-2008 Frank Mittelbach,
 %%                      The LaTeX3 Project
-%%                  (C) Copyright 2009-2016 The LaTeX3 Project
+%%                  (C) Copyright 2009-2017 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
@@ -27,8 +27,8 @@
 %<*driver|package>
 % The version of expl3 required is tested as early as possible, as
 % some really old versions do not define \ProvidesExplPackage.
-\RequirePackage{expl3}[2017/02/07]
-%<package>\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+%<package>\@ifpackagelater{expl3}{2017/02/10}
 %<package>  {}
 %<package>  {%
 %<package>    \PackageError{xparse}{Support package l3kernel too old}
@@ -42,8 +42,8 @@
 %<package>  }
 \def\ExplFileName{xparse}
 \def\ExplFileDescription{L3 Experimental document command parser}
-\def\ExplFileDate{2017/02/07}
-\def\ExplFileVersion{6846}
+\def\ExplFileDate{2017/02/10}
+\def\ExplFileVersion{6878}
 %</driver|package>
 %<*driver>
 \documentclass[full]{l3doc}
@@ -184,10 +184,11 @@
 %   \item[e] An optional set of \emph{embellishments}, each of which requires a
 %     \emph{value}. If a key is not present, |-NoValue-| is returned.
 %     The returned data is a token list comprising one braced entry per key,
-%     ordered as for the key list in the signature.
+%     ordered as for the key list in the argument specification.  Given as
+%     \texttt{e}\marg{tokens}.
 %     \emph{This is an experimental type}.
-%   \item[E] As for \texttt{E} but returns one or more \meta{defaults}
-%     if values are not given: \texttt{E}\marg{defaults}. See
+%   \item[E] As for \texttt{e} but returns one or more \meta{defaults}
+%     if values are not given: \texttt{E}\marg{tokens}\marg{defaults}. See
 %     Section~\ref{sec:embellishment} for more details.
 % \end{itemize}
 %
@@ -249,10 +250,14 @@
 % argument processors is a somewhat advanced topic, (or at least a less
 % commonly used feature) and is covered in Section~\ref{sec:processors}.
 %
-% By default, an argument of type~\texttt{v} must be at most one line.
-% Prefixing with \texttt{+} allows line breaks within the argument.  The
-% argument is given as a string of characters with category codes~$12$
-% or~$13$, except spaces, which have category code~$10$.
+% 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},
+% \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
+% followed by \texttt{m} type arguments.
 %
 % \subsection{Spacing and optional arguments}
 %
@@ -288,7 +293,7 @@
 % delimited} (\texttt{R}-type) argument is that an error will be raised if
 % the latter is missing. Thus for example
 % \begin{verbatim}
-%   \DeclareDocumentCommand\foo{r()m}
+%   \DeclareDocumentCommand {\foo} {r()m} {}
 %   \foo{oops}
 % \end{verbatim}
 % will lead to an error message being issued. The marker |-NoValue-|
@@ -305,7 +310,8 @@
 % result in the grabbed argument consisting of tokens of category codes
 % $12$~(\enquote{other}) and $13$~(\enquote{active}), except spaces,
 % which are given category code $10$~(\enquote{space}). The argument is
-% delimited in a similar manner to the \LaTeXe{} \cs{verb} function.
+% delimited in a similar manner to the \LaTeXe{} \cs{verb} function, or
+% by (correctly nested) pairs of braces.
 %
 % Functions containing verbatim arguments cannot appear in the arguments
 % of other functions. The \texttt{v}~argument specifier includes code to check
@@ -312,10 +318,60 @@
 % this, and will raise an error if the grabbed argument has already been
 % tokenized by \TeX{} in an irreversible way.
 %
+% By default, an argument of type~\texttt{v} must be at most one line.
+% Prefixing with \texttt{+} allows line breaks within the argument.
+%
 % Users should note that support for verbatim arguments is somewhat
 % experimental. Feedback is therefore very welcome on the \texttt{LaTeX-L}
 % mailing list.
 %
+% \subsection{Default values of arguments}
+%
+% Uppercase argument types (\texttt{O}, \texttt{D}, \ldots{}) allow to
+% specify a default value to be used when the argument is missing; their
+% lower-case counterparts use the special marker |-NoValue-|.  The
+% default value can be expressed in terms of the value of any other
+% arguments by using |#1|, |#2|, and so on.
+% \begin{verbatim}
+%   \DeclareDocumentCommand {\conjugate} { m O{#1ed} O{#2} } {(#1,#2,#3)}
+%   \conjugate {walk}            % => (walk,walked,walked)
+%   \conjugate {find} [found]    % => (find,found,found)
+%   \conjugate {do} [did] [done] % => (do,did,done)
+% \end{verbatim}
+% The default values may refer to arguments that appear later in the
+% argument specification.  For instance a command could accept two
+% optional arguments, equal by default:
+% \begin{verbatim}
+%   \DeclareDocumentCommand {\margins} { O{#3} m O{#1} m } {(#1,#2,#3,#4)}
+%   \margins {a} {b}              % => {(-NoValue-,a,-NoValue-,b)}
+%   \margins [1cm] {a} {b}        % => {(1cm,a,1cm,b)}
+%   \margins {a} [1cm] {b}        % => {(1cm,a,1cm,b)}
+%   \margins [1cm] {a} [2cm] {b}  % => {(1cm,a,2cm,b)}
+% \end{verbatim}
+%
+% Users should note that support for default arguments referring to
+% other arguments is somewhat experimental. Feedback is therefore very
+% welcome on the \texttt{LaTeX-L} mailing list.
+%
+% \subsection{Default values for \enquote{embellishments}}
+% \label{sec:embellishment}
+%
+% The \texttt{E}-type argument allows one default value per test token.
+% This is achieved by giving a list of defaults for each entry in the
+% list, for example:
+% \begin{verbatim}
+%   E{^_}{{UP}{DOWN}}
+% \end{verbatim}
+% If the list of default values is \emph{shorter} than the list of test tokens,
+% the special \cs{NoValue} marker will be returned (as for the \texttt{e}-type
+% argument). Thus for example
+% \begin{verbatim}
+%   E{^_}{{UP}}
+% \end{verbatim}
+% has default \texttt{UP} for the |^| test token, but will return the
+% \cs{NoValue} marker as a default for |_|. This allows mixing of explicit
+% defaults with testing for missing values.
+%
 % \subsection{Declaring commands and environments}
 %
 % With the concept of an argument specifier defined, it is now
@@ -472,25 +528,6 @@
 %   take based on this information.
 % \end{function}
 %
-% \subsection{Default values for \enquote{embellishments}}
-% \label{sec:embellishment}
-%
-% The \texttt{E}-type argument allows one default value per test token.
-% This is achieved by giving a list of defaults for each entry in the
-% list, for example:
-% \begin{verbatim}
-%   E{^_}{{UP}{DOWN}}
-% \end{verbatim}
-% If the list of default values is \emph{shorter} than the list of test tokens,
-% the special \cs{NoValue} marker will be returned (as for the \texttt{e}-type
-% argument). Thus for example
-% \begin{verbatim}
-%   E{^_}{{UP}}
-% \end{verbatim}
-% has default \texttt{UP} for the |^| test token, but will return the
-% \cs{NoValue} marker as a default for |_|. This allows mixing of explicit
-% defaults with testing for missing values.
-%
 % \subsection{Argument processors}
 % \label{sec:processors}
 %
@@ -652,8 +689,8 @@
 %       to mix short and long argument types.
 %     \item The mandatory argument types \texttt{l} and \texttt{u} are
 %       not available.
-%     \item The \enquote{optional group} argument types \texttt{g} and
-%       \texttt{G} are not available.
+%     \item The optional argument types \texttt{g}
+%       and \texttt{G} are not available.
 %     \item The \enquote{verbatim} argument type \texttt{v} is not available.
 %     \item Argument processors (using \texttt{>}) are not available.
 %     \item It is not possible to differentiate between, for example
@@ -742,17 +779,6 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\c_@@_shorthands_prop}
-%   Shorthands are stored as a property list: this is set up here as it
-%   is a constant.
-%    \begin{macrocode}
-\prop_new:N \c_@@_shorthands_prop
-\prop_put:Nnn \c_@@_shorthands_prop { o } { d[] }
-\prop_put:Nnn \c_@@_shorthands_prop { O } { D[] }
-\prop_put:Nnn \c_@@_shorthands_prop { s } { t* }
-%    \end{macrocode}
-% \end{variable}
-%
 % \begin{variable}{\c_@@_special_chars_seq}
 %   In \IniTeX{} mode, we store special characters in a sequence.
 %   Maybe |$| or |&| will have to be added later.
@@ -774,6 +800,22 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\l_@@_all_long_set_bool}
+%   Whether \cs{l_@@_all_long_bool}'s value is fixed yet or not.  This
+%   is to deal with the case of leading \texttt{t}-type argument, whose
+%   \enquote{long} status should be ignored.
+%    \begin{macrocode}
+\bool_new:N \l_@@_all_long_set_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_arg_spec_tl}
+%   Holds the argument specification after normalization of shorthands.
+%    \begin{macrocode}
+\tl_new:N \l_@@_arg_spec_tl
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{variable}{\l_@@_args_tl}
 %   Token list variable for grabbed arguments.
 %    \begin{macrocode}
@@ -781,11 +823,12 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_command_arg_specs_prop}
-%   Used to record all document commands created, and the argument
-%   specifications that go with these.
+% \begin{variable}{\l_@@_args_i_tl, \l_@@_args_ii_tl}
+%   Hold the modified arguments when dealing with default values or
+%   processors.
 %    \begin{macrocode}
-\prop_new:N \l_@@_command_arg_specs_prop
+\tl_new:N \l_@@_args_i_tl
+\tl_new:N \l_@@_args_ii_tl
 %    \end{macrocode}
 % \end{variable}
 %
@@ -798,6 +841,17 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\l_@@_defaults_bool, \l_@@_defaults_tl}
+%   The boolean indicates whether there are any argument with default
+%   value; the token list holds the code to determine these default
+%   values in terms of other arguments, and dummy code for arguments
+%   that do not need a default.
+%    \begin{macrocode}
+\bool_new:N \l_@@_defaults_bool
+\tl_new:N \l_@@_defaults_tl
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{variable}{\l_@@_environment_bool}
 %   Generating environments uses the same mechanism as generating functions.
 %   However, full processing of arguments is always needed for environments,
@@ -807,14 +861,6 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_environment_arg_specs_prop}
-%   Used to record all document environment created, and the argument
-%   specifications that go with these.
-%    \begin{macrocode}
-\prop_new:N \l_@@_environment_arg_specs_prop
-%    \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.
@@ -837,6 +883,14 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\g_@@_grabber_int}
+%   Used (in exceptional cases) to get unique names for grabbers used by
+%   expandable commands.
+%    \begin{macrocode}
+\int_new:N \g_@@_grabber_int
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{variable}{\l_@@_fn_tl}
 %   For passing the pre-formed name of the auxiliary to be used as the
 %   parsing function.
@@ -845,6 +899,14 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\l_@@_fn_code_tl}
+%   For passing the pre-formed name of the auxiliary that contains the
+%   actual code.
+%    \begin{macrocode}
+\tl_new:N \l_@@_fn_code_tl
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{variable}{\l_@@_function_tl}
 %   Holds the control sequence name of the function currently being
 %   defined: used to avoid passing this as an argument and to avoid repeated
@@ -854,6 +916,17 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\l_@@_last_delimiters_tl}
+%   Holds the delimiters (first tokens) of all optional arguments since
+%   the previous mandatory argument, to warn about cases where it would
+%   be impossible to omit optional arguments completely because the
+%   following mandatory argument has the same delimiter as one of the
+%   optional arguments.
+%    \begin{macrocode}
+\tl_new:N \l_@@_last_delimiters_tl
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{variable}{\l_@@_long_bool}
 %   Used to indicate that an argument is long: this is used on a per-argument
 %   basis for non-expandable functions, or for the entire set of arguments
@@ -881,20 +954,25 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_processor_bool}
-%   Indicates that the current argument will be followed by one or more
-%   processors.
+% \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 |+|
+%   (namely is long).
 %    \begin{macrocode}
-\bool_new:N \l_@@_processor_bool
+\bool_new:N \l_@@_prefixed_bool
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_processor_int}
-%   In the grabber routine, each processor is saved with a number
-%   recording the order it was found in. The total is then used to work
-%   back through the grabbers so they apply to the argument right to left.
+% \begin{variable}{\l_@@_process_all_tl, \l_@@_process_one_tl, \l_@@_process_some_bool}
+%   When preparing the signature, the processors that will be applied to
+%   a given argument are collected in \cs{l_@@_process_one_tl}, while
+%   \cs{l_@@_process_all_tl} contains processors for all arguments.  The
+%   boolean indicates whether there are any processors (to bypass the
+%   whole endeavour otherwise).
 %    \begin{macrocode}
-\int_new:N \l_@@_processor_int
+\tl_new:N \l_@@_process_all_tl
+\tl_new:N \l_@@_process_one_tl
+\bool_new:N \l_@@_process_some_bool
 %    \end{macrocode}
 % \end{variable}
 %
@@ -901,6 +979,8 @@
 % \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.
+%   When arguments are grabbed (at point of use of the command/environment),
+%   it also stores the code for grabbing the remaining arguments.
 %    \begin{macrocode}
 \tl_new:N \l_@@_signature_tl
 %    \end{macrocode}
@@ -907,12 +987,15 @@
 % \end{variable}
 %
 % \begin{variable}{\l_@@_tmp_prop, \l_@@_tmpa_tl, \l_@@_tmpb_tl}
+% \begin{macro}{\@@_tmp:w}
 %   Scratch space.
 %    \begin{macrocode}
 \prop_new:N \l_@@_tmp_prop
 \tl_new:N \l_@@_tmpa_tl
 \tl_new:N \l_@@_tmpb_tl
+\cs_new_eq:NN \@@_tmp:w ?
 %    \end{macrocode}
+% \end{macro}
 % \end{variable}
 %
 % \subsection{Declaring commands and environments}
@@ -949,26 +1032,20 @@
         \__msg_kernel_info:nnxx { xparse } { define-command }
           { \token_to_str:N #1 } { \tl_to_str:n {#2} }
       }
-    \prop_put:Nnn \l_@@_command_arg_specs_prop {#1} {#2}
     \bool_set_false:N \l_@@_environment_bool
     \@@_declare_cmd_internal:Nnn #1 {#2}
   }
 %    \end{macrocode}
 %   The real business of defining a document command starts with setting up
-%   the appropriate name, then counting up the number of mandatory arguments.
+%   the appropriate name, then normalizing the argument specification to get rid of
+%   shorthands (this step also counts the number of mandatory arguments).
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_declare_cmd_internal:Nnn #1#2#3
   {
     \tl_set:Nx \l_@@_function_tl { \cs_to_str:N #1 }
-    \@@_count_mandatory:n {#2}
-    \@@_prepare_signature:n {#2}
-    \int_compare:nNnTF \l_@@_current_arg_int = \l_@@_m_args_int
-      {
-        \bool_if:NTF \l_@@_environment_bool
-          { \@@_declare_cmd_mixed:Nn #1 {#3} }
-          { \@@_declare_cmd_all_m:Nn #1 {#3} }
-      }
-      { \@@_declare_cmd_mixed:Nn #1 {#3} }
+    \@@_normalize_arg_spec:n {#2}
+    \exp_args:No \@@_prepare_signature:n \l_@@_arg_spec_tl
+    \@@_declare_cmd_code:Nnn #1 {#2} {#3}
     \@@_break_point:n {#2}
   }
 \cs_generate_variant:Nn \@@_declare_cmd_internal:Nnn { cnx }
@@ -984,69 +1061,68 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_declare_cmd_all_m:Nn, \@@_declare_cmd_mixed:Nn}
+% \begin{macro}{\@@_declare_cmd_code:Nnn}
 % \begin{macro}[aux]
-%   {\@@_declare_cmd_mixed_aux:Nn, \@@_declare_cmd_mixed_expandable:Nn}
-%   When all of the arguments to grab are simple \texttt{m}-type, a short
-%   cut can be taken to provide only a single function. In the case of
-%   expandable commands, this can also happen for \texttt{+m} (as all arguments
-%   in this case must be long).
+%   {\@@_declare_cmd_code_aux:Nnn, \@@_declare_cmd_code_expandable:Nnn}
+%   The appropriate auxiliary is called.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_declare_cmd_all_m:Nn #1#2
+\cs_new_protected:Npn \@@_declare_cmd_code:Nnn
   {
-    \cs_generate_from_arg_count:Ncnn #1
-      {
-        cs_set
-        \bool_if:NF \l_@@_expandable_bool { _protected }
-        \bool_if:NF \l_@@_all_long_bool { _nopar }
-        :Npn
-      }
-      \l_@@_current_arg_int {#2}
-  }
-%    \end{macrocode}
-%   In the case of mixed arguments, any remaining \texttt{m}-type ones are
-%   first added to the signature, then the appropriate auxiliary is called.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_declare_cmd_mixed:Nn
-  {
     \bool_if:NTF \l_@@_expandable_bool
-      { \@@_declare_cmd_mixed_expandable:Nn }
-      { \@@_declare_cmd_mixed_aux:Nn }
+      { \@@_declare_cmd_code_expandable:Nnn }
+      { \@@_declare_cmd_code_aux:Nnn }
    }
 %    \end{macrocode}
-%   Creating standard functions with mixed arg.~specs sets up the main function
-%   to zero the number of processors, set the name of the function (for the
-%   grabber) and clears the list of grabbed arguments.
+%   Standard functions call
+%   \cs{@@_start:nNNnnn}, which receives an auxiliary used for
+%   grabbing arguments, an auxiliary containing the code, and then the
+%   signature, default arguments, and processors.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_declare_cmd_mixed_aux:Nn #1#2
+\cs_new_protected:Npn \@@_declare_cmd_code_aux:Nnn #1#2#3
   {
-    \@@_flush_m_args:
     \cs_generate_from_arg_count:cNnn
       { \l_@@_function_tl \c_space_tl code }
-      \cs_set_protected:Npn \l_@@_current_arg_int {#2}
+      \cs_set_protected:Npn \l_@@_current_arg_int {#3}
     \cs_set_protected_nopar:Npx #1
       {
-        \int_zero:N \l_@@_processor_int
-        \tl_set:Nn \exp_not:N \l_@@_args_tl
-          { \exp_not:c { \l_@@_function_tl \c_space_tl code } }
-        \tl_set:Nn \exp_not:N \l_@@_fn_tl
-          { \exp_not:c { \l_@@_function_tl \c_space_tl } }
-        \exp_not:o \l_@@_signature_tl
-        \exp_not:N \l_@@_args_tl
+        \@@_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
+              { \exp_not:o \l_@@_defaults_tl }
+          }
+          {
+            \bool_if:NT \l_@@_process_some_bool
+              { \exp_not:o \l_@@_process_all_tl }
+          }
       }
   }
-\cs_new_protected:Npn \@@_declare_cmd_mixed_expandable:Nn #1#2
+\cs_new_protected:Npn \@@_declare_cmd_code_expandable:Nnn #1#2#3
   {
     \cs_generate_from_arg_count:cNnn
       { \l_@@_function_tl \c_space_tl code }
-      \cs_set:Npn \l_@@_current_arg_int {#2}
+      \cs_set:Npn \l_@@_current_arg_int {#3}
+    \bool_if:NT \l_@@_defaults_bool
+      {
+        \use:x
+          {
+            \cs_generate_from_arg_count:cNnn
+              { \l_@@_function_tl \c_space_tl defaults }
+              \cs_set:Npn \l_@@_current_arg_int
+              { \exp_not:o \l_@@_defaults_tl }
+          }
+      }
     \cs_set_nopar:Npx #1
       {
-        \exp_not:o \l_@@_signature_tl
-        \exp_not:N \@@_grab_expandable_end:wN
-        \exp_not:c { \l_@@_function_tl \c_space_tl code }
-        \exp_not:N \q_@@
-        \exp_not:c { \l_@@_function_tl \c_space_tl }
+        \exp_not:N \@@_start_expandable:nNNNn
+          { \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:c { \l_@@_function_tl \c_space_tl defaults }
+          { \exp_not:o \l_@@_signature_tl }
       }
     \bool_if:NTF \l_@@_all_long_bool
       { \cs_set:cpx }
@@ -1079,7 +1155,6 @@
         \__msg_kernel_info:nnxx { xparse } { define-environment }
           {#1} { \tl_to_str:n {#2} }
       }
-    \prop_put:Nnn \l_@@_environment_arg_specs_prop {#1} {#2}
     \bool_set_false:N \l_@@_expandable_bool
     \bool_set_true:N \l_@@_environment_bool
     \@@_declare_env_internal:nnnn {#1} {#2}
@@ -1100,7 +1175,7 @@
         \cs_set_nopar:Npx \exp_not:c { environment~ #1 ~end~aux }
           {
             \exp_not:N \exp_not:N \exp_not:c { environment~ #1~end~aux~ }
-            \exp_not:n { \tl_tail:N \l_@@_args_tl }
+            \exp_not:n { \exp_not:o \l_@@_args_tl }
           }
         \exp_not:n {#3}
       }
@@ -1118,154 +1193,549 @@
 % \end{macro}
 % \end{macro}
 %
-% \subsection{Counting mandatory arguments}
+% \subsection{Structure of \pkg{xparse} commands}
 %
-% \begin{macro}{\@@_count_mandatory:n}
-% \begin{macro}{\@@_count_mandatory:N}
-% \begin{macro}[aux]{\@@_count_mandatory:N}
-%   Loop through the signature to count up mandatory arguments before the
-%   main parsing run. First, check if the current token is a short-cut for
-%   another argument type. If it is, expand it and loop again. If not, then
-%   look for a \enquote{counting} function to check the argument type. No error
-%   is raised here if one is not found as one will be raised by later code.
+% \begin{macro}{\@@_start:nNNnnn}
+%   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.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_count_mandatory:n #1
+\cs_new_protected:Npn \@@_start:nNNnnn #1#2#3#4#5#6
   {
-    \int_zero:N \l_@@_mandatory_args_int
-    \@@_count_mandatory:N #1
-      \q_recursion_tail \q_recursion_tail \q_recursion_tail \q_recursion_stop
+    \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_@@_defaults_tl {#5}
+    \tl_set:Nn \l_@@_process_all_tl {#6}
+    #4 \@@_run_code:
   }
-\cs_new_protected:Npn \@@_count_mandatory:N #1
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_run_code:}
+%   After arguments are grabbed, this function is responsible for
+%   inserting default values, running processors, and finally running
+%   the code.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_run_code:
   {
-    \quark_if_recursion_tail_stop:N #1
-    \prop_get:NnNTF \c_@@_shorthands_prop {#1} \l_@@_tmpa_tl
-      { \exp_after:wN \@@_count_mandatory:N \l_@@_tmpa_tl }
-      { \@@_count_mandatory_aux:N #1 }
+    \tl_if_empty:NF \l_@@_defaults_tl { \@@_defaults: }
+    \tl_if_empty:NF \l_@@_process_all_tl { \@@_args_process: }
+    \exp_after:wN \l_@@_fn_code_tl \l_@@_args_tl
   }
-\cs_new_protected:Npn \@@_count_mandatory_aux:N #1
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_defaults:}
+% \begin{macro}[aux]{\@@_defaults_def:, \@@_defaults_def:nn, \@@_defaults_def:nnn, \@@_defaults_def_aux:nn}
+% \begin{macro}[aux]{\@@_defaults_aux:,  \@@_defaults_error:w}
+%   First construct \cs{@@_tmp:w} (see below) that will receive
+%   the arguments found so far and determine default values for any
+%   missing argument.  Then call it repeatedly until the set of
+%   arguments stabilizes.  Since that could lead to an infinite loop we
+%   only call it up to nine times, the maximal number needed for
+%   stabilization if there is a chain of arguments that depend on each
+%   other.  If that fails to stabilize raise an error.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_defaults:
   {
-    \cs_if_exist_use:cF { @@_count_type_ \token_to_str:N #1 :w }
-      { \@@_count_type_m:w }
+    \@@_defaults_def:
+    \tl_set_eq:NN \l_@@_args_i_tl \l_@@_args_tl
+    \@@_defaults_aux: \@@_defaults_aux: \@@_defaults_aux:
+    \@@_defaults_aux: \@@_defaults_aux: \@@_defaults_aux:
+    \@@_defaults_aux: \@@_defaults_aux: \@@_defaults_aux:
+    \@@_defaults_error:w
+    \q_recursion_stop
+    \tl_set_eq:NN \l_@@_args_tl \l_@@_args_i_tl
   }
+\cs_new_protected:Npn \@@_defaults_aux:
+  {
+    \tl_set:Nx \l_@@_args_ii_tl
+      { \exp_after:wN \@@_tmp:w \l_@@_args_i_tl }
+    \tl_if_eq:NNT \l_@@_args_ii_tl \l_@@_args_i_tl
+      { \use_none_delimit_by_q_recursion_stop:w }
+    \tl_set_eq:NN \l_@@_args_i_tl \l_@@_args_ii_tl
+  }
+\cs_new_protected:Npn \@@_defaults_error:w \q_recursion_stop
+  {
+    \__msg_kernel_error:nnx { xparse } { loop-in-defaults }
+      { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
+  }
 %    \end{macrocode}
+%   To construct \cs{@@_tmp:w}, first go through the arguments
+%   found and the corresponding defaults, building a token list with
+%   |{#|\meta{arg number}|}| for arguments found in the input (whose
+%   default will not be used) and otherwise
+%   |{|\cs{exp_not:n}\Arg{default}|}| for arguments whose default will
+%   be used.  The case of \texttt{E}-type arguments, detected by
+%   \cs{tl_if_head_is_group:nTF}, is special because we may need to
+%   partly use an argument found in the input and partly some default.
+%   This case is delayed until \cs{@@_tmp:w} is called: then we
+%   map through the original argument and its corresponding list of
+%   defaults; for each item (corresponding to one embellishment) if a
+%   value has already been found use it otherwise use the default.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_defaults_def:
+  {
+    \tl_clear:N \l_@@_tmpa_tl
+    \int_zero:N \l_@@_current_arg_int
+    \@@_tl_mapthread_function:NNN \l_@@_args_tl \l_@@_defaults_tl
+      \@@_defaults_def:nn
+    \cs_generate_from_arg_count:NNVo \@@_tmp:w \cs_set:Npn
+      \l_@@_current_arg_int \l_@@_tmpa_tl
+  }
+\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNVo }
+\cs_new_protected:Npn \@@_defaults_def:nn
+  {
+    \int_incr:N \l_@@_current_arg_int
+    \exp_args:NV \@@_defaults_def:nnn \l_@@_current_arg_int
+  }
+\cs_new_protected:Npn \@@_defaults_def:nnn #1#2#3
+  {
+    \tl_if_head_is_group:nTF {#3}
+      {
+        \tl_put_right:Nn \l_@@_tmpa_tl
+          {
+            {
+              \exp_args:Nf \@@_tl_mapthread_function:nnN
+                { \tl_item:Nn \l_@@_args_tl {#1} }
+                {#3}
+                \@@_defaults_def_aux:nn
+            }
+          }
+      }
+      {
+        \@@_if_no_value:nTF {#2}
+          {
+            \tl_put_right:Nx \l_@@_tmpa_tl
+              { { \exp_not:N \exp_not:n { \exp_not:o { \use_none:n #3 } } } }
+          }
+          {
+            \tl_put_right:Nn \l_@@_tmpa_tl
+              { { \exp_not:n { ## #1 } } }
+          }
+      }
+  }
+\cs_new:Npn \@@_defaults_def_aux:nn #1#2
+  {
+    \@@_if_no_value:nTF {#1}
+      { { \exp_not:n {#2} } }
+      { { \exp_not:n {#1} } }
+  }
+%    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\@@_args_process:}
+% \begin{macro}[aux]{\@@_args_process_loop:nn, \@@_args_process_aux:n, \@@_args_process_aux:nn}
+%   Loop through arguments (stored in \cs{l_@@_args_tl}) and the
+%   corresponding processors (in \cs{l_@@_process_all_tl})
+%   simultaneously, apply all processors for each argument and store the
+%   result back into \cs{l_@@_args_tl}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_args_process:
+  {
+    \tl_clear:N \l_@@_args_ii_tl
+    \@@_tl_mapthread_function:NNN
+      \l_@@_args_tl
+      \l_@@_process_all_tl
+      \@@_args_process_loop:nn
+    \tl_set_eq:NN \l_@@_args_tl \l_@@_args_ii_tl
+  }
+\cs_new_protected:Npn \@@_args_process_loop:nn #1#2
+  {
+    \tl_set:Nn \ProcessedArgument {#1}
+    \@@_if_no_value:nF {#1}
+      { \tl_map_function:nN {#2} \@@_args_process_aux:n }
+    \tl_put_right:No \l_@@_args_ii_tl
+      { \exp_after:wN { \ProcessedArgument } }
+  }
+\cs_new_protected:Npn \@@_args_process_aux:n
+  { \exp_args:No \@@_args_process_aux:nn { \ProcessedArgument } }
+\cs_new_protected:Npn \@@_args_process_aux:nn #1#2 { #2 {#1} }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_start_expandable:nNNNn}
+%   This is called for all expandable commands.  |#5| is the signature,
+%   responsible for grabbing arguments.  |#4| is used to determine
+%   default values.  |#3| is the code to run.
+%   |#2|~is a function (named after the command) that grabs a single
+%   argument in the input stream.  The argument specification |#1| is
+%   unused but used by diagnostic functions.
+%    \begin{macrocode}
+\cs_new:Npn \@@_start_expandable:nNNNn #1#2#3#4#5
+  { #5 \@@_end_expandable:NNw #4 #3 \q_@@ #2 }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_end_expandable:NNw}
+% \begin{macro}[EXP,aux]{\@@_end_expandable_aux:w}
+% \begin{macro}[EXP,aux]{\@@_end_expandable_aux:nNNN}
+% \begin{macro}[EXP,aux]{\@@_end_expandable_defaults:nnnNNn}
+% \begin{macro}[EXP,aux]{\@@_end_expandable_defaults:nnw}
+% \begin{macro}[EXP,aux]{\@@_end_expandable_defaults:nw}
+% \begin{macro}[EXP,aux]{\@@_end_expandable_defaults_E:nnw}
+%   Followed by a function |#1| to determine default values, the code
+%   |#2|, arguments that have been grabbed, then \cs{q_@@} and a generic
+%   grabber.  The idea to find default values is similar to the
+%   non-expandable case but we cannot define an auxiliary function, so
+%   at every step in the loop we need to go through all arguments
+%   searching for which ones started out as |-NoValue-| and replacing
+%   these by the newly computed values.  In fact we need to keep track
+%   of three versions of all arguments: the original version, the
+%   previous version with default values, and the currently built
+%   version (first argument of \cs{@@_end_expandable_defaults:nnnNNn}).
+%    \begin{macrocode}
+\cs_new:Npn \@@_end_expandable:NNw #1#2
+  { \@@_end_expandable_aux:w #1#2 \prg_do_nothing: }
+\cs_new:Npn \@@_end_expandable_aux:w #1#2#3 \q_@@ #4
+  { \exp_args:No \@@_end_expandable_aux:nNNN {#3} #1 #2 #4 }
+\cs_new:Npn \@@_end_expandable_aux:nNNN #1#2#3#4
+  {
+    \cs_if_exist:NF #2 { \exp_after:wN \use_iv:nnnn }
+    \@@_end_expandable_defaults:nnnNNn {#1} { } {#1} #2#3
+      { } { } { } { } { } { } { } { } { } { }
+      {
+        \__msg_kernel_expandable_error:nnn
+          { xparse } { loop-in-defaults } {#4}
+        \use_iv:nnnn
+      }
+    \q_stop
+  }
+\cs_new:Npn \@@_end_expandable_defaults:nnnNNn #1#2#3#4#5#6
+  {
+    #6
+    \str_if_eq:nnTF {#1} {#2}
+      { \use_i_delimit_by_q_stop:nw { #5 #1 } }
+      {
+        \exp_args:No \@@_tl_mapthread_function:nnN
+          { #4 #1 } {#3}
+          \@@_end_expandable_defaults:nnw
+        \@@_end_expandable_defaults:nnnNNn { } {#1} {#3} #4 #5
+      }
+  }
+\cs_new:Npn \@@_end_expandable_defaults:nnw #1#2
+  {
+    \tl_if_head_is_group:nTF {#1}
+      {
+        \@@_end_expandable_defaults_E:nnw { }
+          #1 \q_nil \q_mark
+          #2 \q_nil
+      }
+      {
+        \@@_if_no_value:nTF {#2}
+          { \exp_args:No \@@_end_expandable_defaults:nw { \use_none:n #1 } }
+          { \@@_end_expandable_defaults:nw {#2} }
+      }
+  }
+\cs_new:Npn \@@_end_expandable_defaults_E:nnw #1#2#3 \q_mark #4
+  {
+    \quark_if_nil:nTF {#2}
+      { \@@_end_expandable_defaults:nw {#1} }
+      {
+        \@@_if_no_value:nTF {#4}
+          { \@@_end_expandable_defaults_E:nnw { #1 {#2} } }
+          { \@@_end_expandable_defaults_E:nnw { #1 {#4} } }
+        #3 \q_mark
+      }
+  }
+\cs_new:Npn \@@_end_expandable_defaults:nw
+    #1#2 \@@_end_expandable_defaults:nnnNNn #3
+  { #2 \@@_end_expandable_defaults:nnnNNn { #3 {#1} } }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Normalizing the argument specifications}
+%
+% The goal here is to expand aliases and check that the argument
+% specification is valid before the main parsing run.  If it is not
+% valid the entire set up is abandoned to avoid any strange internal
+% errors.  A function is provided for each argument type that will grab
+% any extra arguments and call the loop function.
+%
+% The first thing that is done in the loop is to check that the various
+% argument types have the correct number of data items associated with
+% them.  The opportunity is also taken to make sure that where a single
+% token is required, one has actually been supplied.
+%
+% The second is that processors and the marker~|+| for long arguments
+% must be followed by arguments.
+%
+% The third is to check for forbidden types for expandable commands,
+% namely \texttt{g},
+% \texttt{G}, \texttt{l} (as the next left brace may have been inserted
+% by \pkg{xparse} due to a failed search for an optional argument),
+% \texttt{u} (any preceding optional argument may wrap part of the
+% delimiter up in braces), and \texttt{v}.
+%
+% The fourth is that an optional argument should not be followed by a
+% mandatory argument with the same delimiter, as otherwise the optional
+% argument could never be omitted.
+%
+% The last is to count mandatory arguments.
+%
+% \begin{macro}{\@@_normalize_arg_spec:n}
+% \begin{macro}{\@@_normalize_arg_spec_loop:n}
+%   Loop through the argument specification, calling an auxiliary
+%   specific to each argument type.  If any argument is unknown stop the
+%   definition.  After the loop, if there are more than
+%   $9$ arguments, stop.  Additionally, expandable commands may not end
+%   with an optional argument; this case is detected by using the fact
+%   that \cs{l_@@_last_delimiters_tl} is cleared by every mandatory
+%   argument and filled by every optional argument.
+%    \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
+    \@@_normalize_arg_spec_loop:n #1
+      \q_recursion_tail \q_recursion_tail \q_recursion_tail \q_recursion_stop
+    \int_compare:nNnT \l_@@_current_arg_int > 9
+      {
+        \__msg_kernel_error:nnxx { xparse } { too-many-arguments }
+          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+        \@@_bad_def:wn
+      }
+    \bool_if:NT \l_@@_expandable_bool
+      {
+        \tl_if_empty:NF \l_@@_last_delimiters_tl
+          {
+            \__msg_kernel_error:nnxx { xparse } { expandable-ending-optional }
+              { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+            \@@_bad_def:wn
+          }
+      }
+  }
+\cs_new_protected:Npn \@@_normalize_arg_spec_loop:n #1
+  {
+    \quark_if_recursion_tail_stop:n {#1}
+    \int_incr:N \l_@@_current_arg_int
+    \cs_if_exist_use:cF { @@_normalize_type_ \tl_to_str:n {#1} :w }
+      {
+        \__msg_kernel_error:nnxx { xparse } { unknown-argument-type }
+          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+        \@@_bad_def:wn
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \begin{macro}
 %   {
-%     \@@_count_type_>:w,
-%     \@@_count_type_+:w,
-%     \@@_count_type_d:w,
-%     \@@_count_type_D:w,
-%     \@@_count_type_e:w,
-%     \@@_count_type_E:w,
-%     \@@_count_type_g:w,
-%     \@@_count_type_G:w,
-%     \@@_count_type_m:w,
-%     \@@_count_type_r:w,
-%     \@@_count_type_R:w,
-%     \@@_count_type_t:w,
-%     \@@_count_type_u:w
+%     \@@_normalize_type_d:w,
+%     \@@_normalize_type_e:w,
+%     \@@_normalize_type_g:w,
+%     \@@_normalize_type_o:w,
+%     \@@_normalize_type_O:w,
+%     \@@_normalize_type_r:w,
+%     \@@_normalize_type_s:w,
 %   }
-%   For counting the mandatory arguments, a function is provided for each
-%   argument type that will mop any extra arguments and call the loop function.
-%   Only the counting functions for mandatory arguments actually do anything:
-%   the rest are simply there to ensure the loop continues correctly. There are
-%   no count functions for \texttt{l} or \texttt{v} argument types as they are
-%   exactly the same as \texttt{m}, and so a little code can be saved.
+%   These argument types are aliases of more general ones, for example
+%   with the default argument |-NoValue-|.  To easily insert that marker
+%   expanded in the definitions we call \cs{@@_tmp:w} with the argument
+%   |-NoValue-|.  For argument types that need additional data, check
+%   that that data is present (not \cs{q_recursion_tail}) before
+%   proceeding.
+%    \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+  {
+    \cs_new_protected:Npn \@@_normalize_type_d:w ##1##2
+      {
+        \quark_if_recursion_tail_stop_do:nn {##2} { \@@_bad_arg_spec:wn }
+        \@@_normalize_type_D:w {##1} {##2} {#1}
+      }
+    \cs_new_protected:Npn \@@_normalize_type_e:w ##1
+      {
+        \quark_if_recursion_tail_stop_do:nn {##1} { \@@_bad_arg_spec:wn }
+        \@@_normalize_type_E:w {##1} { }
+      }
+    \cs_new_protected:Npn \@@_normalize_type_g:w
+      { \@@_normalize_type_G:w {#1} }
+    \cs_new_protected:Npn \@@_normalize_type_o:w
+      { \@@_normalize_type_D:w [ ] {#1} }
+    \cs_new_protected:Npn \@@_normalize_type_O:w
+      { \@@_normalize_type_D:w [ ] }
+    \cs_new_protected:Npn \@@_normalize_type_r:w ##1##2
+      {
+        \quark_if_recursion_tail_stop_do:nn {##2} { \@@_bad_arg_spec:wn }
+        \@@_normalize_type_R:w {##1} {##2} {#1}
+      }
+    \cs_new_protected:Npn \@@_normalize_type_s:w
+      { \@@_normalize_type_t:w * }
+  }
+\exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
+%    \end{macrocode}
+% \end{macro}
 %
-%   The second thing that can be done here is to check that the signature is
-%   actually valid, such that all of the various argument types have the
-%   correct number of data items associated with them.  If this fails to be
-%   the case, the entire set up is abandoned to avoid any strange internal
-%   errors. The opportunity is also taken to make sure that where a single
-%   token is required, one has actually been supplied.
-%
-%   The third is that processors and the marker~|+| for long arguments
-%   must be followed by arguments.  For this, just check that the next
-%   token is not \cs{q_recursion_tail}, and remember to leave it after
-%   the looping macro.
+% \begin{macro}
+%   {
+%     \@@_normalize_type_>:w,
+%     \@@_normalize_type_+:w,
+%   }
+%   Check that these prefixes have arguments, namely that the next token
+%   is not \cs{q_recursion_tail}, and remember to leave it after the
+%   looping macro.  Processors are forbidden in expandable commands.
+%   If all is good, store the prefix in the cleaned up
+%   \cs{l_@@_arg_spec_tl}, and decrement the argument number as prefixes
+%   do not correspond to arguments.
 %    \begin{macrocode}
-\cs_new_protected:cpn { @@_count_type_>:w } #1#2
+\cs_new_protected:cpn { @@_normalize_type_>:w } #1#2
   {
     \quark_if_recursion_tail_stop_do:nn {#2} { \@@_bad_arg_spec:wn }
-    \@@_count_mandatory:N #2
+    \bool_if:NT \l_@@_expandable_bool
+      {
+        \__msg_kernel_error:nnxx { xparse } { processor-in-expandable }
+          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+        \@@_bad_def:wn
+      }
+    \tl_put_right:Nn \l_@@_arg_spec_tl { > {#1} }
+    \int_decr:N \l_@@_current_arg_int
+    \@@_normalize_arg_spec_loop:n {#2}
   }
-\cs_new_protected:cpn { @@_count_type_+:w } #1
+\cs_new_protected:cpn { @@_normalize_type_+:w } #1
   {
     \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
-    \@@_count_mandatory:N #1
+    \tl_put_right:Nn \l_@@_arg_spec_tl { + }
+    \int_decr:N \l_@@_current_arg_int
+    \@@_normalize_arg_spec_loop:n {#1}
   }
-\cs_new_protected:Npn \@@_count_type_d:w #1#2
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \@@_normalize_type_D:w,
+%     \@@_normalize_type_E:w,
+%     \@@_normalize_type_G:w,
+%     \@@_normalize_type_t:w,
+%   }
+%   Optional argument types.  Check that all required data is present
+%   (and consists of single tokens if applicable) and check for
+%   forbidden types for expandable commands.  For \texttt{E}-type
+%   require that there is at least one embellishment, that each one is a
+%   single token, and that there aren't more optional arguments than
+%   embellishments.  Then store the data in \cs{l_@@_arg_spec_tl}, and
+%   for later checks store in \cs{l_@@_last_delimiters_tl} the tokens
+%   whose presence determines whether there is an optional argument (for
+%   braces store |{}|, seen later as an empty delimiter).
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_normalize_type_D:w #1#2#3
   {
     \@@_single_token_check:n {#1}
     \@@_single_token_check:n {#2}
-    \quark_if_recursion_tail_stop_do:Nn #2 { \@@_bad_arg_spec:wn }
-    \@@_count_mandatory:N
+    \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn }
+    \tl_put_right:Nn \l_@@_arg_spec_tl { D #1 #2 {#3} }
+    \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
+    \@@_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \@@_count_type_D:w #1#2#3
+\cs_new_protected:Npn \@@_normalize_type_E:w #1#2
   {
-    \@@_single_token_check:n {#1}
-    \@@_single_token_check:n {#2}
-    \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn }
-    \@@_count_mandatory:N
+    \quark_if_recursion_tail_stop_do:nn {#2} { \@@_bad_arg_spec:wn }
+    \tl_if_blank:nT {#1} { \@@_bad_arg_spec:wn }
+    \tl_map_function:nN {#1} \@@_single_token_check:n
+    \int_compare:nNnT { \tl_count:n {#2} } > { \tl_count:n {#1} }
+      { \@@_bad_arg_spec:wn }
+    \tl_put_right:Nn \l_@@_arg_spec_tl { E {#1} {#2} }
+    \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
+    \@@_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \@@_count_type_e:w #1
+\cs_new_protected:Npn \@@_normalize_type_G:w #1
   {
     \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
-    \@@_count_mandatory:N
+    \@@_normalize_error_if_expandable:N G
+    \tl_put_right:Nn \l_@@_arg_spec_tl { G {#1} }
+    \tl_put_right:Nn \l_@@_last_delimiters_tl { { } }
+    \@@_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \@@_count_type_E:w #1#2
+\cs_new_protected:Npn \@@_normalize_type_t:w #1
   {
-    \quark_if_recursion_tail_stop_do:nn {#2} { \@@_bad_arg_spec:wn }
-    \@@_count_mandatory:N
+    \@@_single_token_check:n {#1}
+    \quark_if_recursion_tail_stop_do:Nn #1 { \@@_bad_arg_spec:wn }
+    \tl_put_right:Nn \l_@@_arg_spec_tl { t #1 }
+    \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
+    \@@_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \@@_count_type_g:w
-  { \@@_count_mandatory:N }
-\cs_new_protected:Npn \@@_count_type_G:w #1
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \@@_normalize_type_l:w,
+%     \@@_normalize_type_m:w,
+%     \@@_normalize_type_R:w,
+%     \@@_normalize_type_u:w
+%     \@@_normalize_type_v:w
+%   }
+%   Mandatory arguments.  First check the required data is present,
+%   consists of single tokens where applicable, and that the argument
+%   type is allowed for expandable commands if applicable.  For the
+%   \texttt{m} and \texttt{R} argument types check that they do not
+%   follow some optional argument with that delimiter as otherwise the
+%   optional argument could not be omitted.  Then save data in
+%   \cs{l_@@_arg_spec_tl}, count the mandatory argument, and empty the
+%   list of last delimiters.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_normalize_type_l:w
   {
-    \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
-    \@@_count_mandatory:N
-  }
-\cs_new_protected:Npn \@@_count_type_m:w
-  {
+    \@@_normalize_error_if_expandable:N l
+    \tl_put_right:Nn \l_@@_arg_spec_tl { l }
     \int_incr:N \l_@@_mandatory_args_int
-    \@@_count_mandatory:N
+    \tl_clear:N \l_@@_last_delimiters_tl
+    \@@_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \@@_count_type_r:w #1#2
+\cs_new_protected:Npn \@@_normalize_type_m:w
   {
-    \@@_single_token_check:n {#1}
-    \@@_single_token_check:n {#2}
-    \quark_if_recursion_tail_stop_do:Nn #2 { \@@_bad_arg_spec:wn }
+    \@@_delimiter_check:nnn { } { m } { \iow_char:N \{ }
+    \tl_put_right:Nn \l_@@_arg_spec_tl { m }
     \int_incr:N \l_@@_mandatory_args_int
-    \@@_count_mandatory:N
+    \tl_clear:N \l_@@_last_delimiters_tl
+    \@@_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \@@_count_type_R:w #1#2#3
+\cs_new_protected:Npn \@@_normalize_type_R:w #1#2#3
   {
     \@@_single_token_check:n {#1}
     \@@_single_token_check:n {#2}
     \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn }
+    \@@_delimiter_check:nnn {#1} { R/r } { \tl_to_str:n {#1} }
+    \tl_put_right:Nn \l_@@_arg_spec_tl { R #1 #2 {#3} }
     \int_incr:N \l_@@_mandatory_args_int
-    \@@_count_mandatory:N
+    \tl_clear:N \l_@@_last_delimiters_tl
+    \@@_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \@@_count_type_t:w #1
+\cs_new_protected:Npn \@@_normalize_type_u:w #1
   {
-    \@@_single_token_check:n {#1}
-    \quark_if_recursion_tail_stop_do:Nn #1 { \@@_bad_arg_spec:wn }
-    \@@_count_mandatory:N
+    \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
+    \@@_normalize_error_if_expandable:N u
+    \tl_put_right:Nn \l_@@_arg_spec_tl { u {#1} }
+    \int_incr:N \l_@@_mandatory_args_int
+    \tl_clear:N \l_@@_last_delimiters_tl
+    \@@_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \@@_count_type_u:w #1
+\cs_new_protected:Npn \@@_normalize_type_v:w
   {
-    \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
+    \@@_normalize_error_if_expandable:N v
+    \tl_put_right:Nn \l_@@_arg_spec_tl { v }
     \int_incr:N \l_@@_mandatory_args_int
-    \@@_count_mandatory:N
+    \tl_clear:N \l_@@_last_delimiters_tl
+    \@@_normalize_arg_spec_loop:n
   }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}{\@@_single_token_check:n}
-% \begin{macro}[aux]{\@@_single_token_check_aux:nwn}
 %   A spin-out function to check that what should be single tokens really
 %   are single tokens.
 %    \begin{macrocode}
@@ -1272,24 +1742,61 @@
 \cs_new_protected:Npn \@@_single_token_check:n #1
   {
     \exp_args:Nx \tl_if_single_token:nF { \tl_trim_spaces:n {#1} }
-      { \@@_single_token_check_aux:nwn {#1} }
+      {
+        \__msg_kernel_error:nnxx { xparse } { not-single-token }
+          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+        \@@_bad_def:wn
+      }
   }
-\cs_new_protected:Npn \@@_single_token_check_aux:nwn
-  #1#2 \@@_break_point:n #3
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_normalize_error_if_expandable:N}
+%   Called for arguments that are forbidden for expandable commands.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_normalize_error_if_expandable:N #1
   {
-    \__msg_kernel_error:nnx { xparse } { not-single-token }
-      { \tl_to_str:n {#1} } { \tl_to_str:n {#3} }
+    \bool_if:NT \l_@@_expandable_bool
+      {
+        \__msg_kernel_error:nnxx
+          { xparse } { invalid-expandable-argument-type }
+          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+        \@@_bad_def:wn
+      }
   }
 %    \end{macrocode}
 % \end{macro}
+%
+% \begin{macro}{\@@_delimiter_check:nnn}
+%   Called for \texttt{m} and \texttt{R} arguments.  Checks that the
+%   leading token does not coincide with the token denoting the presence
+%   of a previous optional argument.  Instead of dealing with braces for
+%   the \texttt{m}-type we use an empty delimiter to denote that case.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_delimiter_check:nnn #1#2#3
+  {
+    \tl_map_inline:Nn \l_@@_last_delimiters_tl
+      {
+        \tl_if_eq:nnT {##1} {#1}
+          {
+            \__msg_kernel_warning:nnxx { xparse } { optional-mandatory }
+              {#2} {#3}
+          }
+      }
+  }
+%    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_bad_arg_spec:wn}
-%   If the signature is wrong, this provides an escape from the entire
+% \begin{macro}{\@@_bad_arg_spec:wn, \@@_bad_def:wn}
+%   If the argument specification is wrong, this provides an escape from the entire
 %   definition process.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_bad_arg_spec:wn #1 \@@_break_point:n #2
-  { \__msg_kernel_error:nnx { xparse } { bad-arg-spec } { \tl_to_str:n {#2} } }
+  {
+    \__msg_kernel_error:nnxx { xparse } { bad-arg-spec }
+      { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#2} }
+  }
+\cs_new_protected:Npn \@@_bad_def:wn #1 \@@_break_point:n #2 { }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1298,20 +1805,26 @@
 % \begin{macro}{\@@_prepare_signature:n}
 % \begin{macro}{\@@_prepare_signature:N}
 % \begin{macro}{\@@_prepare_signature_bypass:N}
-% \begin{macro}[aux]{\@@_prepare_signature_add:N}
 %   Actually creating the signature uses the same loop approach as counting
 %   up mandatory arguments. There are first a number of variables which need
-%   to be set to track what is going on.
+%   to be set to track what is going on. Many of these variables are unused
+%   when defining expandable commands.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_prepare_signature:n #1
   {
     \bool_set_false:N \l_@@_all_long_bool
+    \bool_set_false:N \l_@@_all_long_set_bool
     \int_zero:N \l_@@_current_arg_int
     \bool_set_false:N \l_@@_long_bool
     \int_zero:N \l_@@_m_args_int
-    \bool_set_false:N \l_@@_processor_bool
+    \bool_set_false:N \l_@@_defaults_bool
+    \tl_clear:N \l_@@_defaults_tl
+    \tl_clear:N \l_@@_process_all_tl
+    \tl_clear:N \l_@@_process_one_tl
+    \bool_set_false:N \l_@@_process_some_bool
     \tl_clear:N \l_@@_signature_tl
     \@@_prepare_signature:N #1 \q_recursion_tail \q_recursion_stop
+    \bool_if:NF \l_@@_expandable_bool { \@@_flush_m_args: }
   }
 %    \end{macrocode}
 %  The main looping function does not take an argument, but carries out the
@@ -1318,49 +1831,32 @@
 %  reset on the processor boolean. This is split off from the rest of the
 %  process so that when actually setting up processors the flag-reset can
 %  be bypassed.
+%
+%  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.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_prepare_signature:N
   {
-    \bool_set_false:N \l_@@_processor_bool
+    \bool_set_false:N \l_@@_prefixed_bool
     \@@_prepare_signature_bypass:N
   }
 \cs_new_protected:Npn \@@_prepare_signature_bypass:N #1
   {
     \quark_if_recursion_tail_stop:N #1
-    \prop_get:NnNTF \c_@@_shorthands_prop {#1} \l_@@_tmpa_tl
-      { \exp_after:wN \@@_prepare_signature:N \l_@@_tmpa_tl }
+    \int_incr:N \l_@@_current_arg_int
+    \use:c
       {
-        \int_incr:N \l_@@_current_arg_int
-        \@@_prepare_signature_add:N #1
-      }
-  }
-%    \end{macrocode}
-%  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.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_prepare_signature_add:N #1
-  {
-    \cs_if_exist_use:cF
-      {
          @@_add
          \bool_if:NT \l_@@_expandable_bool { _expandable }
          _type_  \token_to_str:N #1 :w
       }
-      {
-        \__msg_kernel_error:nnx { xparse } { unknown-argument-type }
-          { \token_to_str:N #1 }
-        \bool_if:NTF \l_@@_expandable_bool
-          { \@@_add_expandable_type_m:w }
-          { \@@_add_type_m:w }
-      }
   }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
-% \end{macro}
 %
 % \subsection{Setting up a standard signature}
 %
@@ -1369,7 +1865,9 @@
 % \texttt{m} arguments.  These are collected and added to the signature
 % all at once by \cs{@@_flush_m_args:}, called for every other argument
 % type.  All of the functions then call the loop function
-% \cs{@@_prepare_signature:N}.
+% \cs{@@_prepare_signature:N}.  Default values of arguments are
+% collected by \cs{@@_add_default:n} rather than being stored with the
+% argument.
 %
 % \begin{macro}{\@@_add_type_+:w}
 %   Making the next argument long means setting the flag and knocking one back
@@ -1380,74 +1878,59 @@
   {
     \@@_flush_m_args:
     \bool_set_true:N \l_@@_long_bool
+    \bool_set_true:N \l_@@_prefixed_bool
     \int_decr:N \l_@@_current_arg_int
-    \@@_prepare_signature:N
+    \@@_prepare_signature_bypass:N
   }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}{\@@_add_type_>:w}
-%   When a processor is found, the function \cs{@@_process_arg:n} is added
-%   to the signature along with the processor code itself. When the signature
-%   is used, the code will be added to an execution list by
-%   \cs{@@_process_arg:n}. Here, the loop calls
-%   \cs{@@_prepare_signature_bypass:N} rather than
+%   When a processor is found, the processor code is stored.  It will be
+%   used by \cs{@@_args_process:} once arguments are all found. Here,
+%   the loop calls \cs{@@_prepare_signature_bypass:N} rather than
 %   \cs{@@_prepare_signature:N} so that the flag is not reset.
 %    \begin{macrocode}
 \cs_new_protected:cpn { @@_add_type_>:w } #1
   {
     \@@_flush_m_args:
-    \bool_set_true:N \l_@@_processor_bool
+    \bool_set_true:N \l_@@_prefixed_bool
+    \bool_set_true:N \l_@@_process_some_bool
     \int_decr:N \l_@@_current_arg_int
-    \tl_put_right:Nn \l_@@_signature_tl { \@@_process_arg:n {#1} }
+    \tl_put_right:Nn \l_@@_process_one_tl { {#1} }
     \@@_prepare_signature_bypass:N
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_type_d:w, \@@_add_type_D:w}
-%   To save on repeated code, \texttt{d} is actually turned into the same
-%   grabber as is used by \texttt{D}, by putting the |-NoValue-| default in
-%   the correct place.
+% \begin{macro}{\@@_add_type_D:w}
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_type_d:w #1#2
-  { \exp_args:NNNo \@@_add_type_D:w #1 #2 \c_@@_no_value_tl }
 \cs_new_protected:Npn \@@_add_type_D:w #1#2#3
   {
     \@@_flush_m_args:
+    \@@_add_default:n {#3}
     \@@_add_grabber_optional:N D
-    \tl_put_right:Nn \l_@@_signature_tl { #1 #2 {#3} }
+    \tl_put_right:Nn \l_@@_signature_tl { #1 #2 }
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_type_e:w, \@@_add_type_E:w}
-%   Setting up for the \texttt{e}-type argument is somewhat specialised as
-%   the |-NoValue-| tokens are inserted by the grabber rather than here. As
-%   such, all that is needed is to pass data straight through.
+% \begin{macro}{\@@_add_type_E:w}
+%   The \texttt{E}-type argument needs a special handling of default
+%   values.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_type_e:w #1
-  { \@@_add_type_E:w {#1} { } }
 \cs_new_protected:Npn \@@_add_type_E:w #1#2
   {
     \@@_flush_m_args:
+    \@@_add_default_E:nn {#1} {#2}
     \@@_add_grabber_optional:N E
-    \tl_put_right:Nn \l_@@_signature_tl { {#1} {#2} }
+    \tl_put_right:Nn \l_@@_signature_tl { {#1} }
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_type_g:w}
-%   The \texttt{g} type is simply an alias for \texttt{G} with the correct
-%   default built-in.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_type_g:w
-  { \exp_args:No \@@_add_type_G:w \c_@@_no_value_tl }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_add_type_G:w}
 %   For the \texttt{G} type, the grabber and the default are added to the
 %   signature.
@@ -1455,8 +1938,8 @@
 \cs_new_protected:Npn \@@_add_type_G:w #1
   {
     \@@_flush_m_args:
+    \@@_add_default:n {#1}
     \@@_add_grabber_optional:N G
-    \tl_put_right:Nn \l_@@_signature_tl { {#1} }
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
@@ -1469,6 +1952,7 @@
 \cs_new_protected:Npn \@@_add_type_l:w
   {
     \@@_flush_m_args:
+    \@@_add_default:
     \@@_add_grabber_mandatory:N l
     \@@_prepare_signature:N
   }
@@ -1485,11 +1969,9 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_add_type_m:w
   {
-    \bool_if:nTF { \l_@@_long_bool || \l_@@_processor_bool }
-      {
-        \@@_flush_m_args:
-        \@@_add_grabber_mandatory:N m
-      }
+    \@@_add_default:
+    \bool_if:NTF \l_@@_prefixed_bool
+      { \@@_add_grabber_mandatory:N m }
       { \int_incr:N \l_@@_m_args_int }
     \@@_prepare_signature:N
   }
@@ -1496,17 +1978,15 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_type_r:w, \@@_add_type_R:w}
-%   The \texttt{r}- and \texttt{R}-type arguments are very similar to the
-%   \texttt{d}- and \texttt{D}-types.
+% \begin{macro}{\@@_add_type_R:w}
+%   The \texttt{R}-type argument is very similar to the \texttt{D}-type.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_type_r:w #1#2
-  { \exp_args:NNNo \@@_add_type_R:w #1 #2 \c_@@_no_value_tl }
 \cs_new_protected:Npn \@@_add_type_R:w #1#2#3
   {
     \@@_flush_m_args:
+    \@@_add_default:n {#3}
     \@@_add_grabber_mandatory:N R
-    \tl_put_right:Nn \l_@@_signature_tl { #1 #2 {#3} }
+    \tl_put_right:Nn \l_@@_signature_tl { #1 #2 }
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
@@ -1519,6 +1999,7 @@
 \cs_new_protected:Npn \@@_add_type_t:w #1
   {
     \@@_flush_m_args:
+    \@@_add_default:
     \@@_add_grabber_optional:N t
     \tl_put_right:Nn \l_@@_signature_tl {#1}
     \@@_prepare_signature:N
@@ -1533,6 +2014,7 @@
 \cs_new_protected:Npn \@@_add_type_u:w #1
   {
     \@@_flush_m_args:
+    \@@_add_default:
     \@@_add_grabber_mandatory:N u
     \tl_put_right:Nn \l_@@_signature_tl { {#1} }
     \@@_prepare_signature:N
@@ -1541,11 +2023,14 @@
 % \end{macro}
 %
 % \begin{macro}{\@@_add_type_v:w}
-%   At this stage, the \texttt{v} argument is identical to \texttt{l}.
+%   At this stage, the \texttt{v} argument is identical to \texttt{l}
+%   except that since the grabber may fail to read a verbatim argument
+%   we need a default value.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_add_type_v:w
   {
     \@@_flush_m_args:
+    \exp_args:No \@@_add_default:n \c_@@_no_value_tl
     \@@_add_grabber_mandatory:N v
     \@@_prepare_signature:N
   }
@@ -1567,6 +2052,8 @@
         \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 } { { } } }
       }
     \int_zero:N \l_@@_m_args_int
   }
@@ -1590,6 +2077,9 @@
           { @@_grab_ #1 \bool_if:NT \l_@@_long_bool { _long } :w }
       }
     \bool_set_false:N \l_@@_long_bool
+    \tl_put_right:Nx \l_@@_process_all_tl
+      { { \exp_not:o \l_@@_process_one_tl } }
+    \tl_clear:N \l_@@_process_one_tl
     \int_decr:N \l_@@_mandatory_args_int
   }
 \cs_new_protected:Npn \@@_add_grabber_optional:N #1
@@ -1606,30 +2096,68 @@
           }
       }
     \bool_set_false:N \l_@@_long_bool
+    \tl_put_right:Nx \l_@@_process_all_tl
+      { { \exp_not:o \l_@@_process_one_tl } }
+    \tl_clear:N \l_@@_process_one_tl
   }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\@@_add_default:n, \@@_add_default:, \@@_add_default_E:nn}
+% \begin{macro}[aux]{\@@_add_default_E_aux:n}
+%   Store the default value of an argument, or rather code that gives
+%   that default value (it may involve other arguments).  Defaults are
+%   always stored with a leading |.| except for \texttt{E}-type
+%   arguments, to distinguish them.  For \texttt{E}-type arguments, pad
+%   the defaults |#2| with some |{-NoValue-}| until there are the same
+%   numbers as embellishments~|#1|.  Then for technical reasons make
+%   sure the first default is wrapped in braces.  These functions are
+%   also used when defining expandable commands.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_default:n #1
+  {
+    \bool_set_true:N \l_@@_defaults_bool
+    \tl_put_right:Nn \l_@@_defaults_tl { { . #1} }
+  }
+\cs_new_protected:Npn \@@_add_default:
+  { \tl_put_right:Nn \l_@@_defaults_tl { . } }
+\cs_new_protected:Npn \@@_add_default_E:nn #1#2
+  {
+    \bool_set_true:N \l_@@_defaults_bool
+    \tl_set:Nx \l_@@_tmpa_tl
+      {
+        \exp_not:n {#2}
+        \prg_replicate:nn
+          { \tl_count:n {#1} - \tl_count:n {#2} }
+          { { \c_@@_no_value_tl } }
+      }
+    \tl_put_right:Nx \l_@@_defaults_tl
+      {
+        {
+          \exp_not:f
+            { \exp_after:wN \@@_add_default_E_aux:n \l_@@_tmpa_tl }
+        }
+      }
+  }
+\cs_new:Npn \@@_add_default_E_aux:n #1 { {#1} }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Setting up expandable types}
 %
-% The approach here is not dissimilar to that for standard types, although
-% types which are not supported in expandable functions give an error. There is
+% The approach here is not dissimilar to that for standard types, but fewer types
+% are supported. There is
 % also a need to define the per-function auxiliaries: this is done here, while
 % the general grabbers are dealt with later.
 %
 % \begin{macro}{\@@_add_expandable_type_+:w}
-%   Check that a plus is given only if it occurs for every argument.
+%   ^^A todo
 %    \begin{macrocode}
 \cs_new_protected:cpn { @@_add_expandable_type_+:w }
   {
     \bool_set_true:N \l_@@_long_bool
-    \int_compare:nNnTF \l_@@_current_arg_int = \c_one
-      { \bool_set_true:N \l_@@_all_long_bool }
-      {
-        \bool_if:NF \l_@@_all_long_bool
-          { \__msg_kernel_error:nn { xparse } { inconsistent-long } }
-      }
     \int_decr:N \l_@@_current_arg_int
     \@@_prepare_signature:N
   }
@@ -1636,79 +2164,56 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_expandable_type_>:w}
-%   No processors in expandable arguments, so this issues an error.
-%    \begin{macrocode}
-\cs_new_protected:cpn { @@_add_expandable_type_>:w } #1
-  {
-    \__msg_kernel_error:nnx { xparse } { processor-in-expandable }
-      { \token_to_str:c { \l_@@_function_tl } }
-    \int_decr:N \l_@@_current_arg_int
-    \@@_prepare_signature:N
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_add_expandable_type_d:w}
 % \begin{macro}{\@@_add_expandable_type_D:w}
-% \begin{macro}{\@@_add_expandable_type_D_aux:NNn}
-% \begin{macro}{\@@_add_expandable_type_D_aux:Nn}
-%   The set up for \texttt{d}- and \texttt{D}-type arguments is the same,
-%   and involves constructing a rather complex auxiliary which is used
+% \begin{macro}{\@@_add_expandable_type_D_aux:NNNn}
+% \begin{macro}{\@@_add_expandable_type_D_aux:NNN}
+% \begin{macro}{\@@_add_expandable_type_D_aux:NN}
+%   The set up for \texttt{D}-type arguments involves constructing a
+%   rather complex auxiliary which is used
 %   repeatedly when grabbing. There is an auxiliary here so that the
-%   \texttt{R}-type can share code readily.
+%   \texttt{R}-type can share code readily: |#1| is |D| or~|R|.
+%   The |_aux:NN| auxiliary is needed if the two delimiting tokens are
+%   identical: in contrast to the non-expandable route, the grabber here
+%   has to act differently for this case.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_d:w #1#2
+\cs_new_protected:Npn \@@_add_expandable_type_D:w
+  { \@@_add_expandable_type_D_aux:NNNn D }
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNNn #1#2#3#4
   {
-    \exp_args:NNNo
-      \@@_add_expandable_type_D:w #1 #2 \c_@@_no_value_tl
+    \@@_add_default:n {#4}
+    \tl_if_eq:nnTF {#2} {#3}
+      { \@@_add_expandable_type_D_aux:NN #1 #2 }
+      { \@@_add_expandable_type_D_aux:NNN #1 #2 #3 }
+    \bool_set_false:N \l_@@_long_bool
+    \@@_prepare_signature:N
   }
-\cs_new_protected:Npn \@@_add_expandable_type_D:w #1#2
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNN #1#2#3
   {
-    \tl_if_eq:nnTF {#1} {#2}
-      {
-        \@@_add_expandable_grabber_optional:n { D_alt }
-        \@@_add_expandable_type_D_aux:Nn #1
-      }
-      {
-        \@@_add_expandable_grabber_optional:n { D }
-        \@@_add_expandable_type_D_aux:NNn #1#2
-      }
-  }
-\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNn #1#2#3
-  {
+    \@@_add_expandable_grabber:n {#1}
     \bool_if:NTF \l_@@_all_long_bool
       { \cs_set:cpx }
       { \cs_set_nopar:cpx }
-      { \l_@@_expandable_aux_name_tl } ##1 ##2 #1 ##3 \q_@@ ##4 #2
+      { \l_@@_expandable_aux_name_tl } ##1 ##2 #2 ##3 \q_@@ ##4 #3
       { ##1 {##2} {##3} {##4} }
     \tl_put_right:Nx \l_@@_signature_tl
       {
         \exp_not:c  { \l_@@_expandable_aux_name_tl }
-        \exp_not:n { #1 #2 {#3} }
+        \exp_not:n { #2 #3 }
       }
-    \bool_set_false:N \l_@@_long_bool
-    \@@_prepare_signature:N
   }
-%    \end{macrocode}
-%  This route is needed if the two delimiting tokens are identical: in
-%  contrast to the non-expandable route, the grabber here has to act
-%  differently for this case.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_D_aux:Nn #1#2
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NN #1#2
   {
+    \@@_add_expandable_grabber:n { #1_alt }
     \bool_if:NTF \l_@@_all_long_bool
       { \cs_set:cpx }
       { \cs_set_nopar:cpx }
-      { \l_@@_expandable_aux_name_tl } ##1 #1 ##2 #1
+      { \l_@@_expandable_aux_name_tl } ##1 #2 ##2 #2
       { ##1 {##2} }
     \tl_put_right:Nx \l_@@_signature_tl
       {
         \exp_not:c  { \l_@@_expandable_aux_name_tl }
-        \exp_not:n { #1 {#2} }
+        \exp_not:n {#2}
       }
-    \bool_set_false:N \l_@@_long_bool
-    \@@_prepare_signature:N
   }
 %    \end{macrocode}
 % \end{macro}
@@ -1716,93 +2221,76 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_expandable_type_g:w}
-% \begin{macro}{\@@_add_expandable_type_G:w}
-%   These are not allowed at all, so there is a complaint and a fall-back.
+% \begin{macro}{\@@_add_expandable_type_E:w}
+% \begin{macro}[aux]{\@@_add_expandable_type_E_aux:n}
+%   For each embellishment, use \cs{@@_get_grabber:NN} to obtain an
+%   auxiliary delimited by that token and store a pair constituted of
+%   the auxiliary and the token in \cs{l_@@_tmpb_tl}, before appending
+%   the whole set of these pairs to the signature, and an equal number
+%   of |-NoValue-| markers (regardless of the default values of
+%   arguments).
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_g:w
+\cs_new_protected:Npn \@@_add_expandable_type_E:w #1#2
   {
-    \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type }
-      { g }
-    \@@_add_expandable_type_m:w
+    \@@_add_default_E:nn {#1} {#2}
+    \@@_add_expandable_grabber:n { E }
+    \tl_clear:N \l_@@_tmpb_tl
+    \tl_map_function:nN {#1} \@@_add_expandable_type_E_aux:n
+    \tl_put_right:Nx \l_@@_signature_tl
+      {
+        { \exp_not:o \l_@@_tmpb_tl }
+        {
+          \prg_replicate:nn { \tl_count:n {#1} }
+            { { \c_@@_no_value_tl } }
+        }
+      }
+    \bool_set_false:N \l_@@_long_bool
+    \@@_prepare_signature:N
   }
-\cs_new_protected:Npn \@@_add_expandable_type_G:w #1
+\cs_new_protected:Npn \@@_add_expandable_type_E_aux:n #1
   {
-    \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type }
-      { G }
-    \@@_add_expandable_type_m:w
+    \@@_get_grabber:NN #1 \l_@@_tmpa_tl
+    \tl_put_right:Nx \l_@@_tmpb_tl
+      { \exp_not:o \l_@@_tmpa_tl \exp_not:N #1 }
   }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_expandable_type_l:w}
-%   Invalid in expandable contexts (as the next left brace may have been
-%   inserted by \pkg{xparse} due to a failed search for an optional argument).
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_l:w
-  {
-    \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type }
-      { l }
-    \@@_add_expandable_type_m:w
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_add_expandable_type_m:w}
 %   Unlike the standard case, when working expandably each argument is always
-%   grabbed separately unless the function takes only \texttt{m}-type
-%   arguments. To deal with the latter case, the value of
-%   \cs{l_@@_m_args_int} needs to be increased appropriately.
+%   grabbed separately.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_add_expandable_type_m:w
   {
-    \int_incr:N \l_@@_m_args_int
-    \@@_add_expandable_grabber_mandatory:n { m }
-    \bool_set_false:N \l_@@_long_bool
+    \@@_add_default:
+    \@@_add_expandable_grabber:n { m }
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_expandable_type_r:w}
 % \begin{macro}{\@@_add_expandable_type_R:w}
-%   The \texttt{r}- and \texttt{R}-types are very similar to \texttt{D}-type
-%   arguments, and so the same internals are used.
+%   The \texttt{R}-type is very similar to the \texttt{D}-type
+%   argument, and so the same internals are used.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_r:w #1#2
-  {
-    \exp_args:NNNo
-      \@@_add_expandable_type_R:w #1 #2 \c_@@_no_value_tl
-  }
-\cs_new_protected:Npn \@@_add_expandable_type_R:w #1#2
-  {
-    \tl_if_eq:nnTF {#1} {#2}
-      {
-        \@@_add_expandable_grabber_mandatory:n { R_alt }
-        \@@_add_expandable_type_D_aux:Nn #1
-      }
-      {
-        \@@_add_expandable_grabber_mandatory:n { R }
-        \@@_add_expandable_type_D_aux:NNn #1#2
-      }
-  }
+\cs_new_protected:Npn \@@_add_expandable_type_R:w
+  { \@@_add_expandable_type_D_aux:NNNn R }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\@@_add_expandable_type_t:w}
+%   An auxiliary delimited by |#1| is built now.  It will be used to
+%   test for the presence of that token.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_add_expandable_type_t:w #1
   {
-    \@@_add_expandable_grabber_optional:n { t }
-    \bool_if:NTF \l_@@_all_long_bool
-      { \cs_set:cpn }
-      { \cs_set_nopar:cpn }
-      { \l_@@_expandable_aux_name_tl } ##1 #1 {##1}
+    \@@_add_default:
+    \@@_add_expandable_grabber_t:
+    \@@_get_grabber:NN #1 \l_@@_tmpa_tl
     \tl_put_right:Nx \l_@@_signature_tl
       {
-        \exp_not:c { \l_@@_expandable_aux_name_tl }
+        \exp_not:o \l_@@_tmpa_tl
         \exp_not:N #1
       }
     \bool_set_false:N \l_@@_long_bool
@@ -1811,94 +2299,102 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_expandable_type_u:w}
-%   Invalid in an expandable context as any preceding optional argument may
-%   wrap part of the delimiter up in braces.
+% \begin{macro}{\@@_add_expandable_grabber:n, \@@_add_expandable_grabber_t:}
+%   For \texttt{t}-type arguments, simply add a grabber to the signature
+%   and reset the boolean keeping track of~\texttt{+} markers (they
+%   should be ignored for the purpose of determining the long status of
+%   the command because they take no argument).  For all other
+%   arguments, if the command's long status is already known then check
+%   that this argument has the correct long status, and otherwise set
+%   the long status to this argument's long status.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_u:w #1
+\cs_new_protected:Npn \@@_add_expandable_grabber:n #1
   {
-    \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type }
-      { u }
-    \@@_add_expandable_type_m:w
+    \bool_if:NTF \l_@@_all_long_set_bool
+      {
+        \bool_if:nT
+          { \bool_xor_p:nn { \l_@@_all_long_bool } { \l_@@_long_bool } }
+          {
+            \__msg_kernel_error:nnx { xparse } { inconsistent-long }
+              { \iow_char:N \\ \l_@@_function_tl }
+            \@@_bad_def:wn
+          }
+      }
+      {
+        \bool_set:Nn \l_@@_all_long_bool { \l_@@_long_bool }
+        \bool_set_true:N \l_@@_all_long_set_bool
+      }
+    \tl_put_right:Nx \l_@@_signature_tl
+      { \exp_not:c { @@_expandable_grab_ #1 :w } }
+    \bool_set_false:N \l_@@_long_bool
   }
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_add_expandable_type_v:w}
-%   Another forbidden type.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_v:w
+\cs_new_protected:Npn \@@_add_expandable_grabber_t:
   {
-    \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type }
-      { v }
-    \@@_add_expandable_type_m:w
+    \tl_put_right:Nn \l_@@_signature_tl
+      { \@@_expandable_grab_t:w }
+    \bool_set_false:N \l_@@_long_bool
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}
-%   {
-%     \@@_add_expandable_grabber_mandatory:n,
-%     \@@_add_expandable_grabber_optional:n
-%   }
-% \begin{macro}[aux]{\@@_add_expandable_long_check:}
-%   Adding a grabber to the signature is very simple here, with only a test to
-%   ensure that optional arguments still have mandatory ones to follow. This
-%   is also a good place to check on the consistency of the long status of
-%   arguments.
+% \begin{macro}{\@@_get_grabber:NN}
+% \begin{macro}[aux]{\@@_get_grabber_auxi:NN}
+% \begin{macro}[aux]{\@@_get_grabber_auxii:NN}
+%   Given a token |#1|, defines an expandable function delimited by that
+%   token and stores it in the token list~|#2|.  The function is named
+%   after the token, unless that function name is already taken by some
+%   other grabber (this can happen in the rare case where delimiters
+%   with different category codes are used in the same document): in
+%   that case use a global counter to get a unique name.  Since the
+%   grabbers are not named after \pkg{xparse} commands they should not
+%   be used to get material from the input stream.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_grabber_mandatory:n #1
+\cs_new_protected:Npn \@@_get_grabber:NN #1#2
   {
-    \@@_add_expandable_long_check:
-    \tl_put_right:Nx \l_@@_signature_tl
-      { \exp_not:c { @@_expandable_grab_ #1 :w } }
-    \bool_set_false:N \l_@@_long_bool
-    \int_decr:N \l_@@_mandatory_args_int
+    \cs_set:Npn \@@_tmp:w ##1 #1 {##1}
+    \exp_args:Nc \@@_get_grabber_auxi:NN
+      { @@_grabber_ \token_to_str:N #1 :w } #2
   }
-\cs_new_protected:Npn \@@_add_expandable_grabber_optional:n #1
+\cs_new_protected:Npn \@@_get_grabber_auxi:NN #1#2
   {
-    \@@_add_expandable_long_check:
-    \int_compare:nNnF \l_@@_mandatory_args_int > \c_zero
-      { \__msg_kernel_error:nn { xparse } { expandable-ending-optional } }
-    \tl_put_right:Nx \l_@@_signature_tl
-      { \exp_not:c { @@_expandable_grab_ #1 :w } }
-    \bool_set_false:N \l_@@_long_bool
+    \cs_if_eq:NNTF \@@_tmp:w #1
+      { \tl_set:Nn #2 {#1} }
+      {
+        \cs_if_exist:NTF #1
+          {
+            \int_gincr:N \g_@@_grabber_int
+            \exp_args:Nc \@@_get_grabber_auxi:NN
+              {
+                @@_grabber_
+                - \int_use:N \g_@@_grabber_int :w
+              }
+              #2
+          }
+          { \@@_get_grabber_auxii:NN #1 #2 }
+      }
   }
-\cs_new_protected:Npn \@@_add_expandable_long_check:
+\cs_new_protected:Npn \@@_get_grabber_auxii:NN #1#2
   {
-    \bool_if:nT { \l_@@_all_long_bool && ! \l_@@_long_bool }
-      { \__msg_kernel_error:nn { xparse } { inconsistent-long } }
+    \cs_set_eq:NN #1 \@@_tmp:w
+    \tl_set:Nn #2 {#1}
   }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
 % \subsection{Grabbing arguments}
 %
 % All of the grabbers follow the same basic pattern. The initial
-% function sets up the appropriate information to define
-% \cs{@@_grab_arg:w} to grab the argument. This means determining
-% whether to use \cs{cs_set:Npn} or \cs{cs_set_nopar:Npn}, and for
-% optional arguments whether to skip spaces. In all cases,
-% \cs{@@_grab_arg:w} is then called to actually do the grabbing.
+% function stores in \cs{l_@@_signature_tl} the code to grab further
+% arguments, defines (the function in) \cs{l_@@_fn_tl} that will grab
+% the argument, and calls it.
 %
-% \begin{macro}{\@@_grab_arg:w}
-% \begin{macro}[aux]{\@@_grab_arg_auxi:w}
-% \begin{macro}[aux]{\@@_grab_arg_auxii:w}
-%   Each time an argument is actually grabbed, \pkg{xparse} defines a
-%   function to do it. In that way, long arguments from previous functions
-%   can be included in the definition of the grabber function, so that
-%   it does not raise an error if not long. The generic function used
-%   for this is reserved here. A couple of auxiliary functions are also
-%   needed in various places.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_arg:w { }
-\cs_new_protected:Npn \@@_grab_arg_auxi:w { }
-\cs_new_protected:Npn \@@_grab_arg_auxii:w { }
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
+% Defining \cs{l_@@_fn_tl} means determining whether to use
+% \cs{cs_set:Npn} or \cs{cs_set_nopar:Npn}, and for optional arguments
+% whether to skip spaces. Once the argument is found, \cs{l_@@_fn_tl}
+% calls \cs{@@_add_arg:n}, responsible for calling processors and
+% grabbing further arguments.
 %
 % \begin{macro}{\@@_grab_D:w}
 % \begin{macro}{\@@_grab_D_long:w}
@@ -1905,25 +2401,25 @@
 % \begin{macro}{\@@_grab_D_trailing:w}
 % \begin{macro}{\@@_grab_D_long_trailing:w}
 %   The generic delimited argument grabber. The auxiliary function does
-%   a peek test before calling \cs{@@_grab_arg:w}, so that the
+%   a peek test before calling \cs{@@_grab_D_call:Nw}, so that the
 %   optional nature of the argument works as expected.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_D:w #1#2#3#4 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_D:w #1#2#3 \@@_run_code:
   {
-    \@@_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected_nopar:Npn
+    \@@_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected_nopar:Npn
       { _ignore_spaces }
   }
-\cs_new_protected:Npn \@@_grab_D_long:w #1#2#3#4 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_D_long:w #1#2#3 \@@_run_code:
   {
-    \@@_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected:Npn
+    \@@_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected:Npn
       { _ignore_spaces }
   }
-\cs_new_protected:Npn \@@_grab_D_trailing:w #1#2#3#4 \l_@@_args_tl
-  { \@@_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected_nopar:Npn { } }
-\cs_new_protected:Npn \@@_grab_D_long_trailing:w #1#2#3#4 \l_@@_args_tl
-  { \@@_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected:Npn { } }
+\cs_new_protected:Npn \@@_grab_D_trailing:w #1#2#3 \@@_run_code:
+  { \@@_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected_nopar:Npn { } }
+\cs_new_protected:Npn \@@_grab_D_long_trailing:w #1#2#3 \@@_run_code:
+  { \@@_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected:Npn { } }
 %    \end{macrocode}
-% \begin{macro}[aux]{\@@_grab_D_aux:NNnnNn}
+% \begin{macro}[aux]{\@@_grab_D_aux:NNnNn}
 % \begin{macro}[aux]{\@@_grab_D_aux:NNnN}
 %   This is a bit complicated. The idea is that, in order to check for
 %   nested optional argument tokens (\texttt{[[...]]} and so on) the
@@ -1933,15 +2429,12 @@
 %   prevents loss of braces, and there is then a test to see if there are
 %   nested delimiters to handle.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_D_aux:NNnnNn #1#2#3#4#5#6
+\cs_new_protected:Npn \@@_grab_D_aux:NNnNn #1#2#3#4#5
   {
-    \@@_grab_D_aux:NNnN #1#2 {#4} #5
-    \use:c { peek_meaning_remove #6 :NTF } #1
-      { \@@_grab_arg:w }
-      {
-        \@@_add_arg:n {#3}
-        #4 \l_@@_args_tl
-      }
+    \@@_grab_D_aux:NNnN #1#2 {#3} #4
+    \use:c { peek_meaning_remove #5 :NTF } #1
+      { \@@_grab_D_call:Nw #1 }
+      { \@@_add_arg:o \c_@@_no_value_tl }
   }
 %    \end{macrocode}
 %   Inside the \enquote{standard} grabber, there is a test to see if the
@@ -1953,48 +2446,22 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_grab_D_aux:NNnN #1#2#3#4
   {
-    \cs_set_protected_nopar:Npn \@@_grab_arg:w
+    \tl_set:Nn \l_@@_signature_tl {#3}
+    \exp_after:wN #4 \l_@@_fn_tl ##1 #2
       {
-        \exp_after:wN #4 \l_@@_fn_tl ####1 #2
+        \tl_if_in:nnTF {##1} {#1}
+          { \@@_grab_D_nested:NNnN #1 #2 {##1} #4 }
           {
-            \tl_if_in:nnTF {####1} {#1}
-              { \@@_grab_D_nested:NNnnN #1 #2 {####1} {#3} #4 }
+            \tl_if_blank:oTF { \use_none:n ##1 }
+              { \@@_add_arg:o { \use_none:n ##1 } }
               {
-                \tl_if_blank:oTF { \use_none:n ####1 }
-                  { \@@_add_arg:o { \use_none:n ####1 } }
-                  {
-                    \str_if_eq_x:nnTF
-                      { \exp_not:o { \use_none:n ####1 } }
-                      { { \exp_not:o { \use_ii:nnn ####1 \q_nil } } }
-                      { \@@_add_arg:o { \use_ii:nn ####1 } }
-                      { \@@_add_arg:o { \use_none:n ####1 } }
-                  }
-                #3 \l_@@_args_tl
+                \str_if_eq_x:nnTF
+                  { \exp_not:o { \use_none:n ##1 } }
+                  { { \exp_not:o { \use_ii:nnn ##1 \q_nil } } }
+                  { \@@_add_arg:o { \use_ii:nn ##1 } }
+                  { \@@_add_arg:o { \use_none:n ##1 } }
               }
           }
-%    \end{macrocode}
-%   This section needs a little explanation. In order to avoid losing any
-%   braces, a token needs to be inserted before the argument to be grabbed.
-%   If the argument runs away because the closing token is missing then this
-%   inserted token shows up in the terminal. Ideally, |#1| would therefore be
-%   used directly, but that is no good as it will mess up the rest of the
-%   grabber. Instead, a copy of |#1| with an altered category code is used,
-%   as this will look right in the terminal but will not mess up the grabber.
-%   The only issue then is that the category code of |#1| is unknown. So there
-%   is a quick test to ensure that the inserted token can never be matched by
-%   the grabber. (This assumes that |#1| and |#2| are not the same character
-%   with different category codes, but that really should not happen in any
-%   sensible document-level syntax.)
-%    \begin{macrocode}
-        \token_if_eq_catcode:NNTF + #1
-          {
-            \exp_after:wN \exp_after:wN \exp_after:wN
-              \l_@@_fn_tl \char_generate:nn { `#1 } { 11 }
-          }
-          {
-            \exp_after:wN \l_@@_fn_tl
-            \token_to_str:N #1
-          }
       }
   }
 %    \end{macrocode}
@@ -2004,7 +2471,7 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
-% \begin{macro}[aux]{\@@_grab_D_nested:NNnnN}
+% \begin{macro}[aux]{\@@_grab_D_nested:NNnN}
 % \begin{macro}[aux]{\@@_grab_D_nested:w}
 % \begin{macro}{\l_@@_nesting_a_tl}
 % \begin{macro}{\l_@@_nesting_b_tl}
@@ -2029,11 +2496,11 @@
 \tl_new:N \l_@@_nesting_a_tl
 \tl_new:N \l_@@_nesting_b_tl
 \quark_new:N \q_@@
-\cs_new_protected:Npn \@@_grab_D_nested:NNnnN #1#2#3#4#5
+\cs_new_protected:Npn \@@_grab_D_nested:NNnN #1#2#3#4
   {
     \tl_clear:N \l_@@_nesting_a_tl
     \tl_clear:N \l_@@_nesting_b_tl
-    \exp_after:wN #5 \l_@@_fn_tl ##1 #1 ##2 \q_@@ ##3 #2
+    \exp_after:wN #4 \l_@@_fn_tl ##1 #1 ##2 \q_@@ ##3 #2
       {
         \tl_put_right:No \l_@@_nesting_a_tl { \use_none:n ##1 #1 }
         \tl_put_right:No \l_@@_nesting_b_tl { \use_i:nn #2 ##3 }
@@ -2056,7 +2523,6 @@
                 \tl_put_right:No \l_@@_nesting_a_tl
                   \l_@@_nesting_b_tl
                 \@@_add_arg:V \l_@@_nesting_a_tl
-                #4 \l_@@_args_tl
               }
           }
       }
@@ -2070,6 +2536,34 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \begin{macro}{\@@_grab_D_call:Nw}
+%   For \texttt{D} and \texttt{R}-type arguments, to avoid losing any
+%   braces, a token needs to be inserted before the argument to be grabbed.
+%   If the argument runs away because the closing token is missing then this
+%   inserted token shows up in the terminal. Ideally, |#1| would therefore be
+%   used directly, but that is no good as it will mess up the rest of the
+%   grabber. Instead, a copy of |#1| with an altered category code is used,
+%   as this will look right in the terminal but will not mess up the grabber.
+%   The only issue then is that the category code of |#1| is unknown. So there
+%   is a quick test to ensure that the inserted token can never be matched by
+%   the grabber. (This assumes that the open and close delimiters are not the
+%   same character with different category codes, but that really should not
+%   happen in any sensible document-level syntax.)
+%    \begin{macrocode}
+\cs_set_protected_nopar:Npn \@@_grab_D_call:Nw #1
+  {
+    \token_if_eq_catcode:NNTF + #1
+      {
+        \exp_after:wN \exp_after:wN \exp_after:wN
+          \l_@@_fn_tl \char_generate:nn { `#1 } { 11 }
+      }
+      {
+        \exp_after:wN \l_@@_fn_tl
+        \token_to_str:N #1
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
 %
 % \begin{macro}
 %   {
@@ -2076,37 +2570,32 @@
 %     \@@_grab_E:w, \@@_grab_E_long:w,
 %     \@@_grab_E_trailing:w, \@@_grab_E_long_trailing:w
 %   }
-% \begin{macro}[aux]{\@@_grab_E:nnnNn}
-% \begin{macro}[aux]{\@@_grab_E_setup:Nw}
+% \begin{macro}[aux]{\@@_grab_E:nnNn}
 % \begin{macro}[aux]{\@@_grab_E_loop:nnN}
 % \begin{macro}[aux]{\@@_grab_E_finalise:}
 %   Everything here needs to point to a loop.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_E:w #1#2#3 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_E:w #1#2 \@@_run_code:
   {
-    \@@_grab_E:nnnNn
-       {#1} {#2} {#3}
+    \@@_grab_E:nnNn {#1} {#2}
       \cs_set_protected_nopar:Npn
       { _ignore_spaces }
   }
-\cs_new_protected:Npn \@@_grab_E_long:w #1#2#3 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_E_long:w #1#2 \@@_run_code:
   {
-    \@@_grab_E:nnnNn
-       {#1} {#2} {#3}
+    \@@_grab_E:nnNn {#1} {#2}
       \cs_set_protected:Npn
       { _ignore_spaces }
   }
-\cs_new_protected:Npn \@@_grab_E_trailing:w #1#2#3 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_E_trailing:w #1#2 \@@_run_code:
   {
-    \@@_grab_E:nnnNn
-       {#1} {#2} {#3}
+    \@@_grab_E:nnNn {#1} {#2}
       \cs_set_protected_nopar:Npn
       { }
   }
-\cs_new_protected:Npn \@@_grab_E_long_trailing:w #1#2#3 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_E_long_trailing:w #1#2 \@@_run_code:
   {
-    \@@_grab_E:nnnNn
-       {#1} {#2} {#3}
+    \@@_grab_E:nnNn {#1} {#2}
       \cs_set_protected:Npn
       { }
   }
@@ -2116,16 +2605,15 @@
 %   they can appear later. The grabbed values are held in a property list
 %   which is then turned into an ordered list to be passed back to the user.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_E:nnnNn #1#2#3#4#5
+\cs_new_protected:Npn \@@_grab_E:nnNn #1#2#3#4
   {
-    \exp_after:wN #4 \l_@@_fn_tl ##1##2##3
+    \exp_after:wN #3 \l_@@_fn_tl ##1##2##3
       {
         \prop_put:Nnn \l_@@_tmp_prop {##1} {##3}
-        \@@_grab_E_loop:nnN {#5} { } ##2 \q_recursion_stop
+        \@@_grab_E_loop:nnN {#4} { } ##2 \q_recursion_stop
       }
     \prop_clear:N \l_@@_tmp_prop
-    \@@_grab_E_setup:Nw
-      #1 \q_recursion_tail \q_mark #2 \q_recursion_tail \q_recursion_stop
+    \tl_set:Nn \l_@@_signature_tl {#2}
     \cs_set_protected:Npn \@@_grab_E_finalise:
       {
         \tl_clear:N \l_@@_tmpa_tl
@@ -2140,22 +2628,9 @@
               }
           }
         \@@_add_arg:V \l_@@_tmpa_tl
-        #3 \l_@@_args_tl
       }
-    \@@_grab_E_loop:nnN {#5} { } #1 \q_recursion_tail \q_recursion_stop
+    \@@_grab_E_loop:nnN {#4} { } #1 \q_recursion_tail \q_recursion_stop
   }
-%    \end{macrocode}
-%   To allow for flexible default values, the list of those given may be
-%   shorter than the number of test tokens. This can readily be achieved
-%   by storing only the given defaults in the property list.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_E_setup:Nw #1#2 \q_mark #3
-  {
-    \quark_if_recursion_tail_stop:N #1
-    \quark_if_recursion_tail_stop:n {#3}
-    \prop_put:Nnn \l_@@_tmp_prop {#1} {#3}
-    \@@_grab_E_setup:Nw #2 \q_mark
-  }
 \cs_new_protected:Npn \@@_grab_E_loop:nnN #1#2#3#4 \q_recursion_stop
   {
     \cs_if_eq:NNTF #3 \q_recursion_tail
@@ -2172,42 +2647,36 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\@@_grab_G:w}
 % \begin{macro}{\@@_grab_G_long:w}
 % \begin{macro}{\@@_grab_G_trailing:w}
 % \begin{macro}{\@@_grab_G_long_trailing:w}
-% \begin{macro}[aux]{\@@_grab_G_aux:nnNn}
+% \begin{macro}[aux]{\@@_grab_G_aux:nNn}
 %   Optional groups are checked by meaning, so that the same code will
 %   work with, for example, Con\TeX{}t-like input.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_G:w #1#2 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_G:w #1 \@@_run_code:
   {
-    \@@_grab_G_aux:nnNn {#1} {#2} \cs_set_protected_nopar:Npn
+    \@@_grab_G_aux:nNn {#1} \cs_set_protected_nopar:Npn
       { _ignore_spaces }
   }
-\cs_new_protected:Npn \@@_grab_G_long:w #1#2 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_G_long:w #1 \@@_run_code:
   {
-    \@@_grab_G_aux:nnNn {#1} {#2} \cs_set_protected:Npn { _ignore_spaces }
+    \@@_grab_G_aux:nNn {#1} \cs_set_protected:Npn { _ignore_spaces }
   }
-\cs_new_protected:Npn \@@_grab_G_trailing:w #1#2 \l_@@_args_tl
-  { \@@_grab_G_aux:nnNn {#1} {#2} \cs_set_protected_nopar:Npn { } }
-\cs_new_protected:Npn \@@_grab_G_long_trailing:w #1#2 \l_@@_args_tl
-  { \@@_grab_G_aux:nnNn {#1} {#2} \cs_set_protected:Npn { } }
-\cs_new_protected:Npn \@@_grab_G_aux:nnNn #1#2#3#4
+\cs_new_protected:Npn \@@_grab_G_trailing:w #1 \@@_run_code:
+  { \@@_grab_G_aux:nNn {#1} \cs_set_protected_nopar:Npn { } }
+\cs_new_protected:Npn \@@_grab_G_long_trailing:w #1 \@@_run_code:
+  { \@@_grab_G_aux:nNn {#1} \cs_set_protected:Npn { } }
+\cs_new_protected:Npn \@@_grab_G_aux:nNn #1#2#3
   {
-    \exp_after:wN #3 \l_@@_fn_tl ##1
-      {
-        \@@_add_arg:n {##1}
-        #2 \l_@@_args_tl
-      }
-    \use:c { peek_meaning #4 :NTF } \c_group_begin_token
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN #2 \l_@@_fn_tl ##1
+      { \@@_add_arg:n {##1} }
+    \use:c { peek_meaning #3 :NTF } \c_group_begin_token
       { \l_@@_fn_tl }
-      {
-        \@@_add_arg:n {#1}
-        #2 \l_@@_args_tl
-      }
+      { \@@_add_arg:o \c_@@_no_value_tl }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2221,17 +2690,15 @@
 % \begin{macro}[aux]{\@@_grab_l_aux:nN}
 %   Argument grabbers for mandatory \TeX{} arguments are pretty simple.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_l:w #1 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_l:w #1 \@@_run_code:
   { \@@_grab_l_aux:nN {#1} \cs_set_protected_nopar:Npn }
-\cs_new_protected:Npn \@@_grab_l_long:w #1 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_l_long:w #1 \@@_run_code:
   { \@@_grab_l_aux:nN {#1} \cs_set_protected:Npn }
 \cs_new_protected:Npn \@@_grab_l_aux:nN #1#2
   {
+    \tl_set:Nn \l_@@_signature_tl {#1}
     \exp_after:wN #2 \l_@@_fn_tl ##1##
-      {
-        \@@_add_arg:n {##1}
-        #1 \l_@@_args_tl
-      }
+      { \@@_add_arg:n {##1} }
     \l_@@_fn_tl
   }
 %    \end{macrocode}
@@ -2243,22 +2710,18 @@
 % \begin{macro}{\@@_grab_m_long:w}
 %   Collecting a single mandatory argument is quite easy.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_m:w #1 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_m:w #1 \@@_run_code:
   {
+    \tl_set:Nn \l_@@_signature_tl {#1}
     \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl ##1
-      {
-        \@@_add_arg:n {##1}
-        #1 \l_@@_args_tl
-      }
+      { \@@_add_arg:n {##1} }
     \l_@@_fn_tl
   }
-\cs_new_protected:Npn \@@_grab_m_long:w #1 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_m_long:w #1 \@@_run_code:
   {
+    \tl_set:Nn \l_@@_signature_tl {#1}
     \exp_after:wN \cs_set_protected:Npn \l_@@_fn_tl ##1
-      {
-        \@@_add_arg:n {##1}
-        #1 \l_@@_args_tl
-      }
+      { \@@_add_arg:n {##1} }
     \l_@@_fn_tl
   }
 %    \end{macrocode}
@@ -2273,93 +2736,72 @@
 % \begin{macro}{\@@_grab_m_6:w}
 % \begin{macro}{\@@_grab_m_7:w}
 % \begin{macro}{\@@_grab_m_8:w}
-%   Grabbing 1--8 mandatory arguments. We don't need to worry about
-%   nine arguments as this is only possible if everything is
-%   mandatory. Each function has an auxiliary so that \cs{par} tokens
-%   from other arguments still work.
+% \begin{macro}{\@@_grab_m_9:w}
+% \begin{macro}[aux]{\@@_grab_m_aux:Nnnnnnnnn}
+%   Grabbing 1--8 mandatory arguments is done by giving 8--1 known
+%   arguments to a 9-argument function that stores them in
+%   \cs{l_@@_args_tl}.  For simplicity, grabbing 9 mandatory arguments
+%   is done by grabbing 5 then 4 arguments.
 %    \begin{macrocode}
-\cs_new_protected:cpn { @@_grab_m_1:w } #1 \l_@@_args_tl
+\cs_new_protected_nopar:Npn \@@_grab_m_aux:Nnnnnnnnn #1#2#3#4#5#6#7#8#9
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl ##1
-      {
-        \tl_put_right:Nn \l_@@_args_tl { {##1} }
-        #1 \l_@@_args_tl
-      }
-    \l_@@_fn_tl
+    \tl_put_right:No \l_@@_args_tl
+      { #1 {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9} }
+    \l_@@_signature_tl \@@_run_code:
   }
-\cs_new_protected:cpn { @@_grab_m_2:w } #1 \l_@@_args_tl
+\cs_new_protected:cpn { @@_grab_m_1:w } #1 \@@_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl
-      ##1##2
-      {
-        \tl_put_right:Nn \l_@@_args_tl { {##1} {##2} }
-        #1 \l_@@_args_tl
-      }
-    \l_@@_fn_tl
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nnnnnnn { } { } { } { } { } { } { }
   }
-\cs_new_protected:cpn { @@_grab_m_3:w } #1 \l_@@_args_tl
+\cs_new_protected:cpn { @@_grab_m_2:w } #1 \@@_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl
-      ##1##2##3
-      {
-        \tl_put_right:Nn \l_@@_args_tl { {##1} {##2} {##3} }
-        #1 \l_@@_args_tl
-      }
-    \l_@@_fn_tl
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nnnnnn { } { } { } { } { } { }
   }
-\cs_new_protected:cpn { @@_grab_m_4:w } #1 \l_@@_args_tl
+\cs_new_protected:cpn { @@_grab_m_3:w } #1 \@@_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl
-      ##1##2##3##4
-      {
-        \tl_put_right:Nn \l_@@_args_tl { {##1} {##2} {##3} {##4} }
-        #1 \l_@@_args_tl
-      }
-    \l_@@_fn_tl
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nnnnn { } { } { } { } { }
   }
-\cs_new_protected:cpn { @@_grab_m_5:w } #1 \l_@@_args_tl
+\cs_new_protected:cpn { @@_grab_m_4:w } #1 \@@_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl
-      ##1##2##3##4##5
-      {
-        \tl_put_right:Nn \l_@@_args_tl { {##1} {##2} {##3} {##4} {##5} }
-        #1 \l_@@_args_tl
-      }
-    \l_@@_fn_tl
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nnnn { } { } { } { }
   }
-\cs_new_protected:cpn { @@_grab_m_6:w } #1 \l_@@_args_tl
+\cs_new_protected:cpn { @@_grab_m_5:w } #1 \@@_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl
-      ##1##2##3##4##5##6
-      {
-        \tl_put_right:Nn \l_@@_args_tl
-          { {##1} {##2} {##3} {##4} {##5} {##6} }
-        #1 \l_@@_args_tl
-      }
-    \l_@@_fn_tl
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nnn { } { } { }
   }
-\cs_new_protected:cpn { @@_grab_m_7:w } #1 \l_@@_args_tl
+\cs_new_protected:cpn { @@_grab_m_6:w } #1 \@@_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl
-      ##1##2##3##4##5##6##7
-      {
-        \tl_put_right:Nn \l_@@_args_tl
-          { {##1} {##2} {##3} {##4} {##5} {##6} {##7} }
-        #1 \l_@@_args_tl
-      }
-    \l_@@_fn_tl
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nn { } { }
   }
-\cs_new_protected:cpn { @@_grab_m_8:w } #1 \l_@@_args_tl
+\cs_new_protected:cpn { @@_grab_m_7:w } #1 \@@_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl
-      ##1##2##3##4##5##6##7##8
-      {
-        \tl_put_right:Nn \l_@@_args_tl
-          { {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} }
-        #1 \l_@@_args_tl
-      }
-    \l_@@_fn_tl
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:n { }
   }
+\cs_new_protected:cpn { @@_grab_m_8:w } #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \prg_do_nothing:
+  }
+\cs_new_protected:cpx { @@_grab_m_9:w }
+  {
+    \exp_not:c { @@_grab_m_5:w }
+    \exp_not:c { @@_grab_m_4:w }
+  }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -2369,27 +2811,29 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\@@_grab_R:w, \@@_grab_R_long:w}
-% \begin{macro}[aux]{\@@_grab_R_aux:NNnnN}
+% \begin{macro}[aux]{\@@_grab_R_aux:NNnN}
 %  The grabber for \texttt{R}-type arguments is basically the same as
 %  that for \texttt{D}-type ones, but always skips spaces (as it is mandatory)
 %  and has a hard-coded error message.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_R:w #1#2#3#4 \l_@@_args_tl
-  { \@@_grab_R_aux:NNnnN #1 #2 {#3} {#4} \cs_set_protected_nopar:Npn }
-\cs_new_protected:Npn \@@_grab_R_long:w #1#2#3#4 \l_@@_args_tl
-  { \@@_grab_R_aux:NNnnN #1 #2 {#3} {#4} \cs_set_protected:Npn }
-\cs_new_protected:Npn \@@_grab_R_aux:NNnnN #1#2#3#4#5
+\cs_new_protected:Npn \@@_grab_R:w #1#2#3 \@@_run_code:
+  { \@@_grab_R_aux:NNnN #1 #2 {#3} \cs_set_protected_nopar:Npn }
+\cs_new_protected:Npn \@@_grab_R_long:w #1#2#3 \@@_run_code:
+  { \@@_grab_R_aux:NNnN #1 #2 {#3} \cs_set_protected:Npn }
+\cs_new_protected:Npn \@@_grab_R_aux:NNnN #1#2#3#4
   {
-    \@@_grab_D_aux:NNnN #1 #2 {#4} #5
+    \@@_grab_D_aux:NNnN #1 #2 {#3} #4
     \peek_meaning_remove_ignore_spaces:NTF #1
-      { \@@_grab_arg:w }
+      { \@@_grab_D_call:Nw #1 }
       {
         \__msg_kernel_error:nnxx { xparse } { missing-required }
-          { \token_to_str:N #1 } { \tl_to_str:n {#3} }
-        \@@_add_arg:n {#3}
-        #4 \l_@@_args_tl
+          { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
+          { \token_to_str:N #1 }
+        \@@_add_arg:o \c_@@_no_value_tl
       }
   }
 %    \end{macrocode}
@@ -2400,34 +2844,24 @@
 % \begin{macro}{\@@_grab_t_long:w}
 % \begin{macro}{\@@_grab_t_trailing:w}
 % \begin{macro}{\@@_grab_t_long_trailing:w}
-% \begin{macro}[aux]{\@@_grab_t_aux:NnNn}
+% \begin{macro}[aux]{\@@_grab_t_aux:NNw}
 %   Dealing with a token is quite easy. Check the match, remove the
 %   token if needed and add a flag to the output.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_t:w #1#2 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_t:w
+  { \@@_grab_t_aux:NNw \peek_meaning_remove_ignore_spaces:NTF }
+\cs_new_eq:NN \@@_grab_t_long:w \@@_grab_t:w
+\cs_new_protected:Npn \@@_grab_t_trailing:w
+  { \@@_grab_t_aux:NNw \peek_meaning_remove:NTF }
+\cs_new_eq:NN \@@_grab_t_long_trailing:w \@@_grab_t_trailing:w
+\cs_new_protected:Npn \@@_grab_t_aux:NNw #1#2#3 \@@_run_code:
   {
-    \@@_grab_t_aux:NnNn #1 {#2} \cs_set_protected_nopar:Npn
-      { _ignore_spaces }
-  }
-\cs_new_protected:Npn \@@_grab_t_long:w #1#2 \l_@@_args_tl
-  { \@@_grab_t_aux:NnNn #1 {#2} \cs_set_protected:Npn { _ignore_spaces } }
-\cs_new_protected:Npn \@@_grab_t_trailing:w #1#2 \l_@@_args_tl
-  { \@@_grab_t_aux:NnNn #1 {#2} \cs_set_protected_nopar:Npn { } }
-\cs_new_protected:Npn \@@_grab_t_long_trailing:w #1#2 \l_@@_args_tl
-  { \@@_grab_t_aux:NnNn #1 {#2} \cs_set_protected:Npn { } }
-\cs_new_protected:Npn \@@_grab_t_aux:NnNn #1#2#3#4
-  {
-    \exp_after:wN #3 \l_@@_fn_tl
+    \tl_set:Nn \l_@@_signature_tl {#3}
+    \exp_after:wN \cs_set_protected:Npn \l_@@_fn_tl
       {
-        \use:c { peek_meaning_remove #4 :NTF } #1
-          {
-            \@@_add_arg:n { \BooleanTrue }
-            #2 \l_@@_args_tl
-          }
-          {
-            \@@_add_arg:n { \BooleanFalse }
-            #2 \l_@@_args_tl
-          }
+        #1 #2
+          { \@@_add_arg:n { \BooleanTrue } }
+          { \@@_add_arg:n { \BooleanFalse } }
       }
     \l_@@_fn_tl
   }
@@ -2444,17 +2878,15 @@
 %   Grabbing up to a list of tokens is quite easy: define the grabber,
 %   and then collect.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_u:w #1#2 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_u:w #1#2 \@@_run_code:
   { \@@_grab_u_aux:nnN {#1} {#2} \cs_set_protected_nopar:Npn }
-\cs_new_protected:Npn \@@_grab_u_long:w #1#2 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_u_long:w #1#2 \@@_run_code:
   { \@@_grab_u_aux:nnN {#1} {#2} \cs_set_protected:Npn }
 \cs_new_protected:Npn \@@_grab_u_aux:nnN #1#2#3
   {
+    \tl_set:Nn \l_@@_signature_tl {#2}
     \exp_after:wN #3 \l_@@_fn_tl ##1 #1
-      {
-        \@@_add_arg:n {##1}
-        #2 \l_@@_args_tl
-      }
+      { \@@_add_arg:n {##1} }
     \l_@@_fn_tl
   }
 %    \end{macrocode}
@@ -2466,7 +2898,6 @@
 % \begin{macro}{\@@_grab_v_long:w}
 % \begin{macro}{\@@_grab_v_aux:w}
 % \begin{macro}{\@@_grab_v_group_end:}
-% \begin{variable}{\l_@@_v_rest_of_signature_tl}
 % \begin{variable}{\l_@@_v_arg_tl}
 %   The opening delimiter is the first non-space token, and is never
 %   read verbatim.  This is required by consistency with the case where
@@ -2484,7 +2915,6 @@
 %   It is ended by \cs{@@_grab_v_group_end:}, which smuggles
 %   the collected argument out of the group.
 %    \begin{macrocode}
-\tl_new:N \l_@@_v_rest_of_signature_tl
 \tl_new:N \l_@@_v_arg_tl
 \cs_new_protected:Npn \@@_grab_v:w
   {
@@ -2496,9 +2926,9 @@
     \bool_set_true:N \l_@@_long_bool
     \@@_grab_v_aux:w
   }
-\cs_new_protected:Npn \@@_grab_v_aux:w #1 \l_@@_args_tl
+\cs_new_protected:Npn \@@_grab_v_aux:w #1 \@@_run_code:
   {
-    \tl_set:Nn \l_@@_v_rest_of_signature_tl {#1}
+    \tl_set:Nn \l_@@_signature_tl {#1}
     \group_begin:
       \group_align_safe_begin:
         \tex_escapechar:D = 92 \scan_stop:
@@ -2523,7 +2953,6 @@
   }
 %    \end{macrocode}
 % \end{variable}
-% \end{variable}
 % \end{macro}
 % \end{macro}
 % \end{macro}
@@ -2586,8 +3015,7 @@
 \cs_new_protected:Npn \@@_grab_v_aux_loop_end:
   {
     \@@_grab_v_group_end:
-    \exp_args:Nx \@@_add_arg:n { \tl_tail:N \l_@@_v_arg_tl }
-    \l_@@_v_rest_of_signature_tl \l_@@_args_tl
+    \@@_add_arg:x { \tl_tail:N \l_@@_v_arg_tl }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2681,7 +3109,6 @@
 \cs_new_protected:Npn \@@_grab_v_aux_abort:n #1
   {
     \@@_grab_v_group_end:
-    \@@_add_arg:o \c_@@_no_value_tl
     \exp_after:wN \exp_after:wN \exp_after:wN
       \peek_meaning_remove:NTF \char_generate:nn { \tex_endlinechar:D } { 6 }
       {
@@ -2689,7 +3116,7 @@
           { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
           { \tl_to_str:N \l_@@_v_arg_tl }
           { \tl_to_str:n {#1} }
-        \l_@@_v_rest_of_signature_tl \l_@@_args_tl
+        \@@_add_arg:o \c_@@_no_value_tl
       }
       {
         \__msg_kernel_error:nnxxx { xparse } { verbatim-tokenized }
@@ -2696,7 +3123,7 @@
           { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
           { \tl_to_str:N \l_@@_v_arg_tl }
           { \tl_to_str:n {#1} }
-        \l_@@_v_rest_of_signature_tl \l_@@_args_tl
+        \@@_add_arg:o \c_@@_no_value_tl
       }
   }
 %    \end{macrocode}
@@ -2732,51 +3159,23 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_arg:n, \@@_add_arg:V, \@@_add_arg:o}
-% \begin{macro}[aux]{\@@_add_arg_aux:n, \@@_add_arg_aux:V}
-%   The argument-storing system provides a single point for interfacing
-%   with processors. They are done in a loop, counting downward. In this
-%   way, the processor which was found last is executed first. The result
-%   is that processors apply from right to left, as intended. Notice that
-%   a set of braces are added back around the result of processing so that
-%   the internal function will correctly pick up one argument for each
-%   input argument.
+% \begin{macro}{\@@_add_arg:n, \@@_add_arg:V, \@@_add_arg:o, \@@_add_arg:x}
+%   When an argument is found it is stored, then further arguments are
+%   grabbed by calling \cs{l_@@_signature_tl}.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_add_arg:n #1
   {
-    \int_compare:nNnTF \l_@@_processor_int = \c_zero
-      { \tl_put_right:Nn \l_@@_args_tl { {#1} } }
-      {
-        \tl_clear:N \ProcessedArgument
-        \@@_if_no_value:nTF {#1}
-          {
-            \int_zero:N \l_@@_processor_int
-            \tl_put_right:Nn \l_@@_args_tl { {#1} }
-          }
-          { \@@_add_arg_aux:n {#1} }
-      }
+    \tl_put_right:Nn \l_@@_args_tl { {#1} }
+    \l_@@_signature_tl \@@_run_code:
   }
-\cs_generate_variant:Nn \@@_add_arg:n { V , o }
-\cs_new_protected:Npn \@@_add_arg_aux:n #1
-  {
-    \use:c { @@_processor_ \int_use:N \l_@@_processor_int :n } {#1}
-    \int_decr:N \l_@@_processor_int
-    \int_compare:nNnTF \l_@@_processor_int = \c_zero
-      {
-        \tl_put_right:Nx \l_@@_args_tl
-          { { \exp_not:V \ProcessedArgument } }
-      }
-      { \@@_add_arg_aux:V \ProcessedArgument }
-}
-\cs_generate_variant:Nn \@@_add_arg_aux:n { V }
+\cs_generate_variant:Nn \@@_add_arg:n { V , o , x }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 % \subsection{Grabbing arguments expandably}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_D:w}
-% \begin{macro}[EXP, aux]{\@@_expandable_grab_D:NNNnwN}
+% \begin{macro}[EXP, aux]{\@@_expandable_grab_D:NNNwNn}
 % \begin{macro}[EXP, aux]{\@@_expandable_grab_D:NNNwNnnn}
 % \begin{macro}[EXP, aux]{\@@_expandable_grab_D:Nw}
 % \begin{macro}[EXP, aux]{\@@_expandable_grab_D:nnNNNwN}
@@ -2785,25 +3184,24 @@
 %   it.
 %    \begin{macrocode}
 \cs_new:Npn \@@_expandable_grab_D:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_D:NNNnwNn #1 \q_@@ #2 } }
+  { #2 { \@@_expandable_grab_D:NNNwNn #1 \q_@@ #2 } }
 %    \end{macrocode}
-%   We then wish to test whether |#7|, which we just grabbed, is exactly |#2|.
+%   We then wish to test whether |#6|, which we just grabbed, is exactly |#2|.
 %   Expand the only grabber function we have, |#1|, once: the two strings below
-%   are equal if and only if |#7| matches |#2| exactly.\footnote{It is obvious
-%   that if \texttt{\#7} matches \texttt{\#2} then the strings are equal. We
+%   are equal if and only if |#6| matches |#2| exactly.\footnote{It is obvious
+%   that if \texttt{\#6} matches \texttt{\#2} then the strings are equal. We
 %   must check the converse. The right-hand-side of \cs{str_if_eq:onTF} does
 %   not end with \texttt{\#3}, implying that the grabber function took
 %   everything as its arguments. The first brace group can only be empty if
-%   \texttt{\#7} starts with \texttt{\#2}, otherwise the brace group preceding
-%   \texttt{\#7} would not vanish. The third brace group is empty, thus the
+%   \texttt{\#6} starts with \texttt{\#2}, otherwise the brace group preceding
+%   \texttt{\#6} would not vanish. The third brace group is empty, thus the
 %   \cs{q_@@} that was used by our grabber \texttt{\#1} must be the one
-%   that we inserted (not some token in \texttt{\#7}), hence the second brace
-%   group contains the end of \texttt{\#7} followed by \texttt{\#2}. Since this
+%   that we inserted (not some token in \texttt{\#6}), hence the second brace
+%   group contains the end of \texttt{\#6} followed by \texttt{\#2}. Since this
 %   is \texttt{\#2} on the right-hand-side, and no brace can be lost there,
-%   \texttt{\#7} must contain nothing else than its leading \texttt{\#2}.} If
-%   |#7| does not match |#2|, then the optional argument is missing, we use the
-%   default |#4|, and put back the argument |#7| in the input stream.
-%   %^^A There is probably a bug similar to the non-expandable O{\par} bug.
+%   \texttt{\#6} must contain nothing else than its leading \texttt{\#2}.} If
+%   |#6| does not match |#2|, then the optional argument is missing, we use the
+%   default |-NoValue-|, and put back the argument |#6| in the input stream.
 %
 %   If it does match, then interesting things need to be done. We will grab the
 %   argument piece by piece, with the following pattern:
@@ -2825,19 +3223,24 @@
 %   \meta{piece 2}. We stop grabbing arguments once the \meta{piece 2} contains
 %   no opening delimiter any more, hence the balance is reached, and the final
 %   argument is \meta{piece 1} \meta{piece 2}.
+%   The indirection via \cs{@@_tmp:w} allows to insert |-NoValue-| expanded.
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_D:NNNnwNn #1#2#3#4#5 \q_@@ #6#7
+\cs_set_protected:Npn \@@_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } { } #7 #2 \q_@@ #3 }
-      { { } {#2} { } }
+    \cs_new:Npn \@@_expandable_grab_D:NNNwNn ##1##2##3##4 \q_@@ ##5##6
       {
-        #1
-          { \@@_expandable_grab_D:NNNwNnnn #1#2#3#5 \q_@@ #6 }
-          \q_nil { } #2 \ERROR \q_@@ \ERROR
+        \str_if_eq:onTF
+          { ##1 { } { } ##6 ##2 \q_@@ ##3 }
+          { { } {##2} { } }
+          {
+            ##1
+              { \@@_expandable_grab_D:NNNwNnnn ##1##2##3##4 \q_@@ ##5 }
+              \q_nil { } ##2 \ERROR \q_@@ \ERROR
+          }
+          { ##4 {#1} \q_@@ ##5 {##6} }
       }
-      { #5 {#4} \q_@@ #6 {#7} }
   }
+\exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
 %    \end{macrocode}
 %   At this stage, |#6| is \cs{q_nil} \Arg{piece 1} \meta{more for piece 1},
 %   and we want to concatenate all that, removing \cs{q_nil}, and keeping the
@@ -2896,26 +3299,30 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_D_alt:w}
-% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:NNnwNn}
-% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:Nw}
+% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:NNwNn}
+% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:Nwn}
 %   When the delimiters are identical, nesting is not possible and a simplified
 %   approach is used. The test concept here is the same as for the case where
 %   the delimiters are different.
 %    \begin{macrocode}
 \cs_new:Npn \@@_expandable_grab_D_alt:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_D_alt:NNnwNn #1 \q_@@ #2 } }
-\cs_new:Npn \@@_expandable_grab_D_alt:NNnwNn #1#2#3#4 \q_@@ #5#6
+  { #2 { \@@_expandable_grab_D_alt:NNwNn #1 \q_@@ #2 } }
+\cs_set_protected:Npn \@@_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } #6 #2 #2 }
-      { { } #2 }
+    \cs_new:Npn \@@_expandable_grab_D_alt:NNwNn ##1##2##3 \q_@@ ##4##5
       {
-        #1
-          { \@@_expandable_grab_D_alt:Nwn #5 #4 \q_@@ }
-          #6 \ERROR
+        \str_if_eq:onTF
+          { ##1 { } ##5 ##2 ##2 }
+          { { } ##2 }
+          {
+            ##1
+              { \@@_expandable_grab_D_alt:Nwn ##4 ##3 \q_@@ }
+              ##5 \ERROR
+          }
+          { ##3 {#1} \q_@@ ##4 {##5} }
       }
-      { #4 {#3} \q_@@ #5 {#6} }
   }
+\exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
 \cs_new:Npn \@@_expandable_grab_D_alt:Nwn #1#2 \q_@@ #3
   {
     \tl_if_blank:oTF { \use_none:n #3 }
@@ -2934,6 +3341,74 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}[EXP]{\@@_expandable_grab_E:w}
+% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_test:nnwn}
+% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_loop:nnnNNw}
+% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_aux:nnw}
+% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_aux:nnnnn}
+% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_end:nnw}
+%   The function will be called repeatedly with two arguments: the set
+%   of pairs \meta{parser} \meta{token}, and the set of arguments found
+%   so far (initially all |{-NoValue-}|).  At each step, grab what
+%   follows in the input stream then call the \texttt{loop:nnnNNwn}
+%   auxiliary to compare it with each possible embellishment in turn.
+%   This auxiliary's |#1| is what was found in the input, |#2| collects
+%   \meta{parser} \meta{token} pairs that did not match, |#3| collects
+%   the corresponding arguments found previously, |#4| and |#5| is the
+%   current pair, |#6| is the remaining pairs, |#7| is empty or two
+%   \cs{q_nil}, and |#8| is the current argument.  If none of the pairs
+%   matched (determined by \cs{quark_if_nil:NTF}) then call the
+%   \texttt{end} auxiliary to stop looking for embellishments,
+%   remembering to put what was grabbed in the input back where it
+%   belongs, and storing the arguments found just before \cs{q_@@}.  If
+%   the current argument |#8| is not |-NoValue-| or if the input |#1|
+%   does not match |#5| (see \texttt{t}-type arguments below for a
+%   similar \cs{str_if_eq:onTF} test) then carry on the loop.
+%   Otherwise, we found a new embellishment: grab the corresponding
+%   argument in the input using the \texttt{:w} auxiliary.  To avoid
+%   losing braces around that auxiliary's argument |#4| we include a
+%   space, which will be eliminated in the next loop through
+%   embellishments.
+%    \begin{macrocode}
+\cs_new:Npn \@@_expandable_grab_E:w #1 \q_@@ #2
+  { #2 { \@@_expandable_grab_E_test:nnwn #1 \q_@@ #2 } }
+\cs_new:Npn \@@_expandable_grab_E_test:nnwn #1#2#3 \q_@@ #4#5
+  {
+    \@@_expandable_grab_E_loop:nnnNNw {#5} { } { }
+      #1 \q_nil \q_nil \q_nil \q_mark #2 \q_nil
+    #3 \q_@@ #4
+  }
+\cs_new:Npn \@@_expandable_grab_E_loop:nnnNNw
+    #1#2#3#4#5#6 \q_nil #7 \q_mark #8
+  {
+    \quark_if_nil:NTF #4
+      { \@@_expandable_grab_E_end:nnw {#1} {#3} }
+      {
+        \@@_if_no_value:nTF {#8}
+          { \str_if_eq:onTF { #4 { } #1 #5 } {#5} }
+          { \use_ii:nn }
+            { \@@_expandable_grab_E_aux:w { #2 #4 #5 #6 } {#3} ~ }
+            {
+              \@@_expandable_grab_E_loop:nnnNNw
+                {#1} { #2 #4 #5 } { #3 {#8} }
+                #6 \q_nil #7 \q_mark
+            }
+      }
+  }
+\cs_new:Npn \@@_expandable_grab_E_aux:w #1 \q_@@ #2
+  { #2 { \@@_expandable_grab_E_aux:nnw #1 \q_@@ #2 } }
+\cs_new:Npn \@@_expandable_grab_E_aux:nnw #1#2#3 \q_nil #4 \q_@@ #5#6
+  { \@@_expandable_grab_E:w {#1} { #2 {#6} #3 } #4 \q_@@ #5 }
+\cs_new:Npn \@@_expandable_grab_E_end:nnw #1#2#3 \q_@@ #4
+  { #3 {#2} \q_@@ #4 {#1} }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \begin{macro}[EXP]{\@@_expandable_grab_m:w}
 % \begin{macro}[EXP, aux]{\@@_expandable_grab_m_aux:wNn}
 %   The mandatory case is easy: find the auxiliary after the \cs{q_@@}, and
@@ -2948,34 +3423,38 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_R:w}
-% \begin{macro}[EXP, aux]{\@@_expandable_grab_R_aux:NNwn}
+% \begin{macro}[EXP, aux]{\@@_expandable_grab_R_aux:NNNwNn}
 %   Much the same as for the \texttt{D}-type argument, with only the lead-off
 %   function varying.
 %    \begin{macrocode}
 \cs_new:Npn \@@_expandable_grab_R:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_R_aux:NNNnwNn #1 \q_@@ #2 } }
-\cs_new:Npn \@@_expandable_grab_R_aux:NNNnwNn #1#2#3#4#5 \q_@@ #6#7
+  { #2 { \@@_expandable_grab_R_aux:NNNwNn #1 \q_@@ #2 } }
+\cs_set_protected:Npn \@@_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } { } #7 #2 \q_@@ #3 }
-      { { } {#2} { } }
+    \cs_new:Npn \@@_expandable_grab_R_aux:NNNwNn ##1##2##3##4 \q_@@ ##5##6
       {
-        #1
-          { \@@_expandable_grab_D:NNNwNnnn #1#2#3#5 \q_@@ #6 }
-          \q_nil { } #2 \ERROR \q_@@ \ERROR
+        \str_if_eq:onTF
+          { ##1 { } { } ##6 ##2 \q_@@ ##3 }
+          { { } {##2} { } }
+          {
+            ##1
+              { \@@_expandable_grab_D:NNNwNnnn ##1##2##3##4 \q_@@ ##5 }
+              \q_nil { } ##2 \ERROR \q_@@ \ERROR
+          }
+          {
+            \__msg_kernel_expandable_error:nnnn
+              { xparse } { missing-required } {##5} {##2}
+            ##4 {#1} \q_@@ ##5 {##6}
+          }
       }
-      {
-        \__msg_kernel_expandable_error:nnn
-          { xparse } { missing-required } {#2}
-        #5 {#4} \q_@@ #6 {#7}
-      }
   }
+\exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_R_alt:w}
-% \begin{macro}[EXP]{\@@_expandable_grab_R_alt_aux:NNnwNn}
+% \begin{macro}[EXP]{\@@_expandable_grab_R_alt_aux:NNwNn}
 %   When the delimiters are identical, nesting is not possible and a simplified
 %   approach is used. The test concept here is the same as for the case where
 %   the delimiters are different.
@@ -2982,22 +3461,26 @@
 %    \begin{macrocode}
 \cs_new:Npn \@@_expandable_grab_R_alt:w #1 \q_@@ #2
   { #2 { \@@_expandable_grab_R_alt_aux:NNnwNn #1 \q_@@ #2 } }
-\cs_new:Npn \@@_expandable_grab_R_alt_aux:NNnwNn #1#2#3#4 \q_@@ #5#6
+\cs_set_protected:Npn \@@_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } #6 #2 #2 }
-      { { } #2 }
+    \cs_new:Npn \@@_expandable_grab_R_alt_aux:NNwNn ##1##2##3 \q_@@ ##4##5
       {
-        #1
-          { \@@_expandable_grab_D_alt:Nwn #5 #4 \q_@@ }
-          #6 \ERROR
+        \str_if_eq:onTF
+          { ##1 { } ##5 ##2 ##2 }
+          { { } ##2 }
+          {
+            ##1
+              { \@@_expandable_grab_D_alt:Nwn ##4 ##3 \q_@@ }
+              ##5 \ERROR
+          }
+          {
+            \__msg_kernel_expandable_error:nnnn
+              { xparse } { missing-required } {##4} {##2}
+            ##3 {#1} \q_@@ ##4 {##5}
+          }
       }
-      {
-        \__msg_kernel_expandable_error:nnn
-          { xparse } { missing-required } {#2}
-        #4 {#3} \q_@@ #5 {#6}
-      }
   }
+\exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -3029,29 +3512,8 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[EXP]{\@@_grab_expandable_end:wN}
-%   For the end of the grabbing sequence: get rid of the generic grabber and
-%   insert the code function followed by its arguments.
-%    \begin{macrocode}
-\cs_new:Npn \@@_grab_expandable_end:wN #1 \q_@@ #2 {#1}
-%    \end{macrocode}
-% \end{macro}
-%
 % \subsection{Argument processors}
 %
-% \begin{macro}{\@@_process_arg:n}
-%   Processors are saved for use later during the grabbing process.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_process_arg:n #1
-  {
-    \int_incr:N \l_@@_processor_int
-    \cs_set_protected:cpx
-      { @@_processor_ \int_use:N \l_@@_processor_int :n } ##1
-      { \exp_not:n {#1} {##1} }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_bool_reverse:N}
 %   A simple reversal.
 %    \begin{macrocode}
@@ -3216,22 +3678,37 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\@@_get_arg_spec:NTF}
+%   If the command is not an \pkg{xparse} command, complain.  If it is,
+%   its second \enquote{item} is the argument specification.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_get_arg_spec:NTF #1#2#3
+  {
+    \@@_cmd_if_xparse:NTF #1
+      {
+        \tl_set:Nx \ArgumentSpecification { \tl_item:Nn #1 { 2 } }
+        #2
+      }
+      {#3}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\@@_get_arg_spec:N}
 % \begin{macro}{\@@_get_arg_spec:n}
 % \begin{variable}{\ArgumentSpecification}
-%   Recovering the argument specification is trivial, using the
-%   branching \cs{prop_get:NnN} function.
+%   Recovering the argument specification is now trivial.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_get_arg_spec:N #1
   {
-    \prop_get:NnNF \l_@@_command_arg_specs_prop {#1}
-      \ArgumentSpecification
+    \@@_get_arg_spec:NTF #1 { }
       { \@@_get_arg_spec_error:N #1 }
   }
 \cs_new_protected:Npn \@@_get_arg_spec:n #1
   {
-    \prop_get:NnNF \l_@@_environment_arg_specs_prop {#1}
-      \ArgumentSpecification
+    \exp_args:Nc \@@_get_arg_spec:NTF
+      { environment~ \tl_to_str:n {#1} }
+      { }
       { \@@_get_arg_spec_error:n {#1} }
   }
 \tl_new:N \ArgumentSpecification
@@ -3247,15 +3724,14 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_show_arg_spec:N #1
   {
-    \prop_get:NnNTF \l_@@_command_arg_specs_prop {#1}
-      \ArgumentSpecification
+    \@@_get_arg_spec:NTF #1
       { \tl_show:N \ArgumentSpecification }
       { \@@_get_arg_spec_error:N #1 }
   }
 \cs_new_protected:Npn \@@_show_arg_spec:n #1
   {
-    \prop_get:NnNTF \l_@@_environment_arg_specs_prop {#1}
-      \ArgumentSpecification
+    \exp_args:Nc \@@_get_arg_spec:NTF
+      { environment~ \tl_to_str:n {#1} }
       { \tl_show:N \ArgumentSpecification }
       { \@@_get_arg_spec_error:n {#1} }
   }
@@ -3342,12 +3818,74 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\@@_tl_mapthread_function:NNN, \@@_tl_mapthread_function:nnN}
+% \begin{macro}[aux]{\@@_tl_mapthread_loop:w}
+%   Analogue of \cs{seq_mapthread_function:NNN} for token lists.
+%    \begin{macrocode}
+\cs_new:Npn \@@_tl_mapthread_function:NNN #1#2#3
+  {
+    \exp_after:wN \exp_after:wN
+    \exp_after:wN \@@_tl_mapthread_loop:w
+    \exp_after:wN \exp_after:wN
+    \exp_after:wN #3
+    \exp_after:wN #1
+    \exp_after:wN \q_recursion_tail
+    \exp_after:wN \q_mark
+    #2
+    \q_recursion_tail
+    \q_recursion_stop
+  }
+\cs_new:Npn \@@_tl_mapthread_function:nnN #1#2#3
+  {
+    \@@_tl_mapthread_loop:w #3
+      #1 \q_recursion_tail \q_mark
+      #2 \q_recursion_tail \q_recursion_stop
+  }
+\cs_new:Npn \@@_tl_mapthread_loop:w #1#2#3 \q_mark #4
+  {
+    \quark_if_recursion_tail_stop:n {#2}
+    \quark_if_recursion_tail_stop:n {#4}
+    #1 {#2} {#4}
+    \@@_tl_mapthread_loop:w #1#3 \q_mark
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_cmd_if_xparse:NTF}
+% \begin{macro}[aux]{\@@_cmd_if_xparse_aux:N}
+%   To determine whether the command is an \pkg{xparse} command check
+%   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:nNNNn}
+%   (expandable command).
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_cmd_if_xparse:NTF #1
+  {
+    \exp_args:Nf \str_case_x:nnTF
+      {
+        \exp_args:Nf \tl_if_empty:nT { \token_get_arg_spec:N #1 }
+          {
+            \exp_last_unbraced:Nf \@@_cmd_if_xparse_aux:w
+              { \token_get_replacement_spec:N #1 } ~ \q_stop
+          }
+      }
+      {
+        { \token_to_str:N \@@_start:nNNnnn } { }
+        { \token_to_str:N \@@_start_expandable:nNNNn } { }
+      }
+  }
+\cs_new:Npn \@@_cmd_if_xparse_aux:w #1 ~ #2 \q_stop {#1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Messages}
 %
 % Some messages intended as errors.
 %    \begin{macrocode}
 \__msg_kernel_new:nnnn { xparse } { bad-arg-spec }
-  { Bad~argument~specification~'#1'. }
+  { Bad~argument~specification~'#2'~for~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
     The~argument~specification~provided~was~not~valid:~
@@ -3384,7 +3922,8 @@
   }
 \__msg_kernel_new:nnnn { xparse } { expandable-ending-optional }
   {
-    Argument~specification~for~expandable~command~ends~with~optional~argument.
+    Argument~specification~'#2'~for~expandable~command~'#1'~
+    ends~with~optional~argument.
   }
   {
     \c__msg_coding_error_text_tl
@@ -3393,7 +3932,7 @@
     argument~with~expandable~commands.
   }
 \__msg_kernel_new:nnnn { xparse } { inconsistent-long }
-  { Inconsistent~long~arguments~for~expandable~command. }
+  { Inconsistent~long~arguments~for~expandable~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
     The~arguments~for~an~expandable~command~must~either~all~be~
@@ -3400,20 +3939,26 @@
     short~or~all~be~long.~You~have~tried~to~mix~the~two~types.
   }
 \__msg_kernel_new:nnnn { xparse } { invalid-expandable-argument-type }
-  { Argument~type~'#1'~not~available~for~an~expandable~function. }
+  { Argument~type~'#2'~not~available~for~expandable~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
-    The~letter~'#1'~does~not~specify~an~argument~type~which~can~be~used~
-    in~an~expandable~function.
+    The~letter~'#2'~does~not~specify~an~argument~type~which~can~be~used~
+    in~an~expandable~command.
     \\ \\
-    LaTeX~will~assume~you~want~a~standard~mandatory~argument~(type~'m').
+    LaTeX~will~ignore~this~entire~definition.
   }
+\__msg_kernel_new:nnnn { xparse } { loop-in-defaults }
+  { Circular~dependency~in~defaults~of~'#1'. }
+  {
+    \c__msg_coding_error_text_tl
+    The~default~values~of~two~or~more~arguments~of~'#1'~depend~on~each~
+    other~in~a~way~that~cannot~be~resolved.
+  }
 \__msg_kernel_new:nnnn { xparse } { missing-required }
-  { Failed~to~find~required~argument~starting~with~'#1'. }
+  { Failed~to~find~required~argument~starting~with~'#2'~for~command~'#1'. }
   {
-    There~is~supposed~to~be~an~argument~to~the~current~function~starting~with~
-    '#1'.~LaTeX~did~not~find~it,~and~will~insert~'#2'~as~the~value~to~be~
-    processed.
+    The~current~command~'#1'~expects~an~argument~starting~with~'#2'.~
+    LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed.
   }
 \__msg_kernel_new:nnnn { xparse } { non-xparse-command }
   { Command~'#1'~not~defined~using~xparse. }
@@ -3448,19 +3993,20 @@
     LaTeX~will~ignore~this~entire~definition.
   }
 \__msg_kernel_new:nnnn { xparse } { not-single-token }
-  { Argument~delimiter~should~be~a~single~token:~'#1'. }
+  { Argument~delimiter~'#2'~for~the~command~'#1'~should~be~a~single~token. }
   {
     \c__msg_coding_error_text_tl
     The~argument~specification~provided~was~not~valid:~
-    in~a~place~where~a~single~token~is~required,~LaTeX~found~'#1'. \\ \\
+    in~a~place~where~a~single~token~is~required,~LaTeX~found~'#2'. \\ \\
     LaTeX~will~ignore~this~entire~definition.
   }
 \__msg_kernel_new:nnnn { xparse } { processor-in-expandable }
-  { Argument~processors~cannot~be~used~with~expandable~functions. }
+  { Argument~processor~'>{#2}'~cannot~be~used~for~the~expandable~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
     The~argument~specification~for~#1~contains~a~processor~function:~
-    this~is~only~supported~for~standard~robust~functions.
+    this~is~only~supported~for~standard~robust~commands. \\ \\
+    LaTeX~will~ignore~this~entire~definition.
   }
 \__msg_kernel_new:nnnn { xparse } { split-excess-tokens }
   { Too~many~'#1'~tokens~when~trying~to~split~argument. }
@@ -3469,12 +4015,20 @@
     at~each~occurrence~of~the~token~'#1',~up~to~a~maximum~of~#2~parts.~
     There~were~too~many~'#1'~tokens.
   }
+\__msg_kernel_new:nnnn { xparse } { too-many-arguments }
+  { Too~many~arguments~in~argument~specification~'#2'~of~command~'#1'. }
+  {
+    \c__msg_coding_error_text_tl
+    The~argument~specification~provided~has~more~than~9~arguments.~
+    This~cannot~be~implemented. \\ \\
+    LaTeX~will~ignore~this~entire~definition.
+  }
 \__msg_kernel_new:nnnn { xparse } { unknown-argument-type }
-  { Unknown~argument~type~'#1'~replaced~by~'m'. }
+  { Unknown~argument~type~'#2'~for~the~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
-    The~letter~'#1'~does~not~specify~a~known~argument~type.~
-    LaTeX~will~assume~you~want~a~standard~mandatory~argument~(type~'m').
+    The~letter~'#2'~does~not~specify~a~known~argument~type.~
+    LaTeX~will~ignore~this~entire~definition.
   }
 \__msg_kernel_new:nnnn { xparse } { unknown-command }
   { Unknown~document~command~'#1'. }
@@ -3533,6 +4087,12 @@
     Redefining~environment~'#1'~
     with~sig.~'#2'~\msg_line_context:.
   }
+\__msg_kernel_new:nnn { xparse } { optional-mandatory }
+  {
+    Since~the~mandatory~argument~'#1'~has~the~same~delimiter~'#2'~
+    as~a~previous~optional~argument,~it~will~not~be~possible~to~
+    omit~all~optional~arguments~when~calling~this~command.
+  }
 %    \end{macrocode}
 %
 % \subsection{User functions}

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx	2017-02-10 23:29:10 UTC (rev 43183)
@@ -27,8 +27,8 @@
 %<*driver|package>
 % The version of expl3 required is tested as early as possible, as
 % some really old versions do not define \ProvidesExplPackage.
-\RequirePackage{expl3}[2017/02/07]
-%<package>\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+%<package>\@ifpackagelater{expl3}{2017/02/10}
 %<package>  {}
 %<package>  {%
 %<package>    \PackageError{xtemplate}{Support package l3kernel too old}
@@ -42,8 +42,8 @@
 %<package>  }
 \def\ExplFileName{xtemplate}
 \def\ExplFileDescription{L3 Experimental prototype document functions}
-\def\ExplFileDate{2017/02/07}
-\def\ExplFileVersion{6846}
+\def\ExplFileDate{2017/02/10}
+\def\ExplFileVersion{6878}
 %</driver|package>
 %<*driver>
 \documentclass[full]{l3doc}

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3flag.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3flag.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3flag.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,8 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3flag.dtx Copyright (C) 2011-2012,2014-2016 The LaTeX3 Project
-\RequirePackage{expl3}[2017/02/07]
-\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+\@ifpackagelater{expl3}{2017/02/10}
   {}
   {%
     \PackageError{l3flag}{Support package l3kernel too old}
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\GetIdInfo$Id: l3flag.dtx 6846 2017-02-07 07:04:19Z joseph $
+\GetIdInfo$Id: l3flag.dtx 6878 2017-02-10 07:40:59Z joseph $
   {L3 Experimental flags}
 \ProvidesExplPackage
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex-trace.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex-trace.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex-trace.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,8 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3regex.dtx Copyright (C) 2011-2016 The LaTeX3 Project
-\RequirePackage{expl3}[2017/02/07]
-\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+\@ifpackagelater{expl3}{2017/02/10}
   {}
   {%
     \PackageError{l3regex}{Support package l3kernel too old}
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\GetIdInfo$Id: l3regex.dtx 6846 2017-02-07 07:04:19Z joseph $
+\GetIdInfo$Id: l3regex.dtx 6878 2017-02-10 07:40:59Z joseph $
   {L3 Experimental regular expressions}
 \ProvidesExplPackage
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3regex.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,8 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3regex.dtx Copyright (C) 2011-2016 The LaTeX3 Project
-\RequirePackage{expl3}[2017/02/07]
-\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+\@ifpackagelater{expl3}{2017/02/10}
   {}
   {%
     \PackageError{l3regex}{Support package l3kernel too old}
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\GetIdInfo$Id: l3regex.dtx 6846 2017-02-07 07:04:19Z joseph $
+\GetIdInfo$Id: l3regex.dtx 6878 2017-02-10 07:40:59Z joseph $
   {L3 Experimental regular expressions}
 \ProvidesExplPackage
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3tl-build.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3tl-build.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/l3str/l3tl-build.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,8 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3tl-build.dtx Copyright (C) 2011-2016 The LaTeX3 Project
-\RequirePackage{expl3}[2017/02/07]
-\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+\@ifpackagelater{expl3}{2017/02/10}
   {}
   {%
     \PackageError{l3tl-build}{Support package l3kernel too old}
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\GetIdInfo$Id: l3tl-build.dtx 6846 2017-02-07 07:04:19Z joseph $
+\GetIdInfo$Id: l3tl-build.dtx 6878 2017-02-10 07:40:59Z joseph $
   {L3 Experimental token list construction}
 \ProvidesExplPackage
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}

Modified: trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3experimental/xgalley/l3galley.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -20,8 +20,8 @@
 %% 
 %% File: l3galley.dtx Copyright (C) 1999-2001, 2004-2009 Frank Mittelbach
 %%                              (C) 2010-2016 The LaTeX3 Project
-\RequirePackage{expl3}[2017/02/07]
-\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+\@ifpackagelater{expl3}{2017/02/10}
   {}
   {%
     \PackageError{l3galley}{Support package l3kernel too old}
@@ -33,7 +33,7 @@
       }%
     \endinput
   }
-\GetIdInfo$Id: l3galley.dtx 6846 2017-02-07 07:04:19Z joseph $
+\GetIdInfo$Id: l3galley.dtx 6878 2017-02-10 07:40:59Z joseph $
   {L3 Experimental galley code}
 \ProvidesExplPackage
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex	2017-02-10 23:29:10 UTC (rev 43183)
@@ -58,8 +58,8 @@
 %% File: expl3.dtx Copyright (C) 1990-2017 The LaTeX3 Project
 \def\ExplFileName{expl3}%
 \def\ExplFileDescription{L3 programming layer}%
-\def\ExplFileDate{2017/02/07}%
-\def\ExplFileVersion{6846}%
+\def\ExplFileDate{2017/02/10}%
+\def\ExplFileVersion{6878}%
 \begingroup
   \def\next{\endgroup}%
   \expandafter\ifx\csname PackageError\endcsname\relax
@@ -10791,7 +10791,7 @@
     \exp_after:wN \__fp_exp_after_o:w \exp:w \exp_end_continue_f:w
     \__fp_sanitize:Nw #1#2; {1000}{0000}{0000}{0000};
   }
-%% File: l3fp-parse.dtx Copyright (C) 2011-2016 The LaTeX3 Project
+%% File: l3fp-parse.dtx Copyright (C) 2011-2017 The LaTeX3 Project
 \int_const:Nn \c__fp_prec_funcii_int { 16 }
 \int_const:Nn \c__fp_prec_func_int   { 15 }
 \int_const:Nn \c__fp_prec_hatii_int  { 14 }
@@ -10906,6 +10906,9 @@
     \exp_after:wN \__fp_parse_infix_after_operand:NwN
     \exp_after:wN #1
     \exp:w \exp_end_continue_f:w
+      \if_meaning:w \box_wd:N #2 \__fp_parse_one_register_wd:w \fi:
+      \if_meaning:w \box_ht:N #2 \__fp_parse_one_register_wd:w \fi:
+      \if_meaning:w \box_dp:N #2 \__fp_parse_one_register_wd:w \fi:
       \exp_after:wN \__fp_parse_one_register_aux:Nw
       \exp_after:wN #2
       \__int_value:w
@@ -10942,6 +10945,20 @@
     \__int_value:w #2 \exp_after:wN ,
     \__int_value:w \__dim_eval:w #1 pt ;
   }
+\cs_new:Npn \__fp_parse_one_register_wd:w
+    #1#2 \exp_after:wN #3#4 \__fp_parse_expand:w
+  {
+    #1
+    \exp_after:wN \__fp_parse_one_register_wd:Nw
+    #4 \__fp_parse_expand:w e
+  }
+\cs_new:Npn \__fp_parse_one_register_wd:Nw #1#2 ;
+  {
+    \exp_after:wN \__fp_from_dim_test:ww
+    \exp_after:wN 0 \exp_after:wN ,
+    \__int_value:w \__dim_eval:w
+      \exp_after:wN \use:n \exp_after:wN { \tex_the:D #1 #2 } ;
+  }
 \cs_new:Npn \__fp_parse_one_digit:NN #1
   {
     \exp_after:wN \__fp_parse_infix_after_operand:NwN
@@ -15490,7 +15507,7 @@
 \fp_new:N \g_tmpa_fp
 \fp_new:N \g_tmpb_fp
 %% File l3sort.dtx (C) Copyright 2012,2014-2017 The LaTeX3 Project
-\GetIdInfo$Id: l3sort.dtx 6842 2017-02-06 21:51:22Z joseph $
+\GetIdInfo$Id: l3sort.dtx 6847 2017-02-07 15:05:44Z bruno $
   {L3 Sorting functions}
 \int_new:N \l__sort_length_int
 \int_new:N \l__sort_min_int

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex	2017-02-10 23:29:10 UTC (rev 43183)
@@ -21,8 +21,8 @@
 %% File: expl3.dtx Copyright (C) 1990-2017 The LaTeX3 Project
 \def\ExplFileName{expl3}%
 \def\ExplFileDescription{L3 programming layer}%
-\def\ExplFileDate{2017/02/07}%
-\def\ExplFileVersion{6846}%
+\def\ExplFileDate{2017/02/10}%
+\def\ExplFileVersion{6878}%
 \let\ExplLoaderFileVersion\ExplFileVersion
 \begingroup
   \def\tempa{LaTeX2e}%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -21,8 +21,8 @@
 %% File: expl3.dtx Copyright (C) 1990-2017 The LaTeX3 Project
 \def\ExplFileName{expl3}%
 \def\ExplFileDescription{L3 programming layer}%
-\def\ExplFileDate{2017/02/07}%
-\def\ExplFileVersion{6846}%
+\def\ExplFileDate{2017/02/10}%
+\def\ExplFileVersion{6878}%
 \let\ExplLoaderFileVersion\ExplFileVersion
 \ProvidesPackage{\ExplFileName}
   [%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3basics}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3bootstrap.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3bootstrap.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3bootstrap.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3bootstrap}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3box.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3box.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3box.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3box}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3candidates.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3candidates.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3candidates.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3candidates}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3clist}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3coffins}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3color.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3color.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3color.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3color}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls	2017-02-10 23:29:10 UTC (rev 43183)
@@ -24,7 +24,7 @@
 \let     \fileversionOld        \ExplFileVersion
 \let \filedescriptionOld        \ExplFileDescription
 \RequirePackage{expl3,xparse,calc}
-\GetIdInfo$Id: l3doc.dtx 6839 2017-02-06 18:52:08Z bruno $
+\GetIdInfo$Id: l3doc.dtx 6847 2017-02-07 15:05:44Z bruno $
           {L3 Experimental documentation class}
 \ProvidesExplClass
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
@@ -842,7 +842,7 @@
   }
 \cs_new_protected:Npn \__codedoc_deprecated_on:n #1
   {
-    \__codedoc_date_compare:nNnT {#1} < { \tex_year:D / \tex_month:D / \tex_day:D }
+    \__codedoc_date_compare:nNnT {#1} < { \tex_year:D - \tex_month:D - \tex_day:D }
       {
         \msg_error:nnxx { l3doc } { deprecated-function }
           { \tl_to_str:N \l__codedoc_macro_argument_tl } {#1}

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3expan}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3file.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3file.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3file.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3file}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3fp}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3int.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3int.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3int.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3int}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3keys}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3msg}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3names.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3names.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3names.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3names}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3prg}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3prop}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3quark}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3seq}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3skip}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3sort.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3sort.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3sort.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3sort}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,17 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
-\typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** The old packages will be removed entirely at the end of 2018.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageWarning
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3str.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3str.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3str.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3str}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3tl}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3token.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3token.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3token.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3oldmodules.dtx Copyright (C) 2014,2016,2017 The LaTeX3 Project
-\def\ExplFileDate{2014/09/06}
-
+\def\ExplFileDate{2017/02/10}
 \def\old at liii@module at name
 {l3token}
 \ProvidesPackage\old at liii@module at name
@@ -32,18 +31,20 @@
 \typeout{** }
 \typeout{** Package \old at liii@module at name\space is obsolete and has been removed!}
 \typeout{** }
-\typeout{** Its functionality is now only provided as part of in the expl3 package}
+\typeout{** Its functionality is now only provided as part of the expl3 package.}
 \typeout{** }
 \typeout{** After showing you an error message you can hit <return> we will continue}
-\typeout{** for now by loading expl3 for you. However, at some point in the future}
-\typeout{** the old packages will be removed.}
+\typeout{** for now by loading expl3 for you. However, the old packages will be}
+\typeout{** removed entirely at the end of 2017.}
 \typeout{** }
 \typeout{** Therefore, please replace '\string\usepackage{\old at liii@module at name}'}
 \typeout{** with '\string\usepackage{expl3}' in your documents as soon as possible.}
 \typeout{** }
 \typeout{*******************************************************************}
-\PackageError\old at liii@module at name{This package is obsolete ---
-   use 'expl3' instead}\@ehc
+\PackageError
+  \old at liii@module at name{This package is obsolete ---
+   use 'expl3' instead}
+  \@ehc
 \RequirePackage{expl3}
 %% 
 %%

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -19,8 +19,8 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: l3keys2e.dtx (C) Copyright 2009,2011-2017 The LaTeX3 Project
-\RequirePackage{expl3}[2017/02/07]
-\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+\@ifpackagelater{expl3}{2017/02/10}
   {}
   {%
     \PackageError{l3keys2e}{Support package l3kernel too old}
@@ -34,8 +34,8 @@
   }
 \def\ExplFileName{l3keys2e}
 \def\ExplFileDescription{LaTeX2e option processing using LaTeX3 keys}
-\def\ExplFileDate{2017/02/07}
-\def\ExplFileVersion{6846}
+\def\ExplFileDate{2017/02/10}
+\def\ExplFileVersion{6878}
 \ProvidesExplPackage
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
 \cs_generate_variant:Nn \clist_put_right:Nn { Nv }

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -20,8 +20,8 @@
 %% 
 %% File: xfrac.dtx Copyright (C) 2004, 2008-2010 Morten Hoegholm
 %%                           (C) 2011,2012,2014-2017 The LaTeX3 Project
-\RequirePackage{expl3}[2017/02/07]
-\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+\@ifpackagelater{expl3}{2017/02/10}
   {}
   {%
     \PackageError{xfrac}{Support package l3kernel too old}
@@ -36,8 +36,8 @@
 \RequirePackage{amstext,graphicx,l3keys2e,textcomp,xparse,xtemplate}
 \def\ExplFileName{xfrac}
 \def\ExplFileDescription{L3 Experimental split-level fractions}
-\def\ExplFileDate{2017/02/07}
-\def\ExplFileVersion{6846}
+\def\ExplFileDate{2017/02/10}
+\def\ExplFileVersion{6878}
 \ProvidesExplPackage
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
 \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	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -22,9 +22,9 @@
 %%                      David Carlisle
 %%                  (C) Copyright 2004-2008 Frank Mittelbach,
 %%                      The LaTeX3 Project
-%%                  (C) Copyright 2009-2016 The LaTeX3 Project
-\RequirePackage{expl3}[2017/02/07]
-\@ifpackagelater{expl3}{2017/02/07}
+%%                  (C) Copyright 2009-2017 The LaTeX3 Project
+\RequirePackage{expl3}[2017/02/10]
+\@ifpackagelater{expl3}{2017/02/10}
   {}
   {%
     \PackageError{xparse}{Support package l3kernel too old}
@@ -38,22 +38,22 @@
   }
 \def\ExplFileName{xparse}
 \def\ExplFileDescription{L3 Experimental document command parser}
-\def\ExplFileDate{2017/02/07}
-\def\ExplFileVersion{6846}
+\def\ExplFileDate{2017/02/10}
+\def\ExplFileVersion{6878}
 \ProvidesExplPackage
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
 \tl_const:Nx \c__xparse_no_value_tl
   { \char_generate:nn { `\- } { 11 } NoValue- }
-\prop_new:N \c__xparse_shorthands_prop
-\prop_put:Nnn \c__xparse_shorthands_prop { o } { d[] }
-\prop_put:Nnn \c__xparse_shorthands_prop { O } { D[] }
-\prop_put:Nnn \c__xparse_shorthands_prop { s } { t* }
 \bool_new:N \l__xparse_all_long_bool
+\bool_new:N \l__xparse_all_long_set_bool
+\tl_new:N \l__xparse_arg_spec_tl
 \tl_new:N \l__xparse_args_tl
-\prop_new:N \l__xparse_command_arg_specs_prop
+\tl_new:N \l__xparse_args_i_tl
+\tl_new:N \l__xparse_args_ii_tl
 \int_new:N \l__xparse_current_arg_int
+\bool_new:N \l__xparse_defaults_bool
+\tl_new:N \l__xparse_defaults_tl
 \bool_new:N \l__xparse_environment_bool
-\prop_new:N \l__xparse_environment_arg_specs_prop
 \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
@@ -61,17 +61,23 @@
     \l__xparse_function_tl \c_space_tl
     ( arg~ \int_use:N \l__xparse_current_arg_int )
   }
+\int_new:N \g__xparse_grabber_int
 \tl_new:N \l__xparse_fn_tl
+\tl_new:N \l__xparse_fn_code_tl
 \tl_new:N \l__xparse_function_tl
+\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_processor_bool
-\int_new:N \l__xparse_processor_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_signature_tl
 \prop_new:N \l__xparse_tmp_prop
 \tl_new:N \l__xparse_tmpa_tl
 \tl_new:N \l__xparse_tmpb_tl
+\cs_new_eq:NN \__xparse_tmp:w ?
 \cs_new_protected:Npn \__xparse_declare_cmd:Nnn
   {
     \bool_set_false:N \l__xparse_expandable_bool
@@ -93,7 +99,6 @@
         \__msg_kernel_info:nnxx { xparse } { define-command }
           { \token_to_str:N #1 } { \tl_to_str:n {#2} }
       }
-    \prop_put:Nnn \l__xparse_command_arg_specs_prop {#1} {#2}
     \bool_set_false:N \l__xparse_environment_bool
     \__xparse_declare_cmd_internal:Nnn #1 {#2}
   }
@@ -100,65 +105,64 @@
 \cs_new_protected:Npn \__xparse_declare_cmd_internal:Nnn #1#2#3
   {
     \tl_set:Nx \l__xparse_function_tl { \cs_to_str:N #1 }
-    \__xparse_count_mandatory:n {#2}
-    \__xparse_prepare_signature:n {#2}
-    \int_compare:nNnTF \l__xparse_current_arg_int = \l__xparse_m_args_int
-      {
-        \bool_if:NTF \l__xparse_environment_bool
-          { \__xparse_declare_cmd_mixed:Nn #1 {#3} }
-          { \__xparse_declare_cmd_all_m:Nn #1 {#3} }
-      }
-      { \__xparse_declare_cmd_mixed:Nn #1 {#3} }
+    \__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}
     \__xparse_break_point:n {#2}
   }
 \cs_generate_variant:Nn \__xparse_declare_cmd_internal:Nnn { cnx }
 \cs_new_eq:NN \__xparse_break_point:n \use_none:n
-\cs_new_protected:Npn \__xparse_declare_cmd_all_m:Nn #1#2
+\cs_new_protected:Npn \__xparse_declare_cmd_code:Nnn
   {
-    \cs_generate_from_arg_count:Ncnn #1
-      {
-        cs_set
-        \bool_if:NF \l__xparse_expandable_bool { _protected }
-        \bool_if:NF \l__xparse_all_long_bool { _nopar }
-        :Npn
-      }
-      \l__xparse_current_arg_int {#2}
-  }
-\cs_new_protected:Npn \__xparse_declare_cmd_mixed:Nn
-  {
     \bool_if:NTF \l__xparse_expandable_bool
-      { \__xparse_declare_cmd_mixed_expandable:Nn }
-      { \__xparse_declare_cmd_mixed_aux:Nn }
+      { \__xparse_declare_cmd_code_expandable:Nnn }
+      { \__xparse_declare_cmd_code_aux:Nnn }
    }
-\cs_new_protected:Npn \__xparse_declare_cmd_mixed_aux:Nn #1#2
+\cs_new_protected:Npn \__xparse_declare_cmd_code_aux:Nnn #1#2#3
   {
-    \__xparse_flush_m_args:
     \cs_generate_from_arg_count:cNnn
       { \l__xparse_function_tl \c_space_tl code }
-      \cs_set_protected:Npn \l__xparse_current_arg_int {#2}
+      \cs_set_protected:Npn \l__xparse_current_arg_int {#3}
     \cs_set_protected_nopar:Npx #1
       {
-        \int_zero:N \l__xparse_processor_int
-        \tl_set:Nn \exp_not:N \l__xparse_args_tl
-          { \exp_not:c { \l__xparse_function_tl \c_space_tl code } }
-        \tl_set:Nn \exp_not:N \l__xparse_fn_tl
-          { \exp_not:c { \l__xparse_function_tl \c_space_tl } }
-        \exp_not:o \l__xparse_signature_tl
-        \exp_not:N \l__xparse_args_tl
+        \__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
+              { \exp_not:o \l__xparse_defaults_tl }
+          }
+          {
+            \bool_if:NT \l__xparse_process_some_bool
+              { \exp_not:o \l__xparse_process_all_tl }
+          }
       }
   }
-\cs_new_protected:Npn \__xparse_declare_cmd_mixed_expandable:Nn #1#2
+\cs_new_protected:Npn \__xparse_declare_cmd_code_expandable:Nnn #1#2#3
   {
     \cs_generate_from_arg_count:cNnn
       { \l__xparse_function_tl \c_space_tl code }
-      \cs_set:Npn \l__xparse_current_arg_int {#2}
+      \cs_set:Npn \l__xparse_current_arg_int {#3}
+    \bool_if:NT \l__xparse_defaults_bool
+      {
+        \use:x
+          {
+            \cs_generate_from_arg_count:cNnn
+              { \l__xparse_function_tl \c_space_tl defaults }
+              \cs_set:Npn \l__xparse_current_arg_int
+              { \exp_not:o \l__xparse_defaults_tl }
+          }
+      }
     \cs_set_nopar:Npx #1
       {
-        \exp_not:o \l__xparse_signature_tl
-        \exp_not:N \__xparse_grab_expandable_end:wN
-        \exp_not:c { \l__xparse_function_tl \c_space_tl code }
-        \exp_not:N \q__xparse
-        \exp_not:c { \l__xparse_function_tl \c_space_tl }
+        \exp_not:N \__xparse_start_expandable:nNNNn
+          { \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:c { \l__xparse_function_tl \c_space_tl defaults }
+          { \exp_not:o \l__xparse_signature_tl }
       }
     \bool_if:NTF \l__xparse_all_long_bool
       { \cs_set:cpx }
@@ -176,7 +180,6 @@
         \__msg_kernel_info:nnxx { xparse } { define-environment }
           {#1} { \tl_to_str:n {#2} }
       }
-    \prop_put:Nnn \l__xparse_environment_arg_specs_prop {#1} {#2}
     \bool_set_false:N \l__xparse_expandable_bool
     \bool_set_true:N \l__xparse_environment_bool
     \__xparse_declare_env_internal:nnnn {#1} {#2}
@@ -188,7 +191,7 @@
         \cs_set_nopar:Npx \exp_not:c { environment~ #1 ~end~aux }
           {
             \exp_not:N \exp_not:N \exp_not:c { environment~ #1~end~aux~ }
-            \exp_not:n { \tl_tail:N \l__xparse_args_tl }
+            \exp_not:n { \exp_not:o \l__xparse_args_tl }
           }
         \exp_not:n {#3}
       }
@@ -200,222 +203,467 @@
     \cs_set_eq:cc {#1}       { environment~ #1 }
     \cs_set_eq:cc { end #1 } { environment~ #1 ~end }
   }
-\cs_new_protected:Npn \__xparse_count_mandatory:n #1
+\cs_new_protected:Npn \__xparse_start: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_defaults_tl {#5}
+    \tl_set:Nn \l__xparse_process_all_tl {#6}
+    #4 \__xparse_run_code:
+  }
+\cs_new_protected:Npn \__xparse_run_code:
+  {
+    \tl_if_empty:NF \l__xparse_defaults_tl { \__xparse_defaults: }
+    \tl_if_empty:NF \l__xparse_process_all_tl { \__xparse_args_process: }
+    \exp_after:wN \l__xparse_fn_code_tl \l__xparse_args_tl
+  }
+\cs_new_protected:Npn \__xparse_defaults:
+  {
+    \__xparse_defaults_def:
+    \tl_set_eq:NN \l__xparse_args_i_tl \l__xparse_args_tl
+    \__xparse_defaults_aux: \__xparse_defaults_aux: \__xparse_defaults_aux:
+    \__xparse_defaults_aux: \__xparse_defaults_aux: \__xparse_defaults_aux:
+    \__xparse_defaults_aux: \__xparse_defaults_aux: \__xparse_defaults_aux:
+    \__xparse_defaults_error:w
+    \q_recursion_stop
+    \tl_set_eq:NN \l__xparse_args_tl \l__xparse_args_i_tl
+  }
+\cs_new_protected:Npn \__xparse_defaults_aux:
+  {
+    \tl_set:Nx \l__xparse_args_ii_tl
+      { \exp_after:wN \__xparse_tmp:w \l__xparse_args_i_tl }
+    \tl_if_eq:NNT \l__xparse_args_ii_tl \l__xparse_args_i_tl
+      { \use_none_delimit_by_q_recursion_stop:w }
+    \tl_set_eq:NN \l__xparse_args_i_tl \l__xparse_args_ii_tl
+  }
+\cs_new_protected:Npn \__xparse_defaults_error:w \q_recursion_stop
+  {
+    \__msg_kernel_error:nnx { xparse } { loop-in-defaults }
+      { \exp_after:wN \token_to_str:N \l__xparse_fn_tl }
+  }
+\cs_new_protected:Npn \__xparse_defaults_def:
+  {
+    \tl_clear:N \l__xparse_tmpa_tl
+    \int_zero:N \l__xparse_current_arg_int
+    \__xparse_tl_mapthread_function:NNN \l__xparse_args_tl \l__xparse_defaults_tl
+      \__xparse_defaults_def:nn
+    \cs_generate_from_arg_count:NNVo \__xparse_tmp:w \cs_set:Npn
+      \l__xparse_current_arg_int \l__xparse_tmpa_tl
+  }
+\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNVo }
+\cs_new_protected:Npn \__xparse_defaults_def:nn
+  {
+    \int_incr:N \l__xparse_current_arg_int
+    \exp_args:NV \__xparse_defaults_def:nnn \l__xparse_current_arg_int
+  }
+\cs_new_protected:Npn \__xparse_defaults_def:nnn #1#2#3
+  {
+    \tl_if_head_is_group:nTF {#3}
+      {
+        \tl_put_right:Nn \l__xparse_tmpa_tl
+          {
+            {
+              \exp_args:Nf \__xparse_tl_mapthread_function:nnN
+                { \tl_item:Nn \l__xparse_args_tl {#1} }
+                {#3}
+                \__xparse_defaults_def_aux:nn
+            }
+          }
+      }
+      {
+        \__xparse_if_no_value:nTF {#2}
+          {
+            \tl_put_right:Nx \l__xparse_tmpa_tl
+              { { \exp_not:N \exp_not:n { \exp_not:o { \use_none:n #3 } } } }
+          }
+          {
+            \tl_put_right:Nn \l__xparse_tmpa_tl
+              { { \exp_not:n { ## #1 } } }
+          }
+      }
+  }
+\cs_new:Npn \__xparse_defaults_def_aux:nn #1#2
+  {
+    \__xparse_if_no_value:nTF {#1}
+      { { \exp_not:n {#2} } }
+      { { \exp_not:n {#1} } }
+  }
+\cs_new_protected:Npn \__xparse_args_process:
+  {
+    \tl_clear:N \l__xparse_args_ii_tl
+    \__xparse_tl_mapthread_function:NNN
+      \l__xparse_args_tl
+      \l__xparse_process_all_tl
+      \__xparse_args_process_loop:nn
+    \tl_set_eq:NN \l__xparse_args_tl \l__xparse_args_ii_tl
+  }
+\cs_new_protected:Npn \__xparse_args_process_loop:nn #1#2
+  {
+    \tl_set:Nn \ProcessedArgument {#1}
+    \__xparse_if_no_value:nF {#1}
+      { \tl_map_function:nN {#2} \__xparse_args_process_aux:n }
+    \tl_put_right:No \l__xparse_args_ii_tl
+      { \exp_after:wN { \ProcessedArgument } }
+  }
+\cs_new_protected:Npn \__xparse_args_process_aux:n
+  { \exp_args:No \__xparse_args_process_aux:nn { \ProcessedArgument } }
+\cs_new_protected:Npn \__xparse_args_process_aux:nn #1#2 { #2 {#1} }
+\cs_new:Npn \__xparse_start_expandable:nNNNn #1#2#3#4#5
+  { #5 \__xparse_end_expandable:NNw #4 #3 \q__xparse #2 }
+\cs_new:Npn \__xparse_end_expandable:NNw #1#2
+  { \__xparse_end_expandable_aux:w #1#2 \prg_do_nothing: }
+\cs_new:Npn \__xparse_end_expandable_aux:w #1#2#3 \q__xparse #4
+  { \exp_args:No \__xparse_end_expandable_aux:nNNN {#3} #1 #2 #4 }
+\cs_new:Npn \__xparse_end_expandable_aux:nNNN #1#2#3#4
+  {
+    \cs_if_exist:NF #2 { \exp_after:wN \use_iv:nnnn }
+    \__xparse_end_expandable_defaults:nnnNNn {#1} { } {#1} #2#3
+      { } { } { } { } { } { } { } { } { } { }
+      {
+        \__msg_kernel_expandable_error:nnn
+          { xparse } { loop-in-defaults } {#4}
+        \use_iv:nnnn
+      }
+    \q_stop
+  }
+\cs_new:Npn \__xparse_end_expandable_defaults:nnnNNn #1#2#3#4#5#6
+  {
+    #6
+    \str_if_eq:nnTF {#1} {#2}
+      { \use_i_delimit_by_q_stop:nw { #5 #1 } }
+      {
+        \exp_args:No \__xparse_tl_mapthread_function:nnN
+          { #4 #1 } {#3}
+          \__xparse_end_expandable_defaults:nnw
+        \__xparse_end_expandable_defaults:nnnNNn { } {#1} {#3} #4 #5
+      }
+  }
+\cs_new:Npn \__xparse_end_expandable_defaults:nnw #1#2
+  {
+    \tl_if_head_is_group:nTF {#1}
+      {
+        \__xparse_end_expandable_defaults_E:nnw { }
+          #1 \q_nil \q_mark
+          #2 \q_nil
+      }
+      {
+        \__xparse_if_no_value:nTF {#2}
+          { \exp_args:No \__xparse_end_expandable_defaults:nw { \use_none:n #1 } }
+          { \__xparse_end_expandable_defaults:nw {#2} }
+      }
+  }
+\cs_new:Npn \__xparse_end_expandable_defaults_E:nnw #1#2#3 \q_mark #4
+  {
+    \quark_if_nil:nTF {#2}
+      { \__xparse_end_expandable_defaults:nw {#1} }
+      {
+        \__xparse_if_no_value:nTF {#4}
+          { \__xparse_end_expandable_defaults_E:nnw { #1 {#2} } }
+          { \__xparse_end_expandable_defaults_E:nnw { #1 {#4} } }
+        #3 \q_mark
+      }
+  }
+\cs_new:Npn \__xparse_end_expandable_defaults:nw
+    #1#2 \__xparse_end_expandable_defaults:nnnNNn #3
+  { #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
-    \__xparse_count_mandatory:N #1
+    \int_zero:N \l__xparse_current_arg_int
+    \tl_clear:N \l__xparse_last_delimiters_tl
+    \tl_clear:N \l__xparse_arg_spec_tl
+    \__xparse_normalize_arg_spec_loop:n #1
       \q_recursion_tail \q_recursion_tail \q_recursion_tail \q_recursion_stop
+    \int_compare:nNnT \l__xparse_current_arg_int > 9
+      {
+        \__msg_kernel_error:nnxx { xparse } { too-many-arguments }
+          { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+        \__xparse_bad_def:wn
+      }
+    \bool_if:NT \l__xparse_expandable_bool
+      {
+        \tl_if_empty:NF \l__xparse_last_delimiters_tl
+          {
+            \__msg_kernel_error:nnxx { xparse } { expandable-ending-optional }
+              { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+            \__xparse_bad_def:wn
+          }
+      }
   }
-\cs_new_protected:Npn \__xparse_count_mandatory:N #1
+\cs_new_protected:Npn \__xparse_normalize_arg_spec_loop:n #1
   {
-    \quark_if_recursion_tail_stop:N #1
-    \prop_get:NnNTF \c__xparse_shorthands_prop {#1} \l__xparse_tmpa_tl
-      { \exp_after:wN \__xparse_count_mandatory:N \l__xparse_tmpa_tl }
-      { \__xparse_count_mandatory_aux:N #1 }
+    \quark_if_recursion_tail_stop:n {#1}
+    \int_incr:N \l__xparse_current_arg_int
+    \cs_if_exist_use:cF { __xparse_normalize_type_ \tl_to_str:n {#1} :w }
+      {
+        \__msg_kernel_error:nnxx { xparse } { unknown-argument-type }
+          { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+        \__xparse_bad_def:wn
+      }
   }
-\cs_new_protected:Npn \__xparse_count_mandatory_aux:N #1
+\cs_set_protected:Npn \__xparse_tmp:w #1
   {
-    \cs_if_exist_use:cF { __xparse_count_type_ \token_to_str:N #1 :w }
-      { \__xparse_count_type_m:w }
+    \cs_new_protected:Npn \__xparse_normalize_type_d:w ##1##2
+      {
+        \quark_if_recursion_tail_stop_do:nn {##2} { \__xparse_bad_arg_spec:wn }
+        \__xparse_normalize_type_D:w {##1} {##2} {#1}
+      }
+    \cs_new_protected:Npn \__xparse_normalize_type_e:w ##1
+      {
+        \quark_if_recursion_tail_stop_do:nn {##1} { \__xparse_bad_arg_spec:wn }
+        \__xparse_normalize_type_E:w {##1} { }
+      }
+    \cs_new_protected:Npn \__xparse_normalize_type_g:w
+      { \__xparse_normalize_type_G:w {#1} }
+    \cs_new_protected:Npn \__xparse_normalize_type_o:w
+      { \__xparse_normalize_type_D:w [ ] {#1} }
+    \cs_new_protected:Npn \__xparse_normalize_type_O:w
+      { \__xparse_normalize_type_D:w [ ] }
+    \cs_new_protected:Npn \__xparse_normalize_type_r:w ##1##2
+      {
+        \quark_if_recursion_tail_stop_do:nn {##2} { \__xparse_bad_arg_spec:wn }
+        \__xparse_normalize_type_R:w {##1} {##2} {#1}
+      }
+    \cs_new_protected:Npn \__xparse_normalize_type_s:w
+      { \__xparse_normalize_type_t:w * }
   }
-\cs_new_protected:cpn { __xparse_count_type_>:w } #1#2
+\exp_args:No \__xparse_tmp:w { \c__xparse_no_value_tl }
+\cs_new_protected:cpn { __xparse_normalize_type_>:w } #1#2
   {
     \quark_if_recursion_tail_stop_do:nn {#2} { \__xparse_bad_arg_spec:wn }
-    \__xparse_count_mandatory:N #2
+    \bool_if:NT \l__xparse_expandable_bool
+      {
+        \__msg_kernel_error:nnxx { xparse } { processor-in-expandable }
+          { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+        \__xparse_bad_def:wn
+      }
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { > {#1} }
+    \int_decr:N \l__xparse_current_arg_int
+    \__xparse_normalize_arg_spec_loop:n {#2}
   }
-\cs_new_protected:cpn { __xparse_count_type_+:w } #1
+\cs_new_protected:cpn { __xparse_normalize_type_+:w } #1
   {
     \quark_if_recursion_tail_stop_do:nn {#1} { \__xparse_bad_arg_spec:wn }
-    \__xparse_count_mandatory:N #1
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { + }
+    \int_decr:N \l__xparse_current_arg_int
+    \__xparse_normalize_arg_spec_loop:n {#1}
   }
-\cs_new_protected:Npn \__xparse_count_type_d:w #1#2
+\cs_new_protected:Npn \__xparse_normalize_type_D:w #1#2#3
   {
     \__xparse_single_token_check:n {#1}
     \__xparse_single_token_check:n {#2}
-    \quark_if_recursion_tail_stop_do:Nn #2 { \__xparse_bad_arg_spec:wn }
-    \__xparse_count_mandatory:N
+    \quark_if_recursion_tail_stop_do:nn {#3} { \__xparse_bad_arg_spec:wn }
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { D #1 #2 {#3} }
+    \tl_put_right:Nn \l__xparse_last_delimiters_tl {#1}
+    \__xparse_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \__xparse_count_type_D:w #1#2#3
+\cs_new_protected:Npn \__xparse_normalize_type_E:w #1#2
   {
-    \__xparse_single_token_check:n {#1}
-    \__xparse_single_token_check:n {#2}
-    \quark_if_recursion_tail_stop_do:nn {#3} { \__xparse_bad_arg_spec:wn }
-    \__xparse_count_mandatory:N
+    \quark_if_recursion_tail_stop_do:nn {#2} { \__xparse_bad_arg_spec:wn }
+    \tl_if_blank:nT {#1} { \__xparse_bad_arg_spec:wn }
+    \tl_map_function:nN {#1} \__xparse_single_token_check:n
+    \int_compare:nNnT { \tl_count:n {#2} } > { \tl_count:n {#1} }
+      { \__xparse_bad_arg_spec:wn }
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { E {#1} {#2} }
+    \tl_put_right:Nn \l__xparse_last_delimiters_tl {#1}
+    \__xparse_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \__xparse_count_type_e:w #1
+\cs_new_protected:Npn \__xparse_normalize_type_G:w #1
   {
     \quark_if_recursion_tail_stop_do:nn {#1} { \__xparse_bad_arg_spec:wn }
-    \__xparse_count_mandatory:N
+    \__xparse_normalize_error_if_expandable:N G
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { G {#1} }
+    \tl_put_right:Nn \l__xparse_last_delimiters_tl { { } }
+    \__xparse_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \__xparse_count_type_E:w #1#2
+\cs_new_protected:Npn \__xparse_normalize_type_t:w #1
   {
-    \quark_if_recursion_tail_stop_do:nn {#2} { \__xparse_bad_arg_spec:wn }
-    \__xparse_count_mandatory:N
+    \__xparse_single_token_check:n {#1}
+    \quark_if_recursion_tail_stop_do:Nn #1 { \__xparse_bad_arg_spec:wn }
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { t #1 }
+    \tl_put_right:Nn \l__xparse_last_delimiters_tl {#1}
+    \__xparse_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \__xparse_count_type_g:w
-  { \__xparse_count_mandatory:N }
-\cs_new_protected:Npn \__xparse_count_type_G:w #1
+\cs_new_protected:Npn \__xparse_normalize_type_l:w
   {
-    \quark_if_recursion_tail_stop_do:nn {#1} { \__xparse_bad_arg_spec:wn }
-    \__xparse_count_mandatory:N
-  }
-\cs_new_protected:Npn \__xparse_count_type_m:w
-  {
+    \__xparse_normalize_error_if_expandable:N l
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { l }
     \int_incr:N \l__xparse_mandatory_args_int
-    \__xparse_count_mandatory:N
+    \tl_clear:N \l__xparse_last_delimiters_tl
+    \__xparse_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \__xparse_count_type_r:w #1#2
+\cs_new_protected:Npn \__xparse_normalize_type_m:w
   {
-    \__xparse_single_token_check:n {#1}
-    \__xparse_single_token_check:n {#2}
-    \quark_if_recursion_tail_stop_do:Nn #2 { \__xparse_bad_arg_spec:wn }
+    \__xparse_delimiter_check:nnn { } { m } { \iow_char:N \{ }
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { m }
     \int_incr:N \l__xparse_mandatory_args_int
-    \__xparse_count_mandatory:N
+    \tl_clear:N \l__xparse_last_delimiters_tl
+    \__xparse_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \__xparse_count_type_R:w #1#2#3
+\cs_new_protected:Npn \__xparse_normalize_type_R:w #1#2#3
   {
     \__xparse_single_token_check:n {#1}
     \__xparse_single_token_check:n {#2}
     \quark_if_recursion_tail_stop_do:nn {#3} { \__xparse_bad_arg_spec:wn }
+    \__xparse_delimiter_check:nnn {#1} { R/r } { \tl_to_str:n {#1} }
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { R #1 #2 {#3} }
     \int_incr:N \l__xparse_mandatory_args_int
-    \__xparse_count_mandatory:N
+    \tl_clear:N \l__xparse_last_delimiters_tl
+    \__xparse_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \__xparse_count_type_t:w #1
+\cs_new_protected:Npn \__xparse_normalize_type_u:w #1
   {
-    \__xparse_single_token_check:n {#1}
-    \quark_if_recursion_tail_stop_do:Nn #1 { \__xparse_bad_arg_spec:wn }
-    \__xparse_count_mandatory:N
+    \quark_if_recursion_tail_stop_do:nn {#1} { \__xparse_bad_arg_spec:wn }
+    \__xparse_normalize_error_if_expandable:N u
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { u {#1} }
+    \int_incr:N \l__xparse_mandatory_args_int
+    \tl_clear:N \l__xparse_last_delimiters_tl
+    \__xparse_normalize_arg_spec_loop:n
   }
-\cs_new_protected:Npn \__xparse_count_type_u:w #1
+\cs_new_protected:Npn \__xparse_normalize_type_v:w
   {
-    \quark_if_recursion_tail_stop_do:nn {#1} { \__xparse_bad_arg_spec:wn }
+    \__xparse_normalize_error_if_expandable:N v
+    \tl_put_right:Nn \l__xparse_arg_spec_tl { v }
     \int_incr:N \l__xparse_mandatory_args_int
-    \__xparse_count_mandatory:N
+    \tl_clear:N \l__xparse_last_delimiters_tl
+    \__xparse_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \__xparse_single_token_check:n #1
   {
     \exp_args:Nx \tl_if_single_token:nF { \tl_trim_spaces:n {#1} }
-      { \__xparse_single_token_check_aux:nwn {#1} }
+      {
+        \__msg_kernel_error:nnxx { xparse } { not-single-token }
+          { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+        \__xparse_bad_def:wn
+      }
   }
-\cs_new_protected:Npn \__xparse_single_token_check_aux:nwn
-  #1#2 \__xparse_break_point:n #3
+\cs_new_protected:Npn \__xparse_normalize_error_if_expandable:N #1
   {
-    \__msg_kernel_error:nnx { xparse } { not-single-token }
-      { \tl_to_str:n {#1} } { \tl_to_str:n {#3} }
+    \bool_if:NT \l__xparse_expandable_bool
+      {
+        \__msg_kernel_error:nnxx
+          { xparse } { invalid-expandable-argument-type }
+          { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#1} }
+        \__xparse_bad_def:wn
+      }
   }
+\cs_new_protected:Npn \__xparse_delimiter_check:nnn #1#2#3
+  {
+    \tl_map_inline:Nn \l__xparse_last_delimiters_tl
+      {
+        \tl_if_eq:nnT {##1} {#1}
+          {
+            \__msg_kernel_warning:nnxx { xparse } { optional-mandatory }
+              {#2} {#3}
+          }
+      }
+  }
 \cs_new_protected:Npn \__xparse_bad_arg_spec:wn #1 \__xparse_break_point:n #2
-  { \__msg_kernel_error:nnx { xparse } { bad-arg-spec } { \tl_to_str:n {#2} } }
+  {
+    \__msg_kernel_error:nnxx { xparse } { bad-arg-spec }
+      { \iow_char:N \\ \l__xparse_function_tl } { \tl_to_str:n {#2} }
+  }
+\cs_new_protected:Npn \__xparse_bad_def:wn #1 \__xparse_break_point:n #2 { }
 \cs_new_protected:Npn \__xparse_prepare_signature:n #1
   {
     \bool_set_false:N \l__xparse_all_long_bool
+    \bool_set_false:N \l__xparse_all_long_set_bool
     \int_zero:N \l__xparse_current_arg_int
     \bool_set_false:N \l__xparse_long_bool
     \int_zero:N \l__xparse_m_args_int
-    \bool_set_false:N \l__xparse_processor_bool
+    \bool_set_false:N \l__xparse_defaults_bool
+    \tl_clear:N \l__xparse_defaults_tl
+    \tl_clear:N \l__xparse_process_all_tl
+    \tl_clear:N \l__xparse_process_one_tl
+    \bool_set_false:N \l__xparse_process_some_bool
     \tl_clear:N \l__xparse_signature_tl
     \__xparse_prepare_signature:N #1 \q_recursion_tail \q_recursion_stop
+    \bool_if:NF \l__xparse_expandable_bool { \__xparse_flush_m_args: }
   }
 \cs_new_protected:Npn \__xparse_prepare_signature:N
   {
-    \bool_set_false:N \l__xparse_processor_bool
+    \bool_set_false:N \l__xparse_prefixed_bool
     \__xparse_prepare_signature_bypass:N
   }
 \cs_new_protected:Npn \__xparse_prepare_signature_bypass:N #1
   {
     \quark_if_recursion_tail_stop:N #1
-    \prop_get:NnNTF \c__xparse_shorthands_prop {#1} \l__xparse_tmpa_tl
-      { \exp_after:wN \__xparse_prepare_signature:N \l__xparse_tmpa_tl }
+    \int_incr:N \l__xparse_current_arg_int
+    \use:c
       {
-        \int_incr:N \l__xparse_current_arg_int
-        \__xparse_prepare_signature_add:N #1
-      }
-  }
-\cs_new_protected:Npn \__xparse_prepare_signature_add:N #1
-  {
-    \cs_if_exist_use:cF
-      {
          __xparse_add
          \bool_if:NT \l__xparse_expandable_bool { _expandable }
          _type_  \token_to_str:N #1 :w
       }
-      {
-        \__msg_kernel_error:nnx { xparse } { unknown-argument-type }
-          { \token_to_str:N #1 }
-        \bool_if:NTF \l__xparse_expandable_bool
-          { \__xparse_add_expandable_type_m:w }
-          { \__xparse_add_type_m:w }
-      }
   }
 \cs_new_protected:cpn { __xparse_add_type_+:w }
   {
     \__xparse_flush_m_args:
     \bool_set_true:N \l__xparse_long_bool
+    \bool_set_true:N \l__xparse_prefixed_bool
     \int_decr:N \l__xparse_current_arg_int
-    \__xparse_prepare_signature:N
+    \__xparse_prepare_signature_bypass:N
   }
 \cs_new_protected:cpn { __xparse_add_type_>:w } #1
   {
     \__xparse_flush_m_args:
-    \bool_set_true:N \l__xparse_processor_bool
+    \bool_set_true:N \l__xparse_prefixed_bool
+    \bool_set_true:N \l__xparse_process_some_bool
     \int_decr:N \l__xparse_current_arg_int
-    \tl_put_right:Nn \l__xparse_signature_tl { \__xparse_process_arg:n {#1} }
+    \tl_put_right:Nn \l__xparse_process_one_tl { {#1} }
     \__xparse_prepare_signature_bypass:N
   }
-\cs_new_protected:Npn \__xparse_add_type_d:w #1#2
-  { \exp_args:NNNo \__xparse_add_type_D:w #1 #2 \c__xparse_no_value_tl }
 \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
-    \tl_put_right:Nn \l__xparse_signature_tl { #1 #2 {#3} }
+    \tl_put_right:Nn \l__xparse_signature_tl { #1 #2 }
     \__xparse_prepare_signature:N
   }
-\cs_new_protected:Npn \__xparse_add_type_e:w #1
-  { \__xparse_add_type_E:w {#1} { } }
 \cs_new_protected:Npn \__xparse_add_type_E:w #1#2
   {
     \__xparse_flush_m_args:
+    \__xparse_add_default_E:nn {#1} {#2}
     \__xparse_add_grabber_optional:N E
-    \tl_put_right:Nn \l__xparse_signature_tl { {#1} {#2} }
+    \tl_put_right:Nn \l__xparse_signature_tl { {#1} }
     \__xparse_prepare_signature:N
   }
-\cs_new_protected:Npn \__xparse_add_type_g:w
-  { \exp_args:No \__xparse_add_type_G:w \c__xparse_no_value_tl }
 \cs_new_protected:Npn \__xparse_add_type_G:w #1
   {
     \__xparse_flush_m_args:
+    \__xparse_add_default:n {#1}
     \__xparse_add_grabber_optional:N G
-    \tl_put_right:Nn \l__xparse_signature_tl { {#1} }
     \__xparse_prepare_signature:N
   }
 \cs_new_protected:Npn \__xparse_add_type_l:w
   {
     \__xparse_flush_m_args:
+    \__xparse_add_default:
     \__xparse_add_grabber_mandatory:N l
     \__xparse_prepare_signature:N
   }
 \cs_new_protected:Npn \__xparse_add_type_m:w
   {
-    \bool_if:nTF { \l__xparse_long_bool || \l__xparse_processor_bool }
-      {
-        \__xparse_flush_m_args:
-        \__xparse_add_grabber_mandatory:N m
-      }
+    \__xparse_add_default:
+    \bool_if:NTF \l__xparse_prefixed_bool
+      { \__xparse_add_grabber_mandatory:N m }
       { \int_incr:N \l__xparse_m_args_int }
     \__xparse_prepare_signature:N
   }
-\cs_new_protected:Npn \__xparse_add_type_r:w #1#2
-  { \exp_args:NNNo \__xparse_add_type_R:w #1 #2 \c__xparse_no_value_tl }
 \cs_new_protected:Npn \__xparse_add_type_R:w #1#2#3
   {
     \__xparse_flush_m_args:
+    \__xparse_add_default:n {#3}
     \__xparse_add_grabber_mandatory:N R
-    \tl_put_right:Nn \l__xparse_signature_tl { #1 #2 {#3} }
+    \tl_put_right:Nn \l__xparse_signature_tl { #1 #2 }
     \__xparse_prepare_signature:N
   }
 \cs_new_protected:Npn \__xparse_add_type_t:w #1
   {
     \__xparse_flush_m_args:
+    \__xparse_add_default:
     \__xparse_add_grabber_optional:N t
     \tl_put_right:Nn \l__xparse_signature_tl {#1}
     \__xparse_prepare_signature:N
@@ -423,6 +671,7 @@
 \cs_new_protected:Npn \__xparse_add_type_u:w #1
   {
     \__xparse_flush_m_args:
+    \__xparse_add_default:
     \__xparse_add_grabber_mandatory:N u
     \tl_put_right:Nn \l__xparse_signature_tl { {#1} }
     \__xparse_prepare_signature:N
@@ -430,6 +679,7 @@
 \cs_new_protected:Npn \__xparse_add_type_v:w
   {
     \__xparse_flush_m_args:
+    \exp_args:No \__xparse_add_default:n \c__xparse_no_value_tl
     \__xparse_add_grabber_mandatory:N v
     \__xparse_prepare_signature:N
   }
@@ -440,6 +690,8 @@
         \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
   }
@@ -451,6 +703,9 @@
           { __xparse_grab_ #1 \bool_if:NT \l__xparse_long_bool { _long } :w }
       }
     \bool_set_false:N \l__xparse_long_bool
+    \tl_put_right:Nx \l__xparse_process_all_tl
+      { { \exp_not:o \l__xparse_process_one_tl } }
+    \tl_clear:N \l__xparse_process_one_tl
     \int_decr:N \l__xparse_mandatory_args_int
   }
 \cs_new_protected:Npn \__xparse_add_grabber_optional:N #1
@@ -467,231 +722,229 @@
           }
       }
     \bool_set_false:N \l__xparse_long_bool
+    \tl_put_right:Nx \l__xparse_process_all_tl
+      { { \exp_not:o \l__xparse_process_one_tl } }
+    \tl_clear:N \l__xparse_process_one_tl
   }
-\cs_new_protected:cpn { __xparse_add_expandable_type_+:w }
+\cs_new_protected:Npn \__xparse_add_default:n #1
   {
-    \bool_set_true:N \l__xparse_long_bool
-    \int_compare:nNnTF \l__xparse_current_arg_int = \c_one
-      { \bool_set_true:N \l__xparse_all_long_bool }
+    \bool_set_true:N \l__xparse_defaults_bool
+    \tl_put_right:Nn \l__xparse_defaults_tl { { . #1} }
+  }
+\cs_new_protected:Npn \__xparse_add_default:
+  { \tl_put_right:Nn \l__xparse_defaults_tl { . } }
+\cs_new_protected:Npn \__xparse_add_default_E:nn #1#2
+  {
+    \bool_set_true:N \l__xparse_defaults_bool
+    \tl_set:Nx \l__xparse_tmpa_tl
       {
-        \bool_if:NF \l__xparse_all_long_bool
-          { \__msg_kernel_error:nn { xparse } { inconsistent-long } }
+        \exp_not:n {#2}
+        \prg_replicate:nn
+          { \tl_count:n {#1} - \tl_count:n {#2} }
+          { { \c__xparse_no_value_tl } }
       }
-    \int_decr:N \l__xparse_current_arg_int
-    \__xparse_prepare_signature:N
+    \tl_put_right:Nx \l__xparse_defaults_tl
+      {
+        {
+          \exp_not:f
+            { \exp_after:wN \__xparse_add_default_E_aux:n \l__xparse_tmpa_tl }
+        }
+      }
   }
-\cs_new_protected:cpn { __xparse_add_expandable_type_>:w } #1
+\cs_new:Npn \__xparse_add_default_E_aux:n #1 { {#1} }
+\cs_new_protected:cpn { __xparse_add_expandable_type_+:w }
   {
-    \__msg_kernel_error:nnx { xparse } { processor-in-expandable }
-      { \token_to_str:c { \l__xparse_function_tl } }
+    \bool_set_true:N \l__xparse_long_bool
     \int_decr:N \l__xparse_current_arg_int
     \__xparse_prepare_signature:N
   }
-\cs_new_protected:Npn \__xparse_add_expandable_type_d:w #1#2
+\cs_new_protected:Npn \__xparse_add_expandable_type_D:w
+  { \__xparse_add_expandable_type_D_aux:NNNn D }
+\cs_new_protected:Npn \__xparse_add_expandable_type_D_aux:NNNn #1#2#3#4
   {
-    \exp_args:NNNo
-      \__xparse_add_expandable_type_D:w #1 #2 \c__xparse_no_value_tl
+    \__xparse_add_default:n {#4}
+    \tl_if_eq:nnTF {#2} {#3}
+      { \__xparse_add_expandable_type_D_aux:NN #1 #2 }
+      { \__xparse_add_expandable_type_D_aux:NNN #1 #2 #3 }
+    \bool_set_false:N \l__xparse_long_bool
+    \__xparse_prepare_signature:N
   }
-\cs_new_protected:Npn \__xparse_add_expandable_type_D:w #1#2
+\cs_new_protected:Npn \__xparse_add_expandable_type_D_aux:NNN #1#2#3
   {
-    \tl_if_eq:nnTF {#1} {#2}
-      {
-        \__xparse_add_expandable_grabber_optional:n { D_alt }
-        \__xparse_add_expandable_type_D_aux:Nn #1
-      }
-      {
-        \__xparse_add_expandable_grabber_optional:n { D }
-        \__xparse_add_expandable_type_D_aux:NNn #1#2
-      }
-  }
-\cs_new_protected:Npn \__xparse_add_expandable_type_D_aux:NNn #1#2#3
-  {
+    \__xparse_add_expandable_grabber:n {#1}
     \bool_if:NTF \l__xparse_all_long_bool
       { \cs_set:cpx }
       { \cs_set_nopar:cpx }
-      { \l__xparse_expandable_aux_name_tl } ##1 ##2 #1 ##3 \q__xparse ##4 #2
+      { \l__xparse_expandable_aux_name_tl } ##1 ##2 #2 ##3 \q__xparse ##4 #3
       { ##1 {##2} {##3} {##4} }
     \tl_put_right:Nx \l__xparse_signature_tl
       {
         \exp_not:c  { \l__xparse_expandable_aux_name_tl }
-        \exp_not:n { #1 #2 {#3} }
+        \exp_not:n { #2 #3 }
       }
-    \bool_set_false:N \l__xparse_long_bool
-    \__xparse_prepare_signature:N
   }
-\cs_new_protected:Npn \__xparse_add_expandable_type_D_aux:Nn #1#2
+\cs_new_protected:Npn \__xparse_add_expandable_type_D_aux:NN #1#2
   {
+    \__xparse_add_expandable_grabber:n { #1_alt }
     \bool_if:NTF \l__xparse_all_long_bool
       { \cs_set:cpx }
       { \cs_set_nopar:cpx }
-      { \l__xparse_expandable_aux_name_tl } ##1 #1 ##2 #1
+      { \l__xparse_expandable_aux_name_tl } ##1 #2 ##2 #2
       { ##1 {##2} }
     \tl_put_right:Nx \l__xparse_signature_tl
       {
         \exp_not:c  { \l__xparse_expandable_aux_name_tl }
-        \exp_not:n { #1 {#2} }
+        \exp_not:n {#2}
       }
+  }
+\cs_new_protected:Npn \__xparse_add_expandable_type_E:w #1#2
+  {
+    \__xparse_add_default_E:nn {#1} {#2}
+    \__xparse_add_expandable_grabber:n { E }
+    \tl_clear:N \l__xparse_tmpb_tl
+    \tl_map_function:nN {#1} \__xparse_add_expandable_type_E_aux:n
+    \tl_put_right:Nx \l__xparse_signature_tl
+      {
+        { \exp_not:o \l__xparse_tmpb_tl }
+        {
+          \prg_replicate:nn { \tl_count:n {#1} }
+            { { \c__xparse_no_value_tl } }
+        }
+      }
     \bool_set_false:N \l__xparse_long_bool
     \__xparse_prepare_signature:N
   }
-\cs_new_protected:Npn \__xparse_add_expandable_type_g:w
+\cs_new_protected:Npn \__xparse_add_expandable_type_E_aux:n #1
   {
-    \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type }
-      { g }
-    \__xparse_add_expandable_type_m:w
+    \__xparse_get_grabber:NN #1 \l__xparse_tmpa_tl
+    \tl_put_right:Nx \l__xparse_tmpb_tl
+      { \exp_not:o \l__xparse_tmpa_tl \exp_not:N #1 }
   }
-\cs_new_protected:Npn \__xparse_add_expandable_type_G:w #1
-  {
-    \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type }
-      { G }
-    \__xparse_add_expandable_type_m:w
-  }
-\cs_new_protected:Npn \__xparse_add_expandable_type_l:w
-  {
-    \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type }
-      { l }
-    \__xparse_add_expandable_type_m:w
-  }
 \cs_new_protected:Npn \__xparse_add_expandable_type_m:w
   {
-    \int_incr:N \l__xparse_m_args_int
-    \__xparse_add_expandable_grabber_mandatory:n { m }
-    \bool_set_false:N \l__xparse_long_bool
+    \__xparse_add_default:
+    \__xparse_add_expandable_grabber:n { m }
     \__xparse_prepare_signature:N
   }
-\cs_new_protected:Npn \__xparse_add_expandable_type_r:w #1#2
-  {
-    \exp_args:NNNo
-      \__xparse_add_expandable_type_R:w #1 #2 \c__xparse_no_value_tl
-  }
-\cs_new_protected:Npn \__xparse_add_expandable_type_R:w #1#2
-  {
-    \tl_if_eq:nnTF {#1} {#2}
-      {
-        \__xparse_add_expandable_grabber_mandatory:n { R_alt }
-        \__xparse_add_expandable_type_D_aux:Nn #1
-      }
-      {
-        \__xparse_add_expandable_grabber_mandatory:n { R }
-        \__xparse_add_expandable_type_D_aux:NNn #1#2
-      }
-  }
+\cs_new_protected:Npn \__xparse_add_expandable_type_R:w
+  { \__xparse_add_expandable_type_D_aux:NNNn R }
 \cs_new_protected:Npn \__xparse_add_expandable_type_t:w #1
   {
-    \__xparse_add_expandable_grabber_optional:n { t }
-    \bool_if:NTF \l__xparse_all_long_bool
-      { \cs_set:cpn }
-      { \cs_set_nopar:cpn }
-      { \l__xparse_expandable_aux_name_tl } ##1 #1 {##1}
+    \__xparse_add_default:
+    \__xparse_add_expandable_grabber_t:
+    \__xparse_get_grabber:NN #1 \l__xparse_tmpa_tl
     \tl_put_right:Nx \l__xparse_signature_tl
       {
-        \exp_not:c { \l__xparse_expandable_aux_name_tl }
+        \exp_not:o \l__xparse_tmpa_tl
         \exp_not:N #1
       }
     \bool_set_false:N \l__xparse_long_bool
     \__xparse_prepare_signature:N
   }
-\cs_new_protected:Npn \__xparse_add_expandable_type_u:w #1
+\cs_new_protected:Npn \__xparse_add_expandable_grabber:n #1
   {
-    \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type }
-      { u }
-    \__xparse_add_expandable_type_m:w
-  }
-\cs_new_protected:Npn \__xparse_add_expandable_type_v:w
-  {
-    \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type }
-      { v }
-    \__xparse_add_expandable_type_m:w
-  }
-\cs_new_protected:Npn \__xparse_add_expandable_grabber_mandatory:n #1
-  {
-    \__xparse_add_expandable_long_check:
+    \bool_if:NTF \l__xparse_all_long_set_bool
+      {
+        \bool_if:nT
+          { \bool_xor_p:nn { \l__xparse_all_long_bool } { \l__xparse_long_bool } }
+          {
+            \__msg_kernel_error:nnx { xparse } { inconsistent-long }
+              { \iow_char:N \\ \l__xparse_function_tl }
+            \__xparse_bad_def:wn
+          }
+      }
+      {
+        \bool_set:Nn \l__xparse_all_long_bool { \l__xparse_long_bool }
+        \bool_set_true:N \l__xparse_all_long_set_bool
+      }
     \tl_put_right:Nx \l__xparse_signature_tl
       { \exp_not:c { __xparse_expandable_grab_ #1 :w } }
     \bool_set_false:N \l__xparse_long_bool
-    \int_decr:N \l__xparse_mandatory_args_int
   }
-\cs_new_protected:Npn \__xparse_add_expandable_grabber_optional:n #1
+\cs_new_protected:Npn \__xparse_add_expandable_grabber_t:
   {
-    \__xparse_add_expandable_long_check:
-    \int_compare:nNnF \l__xparse_mandatory_args_int > \c_zero
-      { \__msg_kernel_error:nn { xparse } { expandable-ending-optional } }
-    \tl_put_right:Nx \l__xparse_signature_tl
-      { \exp_not:c { __xparse_expandable_grab_ #1 :w } }
+    \tl_put_right:Nn \l__xparse_signature_tl
+      { \__xparse_expandable_grab_t:w }
     \bool_set_false:N \l__xparse_long_bool
   }
-\cs_new_protected:Npn \__xparse_add_expandable_long_check:
+\cs_new_protected:Npn \__xparse_get_grabber:NN #1#2
   {
-    \bool_if:nT { \l__xparse_all_long_bool && ! \l__xparse_long_bool }
-      { \__msg_kernel_error:nn { xparse } { inconsistent-long } }
+    \cs_set:Npn \__xparse_tmp:w ##1 #1 {##1}
+    \exp_args:Nc \__xparse_get_grabber_auxi:NN
+      { __xparse_grabber_ \token_to_str:N #1 :w } #2
   }
-\cs_new_protected:Npn \__xparse_grab_arg:w { }
-\cs_new_protected:Npn \__xparse_grab_arg_auxi:w { }
-\cs_new_protected:Npn \__xparse_grab_arg_auxii:w { }
-\cs_new_protected:Npn \__xparse_grab_D:w #1#2#3#4 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_get_grabber_auxi:NN #1#2
   {
-    \__xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected_nopar:Npn
+    \cs_if_eq:NNTF \__xparse_tmp:w #1
+      { \tl_set:Nn #2 {#1} }
+      {
+        \cs_if_exist:NTF #1
+          {
+            \int_gincr:N \g__xparse_grabber_int
+            \exp_args:Nc \__xparse_get_grabber_auxi:NN
+              {
+                __xparse_grabber_
+                - \int_use:N \g__xparse_grabber_int :w
+              }
+              #2
+          }
+          { \__xparse_get_grabber_auxii:NN #1 #2 }
+      }
+  }
+\cs_new_protected:Npn \__xparse_get_grabber_auxii:NN #1#2
+  {
+    \cs_set_eq:NN #1 \__xparse_tmp:w
+    \tl_set:Nn #2 {#1}
+  }
+\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
       { _ignore_spaces }
   }
-\cs_new_protected:Npn \__xparse_grab_D_long:w #1#2#3#4 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_D_long:w #1#2#3 \__xparse_run_code:
   {
-    \__xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected:Npn
+    \__xparse_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected:Npn
       { _ignore_spaces }
   }
-\cs_new_protected:Npn \__xparse_grab_D_trailing:w #1#2#3#4 \l__xparse_args_tl
-  { \__xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected_nopar:Npn { } }
-\cs_new_protected:Npn \__xparse_grab_D_long_trailing:w #1#2#3#4 \l__xparse_args_tl
-  { \__xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected:Npn { } }
-\cs_new_protected:Npn \__xparse_grab_D_aux:NNnnNn #1#2#3#4#5#6
+\cs_new_protected:Npn \__xparse_grab_D_trailing:w #1#2#3 \__xparse_run_code:
+  { \__xparse_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected_nopar:Npn { } }
+\cs_new_protected:Npn \__xparse_grab_D_long_trailing:w #1#2#3 \__xparse_run_code:
+  { \__xparse_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected:Npn { } }
+\cs_new_protected:Npn \__xparse_grab_D_aux:NNnNn #1#2#3#4#5
   {
-    \__xparse_grab_D_aux:NNnN #1#2 {#4} #5
-    \use:c { peek_meaning_remove #6 :NTF } #1
-      { \__xparse_grab_arg:w }
-      {
-        \__xparse_add_arg:n {#3}
-        #4 \l__xparse_args_tl
-      }
+    \__xparse_grab_D_aux:NNnN #1#2 {#3} #4
+    \use:c { peek_meaning_remove #5 :NTF } #1
+      { \__xparse_grab_D_call:Nw #1 }
+      { \__xparse_add_arg:o \c__xparse_no_value_tl }
   }
 \cs_new_protected:Npn \__xparse_grab_D_aux:NNnN #1#2#3#4
   {
-    \cs_set_protected_nopar:Npn \__xparse_grab_arg:w
+    \tl_set:Nn \l__xparse_signature_tl {#3}
+    \exp_after:wN #4 \l__xparse_fn_tl ##1 #2
       {
-        \exp_after:wN #4 \l__xparse_fn_tl ####1 #2
+        \tl_if_in:nnTF {##1} {#1}
+          { \__xparse_grab_D_nested:NNnN #1 #2 {##1} #4 }
           {
-            \tl_if_in:nnTF {####1} {#1}
-              { \__xparse_grab_D_nested:NNnnN #1 #2 {####1} {#3} #4 }
+            \tl_if_blank:oTF { \use_none:n ##1 }
+              { \__xparse_add_arg:o { \use_none:n ##1 } }
               {
-                \tl_if_blank:oTF { \use_none:n ####1 }
-                  { \__xparse_add_arg:o { \use_none:n ####1 } }
-                  {
-                    \str_if_eq_x:nnTF
-                      { \exp_not:o { \use_none:n ####1 } }
-                      { { \exp_not:o { \use_ii:nnn ####1 \q_nil } } }
-                      { \__xparse_add_arg:o { \use_ii:nn ####1 } }
-                      { \__xparse_add_arg:o { \use_none:n ####1 } }
-                  }
-                #3 \l__xparse_args_tl
+                \str_if_eq_x:nnTF
+                  { \exp_not:o { \use_none:n ##1 } }
+                  { { \exp_not:o { \use_ii:nnn ##1 \q_nil } } }
+                  { \__xparse_add_arg:o { \use_ii:nn ##1 } }
+                  { \__xparse_add_arg:o { \use_none:n ##1 } }
               }
           }
-        \token_if_eq_catcode:NNTF + #1
-          {
-            \exp_after:wN \exp_after:wN \exp_after:wN
-              \l__xparse_fn_tl \char_generate:nn { `#1 } { 11 }
-          }
-          {
-            \exp_after:wN \l__xparse_fn_tl
-            \token_to_str:N #1
-          }
       }
   }
 \tl_new:N \l__xparse_nesting_a_tl
 \tl_new:N \l__xparse_nesting_b_tl
 \quark_new:N \q__xparse
-\cs_new_protected:Npn \__xparse_grab_D_nested:NNnnN #1#2#3#4#5
+\cs_new_protected:Npn \__xparse_grab_D_nested:NNnN #1#2#3#4
   {
     \tl_clear:N \l__xparse_nesting_a_tl
     \tl_clear:N \l__xparse_nesting_b_tl
-    \exp_after:wN #5 \l__xparse_fn_tl ##1 #1 ##2 \q__xparse ##3 #2
+    \exp_after:wN #4 \l__xparse_fn_tl ##1 #1 ##2 \q__xparse ##3 #2
       {
         \tl_put_right:No \l__xparse_nesting_a_tl { \use_none:n ##1 #1 }
         \tl_put_right:No \l__xparse_nesting_b_tl { \use_i:nn #2 ##3 }
@@ -714,7 +967,6 @@
                 \tl_put_right:No \l__xparse_nesting_a_tl
                   \l__xparse_nesting_b_tl
                 \__xparse_add_arg:V \l__xparse_nesting_a_tl
-                #4 \l__xparse_args_tl
               }
           }
       }
@@ -722,44 +974,51 @@
   }
 \cs_new:Npn \__xparse_grab_D_nested:w #1 \q_nil \q_stop
   { \exp_not:o { \use_none:n #1 } }
-\cs_new_protected:Npn \__xparse_grab_E:w #1#2#3 \l__xparse_args_tl
+\cs_set_protected_nopar:Npn \__xparse_grab_D_call:Nw #1
   {
-    \__xparse_grab_E:nnnNn
-       {#1} {#2} {#3}
+    \token_if_eq_catcode:NNTF + #1
+      {
+        \exp_after:wN \exp_after:wN \exp_after:wN
+          \l__xparse_fn_tl \char_generate:nn { `#1 } { 11 }
+      }
+      {
+        \exp_after:wN \l__xparse_fn_tl
+        \token_to_str:N #1
+      }
+  }
+\cs_new_protected:Npn \__xparse_grab_E:w #1#2 \__xparse_run_code:
+  {
+    \__xparse_grab_E:nnNn {#1} {#2}
       \cs_set_protected_nopar:Npn
       { _ignore_spaces }
   }
-\cs_new_protected:Npn \__xparse_grab_E_long:w #1#2#3 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_E_long:w #1#2 \__xparse_run_code:
   {
-    \__xparse_grab_E:nnnNn
-       {#1} {#2} {#3}
+    \__xparse_grab_E:nnNn {#1} {#2}
       \cs_set_protected:Npn
       { _ignore_spaces }
   }
-\cs_new_protected:Npn \__xparse_grab_E_trailing:w #1#2#3 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_E_trailing:w #1#2 \__xparse_run_code:
   {
-    \__xparse_grab_E:nnnNn
-       {#1} {#2} {#3}
+    \__xparse_grab_E:nnNn {#1} {#2}
       \cs_set_protected_nopar:Npn
       { }
   }
-\cs_new_protected:Npn \__xparse_grab_E_long_trailing:w #1#2#3 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_E_long_trailing:w #1#2 \__xparse_run_code:
   {
-    \__xparse_grab_E:nnnNn
-       {#1} {#2} {#3}
+    \__xparse_grab_E:nnNn {#1} {#2}
       \cs_set_protected:Npn
       { }
   }
-\cs_new_protected:Npn \__xparse_grab_E:nnnNn #1#2#3#4#5
+\cs_new_protected:Npn \__xparse_grab_E:nnNn #1#2#3#4
   {
-    \exp_after:wN #4 \l__xparse_fn_tl ##1##2##3
+    \exp_after:wN #3 \l__xparse_fn_tl ##1##2##3
       {
         \prop_put:Nnn \l__xparse_tmp_prop {##1} {##3}
-        \__xparse_grab_E_loop:nnN {#5} { } ##2 \q_recursion_stop
+        \__xparse_grab_E_loop:nnN {#4} { } ##2 \q_recursion_stop
       }
     \prop_clear:N \l__xparse_tmp_prop
-    \__xparse_grab_E_setup:Nw
-      #1 \q_recursion_tail \q_mark #2 \q_recursion_tail \q_recursion_stop
+    \tl_set:Nn \l__xparse_signature_tl {#2}
     \cs_set_protected:Npn \__xparse_grab_E_finalise:
       {
         \tl_clear:N \l__xparse_tmpa_tl
@@ -774,17 +1033,9 @@
               }
           }
         \__xparse_add_arg:V \l__xparse_tmpa_tl
-        #3 \l__xparse_args_tl
       }
-    \__xparse_grab_E_loop:nnN {#5} { } #1 \q_recursion_tail \q_recursion_stop
+    \__xparse_grab_E_loop:nnN {#4} { } #1 \q_recursion_tail \q_recursion_stop
   }
-\cs_new_protected:Npn \__xparse_grab_E_setup:Nw #1#2 \q_mark #3
-  {
-    \quark_if_recursion_tail_stop:N #1
-    \quark_if_recursion_tail_stop:n {#3}
-    \prop_put:Nnn \l__xparse_tmp_prop {#1} {#3}
-    \__xparse_grab_E_setup:Nw #2 \q_mark
-  }
 \cs_new_protected:Npn \__xparse_grab_E_loop:nnN #1#2#3#4 \q_recursion_stop
   {
     \cs_if_eq:NNTF #3 \q_recursion_tail
@@ -796,203 +1047,156 @@
       }
   }
 \cs_new_protected:Npn \__xparse_grab_E_finalise: { }
-\cs_new_protected:Npn \__xparse_grab_G:w #1#2 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_G:w #1 \__xparse_run_code:
   {
-    \__xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_protected_nopar:Npn
+    \__xparse_grab_G_aux:nNn {#1} \cs_set_protected_nopar:Npn
       { _ignore_spaces }
   }
-\cs_new_protected:Npn \__xparse_grab_G_long:w #1#2 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_G_long:w #1 \__xparse_run_code:
   {
-    \__xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_protected:Npn { _ignore_spaces }
+    \__xparse_grab_G_aux:nNn {#1} \cs_set_protected:Npn { _ignore_spaces }
   }
-\cs_new_protected:Npn \__xparse_grab_G_trailing:w #1#2 \l__xparse_args_tl
-  { \__xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_protected_nopar:Npn { } }
-\cs_new_protected:Npn \__xparse_grab_G_long_trailing:w #1#2 \l__xparse_args_tl
-  { \__xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_protected:Npn { } }
-\cs_new_protected:Npn \__xparse_grab_G_aux:nnNn #1#2#3#4
+\cs_new_protected:Npn \__xparse_grab_G_trailing:w #1 \__xparse_run_code:
+  { \__xparse_grab_G_aux:nNn {#1} \cs_set_protected_nopar:Npn { } }
+\cs_new_protected:Npn \__xparse_grab_G_long_trailing:w #1 \__xparse_run_code:
+  { \__xparse_grab_G_aux:nNn {#1} \cs_set_protected:Npn { } }
+\cs_new_protected:Npn \__xparse_grab_G_aux:nNn #1#2#3
   {
-    \exp_after:wN #3 \l__xparse_fn_tl ##1
-      {
-        \__xparse_add_arg:n {##1}
-        #2 \l__xparse_args_tl
-      }
-    \use:c { peek_meaning #4 :NTF } \c_group_begin_token
+    \tl_set:Nn \l__xparse_signature_tl {#1}
+    \exp_after:wN #2 \l__xparse_fn_tl ##1
+      { \__xparse_add_arg:n {##1} }
+    \use:c { peek_meaning #3 :NTF } \c_group_begin_token
       { \l__xparse_fn_tl }
-      {
-        \__xparse_add_arg:n {#1}
-        #2 \l__xparse_args_tl
-      }
+      { \__xparse_add_arg:o \c__xparse_no_value_tl }
   }
-\cs_new_protected:Npn \__xparse_grab_l:w #1 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_l:w #1 \__xparse_run_code:
   { \__xparse_grab_l_aux:nN {#1} \cs_set_protected_nopar:Npn }
-\cs_new_protected:Npn \__xparse_grab_l_long:w #1 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_l_long:w #1 \__xparse_run_code:
   { \__xparse_grab_l_aux:nN {#1} \cs_set_protected:Npn }
 \cs_new_protected:Npn \__xparse_grab_l_aux:nN #1#2
   {
+    \tl_set:Nn \l__xparse_signature_tl {#1}
     \exp_after:wN #2 \l__xparse_fn_tl ##1##
-      {
-        \__xparse_add_arg:n {##1}
-        #1 \l__xparse_args_tl
-      }
+      { \__xparse_add_arg:n {##1} }
     \l__xparse_fn_tl
   }
-\cs_new_protected:Npn \__xparse_grab_m:w #1 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_m:w #1 \__xparse_run_code:
   {
+    \tl_set:Nn \l__xparse_signature_tl {#1}
     \exp_after:wN \cs_set_protected_nopar:Npn \l__xparse_fn_tl ##1
-      {
-        \__xparse_add_arg:n {##1}
-        #1 \l__xparse_args_tl
-      }
+      { \__xparse_add_arg:n {##1} }
     \l__xparse_fn_tl
   }
-\cs_new_protected:Npn \__xparse_grab_m_long:w #1 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_m_long:w #1 \__xparse_run_code:
   {
+    \tl_set:Nn \l__xparse_signature_tl {#1}
     \exp_after:wN \cs_set_protected:Npn \l__xparse_fn_tl ##1
-      {
-        \__xparse_add_arg:n {##1}
-        #1 \l__xparse_args_tl
-      }
+      { \__xparse_add_arg:n {##1} }
     \l__xparse_fn_tl
   }
-\cs_new_protected:cpn { __xparse_grab_m_1:w } #1 \l__xparse_args_tl
+\cs_new_protected_nopar:Npn \__xparse_grab_m_aux:Nnnnnnnnn #1#2#3#4#5#6#7#8#9
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l__xparse_fn_tl ##1
-      {
-        \tl_put_right:Nn \l__xparse_args_tl { {##1} }
-        #1 \l__xparse_args_tl
-      }
-    \l__xparse_fn_tl
+    \tl_put_right:No \l__xparse_args_tl
+      { #1 {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9} }
+    \l__xparse_signature_tl \__xparse_run_code:
   }
-\cs_new_protected:cpn { __xparse_grab_m_2:w } #1 \l__xparse_args_tl
+\cs_new_protected:cpn { __xparse_grab_m_1:w } #1 \__xparse_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l__xparse_fn_tl
-      ##1##2
-      {
-        \tl_put_right:Nn \l__xparse_args_tl { {##1} {##2} }
-        #1 \l__xparse_args_tl
-      }
-    \l__xparse_fn_tl
+    \tl_set:Nn \l__xparse_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__xparse_fn_tl \__xparse_grab_m_aux:Nnnnnnnnn
+    \l__xparse_fn_tl \use_none:nnnnnnn { } { } { } { } { } { } { }
   }
-\cs_new_protected:cpn { __xparse_grab_m_3:w } #1 \l__xparse_args_tl
+\cs_new_protected:cpn { __xparse_grab_m_2:w } #1 \__xparse_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l__xparse_fn_tl
-      ##1##2##3
-      {
-        \tl_put_right:Nn \l__xparse_args_tl { {##1} {##2} {##3} }
-        #1 \l__xparse_args_tl
-      }
-    \l__xparse_fn_tl
+    \tl_set:Nn \l__xparse_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__xparse_fn_tl \__xparse_grab_m_aux:Nnnnnnnnn
+    \l__xparse_fn_tl \use_none:nnnnnn { } { } { } { } { } { }
   }
-\cs_new_protected:cpn { __xparse_grab_m_4:w } #1 \l__xparse_args_tl
+\cs_new_protected:cpn { __xparse_grab_m_3:w } #1 \__xparse_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l__xparse_fn_tl
-      ##1##2##3##4
-      {
-        \tl_put_right:Nn \l__xparse_args_tl { {##1} {##2} {##3} {##4} }
-        #1 \l__xparse_args_tl
-      }
-    \l__xparse_fn_tl
+    \tl_set:Nn \l__xparse_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__xparse_fn_tl \__xparse_grab_m_aux:Nnnnnnnnn
+    \l__xparse_fn_tl \use_none:nnnnn { } { } { } { } { }
   }
-\cs_new_protected:cpn { __xparse_grab_m_5:w } #1 \l__xparse_args_tl
+\cs_new_protected:cpn { __xparse_grab_m_4:w } #1 \__xparse_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l__xparse_fn_tl
-      ##1##2##3##4##5
-      {
-        \tl_put_right:Nn \l__xparse_args_tl { {##1} {##2} {##3} {##4} {##5} }
-        #1 \l__xparse_args_tl
-      }
-    \l__xparse_fn_tl
+    \tl_set:Nn \l__xparse_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__xparse_fn_tl \__xparse_grab_m_aux:Nnnnnnnnn
+    \l__xparse_fn_tl \use_none:nnnn { } { } { } { }
   }
-\cs_new_protected:cpn { __xparse_grab_m_6:w } #1 \l__xparse_args_tl
+\cs_new_protected:cpn { __xparse_grab_m_5:w } #1 \__xparse_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l__xparse_fn_tl
-      ##1##2##3##4##5##6
-      {
-        \tl_put_right:Nn \l__xparse_args_tl
-          { {##1} {##2} {##3} {##4} {##5} {##6} }
-        #1 \l__xparse_args_tl
-      }
-    \l__xparse_fn_tl
+    \tl_set:Nn \l__xparse_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__xparse_fn_tl \__xparse_grab_m_aux:Nnnnnnnnn
+    \l__xparse_fn_tl \use_none:nnn { } { } { }
   }
-\cs_new_protected:cpn { __xparse_grab_m_7:w } #1 \l__xparse_args_tl
+\cs_new_protected:cpn { __xparse_grab_m_6:w } #1 \__xparse_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l__xparse_fn_tl
-      ##1##2##3##4##5##6##7
-      {
-        \tl_put_right:Nn \l__xparse_args_tl
-          { {##1} {##2} {##3} {##4} {##5} {##6} {##7} }
-        #1 \l__xparse_args_tl
-      }
-    \l__xparse_fn_tl
+    \tl_set:Nn \l__xparse_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__xparse_fn_tl \__xparse_grab_m_aux:Nnnnnnnnn
+    \l__xparse_fn_tl \use_none:nn { } { }
   }
-\cs_new_protected:cpn { __xparse_grab_m_8:w } #1 \l__xparse_args_tl
+\cs_new_protected:cpn { __xparse_grab_m_7:w } #1 \__xparse_run_code:
   {
-    \exp_after:wN \cs_set_protected_nopar:Npn \l__xparse_fn_tl
-      ##1##2##3##4##5##6##7##8
-      {
-        \tl_put_right:Nn \l__xparse_args_tl
-          { {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} }
-        #1 \l__xparse_args_tl
-      }
-    \l__xparse_fn_tl
+    \tl_set:Nn \l__xparse_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__xparse_fn_tl \__xparse_grab_m_aux:Nnnnnnnnn
+    \l__xparse_fn_tl \use_none:n { }
   }
-\cs_new_protected:Npn \__xparse_grab_R:w #1#2#3#4 \l__xparse_args_tl
-  { \__xparse_grab_R_aux:NNnnN #1 #2 {#3} {#4} \cs_set_protected_nopar:Npn }
-\cs_new_protected:Npn \__xparse_grab_R_long:w #1#2#3#4 \l__xparse_args_tl
-  { \__xparse_grab_R_aux:NNnnN #1 #2 {#3} {#4} \cs_set_protected:Npn }
-\cs_new_protected:Npn \__xparse_grab_R_aux:NNnnN #1#2#3#4#5
+\cs_new_protected:cpn { __xparse_grab_m_8:w } #1 \__xparse_run_code:
   {
-    \__xparse_grab_D_aux:NNnN #1 #2 {#4} #5
+    \tl_set:Nn \l__xparse_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__xparse_fn_tl \__xparse_grab_m_aux:Nnnnnnnnn
+    \l__xparse_fn_tl \prg_do_nothing:
+  }
+\cs_new_protected:cpx { __xparse_grab_m_9:w }
+  {
+    \exp_not:c { __xparse_grab_m_5:w }
+    \exp_not:c { __xparse_grab_m_4:w }
+  }
+\cs_new_protected:Npn \__xparse_grab_R:w #1#2#3 \__xparse_run_code:
+  { \__xparse_grab_R_aux:NNnN #1 #2 {#3} \cs_set_protected_nopar:Npn }
+\cs_new_protected:Npn \__xparse_grab_R_long:w #1#2#3 \__xparse_run_code:
+  { \__xparse_grab_R_aux:NNnN #1 #2 {#3} \cs_set_protected:Npn }
+\cs_new_protected:Npn \__xparse_grab_R_aux:NNnN #1#2#3#4
+  {
+    \__xparse_grab_D_aux:NNnN #1 #2 {#3} #4
     \peek_meaning_remove_ignore_spaces:NTF #1
-      { \__xparse_grab_arg:w }
+      { \__xparse_grab_D_call:Nw #1 }
       {
         \__msg_kernel_error:nnxx { xparse } { missing-required }
-          { \token_to_str:N #1 } { \tl_to_str:n {#3} }
-        \__xparse_add_arg:n {#3}
-        #4 \l__xparse_args_tl
+          { \exp_after:wN \token_to_str:N \l__xparse_fn_tl }
+          { \token_to_str:N #1 }
+        \__xparse_add_arg:o \c__xparse_no_value_tl
       }
   }
-\cs_new_protected:Npn \__xparse_grab_t:w #1#2 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_t:w
+  { \__xparse_grab_t_aux:NNw \peek_meaning_remove_ignore_spaces:NTF }
+\cs_new_eq:NN \__xparse_grab_t_long:w \__xparse_grab_t:w
+\cs_new_protected:Npn \__xparse_grab_t_trailing:w
+  { \__xparse_grab_t_aux:NNw \peek_meaning_remove:NTF }
+\cs_new_eq:NN \__xparse_grab_t_long_trailing:w \__xparse_grab_t_trailing:w
+\cs_new_protected:Npn \__xparse_grab_t_aux:NNw #1#2#3 \__xparse_run_code:
   {
-    \__xparse_grab_t_aux:NnNn #1 {#2} \cs_set_protected_nopar:Npn
-      { _ignore_spaces }
-  }
-\cs_new_protected:Npn \__xparse_grab_t_long:w #1#2 \l__xparse_args_tl
-  { \__xparse_grab_t_aux:NnNn #1 {#2} \cs_set_protected:Npn { _ignore_spaces } }
-\cs_new_protected:Npn \__xparse_grab_t_trailing:w #1#2 \l__xparse_args_tl
-  { \__xparse_grab_t_aux:NnNn #1 {#2} \cs_set_protected_nopar:Npn { } }
-\cs_new_protected:Npn \__xparse_grab_t_long_trailing:w #1#2 \l__xparse_args_tl
-  { \__xparse_grab_t_aux:NnNn #1 {#2} \cs_set_protected:Npn { } }
-\cs_new_protected:Npn \__xparse_grab_t_aux:NnNn #1#2#3#4
-  {
-    \exp_after:wN #3 \l__xparse_fn_tl
+    \tl_set:Nn \l__xparse_signature_tl {#3}
+    \exp_after:wN \cs_set_protected:Npn \l__xparse_fn_tl
       {
-        \use:c { peek_meaning_remove #4 :NTF } #1
-          {
-            \__xparse_add_arg:n { \BooleanTrue }
-            #2 \l__xparse_args_tl
-          }
-          {
-            \__xparse_add_arg:n { \BooleanFalse }
-            #2 \l__xparse_args_tl
-          }
+        #1 #2
+          { \__xparse_add_arg:n { \BooleanTrue } }
+          { \__xparse_add_arg:n { \BooleanFalse } }
       }
     \l__xparse_fn_tl
   }
-\cs_new_protected:Npn \__xparse_grab_u:w #1#2 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_u:w #1#2 \__xparse_run_code:
   { \__xparse_grab_u_aux:nnN {#1} {#2} \cs_set_protected_nopar:Npn }
-\cs_new_protected:Npn \__xparse_grab_u_long:w #1#2 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_u_long:w #1#2 \__xparse_run_code:
   { \__xparse_grab_u_aux:nnN {#1} {#2} \cs_set_protected:Npn }
 \cs_new_protected:Npn \__xparse_grab_u_aux:nnN #1#2#3
   {
+    \tl_set:Nn \l__xparse_signature_tl {#2}
     \exp_after:wN #3 \l__xparse_fn_tl ##1 #1
-      {
-        \__xparse_add_arg:n {##1}
-        #2 \l__xparse_args_tl
-      }
+      { \__xparse_add_arg:n {##1} }
     \l__xparse_fn_tl
   }
-\tl_new:N \l__xparse_v_rest_of_signature_tl
 \tl_new:N \l__xparse_v_arg_tl
 \cs_new_protected:Npn \__xparse_grab_v:w
   {
@@ -1004,9 +1208,9 @@
     \bool_set_true:N \l__xparse_long_bool
     \__xparse_grab_v_aux:w
   }
-\cs_new_protected:Npn \__xparse_grab_v_aux:w #1 \l__xparse_args_tl
+\cs_new_protected:Npn \__xparse_grab_v_aux:w #1 \__xparse_run_code:
   {
-    \tl_set:Nn \l__xparse_v_rest_of_signature_tl {#1}
+    \tl_set:Nn \l__xparse_signature_tl {#1}
     \group_begin:
       \group_align_safe_begin:
         \tex_escapechar:D = 92 \scan_stop:
@@ -1061,8 +1265,7 @@
 \cs_new_protected:Npn \__xparse_grab_v_aux_loop_end:
   {
     \__xparse_grab_v_group_end:
-    \exp_args:Nx \__xparse_add_arg:n { \tl_tail:N \l__xparse_v_arg_tl }
-    \l__xparse_v_rest_of_signature_tl \l__xparse_args_tl
+    \__xparse_add_arg:x { \tl_tail:N \l__xparse_v_arg_tl }
   }
 \int_new:N \l__xparse_v_nesting_int
 \cs_new_protected:Npx \__xparse_grab_v_bgroup:
@@ -1113,7 +1316,6 @@
 \cs_new_protected:Npn \__xparse_grab_v_aux_abort:n #1
   {
     \__xparse_grab_v_group_end:
-    \__xparse_add_arg:o \c__xparse_no_value_tl
     \exp_after:wN \exp_after:wN \exp_after:wN
       \peek_meaning_remove:NTF \char_generate:nn { \tex_endlinechar:D } { 6 }
       {
@@ -1121,7 +1323,7 @@
           { \exp_after:wN \token_to_str:N \l__xparse_fn_tl }
           { \tl_to_str:N \l__xparse_v_arg_tl }
           { \tl_to_str:n {#1} }
-        \l__xparse_v_rest_of_signature_tl \l__xparse_args_tl
+        \__xparse_add_arg:o \c__xparse_no_value_tl
       }
       {
         \__msg_kernel_error:nnxxx { xparse } { verbatim-tokenized }
@@ -1128,7 +1330,7 @@
           { \exp_after:wN \token_to_str:N \l__xparse_fn_tl }
           { \tl_to_str:N \l__xparse_v_arg_tl }
           { \tl_to_str:n {#1} }
-        \l__xparse_v_rest_of_signature_tl \l__xparse_args_tl
+        \__xparse_add_arg:o \c__xparse_no_value_tl
       }
   }
 \cs_new_protected:Npn \__xparse_grab_v_aux_put:N #1
@@ -1143,45 +1345,28 @@
   { \str_if_eq_x:nnTF { } { \str_tail:n {#1} } }
 \cs_new_protected:Npn \__xparse_add_arg:n #1
   {
-    \int_compare:nNnTF \l__xparse_processor_int = \c_zero
-      { \tl_put_right:Nn \l__xparse_args_tl { {#1} } }
-      {
-        \tl_clear:N \ProcessedArgument
-        \__xparse_if_no_value:nTF {#1}
-          {
-            \int_zero:N \l__xparse_processor_int
-            \tl_put_right:Nn \l__xparse_args_tl { {#1} }
-          }
-          { \__xparse_add_arg_aux:n {#1} }
-      }
+    \tl_put_right:Nn \l__xparse_args_tl { {#1} }
+    \l__xparse_signature_tl \__xparse_run_code:
   }
-\cs_generate_variant:Nn \__xparse_add_arg:n { V , o }
-\cs_new_protected:Npn \__xparse_add_arg_aux:n #1
-  {
-    \use:c { __xparse_processor_ \int_use:N \l__xparse_processor_int :n } {#1}
-    \int_decr:N \l__xparse_processor_int
-    \int_compare:nNnTF \l__xparse_processor_int = \c_zero
-      {
-        \tl_put_right:Nx \l__xparse_args_tl
-          { { \exp_not:V \ProcessedArgument } }
-      }
-      { \__xparse_add_arg_aux:V \ProcessedArgument }
-}
-\cs_generate_variant:Nn \__xparse_add_arg_aux:n { V }
+\cs_generate_variant:Nn \__xparse_add_arg:n { V , o , x }
 \cs_new:Npn \__xparse_expandable_grab_D:w #1 \q__xparse #2
-  { #2 { \__xparse_expandable_grab_D:NNNnwNn #1 \q__xparse #2 } }
-\cs_new:Npn \__xparse_expandable_grab_D:NNNnwNn #1#2#3#4#5 \q__xparse #6#7
+  { #2 { \__xparse_expandable_grab_D:NNNwNn #1 \q__xparse #2 } }
+\cs_set_protected:Npn \__xparse_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } { } #7 #2 \q__xparse #3 }
-      { { } {#2} { } }
+    \cs_new:Npn \__xparse_expandable_grab_D:NNNwNn ##1##2##3##4 \q__xparse ##5##6
       {
-        #1
-          { \__xparse_expandable_grab_D:NNNwNnnn #1#2#3#5 \q__xparse #6 }
-          \q_nil { } #2 \ERROR \q__xparse \ERROR
+        \str_if_eq:onTF
+          { ##1 { } { } ##6 ##2 \q__xparse ##3 }
+          { { } {##2} { } }
+          {
+            ##1
+              { \__xparse_expandable_grab_D:NNNwNnnn ##1##2##3##4 \q__xparse ##5 }
+              \q_nil { } ##2 \ERROR \q__xparse \ERROR
+          }
+          { ##4 {#1} \q__xparse ##5 {##6} }
       }
-      { #5 {#4} \q__xparse #6 {#7} }
   }
+\exp_args:No \__xparse_tmp:w { \c__xparse_no_value_tl }
 \cs_new:Npn \__xparse_expandable_grab_D:NNNwNnnn #1#2#3#4 \q__xparse #5#6#7#8
   {
     \exp_args:Nof \__xparse_expandable_grab_D:nnNNNwN
@@ -1213,19 +1398,23 @@
       }
   }
 \cs_new:Npn \__xparse_expandable_grab_D_alt:w #1 \q__xparse #2
-  { #2 { \__xparse_expandable_grab_D_alt:NNnwNn #1 \q__xparse #2 } }
-\cs_new:Npn \__xparse_expandable_grab_D_alt:NNnwNn #1#2#3#4 \q__xparse #5#6
+  { #2 { \__xparse_expandable_grab_D_alt:NNwNn #1 \q__xparse #2 } }
+\cs_set_protected:Npn \__xparse_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } #6 #2 #2 }
-      { { } #2 }
+    \cs_new:Npn \__xparse_expandable_grab_D_alt:NNwNn ##1##2##3 \q__xparse ##4##5
       {
-        #1
-          { \__xparse_expandable_grab_D_alt:Nwn #5 #4 \q__xparse }
-          #6 \ERROR
+        \str_if_eq:onTF
+          { ##1 { } ##5 ##2 ##2 }
+          { { } ##2 }
+          {
+            ##1
+              { \__xparse_expandable_grab_D_alt:Nwn ##4 ##3 \q__xparse }
+              ##5 \ERROR
+          }
+          { ##3 {#1} \q__xparse ##4 {##5} }
       }
-      { #4 {#3} \q__xparse #5 {#6} }
   }
+\exp_args:No \__xparse_tmp:w { \c__xparse_no_value_tl }
 \cs_new:Npn \__xparse_expandable_grab_D_alt:Nwn #1#2 \q__xparse #3
   {
     \tl_if_blank:oTF { \use_none:n #3 }
@@ -1239,46 +1428,85 @@
       }
         #2 \q__xparse #1
   }
+\cs_new:Npn \__xparse_expandable_grab_E:w #1 \q__xparse #2
+  { #2 { \__xparse_expandable_grab_E_test:nnwn #1 \q__xparse #2 } }
+\cs_new:Npn \__xparse_expandable_grab_E_test:nnwn #1#2#3 \q__xparse #4#5
+  {
+    \__xparse_expandable_grab_E_loop:nnnNNw {#5} { } { }
+      #1 \q_nil \q_nil \q_nil \q_mark #2 \q_nil
+    #3 \q__xparse #4
+  }
+\cs_new:Npn \__xparse_expandable_grab_E_loop:nnnNNw
+    #1#2#3#4#5#6 \q_nil #7 \q_mark #8
+  {
+    \quark_if_nil:NTF #4
+      { \__xparse_expandable_grab_E_end:nnw {#1} {#3} }
+      {
+        \__xparse_if_no_value:nTF {#8}
+          { \str_if_eq:onTF { #4 { } #1 #5 } {#5} }
+          { \use_ii:nn }
+            { \__xparse_expandable_grab_E_aux:w { #2 #4 #5 #6 } {#3} ~ }
+            {
+              \__xparse_expandable_grab_E_loop:nnnNNw
+                {#1} { #2 #4 #5 } { #3 {#8} }
+                #6 \q_nil #7 \q_mark
+            }
+      }
+  }
+\cs_new:Npn \__xparse_expandable_grab_E_aux:w #1 \q__xparse #2
+  { #2 { \__xparse_expandable_grab_E_aux:nnw #1 \q__xparse #2 } }
+\cs_new:Npn \__xparse_expandable_grab_E_aux:nnw #1#2#3 \q_nil #4 \q__xparse #5#6
+  { \__xparse_expandable_grab_E:w {#1} { #2 {#6} #3 } #4 \q__xparse #5 }
+\cs_new:Npn \__xparse_expandable_grab_E_end:nnw #1#2#3 \q__xparse #4
+  { #3 {#2} \q__xparse #4 {#1} }
 \cs_new:Npn \__xparse_expandable_grab_m:w #1 \q__xparse #2
   { #2 { \__xparse_expandable_grab_m_aux:wNn #1 \q__xparse #2 } }
 \cs_new:Npn \__xparse_expandable_grab_m_aux:wNn #1 \q__xparse #2#3
   { #1 {#3} \q__xparse #2 }
 \cs_new:Npn \__xparse_expandable_grab_R:w #1 \q__xparse #2
-  { #2 { \__xparse_expandable_grab_R_aux:NNNnwNn #1 \q__xparse #2 } }
-\cs_new:Npn \__xparse_expandable_grab_R_aux:NNNnwNn #1#2#3#4#5 \q__xparse #6#7
+  { #2 { \__xparse_expandable_grab_R_aux:NNNwNn #1 \q__xparse #2 } }
+\cs_set_protected:Npn \__xparse_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } { } #7 #2 \q__xparse #3 }
-      { { } {#2} { } }
+    \cs_new:Npn \__xparse_expandable_grab_R_aux:NNNwNn ##1##2##3##4 \q__xparse ##5##6
       {
-        #1
-          { \__xparse_expandable_grab_D:NNNwNnnn #1#2#3#5 \q__xparse #6 }
-          \q_nil { } #2 \ERROR \q__xparse \ERROR
+        \str_if_eq:onTF
+          { ##1 { } { } ##6 ##2 \q__xparse ##3 }
+          { { } {##2} { } }
+          {
+            ##1
+              { \__xparse_expandable_grab_D:NNNwNnnn ##1##2##3##4 \q__xparse ##5 }
+              \q_nil { } ##2 \ERROR \q__xparse \ERROR
+          }
+          {
+            \__msg_kernel_expandable_error:nnnn
+              { xparse } { missing-required } {##5} {##2}
+            ##4 {#1} \q__xparse ##5 {##6}
+          }
       }
-      {
-        \__msg_kernel_expandable_error:nnn
-          { xparse } { missing-required } {#2}
-        #5 {#4} \q__xparse #6 {#7}
-      }
   }
+\exp_args:No \__xparse_tmp:w { \c__xparse_no_value_tl }
 \cs_new:Npn \__xparse_expandable_grab_R_alt:w #1 \q__xparse #2
   { #2 { \__xparse_expandable_grab_R_alt_aux:NNnwNn #1 \q__xparse #2 } }
-\cs_new:Npn \__xparse_expandable_grab_R_alt_aux:NNnwNn #1#2#3#4 \q__xparse #5#6
+\cs_set_protected:Npn \__xparse_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } #6 #2 #2 }
-      { { } #2 }
+    \cs_new:Npn \__xparse_expandable_grab_R_alt_aux:NNwNn ##1##2##3 \q__xparse ##4##5
       {
-        #1
-          { \__xparse_expandable_grab_D_alt:Nwn #5 #4 \q__xparse }
-          #6 \ERROR
+        \str_if_eq:onTF
+          { ##1 { } ##5 ##2 ##2 }
+          { { } ##2 }
+          {
+            ##1
+              { \__xparse_expandable_grab_D_alt:Nwn ##4 ##3 \q__xparse }
+              ##5 \ERROR
+          }
+          {
+            \__msg_kernel_expandable_error:nnnn
+              { xparse } { missing-required } {##4} {##2}
+            ##3 {#1} \q__xparse ##4 {##5}
+          }
       }
-      {
-        \__msg_kernel_expandable_error:nnn
-          { xparse } { missing-required } {#2}
-        #4 {#3} \q__xparse #5 {#6}
-      }
   }
+\exp_args:No \__xparse_tmp:w { \c__xparse_no_value_tl }
 \cs_new:Npn \__xparse_expandable_grab_t:w #1 \q__xparse #2
   { #2 { \__xparse_expandable_grab_t_aux:NNwn #1 \q__xparse #2 } }
 \cs_new:Npn \__xparse_expandable_grab_t_aux:NNwn #1#2#3 \q__xparse #4#5
@@ -1289,14 +1517,6 @@
   }
 \cs_new:Npn \__xparse_put_arg_expandable:nw #1#2 \q__xparse { #2 {#1} \q__xparse }
 \cs_generate_variant:Nn \__xparse_put_arg_expandable:nw { o }
-\cs_new:Npn \__xparse_grab_expandable_end:wN #1 \q__xparse #2 {#1}
-\cs_new_protected:Npn \__xparse_process_arg:n #1
-  {
-    \int_incr:N \l__xparse_processor_int
-    \cs_set_protected:cpx
-      { __xparse_processor_ \int_use:N \l__xparse_processor_int :n } ##1
-      { \exp_not:n {#1} {##1} }
-  }
 \cs_new_protected:Npn \__xparse_bool_reverse:N #1
   {
     \bool_if:NTF #1
@@ -1407,30 +1627,38 @@
           { \tl_to_str:n {#1} }
       }
   }
+\cs_new_protected:Npn \__xparse_get_arg_spec:NTF #1#2#3
+  {
+    \__xparse_cmd_if_xparse:NTF #1
+      {
+        \tl_set:Nx \ArgumentSpecification { \tl_item:Nn #1 { 2 } }
+        #2
+      }
+      {#3}
+  }
 \cs_new_protected:Npn \__xparse_get_arg_spec:N #1
   {
-    \prop_get:NnNF \l__xparse_command_arg_specs_prop {#1}
-      \ArgumentSpecification
+    \__xparse_get_arg_spec:NTF #1 { }
       { \__xparse_get_arg_spec_error:N #1 }
   }
 \cs_new_protected:Npn \__xparse_get_arg_spec:n #1
   {
-    \prop_get:NnNF \l__xparse_environment_arg_specs_prop {#1}
-      \ArgumentSpecification
+    \exp_args:Nc \__xparse_get_arg_spec:NTF
+      { environment~ \tl_to_str:n {#1} }
+      { }
       { \__xparse_get_arg_spec_error:n {#1} }
   }
 \tl_new:N \ArgumentSpecification
 \cs_new_protected:Npn \__xparse_show_arg_spec:N #1
   {
-    \prop_get:NnNTF \l__xparse_command_arg_specs_prop {#1}
-      \ArgumentSpecification
+    \__xparse_get_arg_spec:NTF #1
       { \tl_show:N \ArgumentSpecification }
       { \__xparse_get_arg_spec_error:N #1 }
   }
 \cs_new_protected:Npn \__xparse_show_arg_spec:n #1
   {
-    \prop_get:NnNTF \l__xparse_environment_arg_specs_prop {#1}
-      \ArgumentSpecification
+    \exp_args:Nc \__xparse_get_arg_spec:NTF
+      { environment~ \tl_to_str:n {#1} }
       { \tl_show:N \ArgumentSpecification }
       { \__xparse_get_arg_spec_error:n {#1} }
   }
@@ -1483,8 +1711,50 @@
       }
     }
 \group_end:
+\cs_new:Npn \__xparse_tl_mapthread_function:NNN #1#2#3
+  {
+    \exp_after:wN \exp_after:wN
+    \exp_after:wN \__xparse_tl_mapthread_loop:w
+    \exp_after:wN \exp_after:wN
+    \exp_after:wN #3
+    \exp_after:wN #1
+    \exp_after:wN \q_recursion_tail
+    \exp_after:wN \q_mark
+    #2
+    \q_recursion_tail
+    \q_recursion_stop
+  }
+\cs_new:Npn \__xparse_tl_mapthread_function:nnN #1#2#3
+  {
+    \__xparse_tl_mapthread_loop:w #3
+      #1 \q_recursion_tail \q_mark
+      #2 \q_recursion_tail \q_recursion_stop
+  }
+\cs_new:Npn \__xparse_tl_mapthread_loop:w #1#2#3 \q_mark #4
+  {
+    \quark_if_recursion_tail_stop:n {#2}
+    \quark_if_recursion_tail_stop:n {#4}
+    #1 {#2} {#4}
+    \__xparse_tl_mapthread_loop:w #1#3 \q_mark
+  }
+\cs_new_protected:Npn \__xparse_cmd_if_xparse:NTF #1
+  {
+    \exp_args:Nf \str_case_x:nnTF
+      {
+        \exp_args:Nf \tl_if_empty:nT { \token_get_arg_spec:N #1 }
+          {
+            \exp_last_unbraced:Nf \__xparse_cmd_if_xparse_aux:w
+              { \token_get_replacement_spec:N #1 } ~ \q_stop
+          }
+      }
+      {
+        { \token_to_str:N \__xparse_start:nNNnnn } { }
+        { \token_to_str:N \__xparse_start_expandable:nNNNn } { }
+      }
+  }
+\cs_new:Npn \__xparse_cmd_if_xparse_aux:w #1 ~ #2 \q_stop {#1}
 \__msg_kernel_new:nnnn { xparse } { bad-arg-spec }
-  { Bad~argument~specification~'#1'. }
+  { Bad~argument~specification~'#2'~for~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
     The~argument~specification~provided~was~not~valid:~
@@ -1521,7 +1791,8 @@
   }
 \__msg_kernel_new:nnnn { xparse } { expandable-ending-optional }
   {
-    Argument~specification~for~expandable~command~ends~with~optional~argument.
+    Argument~specification~'#2'~for~expandable~command~'#1'~
+    ends~with~optional~argument.
   }
   {
     \c__msg_coding_error_text_tl
@@ -1530,7 +1801,7 @@
     argument~with~expandable~commands.
   }
 \__msg_kernel_new:nnnn { xparse } { inconsistent-long }
-  { Inconsistent~long~arguments~for~expandable~command. }
+  { Inconsistent~long~arguments~for~expandable~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
     The~arguments~for~an~expandable~command~must~either~all~be~
@@ -1537,20 +1808,26 @@
     short~or~all~be~long.~You~have~tried~to~mix~the~two~types.
   }
 \__msg_kernel_new:nnnn { xparse } { invalid-expandable-argument-type }
-  { Argument~type~'#1'~not~available~for~an~expandable~function. }
+  { Argument~type~'#2'~not~available~for~expandable~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
-    The~letter~'#1'~does~not~specify~an~argument~type~which~can~be~used~
-    in~an~expandable~function.
+    The~letter~'#2'~does~not~specify~an~argument~type~which~can~be~used~
+    in~an~expandable~command.
     \\ \\
-    LaTeX~will~assume~you~want~a~standard~mandatory~argument~(type~'m').
+    LaTeX~will~ignore~this~entire~definition.
   }
+\__msg_kernel_new:nnnn { xparse } { loop-in-defaults }
+  { Circular~dependency~in~defaults~of~'#1'. }
+  {
+    \c__msg_coding_error_text_tl
+    The~default~values~of~two~or~more~arguments~of~'#1'~depend~on~each~
+    other~in~a~way~that~cannot~be~resolved.
+  }
 \__msg_kernel_new:nnnn { xparse } { missing-required }
-  { Failed~to~find~required~argument~starting~with~'#1'. }
+  { Failed~to~find~required~argument~starting~with~'#2'~for~command~'#1'. }
   {
-    There~is~supposed~to~be~an~argument~to~the~current~function~starting~with~
-    '#1'.~LaTeX~did~not~find~it,~and~will~insert~'#2'~as~the~value~to~be~
-    processed.
+    The~current~command~'#1'~expects~an~argument~starting~with~'#2'.~
+    LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed.
   }
 \__msg_kernel_new:nnnn { xparse } { non-xparse-command }
   { Command~'#1'~not~defined~using~xparse. }
@@ -1585,19 +1862,20 @@
     LaTeX~will~ignore~this~entire~definition.
   }
 \__msg_kernel_new:nnnn { xparse } { not-single-token }
-  { Argument~delimiter~should~be~a~single~token:~'#1'. }
+  { Argument~delimiter~'#2'~for~the~command~'#1'~should~be~a~single~token. }
   {
     \c__msg_coding_error_text_tl
     The~argument~specification~provided~was~not~valid:~
-    in~a~place~where~a~single~token~is~required,~LaTeX~found~'#1'. \\ \\
+    in~a~place~where~a~single~token~is~required,~LaTeX~found~'#2'. \\ \\
     LaTeX~will~ignore~this~entire~definition.
   }
 \__msg_kernel_new:nnnn { xparse } { processor-in-expandable }
-  { Argument~processors~cannot~be~used~with~expandable~functions. }
+  { Argument~processor~'>{#2}'~cannot~be~used~for~the~expandable~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
     The~argument~specification~for~#1~contains~a~processor~function:~
-    this~is~only~supported~for~standard~robust~functions.
+    this~is~only~supported~for~standard~robust~commands. \\ \\
+    LaTeX~will~ignore~this~entire~definition.
   }
 \__msg_kernel_new:nnnn { xparse } { split-excess-tokens }
   { Too~many~'#1'~tokens~when~trying~to~split~argument. }
@@ -1606,12 +1884,20 @@
     at~each~occurrence~of~the~token~'#1',~up~to~a~maximum~of~#2~parts.~
     There~were~too~many~'#1'~tokens.
   }
+\__msg_kernel_new:nnnn { xparse } { too-many-arguments }
+  { Too~many~arguments~in~argument~specification~'#2'~of~command~'#1'. }
+  {
+    \c__msg_coding_error_text_tl
+    The~argument~specification~provided~has~more~than~9~arguments.~
+    This~cannot~be~implemented. \\ \\
+    LaTeX~will~ignore~this~entire~definition.
+  }
 \__msg_kernel_new:nnnn { xparse } { unknown-argument-type }
-  { Unknown~argument~type~'#1'~replaced~by~'m'. }
+  { Unknown~argument~type~'#2'~for~the~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
-    The~letter~'#1'~does~not~specify~a~known~argument~type.~
-    LaTeX~will~assume~you~want~a~standard~mandatory~argument~(type~'m').
+    The~letter~'#2'~does~not~specify~a~known~argument~type.~
+    LaTeX~will~ignore~this~entire~definition.
   }
 \__msg_kernel_new:nnnn { xparse } { unknown-command }
   { Unknown~document~command~'#1'. }
@@ -1666,6 +1952,12 @@
     Redefining~environment~'#1'~
     with~sig.~'#2'~\msg_line_context:.
   }
+\__msg_kernel_new:nnn { xparse } { optional-mandatory }
+  {
+    Since~the~mandatory~argument~'#1'~has~the~same~delimiter~'#2'~
+    as~a~previous~optional~argument,~it~will~not~be~possible~to~
+    omit~all~optional~arguments~when~calling~this~command.
+  }
 \cs_new_eq:NN \BooleanFalse \c_false_bool
 \cs_new_eq:NN \BooleanTrue  \c_true_bool
 \cs_new_protected:Npn \DeclareDocumentCommand #1#2#3

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty	2017-02-10 23:28:14 UTC (rev 43182)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty	2017-02-10 23:29:10 UTC (rev 43183)
@@ -23,8 +23,8 @@
 %%                     (C) Copyright 2004-2010 Frank Mittelbach,
 %%                         The LaTeX3 Project
 %%                     (C) Copyright 2011-2016 The LaTeX3 Project
-\RequirePackage{expl3}[2017/02/07]
-\@ifpackagelater{expl3}{2017/02/07}
+\RequirePackage{expl3}[2017/02/10]
+\@ifpackagelater{expl3}{2017/02/10}
   {}
   {%
     \PackageError{xtemplate}{Support package l3kernel too old}
@@ -38,8 +38,8 @@
   }
 \def\ExplFileName{xtemplate}
 \def\ExplFileDescription{L3 Experimental prototype document functions}
-\def\ExplFileDate{2017/02/07}
-\def\ExplFileVersion{6846}
+\def\ExplFileDate{2017/02/10}
+\def\ExplFileVersion{6878}
 \ProvidesExplPackage
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
 \tl_const:Nn \c__xtemplate_code_root_tl      { template~code~>~ }



More information about the tex-live-commits mailing list