%%
%% This is file `datatool.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% datatool.dtx  (with options: `datatool.sty,package')
%% 
%%  datatool.dtx
%%  Copyright 2009 Nicola Talbot
%% 
%%  This work may be distributed and/or modified under the
%%  conditions of the LaTeX Project Public License, either version 1.3
%%  of this license of (at your option) any later version.
%%  The latest version of this license is in
%%    http://www.latex-project.org/lppl.txt
%%  and version 1.3 or later is part of all distributions of LaTeX
%%  version 2005/12/01 or later.
%% 
%%  This work has the LPPL maintenance status `maintained'.
%% 
%%  The Current Maintainer of this work is Nicola Talbot.
%% 
%%  This work consists of the files datatool.dtx and datatool.ins and the derived files datatool.sty, datapie.sty, dataplot.sty, databar.sty, databib.sty, databib.bst.
%% 
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{datatool}[2009/03/27 v2.01 (NLCT)]
\RequirePackage{xkeyval}
\RequirePackage{ifthen}
\RequirePackage{xfor}
\RequirePackage{fp}
\RequirePackage{substr}
\RequirePackage{etex}
\newcommand*{\@dtl@separator}{,}
\newcommand*{\DTLsetseparator}[1]{%
\renewcommand*{\@dtl@separator}{#1}%
\@dtl@construct@lopoffs
}
\begingroup
\catcode`\ 12
\gdef\DTLsettabseparator{%
  \catcode`\ 12
  \DTLsetseparator{ }%
}
\endgroup
\begingroup
\catcode`\"12\relax
\gdef\@dtl@delimiter{"}
\endgroup
\newcommand*\DTLsetdelimiter[1]{%
\renewcommand*{\@dtl@delimiter}{#1}%
\@dtl@construct@lopoffs}
\edef\@dtl@construct@lopoff#1#2{%
\noexpand\long\noexpand\def\noexpand\@dtl@lopoff#1##1##2\noexpand
\to##3##4{%
\noexpand\ifx#2##1\noexpand\relax
\noexpand\@dtl@qlopoff#1##1##2\noexpand\to##3##4\relax
\noexpand\else
\noexpand\@dtl@lop@ff#1##1##2\noexpand\to##3##4\relax
\noexpand\fi
}}
\edef\@dtl@construct@qlopoff#1#2{%
\noexpand\long\noexpand\def\noexpand\@dtl@qlopoff#1#2##1#2#1##2\noexpand
\to##3##4{%
\noexpand\def##4{##1}\noexpand\def##3{#1##2}%
}}
\edef\@dtl@construct@lop@ff#1{%
\noexpand\long\noexpand\def\noexpand\@dtl@lop@ff#1##1#1##2\noexpand
\to##3##4{%
\noexpand\def##4{##1}\noexpand\def##3{#1##2}%
}}
\newcommand{\@dtl@construct@lopoffs}{%
\edef\@dtl@chars{{\@dtl@separator}{\@dtl@delimiter}}%
\expandafter\@dtl@construct@lopoff\@dtl@chars
\expandafter\@dtl@construct@qlopoff\@dtl@chars
\expandafter\@dtl@construct@lop@ff\expandafter{\@dtl@separator}%
}
\newcommand*{\@dtl@decimal}{.}
\newcommand*{\@dtl@numbergroupchar}{,}
\newcommand*{\DTLsetnumberchars}[2]{%
\renewcommand*{\@dtl@numbergroupchar}{#1}%
\renewcommand*{\@dtl@decimal}{#2}%
\@dtl@construct@getnums
\@dtl@construct@stripnumgrpchar{#1}}
\edef\@dtl@construct@getintfrac#1{%
\noexpand\def\noexpand\@dtl@getintfrac##1#1##2\noexpand\relax{%
\noexpand\@dtl@get@intpart{##1}%
\noexpand\def\noexpand\@dtl@fracpart{##2}%
\noexpand\ifx\noexpand\@empty\noexpand\@dtl@fracpart
 \noexpand\def\noexpand\@dtl@fracpart{0}%
\noexpand\else
 \noexpand\@dtl@getfracpart##2\noexpand\relax
 \noexpand\@dtl@choptrailingzeroes{\noexpand\@dtl@fracpart}%
\noexpand\fi
}%
\noexpand\def\noexpand\@dtl@getfracpart##1#1\noexpand\relax{%
\noexpand\def\noexpand\@dtl@fracpart{##1}%
}%
\noexpand\def\noexpand\DTLconverttodecimal##1##2{%
\noexpand\dtl@ifsingle{##1}%
{\noexpand\expandafter\noexpand\toks@\noexpand\expandafter{##1}%
\noexpand\edef\noexpand\@dtl@tmp{\noexpand\the\noexpand\toks@}}%
{\noexpand\def\noexpand\@dtl@tmp{##1}}%
 \noexpand\@dtl@standardize@currency\noexpand\@dtl@tmp
 \noexpand\ifx\noexpand\@dtl@org@currency\noexpand\@empty
 \noexpand\else
   \noexpand\let\noexpand\@dtl@currency\noexpand\@dtl@org@currency
 \noexpand\fi
\noexpand\expandafter
\noexpand\@dtl@getintfrac\noexpand\@dtl@tmp#1\noexpand\relax
\noexpand\edef##2{\noexpand\@dtl@intpart.\noexpand\@dtl@fracpart}}%
}
\newcommand*{\@dtl@construct@getnums}{%
\expandafter\@dtl@construct@getintfrac\expandafter{\@dtl@decimal}}
\newcommand*{\@dtl@get@intpart}[1]{%
\@dtl@tmpcount=1\relax
\def\@dtl@intpart{#1}%
\ifx\@dtl@intpart\@empty
  \def\@dtl@intpart{0}%
\else
  \def\@dtl@intpart{}%
  \@dtl@get@int@part#1.\relax%
\fi
\ifnum\@dtl@tmpcount<0\relax
  \edef\@dtl@intpart{-\@dtl@intpart}%
\fi
\@dtl@strip@numgrpchar{\@dtl@intpart}%
}
\def\@dtl@get@int@part#1#2\relax{%
\def\@dtl@argi{#1}%
\def\@dtl@argii{#2}%
\ifx\protect#1\relax%
  \let\@dtl@get@nextintpart=\@dtl@get@int@part
\else
  \expandafter\ifx\@dtl@argi\$%
    \let\@dtl@get@nextintpart=\@dtl@get@int@part
  \else
    \ifx-#1%
      \multiply\@dtl@tmpcount by -1\relax
      \let\@dtl@get@nextintpart=\@dtl@get@int@part
    \else
      \if\@dtl@argi+%
        \let\@dtl@get@nextintpart=\@dtl@get@int@part
      \else
        \def\@dtl@intpart{#1}%
        \ifx.\@dtl@argii
          \let\@dtl@get@nextintpart=\@gobble
        \else
          \let\@dtl@get@nextintpart=\@dtl@get@next@intpart
        \fi
      \fi
    \fi
  \fi
\fi
\@dtl@get@nextintpart#2\relax
}
\def\@dtl@get@next@intpart#1.\relax{%
\edef\@dtl@intpart{\@dtl@intpart#1}%
}
\newcommand*{\@dtl@choptrailingzeroes}[1]{%
\def\@dtl@tmpcpz{}%
\expandafter\@dtl@chop@trailingzeroes#1\@nil%
\let#1=\@dtl@tmpcpz
}
\def\@dtl@chop@trailingzeroes#1#2\@nil{%
\FPifeq{#2}{0}%
  \edef\@dtl@tmpcpz{\@dtl@tmpcpz#1}%
  \let\@dtl@chopzeroesnext=\@dtl@gobbletonil
\else
 \edef\@dtl@tmpcpz{\@dtl@tmpcpz#1}%
 \let\@dtl@chopzeroesnext=\@dtl@chop@trailingzeroes
\fi
\@dtl@chopzeroesnext#2\@nil
}
\def\@dtl@gobbletonil#1\@nil{}
\newcommand*{\dtl@truncatedecimal}[1]{%
\expandafter\@dtl@truncatedecimal#1.\@nil#1}
\def\@dtl@truncatedecimal#1.#2\@nil#3{%
\def#3{#1}}
\newcommand*{\@dtl@strip@numgrpchar}[1]{%
\def\@dtl@stripped{}%
\edef\@dtl@do@stripnumgrpchar{%
\noexpand\@@dtl@strip@numgrpchar#1\@dtl@numbergroupchar
\noexpand\relax}%
\@dtl@do@stripnumgrpchar
\let#1=\@dtl@stripped
}
\edef\@dtl@construct@stripnumgrpchar#1{%
\noexpand\def\noexpand\@@dtl@strip@numgrpchar##1#1##2\noexpand\relax{%
\noexpand\expandafter\noexpand\toks@\noexpand\expandafter
{\noexpand\@dtl@stripped}%
\noexpand\edef\noexpand\@dtl@stripped{\noexpand\the\noexpand\toks@
##1}%
\noexpand\def\noexpand\@dtl@tmp{##2}%
\noexpand\ifx\noexpand\@dtl@tmp\noexpand\@empty
 \noexpand\let\noexpand\@dtl@next=\noexpand\relax
\noexpand\else
 \noexpand\let\noexpand\@dtl@next=\noexpand\@@dtl@strip@numgrpchar
\noexpand\fi
\noexpand\@dtl@next##2\noexpand\relax
}%
}
\newcommand*{\DTLdecimaltolocale}[2]{%
\edef\@dtl@tmpdtl{#1}%
\expandafter\@dtl@decimaltolocale\@dtl@tmpdtl.\relax
\FPifeq{\@dtl@fracpart}{0}%
 \edef#2{\@dtl@intpart}%
\else
 \edef#2{\@dtl@intpart\@dtl@decimal\@dtl@fracpart}%
\fi
}
\def\@dtl@decimaltolocale#1.#2\relax{%
\@dtl@decimaltolocaleint{#1}%
\def\@dtl@fracpart{#2}%
\ifx\@dtl@fracpart\@empty
 \def\@dtl@fracpart{0}%
\else
 \@dtl@decimaltolocalefrac#2\relax
\fi
}
\def\@dtl@decimaltolocaleint#1{%
\@dtl@tmpcount=0\relax
\@dtl@countdigits#1.\relax
\@dtl@numgrpsepcount=\@dtl@tmpcount\relax
\divide\@dtl@numgrpsepcount by 3\relax
\multiply\@dtl@numgrpsepcount by 3\relax
\advance\@dtl@numgrpsepcount by -\@dtl@tmpcount\relax
\ifnum\@dtl@numgrpsepcount<0\relax
  \advance\@dtl@numgrpsepcount by 3\relax
\fi
\def\@dtl@intpart{}%
\@dtl@decimal@to@localeint#1.\relax
}
\def\@dtl@countdigits#1#2\relax{%
\advance\@dtl@tmpcount by 1\relax
\ifx.#2\relax
 \let\@dtl@countnext=\@gobble
\else
 \let\@dtl@countnext=\@dtl@countdigits
\fi
\@dtl@countnext#2\relax
}
\def\@dtl@decimal@to@localeint#1#2\relax{%
\advance\@dtl@numgrpsepcount by 1\relax
\ifx.#2\relax
 \edef\@dtl@intpart{\@dtl@intpart#1}%
 \let\@dtl@localeintnext=\@gobble
\else
 \ifnum\@dtl@numgrpsepcount=3\relax
   \edef\@dtl@intpart{\@dtl@intpart#1\@dtl@numbergroupchar}%
   \@dtl@numgrpsepcount=0\relax
 \else
   \ifnum\@dtl@numgrpsepcount>3\relax
     \@dtl@numgrpsepcount=0\relax
   \fi
   \edef\@dtl@intpart{\@dtl@intpart#1}%
 \fi
 \let\@dtl@localeintnext=\@dtl@decimal@to@localeint
\fi
\@dtl@localeintnext#2\relax
}
\def\@dtl@decimaltolocalefrac#1.\relax{%
\def\@dtl@fracpart{#1}%
\@dtl@choptrailingzeroes{\@dtl@fracpart}%
}
\newcommand*{\DTLdecimaltocurrency}[2]{%
\edef\@dtl@tmpdtl{#1}%
\expandafter\@dtl@decimaltolocale\@dtl@tmpdtl.\relax
\dtl@truncatedecimal\@dtl@tmpdtl
\@dtl@tmpcount=\@dtl@tmpdtl\relax
\expandafter\@dtl@toks\expandafter{\@dtl@currency}%
\FPifeq{\@dtl@fracpart}{0}%
 \ifnum\@dtl@tmpcount<0\relax
   \@dtl@tmpcount = -\@dtl@tmpcount\relax
   \edef#2{-\the\@dtl@toks\the\@dtl@tmpcount\@dtl@decimal00}%
 \else
   \edef#2{\the\@dtl@toks\@dtl@intpart\@dtl@decimal00}%
 \fi
\else
 \ifnum\@dtl@tmpcount<0\relax
   \@dtl@tmpcount = -\@dtl@tmpcount\relax
   \ifnum\@dtl@fracpart<10\relax
     \edef#2{-\the\@dtl@toks\number\@dtl@tmpcount
        \@dtl@decimal\@dtl@fracpart0}%
   \else
     \edef#2{-\the\@dtl@toks\number\@dtl@tmpcount
        \@dtl@decimal\@dtl@fracpart}%
   \fi
 \else
   \ifnum\@dtl@fracpart<10\relax
     \edef#2{\the\@dtl@toks\@dtl@intpart\@dtl@decimal\@dtl@fracpart0}%
   \else
     \edef#2{\the\@dtl@toks\@dtl@intpart\@dtl@decimal\@dtl@fracpart}%
   \fi
 \fi
\fi
}
\@dtl@construct@lopoffs
\@dtl@construct@getnums
\expandafter\@dtl@construct@stripnumgrpchar\expandafter
{\@dtl@numbergroupchar}
\define@key{datatool.sty}{separator}{%
\DTLsetseparator{#1}}
\define@key{datatool.sty}{delimiter}{%
\DTLsetdelimiter{#1}}
\define@boolkey{datatool.sty}[dtl]{verbose}[true]{%
\ifdtlverbose \FPmessagestrue\else \FPmessagesfalse\fi}
\newcommand*{\dtl@message}[1]{%
\ifdtlverbose\typeout{#1}\fi}
\ProcessOptionsX
\DeclareRobustCommand\DTLpar{\@par}
\newcount\@dtl@datatype
\newcount\@dtl@tmpcount
\newlength\dtl@tmplength
\newcount\@dtl@numgrpsepcount
\newcommand{\@dtl@checknumerical}[1]{%
\@dtl@numgrpsepfalse
\def\@dtl@tmp{#1}%
\ifx\@empty#1\@empty
 \@dtl@datatype=0\relax
\else
 \dtl@ifsingle{#1}%
 {\expandafter\toks@\expandafter{#1}%
 \edef\@dtl@tmp{\the\toks@}}%
 {\def\@dtl@tmp{#1}}%
 \@dtl@tmpcount=0\relax
 \@dtl@datatype=0\relax
 \@dtl@numgrpsepcount=2\relax
 \@dtl@standardize@currency\@dtl@tmp
 \ifx\@dtl@org@currency\@empty
 \else
   \let\@dtl@currency\@dtl@org@currency
 \fi
 \expandafter\@dtl@checknumericalstart\@dtl@tmp\@nil\@nil
\fi
\ifnum\@dtl@numgrpsepcount>-1\relax
  \if@dtl@numgrpsep
    \ifnum\@dtl@numgrpsepcount=3\relax
    \else
      \@dtl@datatype=0\relax
    \fi
  \fi
\fi
}
\def\@dtl@checknumericalstart#1#2\@nil\@nil{%
\ifx#1\protect
  \@dtl@checknumericalstart#2\@nil\@nil\relax
\else
  \ifx-#1\relax
    \def\@dtl@tmp{#2}%
    \ifx\@empty\@dtl@tmp
      \@dtl@datatype=0\relax
    \else
      \ifnum\@dtl@datatype=0\relax
        \@dtl@datatype=1\relax
      \fi
      \@dtl@checknumericalstart#2\@nil\@nil\relax
    \fi
  \else
    \ifx+#1\relax
      \def\@dtl@tmp{#2}%
      \ifx\@empty\@dtl@tmp
        \@dtl@datatype=0\relax
      \else
        \ifnum\@dtl@datatype=0\relax
          \@dtl@datatype=1\relax
        \fi
        \@dtl@checknumericalstart#2\@nil\@nil\relax
      \fi
    \else
    \def\@dtl@tmp{#1}%
      \ifx#1\$\relax
        \@dtl@datatype=3\relax
        \@dtl@checknumericalstart#2\@nil\@nil\relax
      \else
        \ifx\@empty\@dtl@tmp
          \@dtl@datatype=0\relax
        \else
          \ifnum\@dtl@datatype=0\relax
            \@dtl@datatype=1\relax
          \fi
          \@dtl@checknumericalloop#1#2\@nil\@nil\relax
        \fi
      \fi
    \fi
  \fi
\fi
}
\newif\if@dtl@numgrpsep
\newcommand*{\@dtl@ifDigitOrDecimalSep}[3]{%
\ifx0#1\relax
 #2%
\else
 \ifx1#1\relax
  #2%
 \else
   \ifx2#1\relax
     #2%
   \else
     \ifx3#1\relax
       #2%
     \else
       \ifx4#1\relax
         #2%
       \else
         \ifx5#1\relax
          #2%
         \else
           \ifx6#1\relax
             #2%
           \else
             \ifx7#1\relax
               #2%
             \else
               \ifx8#1\relax
                 #2%
               \else
                 \ifx9#1\relax
                   #2%
                 \else
                   \expandafter\ifx\@dtl@decimal#1\relax
                     #2%
                   \else
                     #3%
                   \fi
                 \fi
               \fi
             \fi
           \fi
         \fi
       \fi
     \fi
   \fi
 \fi
\fi
}
\def\@dtl@checknumericalloop#1#2\@nil{%
\def\@dtl@tmp{#1}%
\ifx\@nnil\@dtl@tmp\relax
 \let\@dtl@chcknumnext=\@dtl@checknumericalnoop%
\else
  \@dtl@ifDigitOrDecimalSep{#1}{%
  \let\@dtl@chcknumnext=\@dtl@checknumericalloop%
  \expandafter\ifx\@dtl@decimal#1\relax
     \if@dtl@numgrpsep
       \ifnum\@dtl@numgrpsepcount=3\relax
        \@dtl@numgrpsepcount=-1\relax
       \else
        \@dtl@datatype=0\relax
        \let\@dtl@chcknumnext=\@dtl@checknumericalnoop
       \fi
     \else
       \@dtl@numgrpsepcount=-1\relax
     \fi
   \else
     \ifnum\@dtl@numgrpsepcount=-1\relax
     \else
       \advance\@dtl@numgrpsepcount by 1\relax
     \fi
   \fi
}{%
\ifx\@dtl@numbergroupchar\@dtl@tmp\relax
  \@dtl@numgrpseptrue
  \ifnum\@dtl@numgrpsepcount<3\relax
    \@dtl@datatype=0\relax
    \let\@dtl@chcknumnext=\@dtl@checknumericalnoop
  \else
     \@dtl@numgrpsepcount=0\relax
  \fi
\else
  \@dtl@datatype=0\relax
  \let\@dtl@chcknumnext=\@dtl@checknumericalnoop
\fi
}%
  \ifx\@dtl@decimal\@dtl@tmp\relax
   \ifnum\@dtl@datatype<3\relax
     \@dtl@datatype=2\relax
   \fi
   \advance\@dtl@tmpcount by 1\relax
   \ifnum\@dtl@tmpcount>1\relax
     \@dtl@datatype=0\relax
     \let\@dtl@chcknumnext=\@dtl@checknumericalnoop%
   \fi
  \fi
\fi
\@dtl@chcknumnext#2\@nil
}
\def\@dtl@checknumericalnoop#1\@nil#2{}
\newcommand{\DTLifnumerical}[3]{%
\@dtl@checknumerical{#1}%
\ifnum\@dtl@datatype=0\relax#3\else#2\fi
}
\newcommand{\DTLifreal}[3]{%
\@dtl@checknumerical{#1}%
\ifnum\@dtl@datatype=2\relax #2\else #3\fi
}
\newcommand{\DTLifint}[3]{%
\@dtl@checknumerical{#1}%
\ifnum\@dtl@datatype=1\relax #2\else #3\fi
}
\newcommand{\DTLifstring}[3]{%
\@dtl@checknumerical{#1}%
\ifnum\@dtl@datatype=0\relax #2\else #3\fi
}
\newcommand{\DTLifcurrency}[3]{%
\@dtl@checknumerical{#1}%
\ifnum\@dtl@datatype=3\relax #2\else #3\fi
}
\newcommand*{\DTLifcurrencyunit}[4]{%
\@dtl@checknumerical{#1}%
\ifnum\@dtl@datatype=3\relax
  \ifthenelse{\equal{\@dtl@org@currency}{#2}}{#3}{#4}%
\else
  #4%
\fi
}
\newcommand{\DTLifcasedatatype}[5]{%
\@dtl@checknumerical{#1}%
\ifcase\@dtl@datatype
 #2% string
\or
 #3% integer
\or
 #4% number
\or
 #5% currency
\fi
}
\newcommand*{\dtl@testbothnumerical}[2]{%
\dtl@ifsingle{#1}{%
 \edef\@dtl@tmp{#1}}{%
 \def\@dtl@tmp{#1}}%
\expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}%
\edef\@dtl@firsttype{\number\@dtl@datatype}%
\dtl@ifsingle{#2}{%
 \edef\@dtl@tmp{#2}}{%
 \def\@dtl@tmp{#2}}%
\expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}%
\multiply\@dtl@datatype by \@dtl@firsttype\relax
\ifnum\@dtl@datatype>0\relax
 \@dtl@conditiontrue
\else
 \@dtl@conditionfalse
\fi
}
\newcommand*{\DTLifnumlt}[4]{%
  \DTLconverttodecimal{#1}{\@dtl@numi}%
  \DTLconverttodecimal{#2}{\@dtl@numii}%
  \FPiflt{\@dtl@numi}{\@dtl@numii}%
   #3%
  \else
   #4%
  \fi
}
\newcommand*{\dtlcompare}[3]{%
\dtl@subnobrsp{#2}{\@dtl@argA}%
\dtl@subnobrsp{#3}{\@dtl@argB}%
\ifx\@dtl@argA\@empty
 \ifx\@dtl@argB\@empty
   #1=0\relax
 \else
   #1=-1\relax
 \fi
\else
  \ifx\@dtl@argB\@empty
    #1=1\relax
  \else
    \DTLsubstituteall{\@dtl@argA}{ }{\space }%
    \DTLsubstituteall{\@dtl@argB}{ }{\space }%
    \expandafter\dtl@getfirst\@dtl@argA\end
    \let\dtl@firstA=\dtl@first
    \let\dtl@restA=\dtl@rest
    \expandafter\dtl@getfirst\@dtl@argB\end
    \let\dtl@firstB=\dtl@first
    \let\dtl@restB=\dtl@rest
    \expandafter\dtl@ifsingle\expandafter{\dtl@firstA}{%
    \expandafter\dtl@ifsingle\expandafter{\dtl@firstB}{%
    \expandafter\dtl@setcharcode\expandafter{\dtl@firstA}{\dtl@codeA}%
    \expandafter\dtl@setcharcode\expandafter{\dtl@firstB}{\dtl@codeB}%
    \ifnum\dtl@codeA=-1\relax
      \ifnum\dtl@codeB=-1\relax
         \protected@edef\dtl@donext{%
           \noexpand\dtlcompare{\noexpand#1}{\dtl@restA}{\dtl@restB}}%
         \dtl@donext
      \else
         \protected@edef\dtl@donext{%
           \noexpand\dtlcompare
             {\noexpand#1}{\dtl@restA}{\dtl@firstB\dtl@restB}}%
         \dtl@donext
      \fi
    \else
      \ifnum\dtl@codeB=-1\relax
         \protected@edef\dtl@donext{%
           \noexpand\dtlcompare
             {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@restB}}%
         \dtl@donext
      \else
        \ifnum\dtl@codeA<\dtl@codeB
          #1=-1\relax
        \else
          \ifnum\dtl@codeA>\dtl@codeB
            #1=1\relax
          \else
             \ifx\dtl@restA\@empty
               \ifx\dtl@restB\@empty
                 #1=0\relax
               \else
                 #1=-1\relax
               \fi
             \else
               \ifx\restB\@empty
                 #1=1\relax
               \else
                 \protected@edef\dtl@donext{%
                   \noexpand\dtlcompare
                     {\noexpand#1}{\dtl@restA}{\dtl@restB}}%
                 \dtl@donext
               \fi
             \fi
          \fi
        \fi
      \fi
    \fi
    }{%
    \protected@edef\dtl@donext{%
      \noexpand\dtlcompare
        {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
    \dtl@donext
    }}{%
    \protected@edef\dtl@donext{%
      \noexpand\dtlcompare
        {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
    \dtl@donext
    }%
  \fi
\fi
}
\def\dtl@getfirst#1#2\end{%
\def\dtl@first{#1}%
\ifx\dtl@first\@empty
 \def\dtl@rest{#2}%
\else
 \dtl@ifsingle{#1}{\def\dtl@rest{#2}}{\dtl@getfirst#1#2\end}%
\fi
}
\newcount\dtl@codeA
\newcount\dtl@codeB
\newcommand*{\dtl@setcharcode}[2]{%
\def\@dtl@tmp{#1}%
\ifx\@dtl@tmp\@empty
 #2=-1\relax
\else
 \ifx#1\space\relax
   #2=`\ \relax
 \else
   \ifx#1~\relax
     #2=`\ \relax
   \else
     \ifcat\noexpand#1\relax%
       #2=-1\relax
     \else
       #2=`#1\relax
     \fi
   \fi
 \fi
\fi
}
\newcommand*{\dtl@setlccharcode}[2]{%
\def\@dtl@tmp{#1}%
\ifx\@dtl@tmp\@empty
 #2=-1\relax
\else
 \ifx#1\space\relax
   #2=`\ \relax
 \else
   \ifx#1~\relax
     #2=`\ \relax
   \else
     \ifcat\noexpand#1\relax%
       #2=-1\relax
     \else
       #2=\lccode`#1\relax
     \fi
   \fi
 \fi
\fi
}
\newcommand*{\dtlicompare}[3]{%
\dtl@subnobrsp{#2}{\@dtl@argA}%
\dtl@subnobrsp{#3}{\@dtl@argB}%
\ifx\@dtl@argA\@empty
 \ifx\@dtl@argB\@empty
   #1=0\relax
 \else
   #1=-1\relax
 \fi
\else
  \ifx\@dtl@argB\@empty
    #1=1\relax
  \else
    \DTLsubstituteall{\@dtl@argA}{ }{\space }%
    \DTLsubstituteall{\@dtl@argB}{ }{\space }%
    \expandafter\dtl@getfirst\@dtl@argA\end
    \let\dtl@firstA=\dtl@first
    \let\dtl@restA=\dtl@rest
    \expandafter\dtl@getfirst\@dtl@argB\end
    \let\dtl@firstB=\dtl@first
    \let\dtl@restB=\dtl@rest
    \expandafter\dtl@ifsingle\expandafter{\dtl@firstA}{%
    \expandafter\dtl@ifsingle\expandafter{\dtl@firstB}{%
    \expandafter\dtl@setlccharcode\expandafter{\dtl@firstA}{\dtl@codeA}%
    \expandafter\dtl@setlccharcode\expandafter{\dtl@firstB}{\dtl@codeB}%
    \ifnum\dtl@codeA=-1\relax
      \ifnum\dtl@codeB=-1\relax
         \protected@edef\dtl@donext{%
           \noexpand\dtlicompare{\noexpand#1}{\dtl@restA}{\dtl@restB}}%
         \dtl@donext
      \else
         \protected@edef\dtl@donext{%
           \noexpand\dtlicompare
             {\noexpand#1}{\dtl@restA}{\dtl@firstB\dtl@restB}}%
         \dtl@donext
      \fi
    \else
      \ifnum\dtl@codeB=-1\relax
         \protected@edef\dtl@donext{%
           \noexpand\dtlicompare
             {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@restB}}%
         \dtl@donext
      \else
        \ifnum\dtl@codeA<\dtl@codeB
          #1=-1\relax
        \else
          \ifnum\dtl@codeA>\dtl@codeB
            #1=1\relax
          \else
             \ifx\dtl@restA\@empty
               \ifx\dtl@restB\@empty
                 #1=0\relax
               \else
                 #1=-1\relax
               \fi
             \else
               \ifx\restB\@empty
                 #1=1\relax
               \else
                 \protected@edef\dtl@donext{%
                   \noexpand\dtlicompare
                     {\noexpand#1}{\dtl@restA}{\dtl@restB}}%
                 \dtl@donext
               \fi
             \fi
          \fi
        \fi
      \fi
    \fi
    }{%
    \protected@edef\dtl@donext{%
      \noexpand\dtlicompare
        {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
    \dtl@donext
    }}{%
    \protected@edef\dtl@donext{%
      \noexpand\dtlicompare
        {\noexpand#1}{\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
    \dtl@donext
    }%
  \fi
\fi
}
\newcommand*{\DTLifstringlt}{\@ifstar\@sDTLifstringlt\@DTLifstringlt}
\newcommand*{\@DTLifstringlt}[4]{%
\protected@edef\@dtl@tmpcmp{%
  \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}%
\@dtl@tmpcmp
\ifnum\@dtl@tmpcount<0\relax
  #3%
\else
  #4%
\fi
}
\newcommand*{\@sDTLifstringlt}[4]{%
\protected@edef\@dtl@tmpcmp{%
  \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}%
\@dtl@tmpcmp
\ifnum\@dtl@tmpcount<0\relax
  #3%
\else
  #4%
\fi
}
\newcommand*{\DTLiflt}{\@ifstar\@sDTLiflt\@DTLiflt}
\newcommand*{\@DTLiflt}[4]{%
\dtl@testbothnumerical{#1}{#2}%
\if@dtl@condition
 \DTLifnumlt{#1}{#2}{#3}{#4}%
\else
 \@DTLifstringlt{#1}{#2}{#3}{#4}%
\fi
}
\newcommand*{\@sDTLiflt}[4]{%
\dtl@testbothnumerical{#1}{#2}%
\if@dtl@condition
 \DTLifnumlt{#1}{#2}{#3}{#4}%
\else
 \@sDTLifstringlt{#1}{#2}{#3}{#4}%
\fi
}
\newcommand*{\DTLifnumgt}[4]{%
  \DTLconverttodecimal{#1}{\@dtl@numi}%
  \DTLconverttodecimal{#2}{\@dtl@numii}%
  \FPifgt{\@dtl@numi}{\@dtl@numii}%
   #3%
  \else
   #4%
  \fi
}
\newcommand*{\DTLifstringgt}{\@ifstar\@sDTLifstringgt\@DTLifstringgt}
\newcommand*{\@DTLifstringgt}[4]{%
\protected@edef\@dtl@tmpcmp{%
  \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}%
\@dtl@tmpcmp
\ifnum\@dtl@tmpcount>0\relax
  #3%
\else
  #4%
\fi
}
\newcommand*{\@sDTLifstringgt}[4]{%
\protected@edef\@dtl@tmpcmp{%
  \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}%
\@dtl@tmpcmp
\ifnum\@dtl@tmpcount>0\relax
  #3%
\else
  #4%
\fi
}
\newcommand*{\DTLifgt}{\@ifstar\@sDTLifgt\@DTLifgt}
\newcommand*{\@DTLifgt}[4]{%
\dtl@testbothnumerical{#1}{#2}%
\if@dtl@condition
 \DTLifnumgt{#1}{#2}{#3}{#4}%
\else
 \@DTLifstringgt{#1}{#2}{#3}{#4}%
\fi
}
\newcommand*{\@sDTLifgt}[4]{%
\dtl@testbothnumerical{#1}{#2}%
\if@dtl@condition
 \DTLifnumgt{#1}{#2}{#3}{#4}%
\else
 \@sDTLifstringgt{#1}{#2}{#3}{#4}%
\fi
}
\newcommand*{\DTLifnumeq}[4]{%
  \DTLconverttodecimal{#1}{\@dtl@numi}%
  \DTLconverttodecimal{#2}{\@dtl@numii}%
  \FPifeq{\@dtl@numi}{\@dtl@numii}%
   #3%
  \else
   #4%
  \fi
}
\newcommand*{\DTLifstringeq}{\@ifstar\@sDTLifstringeq\@DTLifstringeq}
\newcommand*{\@DTLifstringeq}[4]{%
\protected@edef\@dtl@tmpcmp{%
  \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}%
\@dtl@tmpcmp
\ifnum\@dtl@tmpcount=0\relax
  #3%
\else
  #4%
\fi
}
\newcommand*{\@sDTLifstringeq}[4]{%
\protected@edef\@dtl@tmpcmp{%
  \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}%
\@dtl@tmpcmp
\ifnum\@dtl@tmpcount=0\relax
  #3%
\else
  #4%
\fi
}
\newcommand*{\DTLifeq}{\@ifstar\@sDTLifeq\@DTLifeq}
\newcommand*{\@DTLifeq}[4]{%
\dtl@testbothnumerical{#1}{#2}%
\if@dtl@condition
 \DTLifnumeq{#1}{#2}{#3}{#4}%
\else
 \@DTLifstringeq{#1}{#2}{#3}{#4}%
\fi
}
\newcommand*{\@sDTLifeq}[4]{%
\dtl@testbothnumerical{#1}{#2}%
\if@dtl@condition
 \DTLifnumeq{#1}{#2}{#3}{#4}%
\else
 \@sDTLifstringeq{#1}{#2}{#3}{#4}%
\fi
}
\newcommand*{\DTLifSubString}[4]{%
\protected@edef\@dtl@tmp{\noexpand\dtl@testifsubstring
{#1}{#2}}%
\@dtl@tmp
\if@dtl@condition
 #3%
\else
 #4%
\fi
}
\newcommand*{\dtl@testifsubstring}[2]{%
\dtl@subnobrsp{#1}{\@dtl@argA}%
\dtl@subnobrsp{#2}{\@dtl@argB}%
\ifx\@dtl@argB\@empty
 \@dtl@conditiontrue
\else
 \ifx\@dtl@argA\@empty
   \@dtl@conditionfalse
 \else
   \dtl@teststartswith{#1}{#2}%
   \if@dtl@condition
   \else
     \DTLsubstituteall{\@dtl@argA}{ }{\space }%
     \expandafter\dtl@getfirst\@dtl@argA\end
     \expandafter\dtl@ifsingle\expandafter{\dtl@first}{%
       \expandafter\dtl@testifsubstring\expandafter{\dtl@rest}{#2}%
     }{%
       \protected@edef\@dtl@donext{\noexpand\dtl@testifsubstring
          {\dtl@first\dtl@rest}{\@dtl@argB}}%
       \@dtl@donext
     }%
   \fi
 \fi
\fi
}
\newcommand*{\DTLifStartsWith}[4]{%
\@dtl@conditionfalse
\protected@edef\@dtl@tmp{\noexpand\dtl@teststartswith{#1}{#2}}%
\@dtl@tmp
\if@dtl@condition
 #3%
\else
 #4%
\fi
}
\newcommand*{\dtl@teststartswith}[2]{%
\dtl@subnobrsp{#1}{\@dtl@argA}%
\dtl@subnobrsp{#2}{\@dtl@argB}%
\ifx\@dtl@argA\@empty
 \ifx\@dtl@argB\@empty
   \@dtl@conditiontrue
 \else
   \@dtl@conditionfalse
 \fi
\else
  \ifx\@dtl@argB\@empty
   \@dtl@conditiontrue
  \else
    \DTLsubstituteall{\@dtl@argA}{ }{\space }%
    \DTLsubstituteall{\@dtl@argB}{ }{\space }%
    \expandafter\dtl@getfirst\@dtl@argA\end
    \let\dtl@firstA=\dtl@first
    \let\dtl@restA=\dtl@rest
    \expandafter\dtl@getfirst\@dtl@argB\end
    \let\dtl@firstB=\dtl@first
    \let\dtl@restB=\dtl@rest
    \expandafter\dtl@ifsingle\expandafter{\dtl@firstA}{%
    \expandafter\dtl@ifsingle\expandafter{\dtl@firstB}{%
    \expandafter\dtl@setcharcode\expandafter{\dtl@firstA}{\dtl@codeA}%
    \expandafter\dtl@setcharcode\expandafter{\dtl@firstB}{\dtl@codeB}%
    \ifnum\dtl@codeA=-1\relax
      \ifnum\dtl@codeB=-1\relax
         \protected@edef\dtl@donext{%
           \noexpand\dtl@teststartswith{\dtl@restA}{\dtl@restB}}%
         \dtl@donext
      \else
         \protected@edef\dtl@donext{%
           \noexpand\dtl@teststartswith
             {\dtl@restA}{\dtl@firstB\dtl@restB}}%
         \dtl@donext
      \fi
    \else
      \ifnum\dtl@codeB=-1\relax
         \protected@edef\dtl@donext{%
           \noexpand\dtl@teststartswith
             {\dtl@firstA\dtl@restA}{\dtl@restB}}%
         \dtl@donext
      \else
        \ifnum\dtl@codeA=\dtl@codeB
          \protected@edef\dtl@donext{%
            \noexpand\dtl@teststartswith{\dtl@restA}{\dtl@restB}}%
          \dtl@donext
        \else
          \@dtl@conditionfalse
        \fi
      \fi
    \fi
    }{%
    \protected@edef\dtl@donext{%
      \noexpand\dtl@teststartswith
        {\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
    \dtl@donext
    }}{%
    \protected@edef\dtl@donext{%
      \noexpand\dtl@teststartswith
        {\dtl@firstA\dtl@restA}{\dtl@firstB\dtl@restB}}%
    }%
  \fi
\fi
}
\newcommand*{\DTLifnumclosedbetween}[5]{%
\DTLconverttodecimal{#1}{\@dtl@numi}%
\DTLconverttodecimal{#2}{\@dtl@numii}%
\DTLconverttodecimal{#3}{\@dtl@numiii}%
\DTLifFPclosedbetween{\@dtl@numi}{\@dtl@numii}{\@dtl@numiii}{#4}{#5}%
}
\newcommand*{\DTLifstringclosedbetween}{%
\@ifstar\@sDTLifstringclosedbetween\@DTLifstringclosedbetween}
\newcommand*{\@DTLifstringclosedbetween}[5]{%
\protected@edef\@dtl@tmpcmp{%
  \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}%
\@dtl@tmpcmp
\let\@dtl@dovalue\relax
\ifnum\@dtl@tmpcount<0\relax
  \def\@dtl@dovalue{#5}%
\fi
\ifx\@dtl@dovalue\relax
  \protected@edef\@dtl@tmpcmp{%
    \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#3}}%
  \@dtl@tmpcmp
  \ifnum\@dtl@tmpcount>0\relax
    \def\@dtl@dovalue{#5}%
  \else
    \def\@dtl@dovalue{#4}%
  \fi
\fi
\@dtl@dovalue
}
\newcommand*{\@sDTLifstringclosedbetween}[5]{%
\protected@edef\@dtl@tmpcmp{%
  \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}%
\@dtl@tmpcmp
\let\@dtl@dovalue\relax
\ifnum\@dtl@tmpcount<0\relax
  \def\@dtl@dovalue{#5}%
\fi
\ifx\@dtl@dovalue\relax
  \protected@edef\@dtl@tmpcmp{%
    \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#3}}%
  \@dtl@tmpcmp
  \ifnum\@dtl@tmpcount>0\relax
    \def\@dtl@dovalue{#5}%
  \else
    \def\@dtl@dovalue{#4}%
  \fi
\fi
\@dtl@dovalue
}
\newcommand*{\DTLifclosedbetween}{%
\@ifstar\@sDTLifclosedbetween\@DTLifclosedbetween}
\newcommand*{\@DTLifclosedbetween}[5]{%
\dtl@testbothnumerical{#2}{#3}%
\if@dtl@condition
  \dtl@ifsingle{#1}{%
    \edef\@dtl@tmp{#1}}{%
    \def\@dtl@tmp{#1}}%
  \expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}%
  \ifnum\@dtl@datatype>0\relax
    \DTLifnumclosedbetween{#1}{#2}{#3}{#4}{#5}%
  \else
    \@DTLifstringclosedbetween{#1}{#2}{#3}{#4}{#5}%
  \fi
\else
  \@DTLifstringclosedbetween{#1}{#2}{#3}{#4}{#5}%
\fi
}
\newcommand*{\@sDTLifclosedbetween}[5]{%
\dtl@testbothnumerical{#2}{#3}%
\if@dtl@condition
  \dtl@ifsingle{#1}{%
    \edef\@dtl@tmp{#1}}{%
    \def\@dtl@tmp{#1}}%
  \expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}%
  \ifnum\@dtl@datatype>0\relax
    \DTLifnumclosedbetween{#1}{#2}{#3}{#4}{#5}%
  \else
    \@sDTLifstringclosedbetween{#1}{#2}{#3}{#4}{#5}%
  \fi
\else
  \@sDTLifstringclosedbetween{#1}{#2}{#3}{#4}{#5}%
\fi
}
\newcommand*{\DTLifnumopenbetween}[5]{%
\DTLconverttodecimal{#1}{\@dtl@numi}%
\DTLconverttodecimal{#2}{\@dtl@numii}%
\DTLconverttodecimal{#3}{\@dtl@numiii}%
\DTLifFPopenbetween{\@dtl@numi}{\@dtl@numii}{\@dtl@numiii}{#4}{#5}%
}
\newcommand*{\DTLifstringopenbetween}{%
\@ifstar\@sDTLifstringopenbetween\@DTLifstringopenbetween}
\newcommand*{\@DTLifstringopenbetween}[5]{%
\protected@edef\@dtl@tmpcmp{%
  \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#2}}%
\@dtl@tmpcmp
\let\@dtl@dovalue\relax
\ifnum\@dtl@tmpcount>0\relax
\else
  \def\@dtl@dovalue{#5}%
\fi
\ifx\@dtl@dovalue\relax
  \protected@edef\@dtl@tmpcmp{%
    \noexpand\dtlcompare{\noexpand\@dtl@tmpcount}{#1}{#3}}%
  \@dtl@tmpcmp
  \ifnum\@dtl@tmpcount<0\relax
    \def\@dtl@dovalue{#4}%
  \else
    \def\@dtl@dovalue{#5}%
  \fi
\fi
\@dtl@dovalue
}
\newcommand*{\@sDTLifstringopenbetween}[5]{%
\protected@edef\@dtl@tmpcmp{%
  \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#2}}%
\@dtl@tmpcmp
\let\@dtl@dovalue\relax
\ifnum\@dtl@tmpcount>0\relax
\else
  \def\@dtl@dovalue{#5}%
\fi
\ifx\@dtl@dovalue\relax
  \protected@edef\@dtl@tmpcmp{%
    \noexpand\dtlicompare{\noexpand\@dtl@tmpcount}{#1}{#3}}%
  \@dtl@tmpcmp
  \ifnum\@dtl@tmpcount<0\relax
    \def\@dtl@dovalue{#4}%
  \else
    \def\@dtl@dovalue{#5}%
  \fi
\fi
\@dtl@dovalue
}
\newcommand*{\DTLifopenbetween}{%
\@ifstar\@sDTLifopenbetween\@DTLifopenbetween}
\newcommand*{\@DTLifopenbetween}[5]{%
\dtl@testbothnumerical{#2}{#3}%
\if@dtl@condition
  \dtl@ifsingle{#1}{%
    \edef\@dtl@tmp{#1}}{%
    \def\@dtl@tmp{#1}}%
  \expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}%
  \ifnum\@dtl@datatype>0\relax
    \DTLifnumopenbetween{#1}{#2}{#3}{#4}{#5}%
  \else
    \@DTLifstringopenbetween{#1}{#2}{#3}{#4}{#5}%
  \fi
\else
  \@DTLifstringopenbetween{#1}{#2}{#3}{#4}{#5}%
\fi
}
\newcommand*{\@sDTLifopenbetween}[5]{%
\dtl@testbothnumerical{#2}{#3}%
\if@dtl@condition
  \dtl@ifsingle{#1}{%
    \edef\@dtl@tmp{#1}}{%
    \def\@dtl@tmp{#1}}%
  \expandafter\@dtl@checknumerical\expandafter{\@dtl@tmp}%
  \ifnum\@dtl@datatype>0\relax
    \DTLifnumopenbetween{#1}{#2}{#3}{#4}{#5}%
  \else
    \@sDTLifstringopenbetween{#1}{#2}{#3}{#4}{#5}%
  \fi
\else
  \@sDTLifstringopenbetween{#1}{#2}{#3}{#4}{#5}%
\fi
}
\newcommand*{\DTLifFPopenbetween}[5]{%
  \let\@dtl@dovalue\relax
  \FPifgt{#1}{#2}%
  \else
    \def\@dtl@dovalue{#5}%
  \fi
  \FPiflt{#1}{#3}%
    \ifx\@dtl@dovalue\relax
      \def\@dtl@dovalue{#4}%
    \fi
  \else
    \def\@dtl@dovalue{#5}%
  \fi
\@dtl@dovalue
}
\newcommand*{\DTLifFPclosedbetween}[5]{%
  \let\@dtl@dovalue\relax
  \FPifgt{#1}{#3}%
    \def\@dtl@dovalue{#5}%
  \fi
  \FPiflt{#1}{#2}%
    \ifx\@dtl@dovalue\relax
      \def\@dtl@dovalue{#5}%
    \fi
  \else
    \def\@dtl@dovalue{#4}%
  \fi
\@dtl@dovalue
}
\newcommand{\DTLiffirstrow}[2]{%
  \PackageError{datatool}{\string\DTLiffirstrow\space can only
  be used inside \string\DTLforeach}{}%
}
\newcommand{\DTLiflastrow}[2]{%
  \PackageError{datatool}{\string\DTLiflastrow\space can only
  be used inside \string\DTLforeach}{}%
}
\newcommand{\DTLifoddrow}[2]{%
  \PackageError{datatool}{\string\DTLifoddrow\space can only
  be used inside \string\DTLforeach}{}%
}
\newif\if@dtl@condition
\newcommand*{\dtl@testlt}[2]{%
\DTLiflt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLislt}[2]{%
\TE@throw\noexpand\dtl@testlt{#1}{#2}\noexpand\if@dtl@condition}
\newcommand*{\dtl@testiclt}[2]{%
\@sDTLiflt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisilt}[2]{%
\TE@throw\noexpand\dtl@testiclt{#1}{#2}\noexpand\if@dtl@condition}
\newcommand*{\dtl@testgt}[2]{%
\DTLifgt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisgt}[2]{%
\TE@throw\noexpand\dtl@testgt{#1}{#2}\noexpand\if@dtl@condition}
\newcommand*{\dtl@testicgt}[2]{%
\@sDTLifgt{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisigt}[2]{%
\TE@throw\noexpand\dtl@testicgt{#1}{#2}\noexpand\if@dtl@condition}
\newcommand*{\dtl@testeq}[2]{%
\DTLifeq{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLiseq}[2]{%
\TE@throw\noexpand\dtl@testeq{#1}{#2}\noexpand\if@dtl@condition}
\newcommand*{\dtl@testiceq}[2]{%
\@sDTLifeq{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisieq}[2]{%
\TE@throw\noexpand\dtl@testiceq{#1}{#2}\noexpand\if@dtl@condition}
\newcommand*{\DTLisSubString}[2]{%
\TE@throw\noexpand\dtl@testifsubstring{#1}{#2}%
\noexpand\if@dtl@condition}
\newcommand*{\DTLisPrefix}[2]{%
\TE@throw\noexpand\dtl@teststartswith{#1}{#2}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testclosedbetween}[3]{%
\DTLifclosedbetween{#1}{#2}{#3}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisclosedbetween}[3]{%
\TE@throw\noexpand\dtl@testclosedbetween{#1}{#2}{#3}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testiclosedbetween}[3]{%
\@sDTLifclosedbetween{#1}{#2}{#3}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisiclosedbetween}[3]{%
\TE@throw\noexpand\dtl@testiclosedbetween{#1}{#2}{#3}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testopenbetween}[3]{%
\DTLifopenbetween{#1}{#2}{#3}{\@dtl@conditiontrue
}{\@dtl@conditionfalse}}
\newcommand*{\DTLisopenbetween}[3]{%
\TE@throw\noexpand\dtl@testopenbetween{#1}{#2}{#3}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testiopenbetween}[3]{%
\@sDTLifopenbetween{#1}{#2}{#3}{\@dtl@conditiontrue
}{\@dtl@conditionfalse}}
\newcommand*{\DTLisiopenbetween}[3]{%
\TE@throw\noexpand\dtl@testiopenbetween{#1}{#2}{#3}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testFPclosedbetween}[3]{%
\DTLifFPclosedbetween{#1}{#2}{#3}%
{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisFPclosedbetween}[3]{%
\TE@throw\noexpand\dtl@testFPclosedbetween{#1}{#2}{#3}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testFPopenbetween}[3]{%
\DTLifFPopenbetween{#1}{#2}{#3}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisFPopenbetween}[3]{%
\TE@throw\noexpand\dtl@testFPopenbetween{#1}{#2}{#3}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testFPislt}[2]{%
\FPiflt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi}
\newcommand*{\DTLisFPlt}[2]{%
\TE@throw\noexpand\dtl@testFPislt{#1}{#2}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testFPisgt}[2]{%
\FPifgt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi}
\newcommand*{\DTLisFPgt}[2]{%
\TE@throw\noexpand\dtl@testFPisgt{#1}{#2}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testFPiseq}[2]{%
\FPifeq{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi}
\newcommand*{\DTLisFPeq}[2]{%
\TE@throw\noexpand\dtl@testFPiseq{#1}{#2}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testFPislteq}[2]{%
\FPiflt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi
\if@dtl@condition
\else
 \dtl@testFPiseq{#1}{#2}%
\fi
}
\newcommand*{\DTLisFPlteq}[2]{%
\TE@throw\noexpand\dtl@testFPislteq{#1}{#2}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@testFPisgteq}[2]{%
\FPifgt{#1}{#2}\@dtl@conditiontrue\else\@dtl@conditionfalse\fi
\if@dtl@condition
\else
 \dtl@testFPiseq{#1}{#2}%
\fi
}
\newcommand*{\DTLisFPgteq}[2]{%
\TE@throw\noexpand\dtl@testFPisgteq{#1}{#2}%
\noexpand\if@dtl@condition}
\newcommand*{\dtl@teststring}[1]{%
\DTLifstring{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisstring}[1]{%
\TE@throw\noexpand\dtl@teststring{#1}\noexpand\if@dtl@condition}
\newcommand*{\dtl@testnumerical}[1]{%
\DTLifnumerical{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}%
}
\newcommand*{\DTLisnumerical}[1]{%
\TE@throw\noexpand\dtl@testnumerical{#1}\noexpand\if@dtl@condition}
\newcommand*{\dtl@testint}[1]{%
\DTLifint{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisint}[1]{%
\TE@throw\noexpand\dtl@testint{#1}\noexpand\if@dtl@condition}
\newcommand*{\dtl@testreal}[1]{%
\DTLifreal{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLisreal}[1]{%
\TE@throw\noexpand\dtl@testreal{#1}\noexpand\if@dtl@condition}
\newcommand*{\dtl@testcurrency}[1]{%
\DTLifcurrency{#1}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLiscurrency}[1]{%
\TE@throw\noexpand\dtl@testcurrency{#1}\noexpand\if@dtl@condition}
\newcommand*{\dtl@testcurrencyunit}[2]{%
\DTLifcurrencyunit{#1}{#2}{\@dtl@conditiontrue}{\@dtl@conditionfalse}}
\newcommand*{\DTLiscurrencyunit}[2]{%
\TE@throw\noexpand\dtl@testcurrencyunit{#1}{#2}%
\noexpand\if@dtl@condition}
\newcommand*{\DTLnewdb}[1]{%
  \DTLifdbexists{#1}%
  {%
     \PackageError{datatool}{Database `#1' already exists}{}%
  }%
  {%
    \dtl@message{Creating database `#1'}%
    \expandafter\newtoks\csname dtldb@#1\endcsname
    \expandafter\newtoks\csname dtlkeys@#1\endcsname{}%
    \expandafter\newcount\csname dtlrows@#1\endcsname
    \expandafter\newcount\csname dtlcols@#1\endcsname
  }%
}
\newcommand*{\DTLrowcount}[1]{%
\expandafter\number\csname dtlrows@#1\endcsname}
\newcommand*{\DTLcolumncount}[1]{%
\expandafter\number\csname dtlcols@#1\endcsname}
\newcommand{\DTLifdbempty}[3]{%
  \DTLifdbexists{#1}%
    {\@DTLifdbempty{#1}{#2}{#3}}%
    {\PackageError{Can't check if database `#1' is empty:
       database doesn't exist}{}{}}%
}
\newcommand{\@DTLifdbempty}[3]{%
  \expandafter\ifnum\csname dtlrows@#1\endcsname=0\relax
    #2%
  \else
    #3%
  \fi
}
\newcommand*{\DTLnewrow}{%
  \@ifstar\@sDTLnewrow\@DTLnewrow
}
\newcommand*{\@DTLnewrow}[1]{%
\DTLifdbexists{#1}%
  {\@sDTLnewrow{#1}}%
  {\PackageErrors{datatool}{Can't add new row to database `#1':
     database doesn't exist}{}}%
}
\newcommand*{\@sDTLnewrow}[1]{%
  \global\advance\csname dtlrows@#1\endcsname by 1\relax
  \toks@gput@right@cx{dtldb@#1}{%
     \noexpand\db@row@elt@w%
       \noexpand\db@row@id@w \number\csname dtlrows@#1\endcsname
       \noexpand\db@row@id@end@%
       \noexpand\db@row@id@w \number\csname dtlrows@#1\endcsname
       \noexpand\db@row@id@end@%
     \noexpand\db@row@elt@end@%
  }%
  \dtl@message{New row added to database `#1'}%
}
\newcount\dtlcolumnnum
\newcount\dtlrownum
\newcommand*{\DTLifhaskey}{\@ifstar\@sDTLifhaskey\@DTLifhaskey}
\newcommand{\@DTLifhaskey}[4]{%
   \DTLifdbexists{#1}%
   {%
     \@sDTLifhaskey{#1}{#2}{#3}{#4}%
   }%
   {%
     \PackageError{datatool}{Database `#1' doesn't exist}{}%
   }%
}
\newcommand{\@sDTLifhaskey}[4]{%
  \@ifundefined{dtl@ci@#1@#2}%
  {%
    #4%
  }%
  {%
    #3%
  }%
}
\newcommand*{\DTLgetcolumnindex}{%
  \@ifstar\@sdtl@getcolumnindex\@dtl@getcolumnindex
}
\newcommand*{\@dtl@getcolumnindex}[3]{%
  \DTLifdbexists{#2}%
  {%
    \@sDTLifhaskey{#2}{#3}%
    {%
      \@sdtl@getcolumnindex{#1}{#2}{#3}%
    }%
    {%
      \PackageError{datatool}{Database `#2' doesn't contain
       key `#3'}{}%
    }%
  }%
  {%
    \PackageError{datatool}{Database `#2' doesn't exist}{}%
  }%
}
\newcommand*{\@sdtl@getcolumnindex}[3]{%
  \expandafter\let\expandafter#1\csname dtl@ci@#2@#3\endcsname
}
\newcommand*{\dtl@columnindex}[2]{%
  \csname dtl@ci@#1@#2\endcsname
}
\newcommand*{\DTLgetkeyforcolumn}{%
  \@ifstar\@sdtlgetkeyforcolumn\@dtlgetkeyforcolumn}
\newcommand*{\@dtlgetkeyforcolumn}[3]{%
  \DTLifdbexists{#2}%
  {%
    \ifnum#3<1\relax
      \PackageError{datatool}{Invalid column index \number#3}{%
      Column indices start at 1}%
    \else
      \expandafter\ifnum\csname dtlcols@#2\endcsname<#3\relax
        \PackageError{datatool}{Index \number#3\space out of
        range for database `#2'}{Database `#2' only has
        \expandafter\number\csname dtlcols@#2\endcsname\space
        columns}%
      \else
        \@sdtlgetkeyforcolumn{#1}{#2}{#3}%
      \fi
    \fi
  }%
  {%
    \PackageError{datatool}{Database `#2' doesn't exists}{}%
  }%
}
\newcommand*{\@sdtlgetkeyforcolumn}[3]{%
  \edef\@dtl@dogetkeyforcolumn{\noexpand\@dtl@getkeyforcolumn
    {\noexpand#1}{#2}{\number#3}}%
  \@dtl@dogetkeyforcolumn
}
\newcommand*{\@dtl@getkeyforcolumn}[3]{%
  \def\@dtl@get@keyforcolumn##1% before stuff
    \db@plist@elt@w% start of block
    \db@col@id@w #3\db@col@id@end@% index
    \db@key@id@w ##2\db@key@id@end@% key
    \db@type@id@w ##3\db@type@id@end@% data type
    \db@header@id@w ##4\db@header@id@end@% header
    \db@col@id@w #3\db@col@id@end@% index
    \db@plist@elt@end@% end of block
    ##5\q@nil{\def#1{##2}}%
  \edef\@dtl@tmp{\expandafter\the\csname dtldb@#2\endcsname}%
  \expandafter\@dtl@getkeyforcolumn\@dtl@tmp
    \db@plist@elt@w% start of block
    \db@col@id@w #3\db@col@id@end@ index
    \db@key@id@w \@nil\db@key@id@end@% key
    \db@type@id@w \db@type@id@end@% data type
    \db@header@id@w \db@header@id@end@% header
    \db@col@id@w #3\db@col@id@end@% index
    \db@plist@elt@end@% end of block
    \q@nil
}
\def\DTLunsettype{}
\def\DTLstringtype{0}
\def\DTLinttype{1}
\def\DTLrealtype{2}
\def\DTLcurrencytype{3}
\newcommand*{\DTLgetdatatype}{%
  \@ifstar\@sdtlgetdatatype\@dtlgetdatatype
}
\newcommand*{\@dtlgetdatatype}[3]{%
  \DTLifdbexists{#2}%
  {%
    \@sDTLifhaskey{#2}{#3}%
    {%
      \@sdtlgetdatatype{#1}{#2}{#3}%
    }%
    {%
      \PackageError{datatool}{Key `#3' undefined in database `#2'}{}%
    }%
  }%
  {%
    \PackageError{datatool}{Database `#2' doesn't exist}{}%
  }%
}
\newcommand*{\@sdtlgetdatatype}[3]{%
  \edef\@dtl@dogetdata{\noexpand\@dtl@getdatatype{\noexpand#1}%
   {\expandafter\the\csname dtlkeys@#2\endcsname}%
   {\dtl@columnindex{#2}{#3}}}%
  \@dtl@dogetdata
}
\newcommand*{\@dtl@getdatatype}[3]{%
  \def\@dtl@get@keydata##1% stuff before
    \db@plist@elt@w% start of key block
     \db@col@id@w #3\db@col@id@end@% column index
      \db@key@id@w ##2\db@key@id@end@% key id
      \db@type@id@w ##3\db@type@id@end@% data type
      \db@header@id@w ##4\db@header@id@end@% header
     \db@col@id@w #3\db@col@id@end@% column index
    \db@plist@elt@end@% end of key block
    ##5% stuff afterwards
    \q@nil{\def#1{##3}}%
  \@dtl@get@keydata#2\q@nil
}
\newcommand*{\@dtl@getprops}[7]{%
  \def\@dtl@get@keydata##1% stuff before
    \db@plist@elt@w% start of key block
     \db@col@id@w #7\db@col@id@end@% column index
      \db@key@id@w ##2\db@key@id@end@% key id
      \db@type@id@w ##3\db@type@id@end@% data type
      \db@header@id@w ##4\db@header@id@end@% header
     \db@col@id@w #7\db@col@id@end@% column index
    \db@plist@elt@end@% end of key block
    ##5% stuff afterwards
    \q@nil{%
      \def#1{##2}% key
      \def#2{##3}% data type
      #3={##4}% header
      #4={##1}% before stuff
      #5={##5}% after stuff
    }%
  \@dtl@get@keydata#6\q@nil
}
\newtoks\@dtl@before
\newtoks\@dtl@after
\newtoks\@dtl@colhead
\newcommand*{\@dtl@updatekeys}[3]{%
  \@sDTLifhaskey{#1}{#2}%
  {%
    \expandafter\dtlcolumnnum\expandafter
      =\dtl@columnindex{#1}{#2}\relax
    \edef\@dtl@dogetprops{\noexpand\@dtl@getprops
      {\noexpand\@dtl@key}{\noexpand\@dtl@type}%
      {\noexpand\@dtl@colhead}{\noexpand\@dtl@before}%
      {\noexpand\@dtl@after}{\the\csname dtlkeys@#1\endcsname}%
      {\number\dtlcolumnnum}}
    \@dtl@dogetprops
    \def\@dtl@tmp{#3}%
    \ifx\@dtl@tmp\@empty
    \else
      \let\@dtl@oldtype\@dtl@type
      \@dtl@checknumerical{#3}%
      \ifx\@dtl@type\@empty
        \edef\@dtl@type{\number\@dtl@datatype}%
      \else
        \ifcase\@dtl@datatype % string
          \def\@dtl@type{0}%
        \or % int
        \or % real
          \ifnum\@dtl@type=1\relax
            \def\@dtl@type{2}%
          \fi
        \or % currency
          \ifnum\@dtl@type>0\relax
            \def\@dtl@type{3}%
          \fi
        \fi
      \fi
      \ifx\@dtl@oldtype\@dtl@type
      \else
        \toks@gconcat@middle@cx{dtlkeys@#1}%
        {\@dtl@before}%
        {%
          \noexpand\db@plist@elt@w% start of key block
            \noexpand\db@col@id@w \the\dtlcolumnnum
              \noexpand\db@col@id@end@% column index
            \noexpand\db@key@id@w #2\noexpand\db@key@id@end@% key id
            \noexpand\db@type@id@w \@dtl@type
              \noexpand\db@type@id@end@% data type
            \noexpand\db@header@id@w \the\@dtl@colhead
              \noexpand\db@header@id@end@% header
            \noexpand\db@col@id@w \the\dtlcolumnnum
              \noexpand\db@col@id@end@% column index
            \noexpand\db@plist@elt@end@% end of key block
        }%
        {\@dtl@after}%
      \fi
    \fi
  }%
  {%
    \expandafter\global\expandafter\advance
      \csname dtlcols@#1\endcsname by 1\relax
    \dtlcolumnnum=\csname dtlcols@#1\endcsname\relax
    \expandafter\xdef\csname dtl@ci@#1@#2\endcsname{%
      \number\dtlcolumnnum}%
    \def\@dtl@tmp{#3}%
    \ifx\@dtl@tmp\@empty
      \edef\@dtl@type{}% don't know data type yet
    \else
      \@dtl@checknumerical{#3}%
      \edef\@dtl@type{\number\@dtl@datatype}%
    \fi
    \toks@gput@right@cx{dtlkeys@#1}%
    {%
      \noexpand\db@plist@elt@w
      \noexpand\db@col@id@w \the\dtlcolumnnum
        \noexpand\db@col@id@end@
      \noexpand\db@key@id@w #2\noexpand\db@key@id@end@
      \noexpand\db@type@id@w \@dtl@type
        \noexpand\db@type@id@end@
      \noexpand\db@header@id@w #2\noexpand\db@header@id@end@
      \noexpand\db@col@id@w \the\dtlcolumnnum
        \noexpand\db@col@id@end@
      \noexpand\db@plist@elt@end@
    }%
  }%
}
\newcommand*{\DTLsetheader}{\@ifstar\@sDTLsetheader\@DTLsetheader}
\newcommand*{\@DTLsetheader}[3]{%
  \DTLifdbexists{#1}%
  {%
    \@sDTLifhaskey{#1}{#2}%
    {%
      \@sDTLsetheader{#1}{#2}{#3}%
    }%
    {%
      \PackageError{datatool}{Database `#1' doesn't contain key
      `#2'}{}%
    }%
  }%
  {%
    \PackageError{datatool}{Database `#1' doesn't exist}{}%
  }%
}
\newcommand*{\@sDTLsetheader}[3]{%
  \expandafter\dtlcolumnnum\expandafter
    =\dtl@columnindex{#1}{#2}\relax
  \@dtl@setheaderforindex{#1}{\dtlcolumnnum}{#3}%
}
\newcommand*{\@dtl@setheaderforindex}[3]{%
  \edef\@dtl@dogetprops{\noexpand\@dtl@getprops
    {\noexpand\@dtl@key}{\noexpand\@dtl@type}%
    {\noexpand\@dtl@colhead}{\noexpand\@dtl@before}%
    {\noexpand\@dtl@after}{\the\csname dtlkeys@#1\endcsname}%
    {\number#2}}
  \@dtl@dogetprops
  \@dtl@colhead={#3}%
  \edef\@dtl@colnum{\number#2}\relax
  \toks@gconcat@middle@cx{dtlkeys@#1}%
  {\@dtl@before}%
  {%
    \noexpand\db@plist@elt@w% start of block
      \noexpand\db@col@id@w \@dtl@colnum
        \noexpand\db@col@id@end@% index
      \noexpand\db@key@id@w \@dtl@key\noexpand\db@key@id@end@% key
      \noexpand\db@type@id@w \@dtl@type
        \noexpand\db@type@id@end@% data type
      \noexpand\db@header@id@w \the\@dtl@colhead
        \noexpand\db@header@id@end@% header
      \noexpand\db@col@id@w \@dtl@colnum
        \noexpand\db@col@id@end@% index
    \noexpand\db@plist@elt@end@% end of block
  }%
  {\@dtl@after}%
}
\newcommand{\DTLnewdbentry}{%
   \@ifstar\@sDTLnewdbentry\@DTLnewdbentry
}
\newcommand{\@DTLnewdbentry}[3]{%
  \DTLifdbexists{#1}%
    {\@sDTLnewdbentry{#1}{#2}{#3}}%
    {\PackageError{datatool}{Can't add new entry to database `#1':
      database doesn't exist}{}}%
}
\newcommand*{\@sDTLnewdbentry}[3]{%
  \@dtl@updatekeys{#1}{#2}{#3}%
  \expandafter\dtlcolumnnum\expandafter
    =\dtl@columnindex{#1}{#2}\relax
  \edef\dtl@dogetrow{\noexpand\dtlgetrow{#1}%
    {\number\csname dtlrows@#1\endcsname}}%
  \dtl@dogetrow
  \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow
     {\noexpand\dtl@entry}{\number\dtlcolumnnum}%
  }%
  \dtl@dogetentry
  \ifx\dtl@entry\dtlnovalue
  \@dtl@toks{#3}%
    \toks@gconcat@middle@cx{dtldb@#1}%
    {\dtlbeforerow}%
    {%
      \noexpand\db@row@elt@w%
      \noexpand\db@row@id@w \number\csname dtlrows@#1\endcsname
        \noexpand\db@row@id@end@%
      \the\dtlcurrentrow
      \noexpand\db@col@id@w \number\dtlcolumnnum
        \noexpand\db@col@id@end@%
          \noexpand\db@col@elt@w \the\@dtl@toks
            \noexpand\db@col@elt@end@%
      \noexpand\db@col@id@w \number\dtlcolumnnum
        \noexpand\db@col@id@end@%
      \noexpand\db@row@id@w \number\csname dtlrows@#1\endcsname
        \noexpand\db@row@id@end@%
      \noexpand\db@row@elt@end@%
    }%
    {\dtlafterrow}%
    \dtl@message{Added #2\space -> #3\space to database `#1'}%
  \else
    \PackageError{datatool}{Can't add entry with ID `#2' to
      current row of database `#1'}{There is already an entry with
      this ID in the current row}%
  \fi
}
\newcommand{\DTLifdbexists}[3]{%
  \@ifundefined{dtldb@#1}{#3}{#2}}
\newcommand*{\@dtl@assign}[2]{%
  \@dtl@assigncmd#1,\@nil\@@{#2}%
}
\def\@dtl@assigncmd#1=#2,#3\@@#4{%
  \@sDTLifhaskey{#4}{#2}%
  {%
    \edef\@dtl@dogetentry{%
      \noexpand\dtlgetentryfromcurrentrow
        {\noexpand#1}{\dtl@columnindex{#4}{#2}}}%
    \@dtl@dogetentry
    \ifx#1\dtlnovalue
      \@@dtl@setnull{#1}{#2}%
    \fi
    \global\let#1=#1\relax
  }%
  {%
    \PackageError{datatool}{Can't assign \string#1\space: there
     is no key `#2' in data base `#4'}{}%
    \global\let#1\DTLstringnull
  }%
  \def\dtl@tmp{#3}%
  \ifx\@nnil\dtl@tmp
    \let\@dtl@next\@dtl@assigncmdnoop
  \else
    \let\@dtl@next\@dtl@assigncmd
  \fi
  \@dtl@next#3\@@{#4}%
}
\def\@dtl@assigncmdnoop#1\@@#2{}
\newcommand*{\@dtl@setnull}[2]{%
  \@sDTLifhaskey{\@dtl@dbname}{#2}%
  {%
    \@@dtl@setnull{#1}{#2}%
  }%
  {%
    \global\let#1=\DTLstringnull
  }%
}
\newcommand*{\@@dtl@setnull}[2]{%
  \@sdtlgetdatatype{\@dtl@type}{\@dtl@dbname}{#2}%
  \ifnum0\@dtl@type=0\relax
    \global\let#1=\DTLstringnull
  \else
    \global\let#1=\DTLnumbernull
  \fi
}
\newcommand*{\DTLstringnull}{NULL}
\newcommand*{\DTLnumbernull}{0}
\newcommand*{\DTLifnull}[3]{%
  \ifx\DTLstringnull#1\relax
    #2%
  \else
    \ifx\DTLnumbernull#1\relax
      #2%
    \else
      #3%
    \fi
  \fi
}
\def\@dtlnovalue{Undefined Value}
\def\dtlnovalue{\@dtlnovalue}
\newcommand*{\DTLgetkeydata}{%
  \@ifstar\@sdtlgetkeydata\@dtlgetkeydata
}
\newcommand*{\@dtlgetkeydata}[5]{%
  \DTLifdbexists{#2}%
  {%
    \@sDTLifhaskey{#2}{#1}%
    {%
      \@sdtlgetkeydata{#1}{#2}{#3}{#4}{#5}%
    }%
    {%
      \PackageError{datatool}{Key `#1' not defined in database
        `#2'}{}%
    }%
  }%
  {%
    \PackageError{datatool}{Database `#2' doesn't exist}{}%
  }%
}
\newcommand*{\@sdtlgetkeydata}[5]{%
  \@sdtl@getcolumnindex{#3}{#2}{#1}%
  \edef\@dtl@dogetkeydata{\noexpand\@dtl@getprops
    {\noexpand\@dtl@key}{\noexpand#4}{\noexpand\@dtl@colhead}%
    {\noexpand\@dtl@before}{\noexpand\@dtl@after}%
    {\expandafter\the\csname dtlkeys@#2\endcsname}%
    {#3}}%
  \@dtl@dogetkeydata
  \edef#5{\the\@dtl@toks}%
}
\newcommand{\dtl@gathervalues}[3][key]{%
  \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)\in{#2}\do
  {%
    \dtlgetentryfromrow{\@dtl@tmp}{\@dtl@col}{\dtlcurrentrow}%
    \ifx\@dtl@tmp\dtlnovalue
      \@dtl@setnull{\@dtl@tmp}{\@dtl@key}%
    \fi
    \expandafter\let\csname @dtl@#1@\@dtl@key\endcsname\@dtl@tmp
  }%
}
\newtoks\dtlcurrentrow
\newtoks\dtlbeforerow
\newtoks\dtlafterrow
\newcommand*{\dtlgetrow}[2]{%
  \expandafter\toks@\expandafter=\csname dtldb@#1\endcsname
  \edef\@dtl@dogetrow{\noexpand\@dtlgetrow{\the\toks@}{\number#2}}%
  \@dtl@dogetrow
}
\newcommand*{\@dtlgetrow}[2]{%
  \def\@dtl@getrow##1% before stuff
    \db@row@elt@w% start of the row
      \db@row@id@w #2\db@row@id@end@% row id
        ##2%
      \db@row@id@w #2\db@row@id@end@% row id
    \db@row@elt@end@% end of the row
        ##3% after stuff
    \q@nil{\dtlbeforerow={##1}\dtlcurrentrow={##2}\dtlafterrow={##3}}%
  \@dtl@getrow#1\q@nil
}
\newcommand*{\dtlgetentryfromcurrentrow}[2]{%
  \dtlgetentryfromrow{#1}{#2}{\dtlcurrentrow}%
}
\newcommand*{\dtlgetentryfromrow}[3]{%
  \edef\@dtl@do@getentry{\noexpand\dtl@getentryfromrow
    {\noexpand#1}{\number#2}{\the#3}}%
  \@dtl@do@getentry
}
\newcommand*{\dtl@getentryfromrow}[3]{%
  \def\dtl@dogetentry##1% before stuff
    \db@col@id@w #2\db@col@id@end@% Column id
      \db@col@elt@w ##2\db@col@elt@end@% Value
    \db@col@id@w #2\db@col@id@end@% Column id
    ##3% Remaining stuff
    \q@nil{\def#1{##2}}%
  \dtl@dogetentry#3%
    \db@col@id@w #2\db@col@id@end@%
      \db@col@elt@w \@dtlnovalue\db@col@elt@end@%
    \db@col@id@w #2\db@col@id@end@%
    \q@nil
}
\newcommand*{\DTLgetvalue}[4]{%
  \edef\dtl@dogetvalue{\noexpand\dtl@getvalue{\noexpand#1}{#2}%
    {\number#3}{\number#4}}%
  \dtl@dogetvalue
}
\newcommand*{\dtl@getvalue}[4]{%
  \def\@dtl@getvalue ##1% stuff before row <r>
     \db@row@id@w #3\db@row@id@end@% row <r> id
        ##2% stuff in row <r> before column <c>
     \db@col@id@w #4\db@col@id@end@% column <c> id
       \db@col@elt@w ##3\db@col@elt@end@% value
     ##4% stuff after value
     \q@nil{\def#1{##3}}%
  \toks@=\csname dtldb@#2\endcsname
  \expandafter\@dtl@getvalue\the\toks@% contents of data base
     \db@row@id@w #3\db@row@id@end@%
       \db@col@id@w #4\db@col@id@end@%
         \db@col@elt@w \@dtlnovalue\db@col@elt@end@% undefined value
     \q@nil
  \ifx#1\dtlnovalue
    \PackageError{datatool}{There is no element at (row=#3,
      column=#4) in database `#2'}{}%
  \fi
}
\newcommand*{\DTLgetlocation}[4]{%
  \def\@dtl@getlocation##1% stuff before value
    \db@col@elt@w #4\db@col@elt@end@% value
    \db@col@id@w ##2\db@col@id@end@% column id
    ##3% stuff after this column
    \db@row@id@w ##4\db@row@id@end@% row id
    ##5% stuff after row
    \q@nil{\def#1{##4}\def#2{##2}}%
  \toks@=\csname dtldb@#3\endcsname
  \expandafter\@dtl@getlocation\the\toks@% contents of data base
    \db@col@elt@w #4\db@col@elt@end@% value
    \db@col@id@w \@dtlnovalue\db@col@id@end@% undefined column id
    \db@row@id@w \@dtlnovalue\db@row@id@end@% undefined row id
    \q@nil
  \ifx#1\dtlnovalue
    \PackageError{datatool}{There is no element `#4' in
      database `#3'}{}%
  \fi
}

\newcommand*{\dtlbreak}{%
  \PackageError{datatool}{Can't break out of anything}{}%
}
\long\def\dtlforint#1=#2\to#3\step#4\do#5{%
  \let\@dtl@orgbreak\dtlbreak
  \def\@dtl@endloophook{}%
  \def\dtlbreak{\def\@dtl@endloophook{#1=#3}}%
  #1=#2\relax
  \ifnum#4<0\relax
    \whiledo{\(#1>#3\)\TE@or\(#1=#3\)}%
    {%
      #5%
      \@dtl@endloophook
      \advance#1 by #4\relax
    }%
  \else
    \whiledo{\(#1<#3\)\TE@or\(#1=#3\)}%
    {%
      #5%
      \@dtl@endloophook
      \advance#1 by #4\relax
    }%
  \fi
  \let\dtlbreak\@dtl@orgbreak
}
\newcount\@dtl@foreach@level
\long\def\dtlgforint#1=#2\to#3\step#4\do#5{%
  \global#1=#2\relax
  \global\advance\@dtl@foreach@level by 1\relax
  \expandafter\global\expandafter
    \let\csname @dtl@endhook@\the\@dtl@foreach@level\endcsname
    \relax
  \expandafter\global\expandafter
    \let\csname @dtl@break@\the\@dtl@foreach@level\endcsname
    \dtlbreak
  \gdef\dtlbreak{\expandafter
     \gdef\csname @dtl@endhook@\the\@dtl@foreach@level\endcsname{%
       #1=#3}}%
  \ifnum#4<0\relax
    \whiledo{\(#1>#3\)\TE@or\(#1=#3\)}%
    {%
      #5%
      \csname @dtl@endhook@\the\@dtl@foreach@level\endcsname
      \global\advance#1 by #4\relax
    }%
  \else
    \whiledo{\(#1<#3\)\TE@or\(#1=#3\)}%
    {%
      #5%
      \csname @dtl@endhook@\the\@dtl@foreach@level\endcsname
      \global\advance#1 by #4\relax
    }%
  \fi
  \expandafter\global\expandafter\let\expandafter\dtlbreak
    \csname @dtl@break@\the\@dtl@foreach@level\endcsname
  \global\advance\@dtl@foreach@level by -1\relax
}
\long\def\@dtlforeachrow(#1,#2)\in#3\do#4{%
  \edef\dtl@tmp{\expandafter\the\csname dtldb@#3\endcsname}%
  \expandafter\@dtl@foreachrow\dtl@tmp
    \db@row@elt@w%
    \db@row@id@w \@nil\db@row@id@end@%
    \db@row@id@w \@nil\db@row@id@end@%
    \db@row@elt@end@%
    \@@{#1}{#2}{#4}\q@nil
}
\long\def\@dtl@foreachrow\db@row@elt@w%
\db@row@id@w #1\db@row@id@end@%
#2\db@row@id@w #3\db@row@id@end@%
\db@row@elt@end@#4\@@#5#6#7\q@nil{%
  \gdef#5{#1}%
  \gdef\@dtl@loopbody{#7}%
  \global\advance\@dtl@foreach@level by 1\relax
  \ifx#5\@nnil
    \expandafter\global\expandafter
      \let\csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname
        =\@dtl@foreachnoop
  \else
    \gdef#6{#2}%
    \expandafter\let
      \csname @dtl@break@\the\@dtl@foreach@level\endcsname
      \dtlbreak
    \gdef\dtlbreak{\expandafter\global\expandafter
      \let\csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname
        =\@dtl@foreachnoop}%
    \expandafter\global\expandafter
      \let\csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname
        =\@dtl@foreachrow
    \@dtl@loopbody
    \expandafter\let\expandafter\dtlbreak
      \csname @dtl@break@\the\@dtl@foreach@level\endcsname
  \fi
  \expandafter\let\expandafter\@dtl@foreachnext
    \csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname
  \global\advance\@dtl@foreach@level by -1\relax
  \@dtl@foreachnext#4\@@{#5}{#6}{#7}\q@nil
}
\long\def\@dtl@foreachnoop#1\@@#2\q@nil{}
\long\def\dtlforeachkey(#1,#2,#3,#4)\in#5\do#6{%
  \gdef\@dtl@loopbody{#6}%
  \edef\@dtl@keys{\expandafter\the\csname dtlkeys@#5\endcsname}%
  \expandafter\@dtl@foreachkey\@dtl@keys
    \db@plist@elt@w%
    \db@col@id@w -1\db@col@id@end@%
    \db@key@id@w \db@key@id@end@%
    \db@type@id@w \db@type@id@end@%
    \db@header@id@w \db@header@id@end@%
    \db@col@id@w -1\db@col@id@end@%
    \db@plist@elt@end@%
    \@@{\@dtl@updatefkcs{#1}{#2}{#3}{#4}}\q@nil
}
\newcommand*{\@dtl@updatefkcs}[8]{%
  \gdef#1{#5}%
  \gdef#2{#6}%
  \gdef#3{#7}%
  \gdef#4{#8}%
}
\long\def\@dtl@foreachkey\db@plist@elt@w%
\db@col@id@w #1\db@col@id@end@%
\db@key@id@w #2\db@key@id@end@%
\db@type@id@w #3\db@type@id@end@%
\db@header@id@w #4\db@header@id@end@%
\db@col@id@w #5\db@col@id@end@%
\db@plist@elt@end@#6\@@#7\q@nil{%
  \ifnum#1=-1\relax
    \let\@dtl@foreachnext\@dtl@foreachnoop
  \else
    #7{#2}{#1}{#3}{#4}%
    \global\advance\@dtl@foreach@level by 1\relax
    \expandafter\let
      \csname @dtl@break@\the\@dtl@foreach@level\endcsname
      \dtlbreak
    \gdef\dtlbreak{\expandafter\global\expandafter
      \let\csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname
        =\@dtl@foreachnoop}%
    \expandafter\global\expandafter
      \let\csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname
        =\@dtl@foreachkey
    \@dtl@loopbody
    \expandafter\let\expandafter\@dtl@foreachnext
      \csname @dtl@foreachnext\the\@dtl@foreach@level\endcsname
    \expandafter\let\expandafter\dtlbreak
      \csname @dtl@break@\the\@dtl@foreach@level\endcsname
    \global\advance\@dtl@foreach@level by -1\relax
  \fi
  \@dtl@foreachnext#6\@@{#7}\q@nil
}
\newcommand*{\dtlforcolumn}{\@ifstar\@sdtlforcolumn\@dtlforcolumn}
\newcommand{\@dtlforcolumn}[4]{%
  \DTLifdbexists{#2}%
  {%
    \@dtlifhaskey{#2}{#3}%
    {%
      \@sdtlforcolumn{#1}{#2}{#3}{#4}%
    }%
    {%
      \PackageError{datatool}{Database `#2' doesn't contain
        key `#3'}{}%
    }%
  }%
  {%
    \PackageError{datatool}{Database `#2' doesn't exist}{}%
  }%
}
\newcommand{\@sdtlforcolumn}[4]{%
    \toks@{#4}%
    \edef\@dtl@doforcol{\noexpand\dtl@forcolumn{\noexpand#1}%
      {\expandafter\the\csname dtldb@#2\endcsname}%
      {\dtl@columnindex{#2}{#3}}{\the\toks@}%
    }%
    \@dtl@doforcol%
}
\newcommand*{\dtlforcolumnidx}{%
  \@ifstar\@sdtlforcolumnidx\@dtlforcolumnidx
}
\newcommand{\@dtlforcolumnidx}[4]{%
  \DTLifdbexists{#2}%
  {%
    \expandafter\ifnum\csname dtlcols@#2\endcsname<#3\relax
      \PackageError{datatool}{Column index \number#3\space out of
        bounds for database `#2'}{Database `#2' only has
        \expandafter\number\csname dtlcols@#2\endcsname\space
        columns}%
    \else
      \ifnum#3<1\relax
       \PackageError{datatool}{Column index \number#3\space out of
        bounds for database `#2'}{Indices start from 1}%
      \else
        \@sdtlforcolumnidx{#1}{#2}{#3}{#4}%
      \fi
    \fi
  }%
  {%
    \PackageError{datatool}{Database `#2' doesn't exist}{}%
  }%
}
\newcommand{\@sdtlforcolumnidx}[4]{%
    \toks@{#4}%
    \edef\@dtl@doforcol{\noexpand\dtl@forcolumn{\noexpand#1}%
      {\expandafter\the\csname dtldb@#2\endcsname}%
      {\number#3}{\the\toks@}%
    }%
    \@dtl@doforcol
}
\newcommand{\dtl@forcolumn}[4]{%
  \let\@dtl@oldbreak\dtlbreak
  \def\dtlbreak{\let\@dtl@forcolnext=\@dtl@forcolnoop}%
  \def\@dtl@forcolumn##1% before stuff
    \db@col@id@w #3\db@col@id@end@% column index
      \db@col@elt@w ##2\db@col@elt@end@% entry
    \db@col@id@w #3\db@col@id@end@% column index
    ##3% after stuff
    \q@nil{%
      \def#1{##2}% assign value to <cs>
      \ifx#1\@nnil
        \let\@dtl@forcolnext=\@dtl@forcolnoop
      \else
        #4%
        \let\@dtl@forcolnext=\@dtl@forcolumn
      \fi
      \@dtl@forcolnext##3\q@nil
    }%
  \@dtl@forcolumn#2%
   \db@col@id@w #3\db@col@id@end@%
     \db@col@elt@w \@nil\db@col@elt@end@%
   \db@col@id@w #3\db@col@id@end@\q@nil
  \let\dtlbreak\@dtl@oldbreak
}
\def\@dtl@forcolnoop#1\q@nil{}

\newcount\dtlforeachlevel
\newcounter{DTLrowi}
\newcounter{DTLrowii}
\newcounter{DTLrowiii}
\newcounter{DTLrow}
\def\theHDTLrow{\arabic{DTLrow}}
\def\theHDTLrowi{\theHDTLrow.\arabic{DTLrowi}}
\def\theHDTLrowii{\theHDTLrowi.\arabic{DTLrowii}}
\def\theHDTLrowiii{\theHDTLrowii.\arabic{DTLrowiii}}
\newcount\dtl@rowi
\newcount\dtl@rowii
\newcount\dtl@rowiii
\newtoks\@dtl@curi
\newtoks\@dtl@previ
\newtoks\@dtl@nexti
\newtoks\@dtl@curii
\newtoks\@dtl@previi
\newtoks\@dtl@nextii
\newtoks\@dtl@curiii
\newtoks\@dtl@previii
\newtoks\@dtl@nextiii
\newcommand*{\DTLsavelastrowcount}[1]{%
\ifnum\dtlforeachlevel>2\relax
  \def#1{0}%
\else
  \ifnum\dtlforeachlevel<0\relax
    \def#1{0}%
  \else
    \@dtl@tmpcount=\dtlforeachlevel
    \advance\@dtl@tmpcount by 1\relax
    \edef#1{\expandafter\number
      \csname c@DTLrow\romannumeral\@dtl@tmpcount\endcsname}%
  \fi
\fi}
\newcommand*{\DTLforeach}{\@ifstar\@sDTLforeach\@DTLforeach}
\newcommand{\@DTLforeach}[4][\boolean{true}]{%
  \DTLifdbexists{#2}%
  {%
    \refstepcounter{DTLrow}%
    \global\c@DTLrow=\c@DTLrow\relax
    \gdef\@dtl@dbname{#2}%
    \global\advance\dtlforeachlevel by 1\relax
    \ifnum\dtlforeachlevel>3\relax
      \PackageError{datatool}{\string\DTLforeach\space nested too
        deeply}{Only 3 levels are allowed}%
    \else
       \@DTLifdbempty{#2}%
       {}%
       {%
        \expandafter\global
          \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
            = 0\relax
        \expandafter\global\expandafter\let%
          \csname @dtl@iffirstrow\the\dtlforeachlevel\endcsname
          \DTLiffirstrow
        \gdef\DTLiffirstrow##1##2{%
          \expandafter\ifnum
           \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
           =1\relax
            ##1%
          \else
            ##2%
          \fi}%
        \expandafter\global\expandafter\let%
          \csname @dtl@iflastrow\the\dtlforeachlevel\endcsname
          \DTLiflastrow
        \gdef\DTLiflastrow##1##2{%
          \expandafter\ifnum
           \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
           =\csname dtlcols@#2\endcsname\relax
            ##1%
          \else
            ##2%
          \fi}%
        \expandafter\global\expandafter\let%
          \csname @dtl@ifoddrow\the\dtlforeachlevel\endcsname
          \DTLifoddrow
        \gdef\DTLifoddrow##1##2{%
          \expandafter\ifodd
           \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
            ##1%
          \else
            ##2%
          \fi}%
        \expandafter\global\expandafter\let
          \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname
            =\@dtl@dbname
        \expandafter\global\expandafter\let
          \csname @dtl@ro@\romannumeral\dtlforeachlevel\endcsname
            = 0\relax
        \dtlgforint
          \csname dtl@row\romannumeral\dtlforeachlevel\endcsname
          =1\to\csname dtlrows@#2\endcsname\step1\do
        {%
          \@dtl@tmpcount=
            \csname dtl@row\romannumeral\dtlforeachlevel\endcsname
          \edef\dtl@dogetrow{\noexpand\dtlgetrow{#2}%
            {\number\@dtl@tmpcount}}%
          \dtl@dogetrow
          \expandafter\global
            \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname
              = \dtlcurrentrow
          \expandafter\global
            \csname @dtl@prev\romannumeral\dtlforeachlevel\endcsname
              = \dtlbeforerow
          \expandafter\global
            \csname @dtl@next\romannumeral\dtlforeachlevel\endcsname
              = \dtlafterrow
          \ifx\relax#3\relax
          \else
            \@dtl@assign{#3}{#2}%
          \fi
          \ifthenelse{#1}%
          {%
            \refstepcounter{DTLrow\romannumeral\dtlforeachlevel}%
            \expandafter\edef\expandafter\DTLcurrentindex%
              \expandafter{%
                 \arabic{DTLrow\romannumeral\dtlforeachlevel}}%
            #4%
            \edef\@dtl@tmp{\expandafter\the
              \csname @dtl@cur\romannumeral
                \dtlforeachlevel\endcsname}%
            \ifx\@dtl@tmp\@nnil
              \expandafter\dtl@decrementrows\expandafter
                 {\csname @dtl@prev\romannumeral
                    \dtlforeachlevel\endcsname
                 }{\csname dtl@row\romannumeral
                   \dtlforeachlevel\endcsname}%
              \expandafter\dtl@decrementrows\expandafter
                 {\csname @dtl@next\romannumeral
                    \dtlforeachlevel\endcsname
                 }{\csname dtl@row\romannumeral
                   \dtlforeachlevel\endcsname}%
              \edef\@dtl@tmp{%
                \expandafter\the
                  \csname @dtl@prev\romannumeral
                    \dtlforeachlevel\endcsname
                \expandafter\the
                  \csname @dtl@next\romannumeral
                     \dtlforeachlevel\endcsname
                }%
              \expandafter\global\expandafter
                 \csname dtldb@#2\endcsname\expandafter{\@dtl@tmp}%
              \expandafter\global\expandafter
                \advance\csname dtlrows@#2\endcsname by -1\relax
              \expandafter\global\expandafter
                \advance\csname dtl@row\romannumeral
                   \dtlforeachlevel\endcsname by -1\relax
            \else
              \@dtl@before=\csname @dtl@prev\romannumeral
                \dtlforeachlevel\endcsname
              \@dtl@after=\csname @dtl@next\romannumeral
                \dtlforeachlevel\endcsname
              \toks@gconcat@middle@cx{dtldb@#2}%
              {\@dtl@before}%
              {%
                \noexpand\db@row@elt@w%
                \noexpand\db@row@id@w \expandafter\number
                  \csname dtl@row\romannumeral
                    \dtlforeachlevel\endcsname
                \noexpand\db@row@id@end@%
                \expandafter\the
                  \csname @dtl@cur\romannumeral
                    \dtlforeachlevel\endcsname
                \noexpand\db@row@id@w \expandafter\number
                  \csname dtl@row\romannumeral
                    \dtlforeachlevel\endcsname
                \noexpand\db@row@id@end@%
                \noexpand\db@row@elt@end@%
                }%
              {\@dtl@after}%
            \fi
          }%
          {}%
         }%
        \expandafter\global\expandafter\let\expandafter\DTLiffirstrow
          \csname @dtl@iffirstrow\the\dtlforeachlevel\endcsname
        \expandafter\global\expandafter\let\expandafter\DTLiflastrow
          \csname @dtl@iflastrow\the\dtlforeachlevel\endcsname
        \expandafter\global\expandafter\let\expandafter\DTLifoddrow
          \csname @dtl@ifoddrow\the\dtlforeachlevel\endcsname
      }%
    \fi
    \global\advance\dtlforeachlevel by -1\relax
  }%
  {%
    \PackageError{datatool}{Database `#2' doesn't exist}{}%
  }%
}
\newcommand{\@sDTLforeach}[4][\boolean{true}]{%
  \DTLifdbexists{#2}%
  {%
    \refstepcounter{DTLrow}%
    \global\c@DTLrow=\c@DTLrow
    \global\advance\dtlforeachlevel by 1\relax
    \ifnum\dtlforeachlevel>3\relax
      \PackageError{datatool}{\string\DTLforeach\space nested too
        deeply}{Only 3 levels are allowed}%
    \else
       \@DTLifdbempty{#2}%
       {}%
       {%
        \expandafter\global
          \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
            = 0\relax
        \expandafter\global\expandafter\let%
          \csname @dtl@iffirstrow\the\dtlforeachlevel\endcsname
          \DTLiffirstrow
        \gdef\DTLiffirstrow##1##2{%
          \expandafter\ifnum
           \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
           =1\relax
            ##1%
          \else
            ##2%
          \fi}%
        \expandafter\global\expandafter\let%
          \csname @dtl@iflastrow\the\dtlforeachlevel\endcsname
          \DTLiflastrow
        \gdef\DTLiflastrow##1##2{%
          \expandafter\ifnum
           \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
           =\csname dtlcols@#2\endcsname\relax
            ##1%
          \else
            ##2%
          \fi}%
        \expandafter\global\expandafter\let%
          \csname @dtl@ifoddrow\the\dtlforeachlevel\endcsname
          \DTLifoddrow
        \gdef\DTLifoddrow##1##2{%
          \expandafter\ifodd
           \csname c@DTLrow\romannumeral\dtlforeachlevel\endcsname
            ##1%
          \else
            ##2%
          \fi}%
        \expandafter\gdef\csname @dtl@dbname@\romannumeral
          \dtlforeachlevel\endcsname{#2}%
        \expandafter\global\expandafter\let
          \csname @dtl@ro@\romannumeral\dtlforeachlevel\endcsname
            = 1\relax
        \@dtlforeachrow(\dtl@thisidx,\dtl@thisrow)\in{#2}\do%
        {%
          \csname dtl@row\romannumeral\dtlforeachlevel\endcsname
            = \dtl@thisidx\relax
          \expandafter\global
            \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname
              = \expandafter{\dtl@thisrow}%
          \ifx\relax#3\relax
          \else
            \dtlcurrentrow=\expandafter{\dtl@thisrow}%
            \@dtl@assign{#3}{#2}%
          \fi
          \ifthenelse{#1}%
          {%
            \refstepcounter{DTLrow\romannumeral\dtlforeachlevel}%
            \expandafter\edef\expandafter\DTLcurrentindex%
              \expandafter{%
                 \arabic{DTLrow\romannumeral\dtlforeachlevel}}%
            #4%
          }%
          {}%
         }%
        \expandafter\global\expandafter\let\expandafter\DTLiffirstrow
          \csname @dtl@iffirstrow\the\dtlforeachlevel\endcsname
        \expandafter\global\expandafter\let\expandafter\DTLiflastrow
          \csname @dtl@iflastrow\the\dtlforeachlevel\endcsname
        \expandafter\global\expandafter\let\expandafter\DTLifoddrow
          \csname @dtl@ifoddrow\the\dtlforeachlevel\endcsname
      }%
    \fi
    \global\advance\dtlforeachlevel by -1\relax
  }%
  {%
    \PackageError{datatool}{Database `#2' doesn't exist}{}%
  }%
}
\newcommand*{\@dtlifreadonly}[2]{%
  \expandafter\ifx
    \csname @dtl@ro@\romannumeral\dtlforeachlevel\endcsname1\relax
    #1%
  \else
    #2%
  \fi
}
\newcommand*{\DTLappendtorow}[2]{%
  \ifnum\dtlforeachlevel=0\relax
    \PackageError{datatool}{\string\DTLappendrow\space can only be
      used inside \string\DTLforeach}{}%
  \else
    \expandafter\let\expandafter\@dtl@thisdb
      \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname
    \@dtlifreadonly
    {%
      \PackageError{datatool}{\string\DTLappendtorow\space can't
       be used inside \DTLforeach*}{The starred version of
       \string\DTLforeach\space is read only}%
    }%
    {%
      \dtlrownum=
        \csname dtl@row\romannumeral\dtlforeachlevel\endcsname\relax
      \@dtl@updatekeys{\@dtl@thisdb}{#1}{#2}%
      \expandafter\dtlcolumnnum\expandafter
        =\dtl@columnindex{\@dtl@thisdb}{#1}\relax
      \dtlcurrentrow =
        \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname
      \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow
        {\noexpand\dtl@entry}{\number\dtlcolumnnum}%
      }%
      \dtl@dogetentry
      \ifx\dtl@entry\dtlnovalue
        \expandafter\@dtl@toks\expandafter{#2}%
        \toks@gput@right@cx{@dtl@cur\romannumeral\dtlforeachlevel}%
        {%
          \noexpand\db@col@id@w \number\dtlcolumnnum
            \noexpand\db@col@id@end@
          \noexpand\db@col@elt@w \the\@dtl@toks
            \noexpand\db@col@elt@end@
          \noexpand\db@col@id@w \number\dtlcolumnnum
            \noexpand\db@col@id@end@
        }%
         \dtl@message{Appended #1\space -> #2\space to database
           `\@dtl@thisdb'}%
      \else
        \PackageError{datatool}{Can't append entry to row:
          there is already an entry for key `#1' in this row}{}%
      \fi
    }%
  \fi
}
\newcommand*{\DTLremoveentryfromrow}[1]{%
  \ifnum\dtlforeachlevel=0\relax
    \PackageError{datatool}{\string\DTLremoventryfromrow\space
      can only be used inside \string\DTLforeach}{}%
  \else
    \expandafter\let\expandafter\@dtl@thisdb
      \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname
    \@dtlifreadonly
    {%
      \PackageError{datatool}{\string\DTLremoveentryfromrow\space
        can't be used inside \string\DTLforeach*}{The starred
        version of \string\DTLforeach\space is read only}%
    }%
    {%
      \dtlrownum=
        \csname dtl@row\romannumeral\dtlforeachlevel\endcsname\relax
      \@dtlifhaskey{\@dtl@thisdb}{#1}%
      {%
        \dtl@getcolumnindex{\thiscol}{\@dtl@thisdb}{#1}\relax
        \dtlcolumnnum=\thiscol\relax
        \dtlcurrentrow =
          \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname
        \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow
          {\noexpand\dtl@entry}{\number\dtlcolumnnum}%
        }%
        \dtl@dogetentry
        \ifx\dtl@entry\dtlnovalue
          \PackageError{datatool}{Can't remove entry given by `#1'
             from current row in database `\@dtl@thisdb': no such
             entry}{The current row doesn't contain an entry for
             key `#1'}%
        \else
          \edef\@dtl@dosplitrow{%
            \noexpand\dtlsplitrow{\the\dtlcurrentrow}%
              {\number\dtlcolumnnum}{\noexpand\dtl@pre}%
              {\noexpand\dtl@post}%
          }%
          \@dtl@dosplitrow
          \expandafter\@dtl@toks\expandafter{\dtl@pre}%
          \expandafter\toks@\expandafter{\dtl@post}%
          \edef\@dtl@tmp{\the\@dtl@toks \the\toks@}%
          \dtlcurrentrow=\expandafter{\@dtl@tmp}%
          \expandafter\global
            \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname
              = \dtlcurrentrow
         \dtl@message{Removed entry given by #1\space from current
           row of database `\@dtl@thisdb'}%
        \fi
      }%
      {%
        \PackageError{datatool}{Can't remove entry given by
          `#1' - no such key exists}{}%
      }%
    }%
  \fi
}
\newcommand*{\DTLreplaceentryforrow}[2]{%
  \ifnum\dtlforeachlevel=0\relax
    \PackageError{datatool}{\string\DTLreplaceentryforrow\space
      can only be used inside \string\DTLforeach}{}%
  \else
    \expandafter\let\expandafter\@dtl@thisdb
      \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname
    \@dtlifreadonly
    {%
      \PackageError{datatool}{\string\DTLreplaceentryforrow\space
        can't be used inside \string\DTLforeach*}{The starred version
        of \string\DTLforeach\space is read only}%
    }%
    {%
      \dtlrownum=
        \csname dtl@row\romannumeral\dtlforeachlevel\endcsname\relax
      \@dtlifhaskey{\@dtl@thisdb}{#1}%
      {%
        \dtl@getcolumnindex{\thiscol}{\@dtl@thisdb}{#1}\relax
        \dtlcolumnnum=\thiscol\relax
        \dtlcurrentrow =
          \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname
        \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow
          {\noexpand\dtl@entry}{\number\dtlcolumnnum}%
        }%
        \dtl@dogetentry
        \ifx\dtl@entry\dtlnovalue
          \PackageError{datatool}{Can't replace entry given by `#1'
             from current row in database `\@dtl@thisdb': no such
             entry}{The current row doesn't contain an entry for
             key `#1'}%
        \else
          \edef\@dtl@dosplitrow{%
            \noexpand\dtlsplitrow{\the\dtlcurrentrow}%
              {\number\dtlcolumnnum}{\noexpand\dtl@pre}%
              {\noexpand\dtl@post}%
          }%
          \@dtl@dosplitrow
          \@dtl@toks{#2}% new value
          \expandafter\@dtl@before\expandafter{\dtl@pre}%
          \expandafter\@dtl@after\expandafter{\dtl@post}%
          \toks@gconcat@middle@cx
            {@dtl@cur\romannumeral\dtlforeachlevel}%
            {\@dtl@before}%
            {%
              \noexpand\db@col@id@w \number\dtlcolumnnum
                \noexpand\db@col@id@end@%
              \noexpand\db@col@elt@w \the\@dtl@toks
                \noexpand\db@col@elt@end@%
              \noexpand\db@col@id@w \number\dtlcolumnnum
                \noexpand\db@col@id@end@%
            }%
            {\@dtl@after}%
         \dtl@message{Updated #1\space -> #2\space in database
           `\@dtl@thisdb'}%
        \fi
      }%
      {%
         \PackageError{datatool}{Can't replace key `#1' - no such
           key in database `\@dtl@thisdb'}{}%
      }%
    }%
  \fi
}
\newcommand*{\DTLremovecurrentrow}{%
  \ifnum\dtlforeachlevel=0\relax
    \PackageError{datatool}{\string\DTLremovecurrentrow\space can
      only be used inside \string\DTLforeach}{}%
  \else
    \expandafter\let\expandafter\@dtl@thisdb
      \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname
    \@dtlifreadonly
    {%
      \PackageError{datatool}{\string\DTLreplaceentryforrow\space
        can't be used inside \string\DTLforeach*}{The starred version
        of \string\DTLforeach\space is read only}%
    }%
    {%
      \expandafter\global
        \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname
          ={\@nil}%
    }%
  \fi
}
\newcommand{\DTLaddentryforrow}[5]{%
  \DTLifdbexists{#1}%
  {
    \def\@dtl@notdone{\PackageError{datatool}{Unable to add entry
      given by key `#4': condition not met for any row in database
      `#1'}{}}%
    \DTLforeach[#3]{#1}{#2}%
    {%
      \DTLappendtorow{#4}{#5}%
      \let\@dtl@notdone\relax
      \dtlbreak
    }%
    \@dtl@notdone
  }%
  {%
    \PackageError{datatool}{Unable to add entry given by key `#4':
      database `#1' doesn't exist}{}%
  }%
}
\newcommand*{\DTLforeachkeyinrow}[2]{%
  \ifnum\dtlforeachlevel=0\relax
    \PackageError{datatool}{\string\DTLforeachkeyinrow\space can only
     be used inside \string\DTLforeach}{}%
  \else
    \expandafter\let\expandafter\@dtl@thisdb
      \csname @dtl@dbname@\romannumeral\dtlforeachlevel\endcsname
    \dtlforeachkey(\dtlkey,\dtlcol,\dtltype,\dtlheader)\in
      \@dtl@thisdb\do{%
      \dtlcurrentrow =
        \csname @dtl@cur\romannumeral\dtlforeachlevel\endcsname
      \edef\dtl@dogetentry{\noexpand\dtlgetentryfromcurrentrow
        {\noexpand#1}{\dtlcol}}%
      \dtl@dogetentry
      \ifx#1\dtlnovalue
        \ifnum0\dtltype=0\relax
          \let#1=\DTLstringnull
        \else
          \let#1=\DTLnumbernull
        \fi
      \fi
      \global\let#1#1%
      \def\@dtl@loop@body{#2}%
      \@dtl@loop@body
    }%
  \fi
}
\newcommand*{\dtlbetweencols}{}
\newcommand*{\dtlbeforecols}{}
\newcommand*{\dtlaftercols}{}
\newcommand*{\dtlstringalign}{l}
\newcommand*{\dtlintalign}{r}
\newcommand*{\dtlrealalign}{r}
\newcommand*{\dtlcurrencyalign}{r}
\newcommand*{\dtladdalign}[4]{%
  \ifnum#3=1\relax
    \protected@edef#1{\dtlbeforecols}%
  \else
    \protected@edef#1{#1\dtlbetweencols}%
  \fi
  \ifx\@empty#2\@empty
    \protected@edef#1{#1c}%
  \else
    \ifcase#2\relax
      \protected@edef#1{#1\dtlstringalign}%
    \or
      \protected@edef#1{#1\dtlintalign}%
    \or
      \protected@edef#1{#1\dtlrealalign}%
    \or
      \protected@edef#1{#1\dtlcurrencyalign}%
    \else
      \protected@edef#1{#1c}%
      \PackageError{datatool}{Unknown data type `#2'}{}%
    \fi
  \fi
  \ifnum#3=#4\relax
    \protected@edef#1{#1\dtlaftercols}%
  \fi
}
\newcommand*{\dtlheaderformat}[1]{\null\hfil\textbf{#1}\hfil\null}
\newcommand*{\dtlstringformat}[1]{#1}
\newcommand*{\dtlintformat}[1]{#1}
\newcommand*{\dtlrealformat}[1]{#1}
\newcommand*{\dtlcurrencyformat}[1]{#1}
\newcommand*{\dtldisplaystarttab}{}
\newcommand*{\dtldisplayendtab}{}
\newcommand*{\dtldisplayafterhead}{}
\newcommand*{\dtldisplaystartrow}{}

\newcommand*{\DTLdisplaydb}[1]{%
  \def\@dtl@doamp{\gdef\@dtl@doamp{&}}
  \def\@dtl@resetdoamp{\gdef\@dtl@doamp{\gdef\@dtl@doamp{&}}}
  \edef\@dtl@maxcols{\expandafter\number
    \csname dtlcols@#1\endcsname}%
  \def\@dtl@tabargs{}%
  \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)%
    \in{#1}\do
  {%
    \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols
  }%
  \edef\@dtl@dobegintab{\noexpand\begin{tabular}{\@dtl@tabargs}}%
  \@dtl@dobegintab
  \dtldisplaystarttab
  \@dtl@resetdoamp
  \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)%
    \in{#1}\do
  {%
    \@dtl@doamp
    \dtlheaderformat{\@dtl@head}%
  }%
  \\%
  \dtldisplayafterhead
  \@dtl@resetdoamp
  \DTLforeach*{#1}{}{%
    \DTLiffirstrow{}{\\\dtldisplaystartrow}%
    \@dtl@resetdoamp
    \DTLforeachkeyinrow{\@dtl@val}%
    {%
      \global\let\@dtl@val\@dtl@val
      \@dtl@doamp
      \@dtl@datatype=0\dtltype\relax
      \ifcase\@dtl@datatype
        \dtlstringformat\@dtl@val
      \or
        \dtlintformat\@dtl@val
      \or
        \dtlrealformat\@dtl@val
      \or
        \dtlcurrencyformat\@dtl@val
      \else
        \@dtl@val
      \fi
    }%
  }%
  \dtldisplayendtab
  \end{tabular}%
}
\define@key{displaylong}{caption}{\def\@dtl@cap{#1}}
\define@key{displaylong}{contcaption}{\def\@dtl@contcap{#1}}
\define@key{displaylong}{shortcaption}{\def\@dtl@shortcap{#1}}
\define@key{displaylong}{label}{\def\@dtl@label{#1}}
\define@key{displaylong}{foot}{\def\@dtl@foot{#1}}
\define@key{displaylong}{lastfoot}{\def\@dtl@lastfoot{#1}}
\newcommand*{\@dtl@resetdostartrow}{%
  \gdef\@dtl@dostartrow{%
    \gdef\@dtl@dostartrow{\\\dtldisplaystartrow}}%
}
\newcommand*{\DTLdisplaylongdb}[2][]{%
  \def\@dtl@cap{\@nil}%
  \def\@dtl@contcap{\@nil}%
  \def\@dtl@label{\@nil}%
  \def\@dtl@shortcap{\@dtl@cap}%
  \def\@dtl@foot{\@nil}%
  \def\@dtl@lastfoot{\@nil}%
  \setkeys{displaylong}{#1}%
  \def\@dtl@doamp{\gdef\@dtl@doamp{&}}
  \def\@dtl@resetdoamp{\gdef\@dtl@doamp{\gdef\@dtl@doamp{&}}}
  \@dtl@resetdostartrow
  \edef\@dtl@maxcols{\expandafter\number
    \csname dtlcols@#2\endcsname}%
  \def\@dtl@tabargs{}%
  \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)%
    \in{#2}\do
  {%
    \dtladdalign\@dtl@tabargs\@dtl@type\@dtl@idx\@dtl@maxcols
  }%
  \edef\@dtl@dobegintab{\noexpand\begin{longtable}{\@dtl@tabargs}}%
  \@dtl@dobegintab
  \dtldisplaystarttab
  \ifx\@dtl@foot\@nnil
  \else
    \@dtl@foot\endfoot
  \fi
  \ifx\@dtl@lastfoot\@nnil
  \else
    \@dtl@lastfoot\endlastfoot
  \fi
  \ifx\@dtl@cap\@nnil
    \@dtl@resetdoamp
    \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)%
      \in{#2}\do
    {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}%
    \@dtl@resetdoamp
    \@dtl@resetdostartrow
    \endhead\dtldisplayafterhead
  \else
    \caption[\@dtl@shortcap]{\@dtl@cap}%
    \ifx\@dtl@label\@nnil
    \else
      \label{\@dtl@label}%
    \fi
    \\%
    \@dtl@resetdoamp
    \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)%
      \in{#2}\do
    {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}%
    \@dtl@resetdoamp
    \@dtl@resetdostartrow
    \endfirsthead
    \ifx\@dtl@contcap\@nnil
      \caption{\@dtl@cap}%
    \else
      \caption{\@dtl@contcap}%
    \fi
    \\%
      \@dtl@resetdoamp
      \dtlforeachkey(\@dtl@key,\@dtl@idx,\@dtl@type,\@dtl@head)%
      \in{#2}\do
      {\@dtl@doamp{\dtlheaderformat{\@dtl@head}}}%
      \@dtl@resetdoamp
      \@dtl@resetdostartrow
    \endhead\dtldisplayafterhead
  \fi
  \DTLforeach*{#2}{}{%
    \@dtl@dostartrow
    \@dtl@resetdoamp
    \DTLforeachkeyinrow{\@dtl@val}%
    {%
      \global\let\@dtl@val\@dtl@val
      \@dtl@doamp
      \@dtl@datatype=0\dtltype\relax
      \ifcase\@dtl@datatype
        \dtlstringformat\@dtl@val
      \or
        \dtlintformat\@dtl@val
      \or
        \dtlrealformat\@dtl@val
      \or
        \dtlcurrencyformat\@dtl@val
      \fi
    }%
  }%
  \dtldisplayendtab
  \end{longtable}%
}
\newcommand*{\dtlswaprows}[3]{%
  \ifnum#2=#3\relax
  \else
    \ifnum#2<#3\relax
      \edef\@dtl@rowAidx{\number#2}%
      \edef\@dtl@rowBidx{\number#3}%
    \else
      \edef\@dtl@rowAidx{\number#3}%
      \edef\@dtl@rowBidx{\number#2}%
    \fi
    \edef\@dtl@dosplit{\noexpand\dtlgetrow{#1}{\@dtl@rowAidx}}%
    \@dtl@dosplit
    \expandafter\def\expandafter\@dtl@firstpart\expandafter
      {\the\dtlbeforerow}%
    \@dtl@toksA=\dtlcurrentrow
    \edef\@dtl@dosplit{\noexpand\@dtlgetrow
      {\the\dtlafterrow}{\@dtl@rowBidx}}%
    \@dtl@dosplit
    \expandafter\def\expandafter\@dtl@secondpart\expandafter
      {\the\dtlbeforerow}%
    \@dtl@toksB=\dtlcurrentrow
    \expandafter\def\expandafter\@dtl@thirdpart\expandafter
      {\the\dtlafterrow}%
    \toks@=\expandafter{\@dtl@firstpart}%
    \@dtl@toks=\expandafter{\@dtl@secondpart}%
    \edef\@dtl@tmp{\the\toks@
     \noexpand\db@row@elt@w%
     \noexpand\db@row@id@w \@dtl@rowAidx\noexpand\db@row@id@end@%
     \the\@dtl@toksB
     \noexpand\db@row@id@w \@dtl@rowAidx\noexpand\db@row@id@end@%
     \noexpand\db@row@elt@end@%
     \the\@dtl@toks}%
    \toks@=\expandafter{\@dtl@tmp}%
    \@dtl@toks=\expandafter{\@dtl@thirdpart}%
    \edef\@dtl@tmp{\the\toks@
     \noexpand\db@row@elt@w%
     \noexpand\db@row@id@w \@dtl@rowBidx\noexpand\db@row@id@end@%
     \the\@dtl@toksA
     \noexpand\db@row@id@w \@dtl@rowBidx\noexpand\db@row@id@end@%
     \noexpand\db@row@elt@end@%
    \the\@dtl@toks}%
    \expandafter\global\csname dtldb@#1\endcsname=\expandafter
      {\@dtl@tmp}%
  \fi
}
\newcommand*{\dtl@decrementrows}[2]{%
  \def\@dtl@newlist{}%
  \edef\@dtl@min{\number#2}%
  \expandafter\@dtl@decrementrows\the#1%
    \db@row@elt@w%
      \db@row@id@w \@nil\db@row@id@end@%
      \db@row@id@w \@nil\db@row@id@end@%
    \db@row@elt@end@%
    \@nil
  #1=\expandafter{\@dtl@newlist}%
}
\def\@dtl@decrementrows\db@row@elt@w\db@row@id@w #1\db@row@id@end@%
#2\db@row@id@w #3\db@row@id@end@\db@row@elt@end@#4\@nil{%
  \def\@dtl@thisrow{#1}%
  \ifx\@dtl@thisrow\@nnil
    \let\@dtl@donextdec=\@dtl@gobbletonil
  \else
    \ifnum\@dtl@thisrow>\@dtl@min
      \@dtl@tmpcount=\@dtl@thisrow\relax
      \advance\@dtl@tmpcount by -1\relax
      \toks@{#2}%
      \@dtl@toks=\expandafter{\@dtl@newlist}%
      \edef\@dtl@newlist{\the\@dtl@toks
        \noexpand\db@row@elt@w% row header
        \noexpand\db@row@id@w \number\@dtl@tmpcount
          \noexpand\db@row@id@end@% row id
         \the\toks@ % row contents
        \noexpand\db@row@id@w \number\@dtl@tmpcount
          \noexpand\db@row@id@end@% row id
        \noexpand\db@row@elt@end@% row end
      }%
    \else
      \toks@{#2}%
      \@dtl@toks=\expandafter{\@dtl@newlist}%
      \edef\@dtl@newlist{\the\@dtl@toks
        \noexpand\db@row@elt@w% row header
        \noexpand\db@row@id@w #1%
          \noexpand\db@row@id@end@% row id
         \the\toks@ % row contents
        \noexpand\db@row@id@w #3%
          \noexpand\db@row@id@end@% row id
        \noexpand\db@row@elt@end@% row end
      }%
    \fi
    \let\@dtl@donextdec=\@dtl@decrementrows
  \fi
  \@dtl@donextdec#4\@nil
}
\newcommand*{\DTLremoverow}[2]{%
  \DTLifdbexists{#1}%
  {%
    \ifnum#2>0\relax
      \expandafter\ifnum\csname dtlrows@#1\endcsname<#2\relax
        \expandafter\ifnum\csname dtlrows@#1\endcsname=1\relax
          \PackageError{datatool}{Can't remove row `\number#2' from
            database `#1': no such row}{Database `#1' only has
            1 row}%
        \else
          \PackageError{datatool}{Can't remove row `\number#2' from
            database `#1': no such row}{Database `#1' only has
            \expandafter\number\csname dtlrows@#1\endcsname\space
            rows}%
        \fi
      \else
        \@DTLremoverow{#1}{#2}%
      \fi
    \else
      \PackageError{datatool}{Can't remove row \number#2: index
        out of bounds}{Row indices start at 1}%
    \fi
  }%
  {%
    \PackageError{datatool}{Can't remove row: database `#1' doesn't
      exist}{}%
  }%
}
\newcommand*{\@DTLremoverow}[2]{%
      \edef\dtl@dogetrow{\noexpand\dtlgetrow{#1}{\number#2}}%
      \dtl@dogetrow
      \expandafter\dtl@decrementrows\expandafter
        {\dtlbeforerow}{#2}%
      \expandafter\dtl@decrementrows\expandafter
        {\dtlafterrow}{#2}%
      \edef\dtl@tmp{\the\dtlbeforerow \the\dtlafterrow}%
      \expandafter\global\csname dtldb@#1\endcsname
        =\expandafter{\dtl@tmp}%
      \expandafter\global\expandafter\advance
        \csname dtlrows@#1\endcsname by -1\relax
}
\newcommand*{\DTLsumforkeys}[1][\boolean{true}\and
 \DTLisnumerical{\DTLthisval}]{%
  \def\@dtl@cond{#1}%
  \@dtlsumforkeys
}
\newcommand*{\@dtlsumforkeys}[4][]{%
  \def#4{0}%
  \@for\@dtl@dbname:=#2\do{%
    \@sDTLforeach{\@dtl@dbname}%
    {#1}% assignment list
    {%
      \@for\@dtl@key:=#3\do{%
        \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}%
        \dtlcurrentrow=\expandafter{\dtl@thisrow}%
        \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}%
        \expandafter\ifthenelse\expandafter{\@dtl@cond}%
          {\DTLadd{#4}{#4}{\DTLthisval}}{}%
      }%
    }%
  }%
}
\newcommand*{\DTLsumcolumn}[3]{%
  \def#3{0}%
  \DTLifdbexists{#1}%
  {%
     \@sDTLifhaskey{#1}{#2}%
     {%
       \@sdtlforcolumn{\DTLthisval}{#1}{#2}%
       {%
         \DTLadd{#3}{#3}{\DTLthisval}%
       }%
     }%
     {%
       \PackageError{datatool}{Key `#2' doesn't
         exist in database `#1'}{}%
     }%
  }%
  {%
    \PackageError{datatool}{Data base `#1' doesn't
      exist}{}%
  }%
}
\newcommand*{\DTLmeanforkeys}[1][\boolean{true}\and
 \DTLisnumerical{\DTLthisval}]{%
  \def\@dtl@cond{#1}%
  \@dtlmeanforkeys
}
\newcount\@dtl@elements
\newcommand*{\@dtlmeanforkeys}[4][]{%
  \def#4{0}%
  \@dtl@elements=0\relax
  \@for\@dtl@dbname:=#2\do{%
    \@sDTLforeach{\@dtl@dbname}%
    {#1}% assignment list
    {%
      \@for\@dtl@key:=#3\do{%
        \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}%
        \dtlcurrentrow=\expandafter{\dtl@thisrow}%
        \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}%
        \expandafter\ifthenelse\expandafter{\@dtl@cond}%
        {%
          \DTLadd{#4}{#4}{\DTLthisval}%
          \advance\@dtl@elements by 1\relax
        }{}%
      }%
    }%
  }%
  \ifnum\@dtl@elements=0\relax
    \PackageError{datatool}{Unable to evaluate mean: no data}{}%
  \else
    \edef\@dtl@n{\number\@dtl@elements}%
    \DTLdiv{#4}{#4}{\@dtl@n}%
  \fi
}
\newcommand*{\DTLmeanforcolumn}[3]{%
  \def#3{0}%
  \@dtl@elements=0\relax
  \DTLifdbexists{#1}%
  {%
     \@sDTLifhaskey{#1}{#2}%
     {%
       \@sdtlforcolumn{\DTLthisval}{#1}{#2}%
       {%
         \DTLadd{#3}{#3}{\DTLthisval}%
         \advance\@dtl@elements by 1\relax
       }%
       \ifnum\@dtl@elements=0\relax
         \PackageError{datatool}{Can't compute mean for
          column `#2' in database `#1': no data}{}%
       \else
         \edef\@dtl@n{\number\@dtl@elements}%
         \DTLdiv{#3}{#3}{\@dtl@n}%
       \fi
     }%
     {%
       \PackageError{datatool}{Key `#2' doesn't
         exist in database `#1'}{}%
     }%
  }%
  {%
    \PackageError{datatool}{Data base `#1' doesn't
      exist}{}%
  }%
}
\newcommand*{\DTLvarianceforkeys}[1][\boolean{true}\and
 \DTLisnumerical{\DTLthisval}]{%
  \def\@dtl@cond{#1}%
  \@dtlvarianceforkeys
}
\newcommand*{\@dtlvarianceforkeys}[4][]{%
  \@dtlmeanforkeys[#1]{#2}{#3}{\dtl@mean}%
  \def#4{0}%
  \@dtl@elements=0\relax
  \@for\@dtl@dbname:=#2\do{%
    \@sDTLforeach{\@dtl@dbname}%
    {#1}% assignment list
    {%
      \@for\@dtl@key:=#3\do{%
        \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}%
        \dtlcurrentrow=\expandafter{\dtl@thisrow}%
        \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}%
        \expandafter\ifthenelse\expandafter{\@dtl@cond}%
        {%
           \DTLsub{\dtl@diff}{\DTLthisval}{\dtl@mean}%
           \DTLmul{\dtl@diff}{\dtl@diff}{\dtl@diff}%
           \DTLadd{#4}{#4}{\dtl@diff}%
           \advance\@dtl@elements by 1\relax
        }{}%
      }%
    }%
  }%
  \ifnum\@dtl@elements=0\relax
    \PackageError{datatool}{Unable to evaluate variance: no data}{}%
  \else
    \edef\@dtl@n{\number\@dtl@elements}%
    \DTLdiv{#4}{#4}{\@dtl@n}%
  \fi
}
\newcommand*{\DTLvarianceforcolumn}[3]{%
  \DTLmeanforcolumn{#1}{#2}{\dtl@mean}%
  \def#3{0}%
  \@dtl@elements=0\relax
  \DTLifdbexists{#1}%
  {%
     \@sDTLifhaskey{#1}{#2}%
     {%
       \@sdtlforcolumn{\DTLthisval}{#1}{#2}%
       {%
         \DTLsub{\dtl@diff}{\DTLthisval}{\dtl@mean}%
         \DTLmul{\dtl@diff}{\dtl@diff}{\dtl@diff}%
         \DTLadd{#3}{#3}{\dtl@diff}%
         \advance\@dtl@elements by 1\relax
       }%
       \ifnum\@dtl@elements=0\relax
         \PackageError{datatool}{Can't compute variance for
          column `#2' in database `#1': no data}{}%
       \else
         \edef\@dtl@n{\number\@dtl@elements}%
         \DTLdiv{#3}{#3}{\@dtl@n}%
       \fi
     }%
     {%
       \PackageError{datatool}{Key `#2' doesn't
         exist in database `#1'}{}%
     }%
  }%
  {%
    \PackageError{datatool}{Data base `#1' doesn't
      exist}{}%
  }%
}
\newcommand*{\DTLsdforkeys}[1][\boolean{true}\and
\DTLisnumerical{\DTLthisval}]{%
  \def\@dtl@cond{#1}%
  \@dtlsdforkeys
}
\newcommand*{\@dtlsdforkeys}[4][]{%
  \@dtlvarianceforkeys[#1]{#2}{#3}{#4}%
  \DTLsqrt{#4}{#4}%
}
\newcommand*{\DTLsdforcolumn}[3]{%
  \DTLvarianceforcolumn{#1}{#2}{#3}%
  \DTLsqrt{#3}{#3}%
}
\newcommand*{\DTLminforkeys}[1][\boolean{true}\and
 \DTLisnumerical{\DTLthisval}]{%
  \def\@dtl@cond{#1}%
  \@dtlminforkeys
}
\newcommand*{\@dtlminforkeys}[4][]{%
  \def#4{}%
  \@for\@dtl@dbname:=#2\do{%
    \@sDTLforeach{\@dtl@dbname}%
    {#1}% assignment list
    {%
      \@for\@dtl@key:=#3\do{%
        \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}%
        \dtlcurrentrow=\expandafter{\dtl@thisrow}%
        \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}%
        \expandafter\ifthenelse\expandafter{\@dtl@cond}%
        {%
          \ifx#4\@empty
            \let#4\DTLthisval
          \else
            \DTLmin{#4}{#4}{\DTLthisval}%
          \fi
        }{}%
      }%
    }%
  }%
}
\newcommand*{\DTLminforcolumn}[3]{%
  \def#3{}%
  \DTLifdbexists{#1}%
  {%
     \@sDTLifhaskey{#1}{#2}%
     {%
       \@sdtlforcolumn{\DTLthisval}{#1}{#2}%
       {%
         \ifx#3\@empty
           \let#3\DTLthisval
         \else
           \DTLmin{#3}{#3}{\DTLthisval}%
         \fi
       }%
     }%
     {%
       \PackageError{datatool}{Key `#2' doesn't
         exist in database `#1'}{}%
     }%
  }%
  {%
    \PackageError{datatool}{Data base `#1' doesn't
      exist}{}%
  }%
}
\newcommand*{\DTLmaxforkeys}[1][\boolean{true}\and
 \DTLisnumerical{\DTLthisval}]{%
  \def\@dtl@cond{#1}%
  \@dtlmaxforkeys
}
\newcommand*{\@dtlmaxforkeys}[4][]{%
  \def#4{}%
  \@for\@dtl@dbname:=#2\do{%
    \@sDTLforeach{\@dtl@dbname}%
    {#1}% assignment list
    {%
      \@for\@dtl@key:=#3\do{%
        \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}%
        \dtlcurrentrow=\expandafter{\dtl@thisrow}%
        \dtlgetentryfromrow{\DTLthisval}{\@dtl@col}{\dtlcurrentrow}%
        \expandafter\ifthenelse\expandafter{\@dtl@cond}%
        {%
          \ifx#4\@empty
            \let#4\DTLthisval
          \else
            \DTLmax{#4}{#4}{\DTLthisval}%
          \fi
        }{}%
      }%
    }%
  }%
}
\newcommand*{\DTLmaxforcolumn}[3]{%
  \def#3{}%
  \DTLifdbexists{#1}%
  {%
     \@sDTLifhaskey{#1}{#2}%
     {%
       \@sdtlforcolumn{\DTLthisval}{#1}{#2}%
       {%
         \ifx#3\@empty
           \let#3\DTLthisval
         \else
           \DTLmax{#3}{#3}{\DTLthisval}%
         \fi
       }%
     }%
     {%
       \PackageError{datatool}{Key `#2' doesn't
         exist in database `#1'}{}%
     }%
  }%
  {%
    \PackageError{datatool}{Data base `#1' doesn't
      exist}{}%
  }%
}
\newcommand*{\DTLcomputebounds}[8][\boolean{true}]{%
\let#5=\relax
\let#6=\relax
\let#7=\relax
\let#8=\relax
\@for\dtl@thisdb:=#2\do{%
  \@sDTLforeach[#1]{\dtl@thisdb}{\DTLthisX=#3,\DTLthisY=#4}{%
    \DTLconverttodecimal{\DTLthisX}{\dtl@decx}%
    \DTLconverttodecimal{\DTLthisY}{\dtl@decy}%
    \ifx#5\relax
      \let#5=\dtl@decx
      \let#6=\dtl@decy
      \let#7=\dtl@decx
      \let#8=\dtl@decy
    \else
      \FPmin{#5}{#5}{\dtl@decx}%
      \FPmin{#6}{#6}{\dtl@decy}%
      \FPmax{#7}{#7}{\dtl@decx}%
      \FPmax{#8}{#8}{\dtl@decy}%
    \fi
  }%
}%
}
\newcommand*{\DTLgetvalueforkey}[5]{%
  \DTLgetrowforkey{\@dtl@row}{#3}{#4}{#5}%
  \@sdtl@getcolumnindex{\@dtl@col}{#3}{#2}%
  {%
    \dtlcurrentrow=\expandafter{\@dtl@row}%
    \edef\@dtl@dogetval{\noexpand\dtlgetentryfromcurrentrow
      {\noexpand\@dtl@val}{\@dtl@col}}%
    \@dtl@dogetval
    \global\let#1=\@dtl@val
  }%
}
\newcommand*{\DTLgetrowforkey}[4]{%
  \global\let#1=\@empty
  \@sDTLforeach{#2}{\dtl@refvalue=#3}{%
    \DTLifnull{\dtl@refvalue}%
    {}%
    {%
      \ifthenelse{\equal{\dtl@refvalue}{#4}}%
      {%
        \xdef#1{\the\dtlcurrentrow}%
        \dtlbreak
      }%
      {}%
    }%
  }%
}
\newcommand*{\dtlsplitrow}[4]{%
  \def\@dtlsplitrow##1%before stuff
    \db@col@id@w #2\db@col@id@end@% column id
      ##2% unwanted stuff
    \db@col@id@w #2\db@col@id@end@% column id
    ##3% after stuff
    \q@nil{\def#3{##1}\def#4{##3}}%
   \@dtlsplitrow#1\q@nil
}
\newtoks\@dtl@list
\newcommand*{\DTLsort}{\@ifstar\@sDTLsort\@DTLsort}
\newcommand{\@DTLsort}[3][]{%
  \DTLifdbexists{#3}%
  {%
    \edef\@dtl@replacementkeys{#1}%
    \edef\@dtl@sortorder{#2}%
    \let\@dtl@comparecs=\dtlcompare
    \dtl@sortdata{#3}%
  }%
  {%
    \PackageError{datatool}{Database `#3' doesn't exist}{}%
  }%
}
\newcommand{\@sDTLsort}[3][]{%
  \DTLifdbexists{#3}%
  {%
    \edef\@dtl@replacementkeys{#1}%
    \edef\@dtl@sortorder{#2}%
    \let\@dtl@comparecs=\dtlicompare
    \dtl@sortdata{#3}%
  }%
  {%
    \PackageError{datatool}{Database `#3' doesn't exist}{}%
  }%
}
\newtoks\@dtl@rowa
\newtoks\@dtl@rowb
\newcommand*{\dtl@sortdata}[1]{%
  \def\@dtl@sortedlist{}%
  \edef\@dtl@dbname{#1}%
  \@dtlforeachrow(\@dtl@rowAnum,\@dtl@rowAcontents)\in{#1}\do{%
    \@dtl@rowa=\expandafter{\@dtl@rowAcontents}%
    \def\@dtl@newlist{}%
  \@dtl@insertdonefalse
  \dtlrownum=0\relax
  \expandafter\@dtl@foreachrow\@dtl@sortedlist
    \db@row@elt@w%
    \db@row@id@w \@nil\db@row@id@end@%
    \db@row@id@w \@nil\db@row@id@end@%
    \db@row@elt@end@%
    \@@{\@dtl@rowBnum}{\@dtl@rowBcontents}{%
      \@dtl@rowb=\expandafter{\@dtl@rowBcontents}%
      \dtlrownum=\@dtl@rowBnum
      \if@dtl@insertdone
        \advance\dtlrownum by 1\relax
      \else
        \@dtl@sortcriteria{\@dtl@rowa}{\@dtl@rowb}%
        \ifnum\dtl@sortresult<0\relax
          \toks@=\expandafter{\@dtl@newlist}%
          \edef\@dtl@newlist{%
            \the\toks@
            \noexpand\db@row@elt@w%
             \noexpand\db@row@id@w \number\dtlrownum
             \noexpand\db@row@id@end@%
             \the\@dtl@rowa
             \noexpand\db@row@id@w \number\dtlrownum
             \noexpand\db@row@id@end@%
            \noexpand\db@row@elt@end@%
          }%
          \advance\dtlrownum by 1\relax
          \@dtl@insertdonetrue
        \fi
      \fi
      \toks@=\expandafter{\@dtl@newlist}%
      \edef\@dtl@newlist{\the\toks@
        \noexpand\db@row@elt@w%
         \noexpand\db@row@id@w \number\dtlrownum
         \noexpand\db@row@id@end@%
         \the\@dtl@rowb
         \noexpand\db@row@id@w \number\dtlrownum
         \noexpand\db@row@id@end@%
        \noexpand\db@row@elt@end@%
      }%
    }\q@nil
    \if@dtl@insertdone
    \else
      \advance\dtlrownum by 1\relax
      \toks@=\expandafter{\@dtl@newlist}%
      \edef\@dtl@newlist{\the\toks@
        \noexpand\db@row@elt@w%
         \noexpand\db@row@id@w \number\dtlrownum
         \noexpand\db@row@id@end@%
         \the\@dtl@rowa
         \noexpand\db@row@id@w \number\dtlrownum
         \noexpand\db@row@id@end@%
        \noexpand\db@row@elt@end@%
      }%
    \fi
    \let\@dtl@sortedlist=\@dtl@newlist
  }%
  \expandafter\global\csname dtldb@#1\endcsname=\expandafter
    {\@dtl@sortedlist}%
}
\newcommand{\@dtl@sortcriteria}[2]{%
  \@for\@dtl@level:=\@dtl@sortorder\do{%
    \expandafter\@dtl@getsortdirection\@dtl@level=\relax
    \let\@dtl@keya=\@dtl@key
    \let\@dtl@keyb=\@dtl@key
    \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@key}%
    \dtlgetentryfromrow{\@dtl@a}{\@dtl@col}{#1}%
    \dtlgetentryfromrow{\@dtl@b}{\@dtl@col}{#2}%
    \ifx\@dtl@a\dtlnovalue
      \@dtl@setnull{\@dtl@a}{\@dtl@key}%
    \fi
    \ifx\@dtl@b\dtlnovalue
      \@dtl@setnull{\@dtl@b}{\@dtl@key}%
    \fi
    \DTLifnull{\@dtl@a}%
    {%
      \@for\@dtl@keya:=\@dtl@replacementkeys\do{%
        \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@keya}%
        \dtlgetentryfromrow{\@dtl@a}{\@dtl@col}{#1}%
        \ifx\@dtl@a\dtlnovalue
          \@dtl@setnull{\@dtl@a}{\@dtl@key}%
        \fi
        \DTLifnull{\@dtl@a}{}{\@endfortrue}%
      }%
      \ifx\@dtl@keya\@nnil
        \let\@dtl@keya\@dtl@key
        \@dtl@setnull{\@dtl@a}{\@dtl@key}%
      \fi
    }%
    {}%
    \DTLifnull{\@dtl@b}%
    {%
      \@for\@dtl@keyb:=\@dtl@replacementkeys\do{%
        \@sdtl@getcolumnindex{\@dtl@col}{\@dtl@dbname}{\@dtl@keyb}%
        \dtlgetentryfromrow{\@dtl@b}{\@dtl@col}{#2}%
        \ifx\@dtl@b\dtlnovalue
          \@dtl@setnull{\@dtl@b}{\@dtl@key}%
        \fi
        \DTLifnull{\@dtl@b}{}{\@endfortrue}%
      }%
      \ifx\@dtl@keyb\@nnil
        \let\@dtl@keyb\@dtl@key
        \@dtl@setnull{\@dtl@b}{\@dtl@key}%
      \fi
    }%
    {}%
    \@dtl@toksA=\expandafter{\@dtl@a}%
    \@dtl@toksB=\expandafter{\@dtl@b}%
    \edef\@dtl@docompare{\noexpand\dtl@compare@
      {\@dtl@keya}{\@dtl@keyb}%
      {\noexpand\@dtl@toksA}{\noexpand\@dtl@toksB}}%
    \@dtl@docompare
    \ifnum\dtl@sortresult=0\relax
      \@endforfalse
    \else
      \@endfortrue
    \fi
  }%
  \multiply\dtl@sortresult by -\@dtl@sortdirection\relax
}
\def\@dtl@getsortdirection#1=#2\relax{%
  \def\@dtl@key{#1}%
  \def\@dtl@sortdirection{#2}%
  \ifx\@dtl@sortdirection\@empty
    \def\@dtl@sortdirection{-1}%
  \else
    \@dtl@get@sortdirection#2%
    \def\@dtl@dir{ascending}%
    \ifx\@dtl@sortdirection\@dtl@dir
      \def\@dtl@sortdirection{-1}%
    \else
      \def\@dtl@dir{descending}%
      \ifx\@dtl@sortdirection\@dtl@dir
        \def\@dtl@sortdirection{1}%
      \else
        \PackageError{datatool}{Invalid sort direction
        `\@dtl@sortdirection'}{The sort direction can only be
         one of `ascending' or `descending'}%
        \def\@dtl@sortdirection{-1}
      \fi
    \fi
  \fi
}
\def\@dtl@get@sortdirection#1={\def\@dtl@sortdirection{#1}}
\newtoks\@dtl@toksA
\newtoks\@dtl@toksB
\newtoks\@dtl@toks
\newcommand{\dtl@compare}[3]{%
  \dtl@compare@{#1}{#1}{#2}{#3}%
}
\newcommand{\dtl@compare@}[4]{%
  \DTLgetdatatype{\@dtl@typeA}{\@dtl@dbname}{#1}%
  \ifx\@dtl@typeA\DTLunsettype
    \let\@dtl@typeA\DTLstringtype
  \fi
  \DTLgetdatatype{\@dtl@typeB}{\@dtl@dbname}{#2}%
  \ifx\@dtl@typeB\DTLunsettype
    \let\@dtl@typeB\DTLstringtype
  \fi
  \@dtl@tmpcount=\@dtl@typeA\relax
  \multiply\@dtl@tmpcount by \@dtl@typeB\relax
  \ifnum\@dtl@tmpcount=0\relax
    \edef\@dtl@tmpcmp{%
      \noexpand\@dtl@comparecs{\noexpand\dtl@sortresult}%
        {\the#3}{\the#4}%
      }%
    \@dtl@tmpcmp
    \ifdtlverbose
      \edef\@dtl@a{\the#3}%
      \edef\@dtl@b{\the#4}%
    \fi
  \else
    \edef\@dtl@a{\the#3}%
    \edef\@dtl@b{\the#4}%
    \DTLifnumlt{\@dtl@a}{\@dtl@b}%
    {%
      \dtl@sortresult=-1\relax
    }%
    {%
      \DTLifnumgt{\@dtl@a}{\@dtl@b}%
      {%
        \dtl@sortresult=1\relax
      }%
      {%
        \dtl@sortresult=0\relax
      }%
    }%
  \fi
  \ifdtlverbose
    \@onelevel@sanitize\@dtl@a
    \@onelevel@sanitize\@dtl@b
    \dtl@message{`\@dtl@a' <=> `\@dtl@b' = \number\dtl@sortresult}%
  \fi
}
\newcommand*{\dtl@choplast}[3]{%
\let#2\@empty
\let#3\@empty
\@for\@dtl@element:=#1\do{%
\ifx#3\@empty
\else
 \ifx#2\@empty
   \expandafter\toks@\expandafter{#3}%
   \edef#2{{\the\toks@}}%
 \else
   \expandafter\toks@\expandafter{#3}%
   \expandafter\@dtl@toks\expandafter{#2}%
   \edef#2{\the\@dtl@toks,{\the\toks@}}%
 \fi
\fi
\let#3=\@dtl@element%
}%
}
\newcommand*{\dtl@chopfirst}[3]{%
\let#2=\@empty
\let#3=\@empty
\@for\@dtl@element:=#1\do{%
 \let#2=\@dtl@element
 \@endfortrue
}%
\if@endfor
 \let#3=\@forremainder
\fi
\@endforfalse
}
\newcommand{\dtl@sortlist}[2]{%
\def\@dtl@sortedlist{}%
\@for\@dtl@currentrow:=#1\do{%
\expandafter\dtl@insertinto\expandafter
  {\@dtl@currentrow}{\@dtl@sortedlist}{#2}%
\@endforfalse}%
\let#1=\@dtl@sortedlist
}
\newcommand{\dtl@insertinto}[3]{%
\def\@dtl@newsortedlist{}%
\@dtl@insertdonefalse
\@for\dtl@srtelement:=#2\do{%
\if@dtl@insertdone
  \expandafter\toks@\expandafter{\dtl@srtelement}%
  \edef\@dtl@newstuff{{\the\toks@}}%
\else
  \expandafter#3\expandafter{\dtl@srtelement}{#1}%
  \ifnum\dtl@sortresult<0\relax
    \expandafter\toks@\expandafter{\dtl@srtelement}%
    \@dtl@toks{#1}%
    \edef\@dtl@newstuff{{\the\@dtl@toks},{\the\toks@}}%
    \@dtl@insertdonetrue
  \else
    \expandafter\toks@\expandafter{\dtl@srtelement}%
    \edef\@dtl@newstuff{{\the\toks@}}%
  \fi
\fi
\ifx\@dtl@newsortedlist\@empty
  \expandafter\toks@\expandafter{\@dtl@newstuff}%
  \edef\@dtl@newsortedlist{\the\toks@}%
\else
  \expandafter\toks@\expandafter{\@dtl@newsortedlist}%
  \expandafter\@dtl@toks\expandafter{\@dtl@newstuff}%
  \edef\@dtl@newsortedlist{\the\toks@,\the\@dtl@toks}%
\fi
\@endforfalse
}%
 \ifx\@dtl@newsortedlist\@empty
   \@dtl@toks{#1}%
   \edef\@dtl@newsortedlist{{\the\@dtl@toks}}%
 \else
   \if@dtl@insertdone
   \else
     \expandafter\toks@\expandafter{\@dtl@newsortedlist}%
     \@dtl@toks{#1}%
     \edef\@dtl@newsortedlist{\the\toks@,{\the\@dtl@toks}}%
   \fi
 \fi
\global\let#2=\@dtl@newsortedlist
}
\newif\if@dtl@insertdone
\newcount\dtl@sortresult
\newcommand{\toks@gput@right@cx}[2]{%
  \def\@toks@name{#1}%
  \edef\@dtl@stuff{#2}%
  \global\csname\@toks@name\endcsname\expandafter
    \expandafter\expandafter{\expandafter\the
    \csname\expandafter\@toks@name\expandafter\endcsname\@dtl@stuff}%
}
\newcommand{\toks@gconcat@middle@cx}[4]{%
  \def\@toks@name{#1}%
  \edef\@dtl@stuff{#3}%
  \global\csname\@toks@name\endcsname\expandafter\expandafter
    \expandafter\expandafter\expandafter
    \expandafter\expandafter{\expandafter\expandafter\expandafter
    \the\expandafter\expandafter\expandafter#2%
    \expandafter\@dtl@stuff\the#4}%
}
\newcommand*{\DTLadd}[3]{%
\DTLconverttodecimal{#2}{\@dtl@numi}%
\DTLconverttodecimal{#3}{\@dtl@numii}%
\FPadd{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@tmp}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@tmp}{#1}%
\fi
}
\newcommand*{\DTLgadd}[3]{%
\DTLadd{\@dtl@tmpii}{#2}{#3}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLaddall}[2]{%
\def\@dtl@sum{0}%
\@for\dtl@thisval:=#2\do{%
  \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}%
  \FPadd{\@dtl@sum}{\@dtl@sum}{\@dtl@num}%
}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@sum}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@sum}{#1}%
\fi
}
\newcommand*{\DTLgaddall}[2]{%
\DTLaddall{\@dtl@tmpi}{#2}%
\global\let#1=\@dtl@tmpi
}
\newcommand*{\DTLsub}[3]{%
\DTLconverttodecimal{#2}{\@dtl@numi}%
\DTLconverttodecimal{#3}{\@dtl@numii}%
\FPsub{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@tmp}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@tmp}{#1}%
\fi
}
\newcommand*{\DTLgsub}[3]{%
\DTLsub{\@dtl@tmpii}{#2}{#3}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLmul}[3]{%
\let\@dtl@thisreplaced=\@empty
\DTLconverttodecimal{#2}{\@dtl@numi}%
\ifx\@dtl@replaced\@empty
\else
  \let\@dtl@thisreplaced=\@dtl@replaced
\fi
\DTLconverttodecimal{#3}{\@dtl@numii}%
\ifx\@dtl@replaced\@empty
\else
  \let\@dtl@thisreplaced=\@dtl@replaced
\fi
\FPmul{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}%
\ifx\@dtl@thisreplaced\@empty
  \DTLdecimaltolocale{\@dtl@tmp}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@tmp}{#1}%
\fi
}
\newcommand*{\DTLgmul}[3]{%
\DTLmul{\@dtl@tmpii}{#2}{#3}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLdiv}[3]{%
\let\@dtl@thisreplaced=\@empty
\DTLconverttodecimal{#2}{\@dtl@numi}%
\ifx\@dtl@replaced\@empty
\else
  \let\@dtl@thisreplaced=\@dtl@replaced
\fi
\DTLconverttodecimal{#3}{\@dtl@numii}%
\FPdiv{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}%
\ifx\@dtl@thisreplaced\@empty
  \DTLdecimaltolocale{\@dtl@tmp}{#1}%
\else
  \ifx\@dtl@thisreplaced\@dtl@replaced
    \DTLdecimaltolocale{\@dtl@tmp}{#1}%
  \else
    \DTLdecimaltocurrency{\@dtl@tmp}{#1}%
  \fi
\fi
}
\newcommand*{\DTLgdiv}[3]{%
\DTLdiv{\@dtl@tmpii}{#2}{#3}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLabs}[2]{%
\DTLconverttodecimal{#2}{\@dtl@numi}%
\FPabs{\@dtl@tmp}{\@dtl@numi}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@tmp}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@tmp}{#1}%
\fi
}
\newcommand*{\DTLgabs}[2]{%
\DTLabs{\@dtl@tmpii}{#2}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLneg}[2]{%
\DTLconverttodecimal{#2}{\@dtl@numi}%
\FPneg{\@dtl@tmp}{\@dtl@numi}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@tmp}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@tmp}{#1}%
\fi
}
\newcommand*{\DTLgneg}[2]{%
\DTLneg{\@dtl@tmpii}{#2}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLsqrt}[2]{%
\DTLconverttodecimal{#2}{\@dtl@numi}%
\FProot{\@dtl@tmpi}{\@dtl@numi}{2}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@tmpi}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@tmpi}{#1}%
\fi
}
\newcommand*{\DTLgsqrt}[2]{%
\DTLsqrt{\@dtl@tmpii}{#2}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLmin}[3]{%
\DTLconverttodecimal{#2}{\@dtl@numi}%
\DTLconverttodecimal{#3}{\@dtl@numii}%
\FPiflt{\@dtl@numi}{\@dtl@numii}%
 \dtl@ifsingle{#2}{%
  \let#1=#2}{%
  \def#1{#2}}%
\else
 \dtl@ifsingle{#3}{%
  \let#1=#3}{%
  \def#1{#3}}%
\fi
}
\newcommand*{\DTLgmin}[3]{%
\DTLmin{\@dtl@tmpii}{#2}{#3}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLminall}[2]{%
\let\@dtl@min=\@empty
\@for\dtl@thisval:=#2\do{%
  \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}%
  \ifx\@dtl@min\@empty
    \let\@dtl@min=\@dtl@num
  \else
    \FPmin{\@dtl@min}{\@dtl@min}{\@dtl@num}%
  \fi
}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@min}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@min}{#1}%
\fi
}
\newcommand*{\DTLgminall}[2]{%
\DTLminall{\@dtl@tmpi}{#2}%
\global\let#1=\@dtl@tmpi
}
\newcommand*{\DTLmax}[3]{%
\DTLconverttodecimal{#2}{\@dtl@numi}%
\DTLconverttodecimal{#3}{\@dtl@numii}%
\FPmax{\@dtl@tmp}{\@dtl@numi}{\@dtl@numii}%
\FPifgt{\@dtl@numi}{\@dtl@numii}%
 \dtl@ifsingle{#2}{%
  \let#1=#2}{%
  \def#1{#2}}%
\else
 \dtl@ifsingle{#3}{%
  \let#1=#3}{%
  \def#1{#3}}%
\fi
}
\newcommand*{\DTLgmax}[3]{%
\DTLmax{\@dtl@tmpii}{#2}{#3}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLmaxall}[2]{%
\let\@dtl@max=\@empty
\@for\dtl@thisval:=#2\do{%
  \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}%
  \ifx\@dtl@max\@empty
    \let\@dtl@max\@dtl@num
  \else
    \FPmax{\@dtl@max}{\@dtl@max}{\@dtl@num}%
  \fi
}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@max}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@max}{#1}%
\fi
}
\newcommand*{\DTLgmaxall}[2]{%
\DTLmaxall{\@dtl@tmpi}{#2}%
\global\let#1=\@dtl@tmpi
}
\newcommand*{\DTLmeanforall}[2]{%
\def\@dtl@mean{0}%
\def\@dtl@n{0}%
\@for\dtl@thisval:=#2\do{%
  \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}%
  \FPadd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}%
  \FPadd{\@dtl@n}{\@dtl@n}{1}%
}%
\FPdiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@mean}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@mean}{#1}%
\fi
}
\newcommand*{\DTLgmeanforall}[2]{%
\DTLmeanforall{\@dtl@tmpi}{#2}%
\global\let#1=\@dtl@tmpi
}
\newcommand*{\DTLvarianceforall}[2]{%
\def\@dtl@mean{0}%
\def\@dtl@n{0}%
\let\@dtl@decvals=\@empty
\@for\dtl@thisval:=#2\do{%
  \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}%
  \ifx\@dtl@decvals\@empty
   \let\@dtl@decvals=\@dtl@num
  \else
   \expandafter\toks@\expandafter{\@dtl@decvals}%
   \edef\@dtl@decvals{\the\toks@,\@dtl@num}%
  \fi
  \FPadd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}%
  \FPadd{\@dtl@n}{\@dtl@n}{1}%
}%
\FPdiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}%
\def\@dtl@var{0}%
\@for\@dtl@num:=\@dtl@decvals\do{%
  \FPsub{\@dtl@diff}{\@dtl@num}{\@dtl@mean}%
  \FPmul{\@dtl@diff}{\@dtl@diff}{\@dtl@diff}%
  \FPadd{\@dtl@var}{\@dtl@var}{\@dtl@diff}%
}%
\FPdiv{\@dtl@var}{\@dtl@var}{\@dtl@n}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@var}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@var}{#1}%
\fi
}
\newcommand*{\DTLgvarianceforall}[2]{%
\DTLvarianceforall{\@dtl@tmpi}{#2}%
\global\let#1=\@dtl@tmpi
}
\newcommand*{\DTLsdforall}[2]{%
\def\@dtl@mean{0}%
\def\@dtl@n{0}%
\let\@dtl@decvals=\@empty
\@for\dtl@thisval:=#2\do{%
  \DTLconverttodecimal{\dtl@thisval}{\@dtl@num}%
  \ifx\@dtl@decvals\@empty
   \let\@dtl@decvals=\@dtl@num
  \else
   \expandafter\toks@\expandafter{\@dtl@decvals}%
   \edef\@dtl@decvals{\the\toks@,\@dtl@num}%
  \fi
  \FPadd{\@dtl@mean}{\@dtl@mean}{\@dtl@num}%
  \FPadd{\@dtl@n}{\@dtl@n}{1}%
}%
\FPdiv{\@dtl@mean}{\@dtl@mean}{\@dtl@n}%
\def\@dtl@sd{0}%
\@for\@dtl@num:=\@dtl@decvals\do{%
  \FPsub{\@dtl@diff}{\@dtl@num}{\@dtl@mean}%
  \FPmul{\@dtl@diff}{\@dtl@diff}{\@dtl@diff}%
  \FPadd{\@dtl@sd}{\@dtl@sd}{\@dtl@diff}%
}%
\FPdiv{\@dtl@sd}{\@dtl@sd}{\@dtl@n}%
\FProot{\@dtl@sd}{\@dtl@sd}{2}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@sd}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@sd}{#1}%
\fi
}
\newcommand*{\DTLgsdforall}[2]{%
\DTLsdforall{\@dtl@tmpi}{#2}%
\global\let#1=\@dtl@tmpi
}
\newcommand*{\DTLround}[3]{%
\DTLconverttodecimal{#2}{\@dtl@numi}%
\FPround{\@dtl@tmp}{\@dtl@numi}{#3}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@tmp}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@tmp}{#1}%
\fi
}
\newcommand*{\DTLground}[3]{%
\DTLround{\@dtl@tmpii}{#2}{#3}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLtrunc}[3]{%
\DTLconverttodecimal{#2}{\@dtl@numi}%
\FPtrunc{\@dtl@tmp}{\@dtl@numi}{#3}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@tmp}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@tmp}{#1}%
\fi
}
\newcommand*{\DTLgtrunc}[3]{%
\DTLtrunc{\@dtl@tmpii}{#2}{#3}%
\global\let#1=\@dtl@tmpii
}
\newcommand*{\DTLclip}[2]{%
\DTLconverttodecimal{#2}{\@dtl@numi}%
\FPclip{\@dtl@tmp}{\@dtl@numi}%
\ifx\@dtl@replaced\@empty
  \DTLdecimaltolocale{\@dtl@tmp}{#1}%
\else
  \DTLdecimaltocurrency{\@dtl@tmp}{#1}%
\fi
}
\newcommand*{\DTLgclip}[3]{%
\DTLclip{\@dtl@tmpii}{#2}%
\global\let#1=\@dtl@tmpii
}
\newcommand*\DTLinitials[1]{%
\def\dtl@initialscmd{}%
\dtl@subnobrsp{#1}{\dtl@string}%
\DTLsubstituteall{\dtl@string}{~}{ }%
\DTLsubstituteall{\dtl@string}{\ }{ }%
\DTLsubstituteall{\dtl@string}{\space}{ }%
\expandafter\dtl@initials\dtl@string{} \@nil%
\dtl@initialscmd}%
\edef\dtl@construct@subnobrsp{%
\noexpand\def\noexpand\@dtl@subnobrsp##1\noexpand\protect
\expandafter\noexpand\csname nobreakspace \endcsname ##2{%
\noexpand\toks@{##1}%
\noexpand\expandafter\noexpand\@dtl@toks\noexpand\expandafter{%
\noexpand\@dtl@string}%
\noexpand\edef\noexpand\@dtl@string{\noexpand\the\noexpand\@dtl@toks
\noexpand\the\noexpand\toks@}%
\noexpand\def\noexpand\@dtl@tmp{##2}%
\noexpand\ifx\noexpand\@dtl@tmp\noexpand\@nnil
  \noexpand\let\noexpand\@dtl@subnobrspnext=\noexpand\relax
\noexpand\else
  \noexpand\toks@{ }%
  \noexpand\expandafter\noexpand\@dtl@toks\noexpand\expandafter{%
  \noexpand\@dtl@string}%
  \noexpand\edef\noexpand\@dtl@string{\noexpand\the\noexpand\@dtl@toks
  \noexpand\the\noexpand\toks@}%
  \noexpand\let\noexpand\@dtl@subnobrspnext=\noexpand\@dtl@subnobrsp
\noexpand\fi
\noexpand\@dtl@subnobrspnext
}%
\noexpand\def\noexpand\dtl@subnobrsp##1##2{%
\noexpand\def\noexpand\@dtl@string{}%
\noexpand\@dtl@subnobrsp ##1\noexpand\protect\expandafter\noexpand
\csname nobreakspace \endcsname \noexpand\@nil
\noexpand\let##2=\noexpand\@dtl@string
}}
\dtl@construct@subnobrsp
\newcommand*{\DTLstoreinitials}[2]{%
\def\dtl@initialscmd{}%
\dtl@subnobrsp{#1}{\dtl@string}%
\DTLsubstituteall{\dtl@string}{~}{ }%
\DTLsubstituteall{\dtl@string}{\ }{ }%
\DTLsubstituteall{\dtl@string}{\space}{ }%
\expandafter\dtl@initials\dtl@string{} \@nil
\let#2=\dtl@initialscmd
}
\def\dtl@initials#1#2 #3{%
\dtl@ifsingle{#1}{%
\ifcat\noexpand#1\relax\relax
   \def\@dtl@donextinitials{\@dtl@initials#2 {#3}}%
\else
   \def\@dtl@donextinitials{\@dtl@initials#1#2 {#3}}%
\fi
}{%
 \def\@dtl@donextinitials{\@dtl@initials{#1}#2 {#3}}%
}%
\@dtl@donextinitials
}
\def\@dtl@initials#1#2 #3{%
\dtl@initialshyphen#2-{}\dtl@endhyp
\expandafter\@dtl@toks\expandafter{\dtl@initialscmd}%
\toks@{#1}%
\ifx\dtl@inithyphen\@empty
\else
  \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@}%
  \expandafter\@dtl@toks\expandafter{\dtl@initialscmd}%
  \expandafter\toks@\expandafter{\dtl@inithyphen}%
\fi
\def\dtl@tmp{#3}%
\ifx\@nnil\dtl@tmp
 \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@\DTLafterinitials}%
 \let\dtl@initialsnext=\@gobble
\else
 \edef\dtl@initialscmd{\the\@dtl@toks\the\toks@\DTLbetweeninitials}%
 \let\dtl@initialsnext=\dtl@initials
\fi
\dtl@initialsnext{#3}}
\def\dtl@initialshyphen#1-#2#3\dtl@endhyp{%
\def\dtl@inithyphen{#2}%
\ifx\dtl@inithyphen\@empty
\else
 \edef\dtl@inithyphen{%
   \DTLafterinitialbeforehyphen\DTLinitialhyphen#2}%
\fi
}
\newcommand*{\DTLafterinitials}{.}
\newcommand*{\DTLbetweeninitials}{.}
\newcommand*{\DTLafterinitialbeforehyphen}{.}
\newcommand*{\DTLinitialhyphen}{-}
\newcommand*{\DTLifAllUpperCase}[3]{%
\protected@edef\dtl@tuc{#1}%
\expandafter\dtl@testifuppercase\dtl@tuc\@nil\relax
\if@dtl@condition#2\else#3\fi
}
\def\dtl@testifuppercase#1#2{%
\def\dtl@argi{#1}%
\def\dtl@argii{#2}%
\def\dtl@tc@rest{}%
\ifx\dtl@argi\@nnil
  \let\dtl@testifuppernext=\@nnil
\else
  \ifx#1\protect
    \let\dtl@testifuppernext=\dtl@testifuppercase
  \else
    \ifx\uppercase#1\relax
      \@dtl@conditiontrue
      \def\dtl@tc@rest{}%
      \let\dtl@testifuppernext=\relax
    \else
      \edef\dtl@tc@arg{\string#1}%
      \expandafter\dtl@test@ifuppercase\dtl@tc@arg\end
      \ifx\dtl@argii\@nnil
        \let\dtl@testifuppernext=\@dtl@gobbletonil
      \fi
    \fi
  \fi
\fi
\ifx\dtl@testifuppernext\relax
 \edef\dtl@dotestifuppernext{%
   \noexpand\dtl@testifuppercase}%
\else
 \ifx\dtl@testifuppernext\@nnil
   \edef\dtl@dotestifuppernext{#2}%
 \else
   \expandafter\toks@\expandafter{\dtl@tc@rest}%
   \@dtl@toks{#2}%
   \edef\dtl@dotestifuppernext{%
     \noexpand\dtl@testifuppernext\the\toks@\the\@dtl@toks}%
 \fi
\fi
\dtl@dotestifuppernext
}
\def\dtl@test@ifuppercase#1#2\end{%
\def\dtl@tc@rest{#2}%
\IfSubStringInString{\string\MakeUppercase}{#1#2}{%
  \@dtl@conditiontrue
  \def\dtl@tc@rest{}%
  \let\dtl@testifuppernext=\relax
}{%
 \IfSubStringInString{\string\MakeTextUppercase}{#1#2}{%
    \@dtl@conditiontrue
    \def\dtl@tc@rest{}%
    \let\dtl@testifuppernext=\relax
 }{%
  \edef\dtl@uccode{\the\uccode`#1}%
  \edef\dtl@code{\number`#1}%
  \ifnum\dtl@code=\dtl@uccode\relax
    \@dtl@conditiontrue
    \let\dtl@testifuppernext=\dtl@testifuppercase
  \else
    \ifnum\dtl@uccode=0\relax
      \@dtl@conditiontrue
      \let\dtl@testifuppernext=\dtl@testifuppercase
    \else
      \@dtl@conditionfalse
      \let\dtl@testifuppernext=\@dtl@gobbletonil
    \fi
  \fi
}}}
\newcommand*{\DTLifAllLowerCase}[3]{%
\protected@edef\dtl@tlc{#1}%
\expandafter\dtl@testiflowercase\dtl@tlc\@nil\relax
\if@dtl@condition#2\else#3\fi
}
\def\dtl@testiflowercase#1#2{%
\def\dtl@argi{#1}%
\def\dtl@argii{#2}%
\ifx\dtl@argi\@nnil
  \let\dtl@testiflowernext=\@nnil
\else
  \ifx#1\protect
    \let\dtl@testiflowernext=\dtl@testiflowercase
  \else
    \ifx\lowercase#1\relax
      \@dtl@conditiontrue
      \def\dtl@tc@rest{}%
      \let\dtl@testiflowernext=\relax
    \else
      \edef\dtl@tc@arg{\string#1}%
      \expandafter\dtl@test@iflowercase\dtl@tc@arg\end
      \ifx\dtl@argii\@nnil
        \let\dtl@testiflowernext=\@dtl@gobbletonil
      \fi
    \fi
  \fi
\fi
\ifx\dtl@testiflowernext\relax
 \edef\dtl@dotestiflowernext{%
   \noexpand\dtl@testiflowercase}%
\else
 \ifx\dtl@testiflowernext\@nnil
   \edef\dtl@dotestiflowernext{#2}%
 \else
   \expandafter\toks@\expandafter{\dtl@tc@rest}%
   \@dtl@toks{#2}%
   \edef\dtl@dotestiflowernext{%
     \noexpand\dtl@testiflowernext\the\toks@\the\@dtl@toks}%
 \fi
\fi
\dtl@dotestiflowernext
}
\def\dtl@test@iflowercase#1#2\end{%
\def\dtl@tc@rest{#2}%
\IfSubStringInString{\string\MakeLowercase}{#1#2}{%
  \@dtl@conditiontrue
  \def\dtl@tc@rest{}%
  \let\dtl@testiflowernext=\relax
}{%
 \IfSubStringInString{\string\MakeTextLowercase}{#1#2}{%
    \@dtl@conditiontrue
    \def\dtl@tc@rest{}%
    \let\dtl@testiflowernext=\relax
 }{%
  \edef\dtl@lccode{\the\lccode`#1}%
  \edef\dtl@code{\number`#1}%
  \ifnum\dtl@code=\dtl@lccode\relax
    \@dtl@conditiontrue
    \let\dtl@testiflowernext=\dtl@testiflowercase
  \else
    \ifnum\dtl@lccode=0\relax
      \@dtl@conditiontrue
      \let\dtl@testiflowernext=\dtl@testiflowercase
    \else
      \@dtl@conditionfalse
      \let\dtl@testiflowernext=\@dtl@gobbletonil
    \fi
  \fi
}}}
\newwrite\@dtl@write
\newcommand*{\DTLsavedb}[2]{%
  \DTLifdbexists{#1}%
  {%
    \openout\@dtl@write
    \def\@dtl@header{}%
    \dtlforeachkey(\@dtl@key,\@dtl@col,\@dtl@type,\@dtl@head)%
      \in{#1}\do
    {%
      \IfSubStringInString{\@dtl@separator}{\@dtl@key}%
      {%
        \ifx\@dtl@header\@empty
          \protected@edef\@dtl@header{%
            \@dtl@delimiter\@dtl@key\@dtl@delimiter}%
        \else
          \toks@=\expandafter{\@dtl@header}%
          \protected@edef\@dtl@header{%
            \the\toks@\@dtl@separator
            \@dtl@delimiter\@dtl@key\@dtl@delimiter}%
        \fi
      }%
      {%
        \ifx\@dtl@header\@empty
          \protected@edef\@dtl@header{\@dtl@key}%
        \else
          \toks@=\expandafter{\@dtl@header}%
          \protected@edef\@dtl@header{\the\toks@
            \@dtl@separator\@dtl@key}%
        \fi
      }%
    }%
    \protected@write\@dtl@write{}{\@dtl@header}%
    \@sDTLforeach{#1}{}%
    {%
      \def\@dtl@row{}%
      \DTLforeachkeyinrow{\@dtl@val}%
      {%
        \IfSubStringInString{\@dtl@separator}{\@dtl@val}%
        {%
          \ifx\@dtl@row\@empty
            \protected@edef\@dtl@row{%
              \@dtl@delimiter\@dtl@val\@dtl@delimiter}%
          \else
            \toks@=\expandafter{\@dtl@row}%
            \protected@edef\@dtl@row{\the\toks@\@dtl@separator
              \@dtl@delimiter\@dtl@val\@dtl@delimiter}%
          \fi
        }%
        {%
          \ifx\@dtl@row\@empty
            \protected@edef\@dtl@row{\@dtl@val}%
          \else
            \toks@=\expandafter{\@dtl@row}%
            \protected@edef\@dtl@row{\the\toks@\@dtl@separator
              \@dtl@val}%
          \fi
        }%
        \protected@write\@dtl@write{}{\@dtl@row}%
      }%
    }%
    \closeout\@dtl@write
  }%
  {%
    \PackageError{datatool}{Can't save database `#1': no such
      database}{}%
  }%
}
\newcommand*{\DTLsavetexdb}[2]{%
  \DTLifdbexists{#1}%
  {%
    \openout\@dtl@write=#2\relax
    \protected@write\@dtl@write{}{\string\DTLnewdb{#1}}%
    \@sDTLforeach{#1}{}%
    {%
      \protected@write\@dtl@write{}{\string\DTLnewrow*{#1}}%
      \DTLforeachkeyinrow{\@dtl@val}%
      {%
        \DTLifnull{\@dtl@val}%
        {\def\@dtl@val{}}%
        {}%
        \protected@write\@dtl@write{}{%
          \string\DTLnewdbentry*{#1}{\dtlkey}{\@dtl@val}}%
      }%
    }%
    \dtlforeachkey(\@dtl@k,\@dtl@c,\@dtl@t,\@dtl@h)\in{#1}\do
    {%
      \@onelevel@sanitize\@dtl@h
      \protected@write\@dtl@write{}{%
        \string\DTLsetheader*{#1}{\@dtl@k}{\@dtl@h}}%
    }%
    \closeout\@dtl@write
  }%
  {%
    \PackageError{datatool}{Can't save database `#1': no such
      database}{}%
  }%
}
\newcommand{\@longempty}{}
\newread\@dtl@read
\newcount\dtl@entrycr
\define@boolkey{loaddb}[dtl]{noheader}[true]{}
\define@key{loaddb}{keys}{%
  \dtl@entrycr=0\relax
  \@for\@dtl@key:=#1\do
  {%
    \advance\dtl@entrycr by 1\relax
    \expandafter
      \edef\csname @dtl@inky@\romannumeral\dtl@entrycr\endcsname{%
        \@dtl@key}%
  }%
}
\define@key{loaddb}{headers}{%
  \dtl@entrycr=0\relax
  \@for\@dtl@head:=#1\do
  {%
    \advance\dtl@entrycr by 1\relax
    \toks@=\expandafter{\@dtl@head}%
    \expandafter
      \edef\csname @dtl@inhd@\romannumeral\dtl@entrycr\endcsname{%
        \the\toks@}%
  }%
}
\newcommand*{\dtldefaultkey}{Column}
\newcommand*{\@dtl@readline}[2]{%
  \read#1 to #2%
  \dtl@trim#2%
}
\newcommand*{\@dtl@readrawline}[2]{%
  \@dtl@rawread#1 to #2%
  \dtl@trim#2%
  \dtl@domappings\@dtl@line
}

\newcommand*{\DTLloaddb}{%
  \let\@dtl@doreadline\@dtl@readline
  \@dtlloaddb
}
\newcommand*{\@dtlloaddb}[3][]{%
  \IfFileExists{#3}{%
  \begingroup
    \catcode`\"12\relax
     \dtlnoheaderfalse
     \setkeys{loaddb}{#1}%
    \openin\@dtl@read=#3%
    \dtl@message{Reading `#3'}%
    \DTLnewdb{#2}%
    \ifeof\@dtl@read
      \PackageWarning{datatool}{File `#3' has no data}%
    \else
      \ifdtlnoheader
      \else
        \loop
          \@dtl@conditionfalse
          \ifeof\@dtl@read
          \else
            \@dtl@doreadline\@dtl@read\@dtl@line
            \ifx\@dtl@line\@longempty
              \@dtl@conditiontrue
            \fi
          \fi
        \if@dtl@condition
        \repeat
        \protected@edef\@dtl@lin@{%
           \@dtl@separator\@dtl@line\@dtl@separator}%
        \dtl@entrycr=0\relax
       \loop
        \expandafter\@dtl@lopoff\@dtl@lin@\to\@dtl@lin@\@dtl@key
        \advance\dtl@entrycr by 1\relax
        \expandafter\@dtl@toks\expandafter{\@dtl@key}%
        \@ifundefined{@dtl@inky@\romannumeral\dtl@entrycr}%
        {%
          \expandafter
            \edef\csname @dtl@inky@\romannumeral
              \dtl@entrycr\endcsname{\the\@dtl@toks}%
        }%
        {%
          \@ifundefined{@dtl@inhd@\romannumeral\dtl@entrycr}%
          {%
            \expandafter
              \edef\csname @dtl@inhd@\romannumeral
                \dtl@entrycr\endcsname{\the\@dtl@toks}%
          }%
          {}%
        }%
        \ifx\@dtl@lin@\@dtl@separator
          \@dtl@conditionfalse
        \else
          \@dtl@conditiontrue
        \fi
       \if@dtl@condition
       \repeat
      \fi
       \ifeof\@dtl@read
          \ifdtlnoheader
            \PackageWarning{datatool}{No data in `#3'}%
          \else
            \PackageWarning{datatool}{Only header row found in `#3'}%
          \fi
       \else
         \@dtl@conditiontrue
         \loop
          \@dtl@doreadline\@dtl@read\@dtl@line
           \ifx\@dtl@line\@longempty
           \else
             \@sDTLnewrow{#2}%
             \expandafter\@dtl@toks\expandafter{\@dtl@line}%
             \edef\@dtl@lin@{\@dtl@separator\the\@dtl@toks
               \@dtl@separator}%
             \dtl@entrycr=0\relax
             {%
               \@dtl@conditiontrue
               \loop
                 \expandafter\@dtl@lopoff\@dtl@lin@\to
                   \@dtl@lin@\@dtl@thisentry
                 \advance\dtl@entrycr by 1\relax
                 \@ifundefined{@dtl@inky@\romannumeral\dtl@entrycr}%
                 {%
                   \edef\@dtl@thiskey{\dtldefaultkey
                     \number\dtl@entrycr}%
                   \expandafter\let
                     \csname @dtl@inky@\romannumeral
                       \dtl@entrycr\endcsname\@dtl@thiskey
                 }%
                 {%
                   \edef\@dtl@thiskey{%
                     \csname @dtl@inky@\romannumeral
                       \dtl@entrycr\endcsname}%
                 }%
                 \expandafter\@dtl@toks\expandafter{\@dtl@thisentry}%
                 \edef\@do@dtlnewentry{\noexpand\@sDTLnewdbentry
                   {#2}{\@dtl@thiskey}{\the\@dtl@toks}}%
                 \@do@dtlnewentry
                 \ifx\@dtl@lin@\@dtl@separator
                   \@dtl@conditionfalse
                 \fi
               \if@dtl@condition
               \repeat
             }%
         \fi
         \ifeof\@dtl@read \@dtl@conditionfalse\fi
         \if@dtl@condition
         \repeat
       \fi
    \fi
    \closein\@dtl@read
     \edef\@dtl@maxcols{\expandafter
       \number\csname dtlcols@#2\endcsname}%
     \dtlgforint\dtl@entrycr=1\to\@dtl@maxcols\step1\do
     {%
       \@ifundefined{@dtl@inhd@\romannumeral\dtl@entrycr}%
       {}%
       {%
          \expandafter\let\expandafter\@dtl@head
            \csname @dtl@inhd@\romannumeral\dtl@entrycr\endcsname
          \@dtl@toks=\expandafter{\@dtl@head}%
          \edef\@dtl@dosetheader{\noexpand\@dtl@setheaderforindex
            {#2}{\number\dtl@entrycr}{\the\@dtl@toks}}%
          \@dtl@dosetheader
       }%
     }%
  \endgroup
  }{%
    \PackageError{datatool}{Can't load database `#2' (file `#3'
    doesn't exist)}{}%
  }%
}
\newcommand{\dtl@trim}[1]{%
\def\@dtl@trmstr{}%
\expandafter\@dtl@starttrim#1\@nil%
\let#1=\@dtl@trmstr
}
\long\def\@dtl@starttrim#1#2{%
\ifx\par#1%
 \def\@dtl@dotrim{\@dtl@trim{} #2}%
\else
 \def\@dtl@dotrim{\@dtl@trim#1#2}%
\fi
\@dtl@dotrim%
}
\long\def\@dtl@trim#1 \@nil{\long\def\@dtl@trmstr{#1}}
\newcommand*\DTLloadrawdb{%
  \let\@dtl@doreadline\@dtl@readrawline
  \@dtlloaddb
}
\begingroup
\catcode`\%=\active
\catcode`$=\active
\catcode`&=\active
\catcode`~=\active
\catcode`_=\active
\catcode`^=\active
\catcode`#=\active
\catcode`?=6\relax
\catcode`<=1\relax
\catcode`>=2\relax
\catcode`\{=\active
\catcode`\}=\active
\gdef\@dtl@rawread?1to?2<\relax
<<\catcode`\%=\active
\catcode`$=\active
\catcode`&=\active
\catcode`~=\active
\catcode`_=\active
\catcode`^=\active
\catcode`#=\active
\catcode`\{=\active
\catcode`\}=\active
\def%<\noexpand\%>\relax
\def$<\noexpand\$>\relax
\def&<\&>\relax
\def#<\#>\relax
\def~<\noexpand\textasciitilde>\relax
\def_<\noexpand\_>\relax
\def^<\noexpand\textasciicircum>\relax
\@dtl@activatebraces
\@dtl@doreadraw?1?2>>>
\gdef\@dtl@doreadraw?1?2<\relax
\read?1 to \tmp
\xdef?2<\tmp>\relax
>
\endgroup
\begingroup
\catcode`\{=\active
\catcode`\}=\active
\catcode`<=1\relax
\catcode`>=2\relax
\gdef\@dtl@activatebraces<%
 \catcode`\{=\active
 \catcode`\}=\active
 \def{<\noexpand\{>%
 \def}<\noexpand\}>%
>%
\endgroup
\newcommand*{\DTLrawmap}[2]{%
\expandafter\@dtl@toks\expandafter{\@dtl@rawmappings}%
\ifx\@dtl@rawmappings\@empty
  \def\@dtl@rawmappings{{#1}{#2}}%
\else
  \def\@dtl@tmp{{#1}{#2}}
  \protected@edef\@dtl@rawmappings{\the\@dtl@toks,\@dtl@tmp}
\fi
}
\newcommand*{\@dtl@rawmappings}{}
\newcommand*{\dtl@domappings}[1]{%
\@for\@dtl@map:=\@dtl@rawmappings\do{%
  \expandafter\DTLsubstitute\expandafter#1\@dtl@map
}}
\newcommand{\DTLsubstitute}[3]{%
\expandafter\DTLsplitstring\expandafter
  {#1}{#2}{\@dtl@beforepart}{\@dtl@afterpart}%
\ifx\@dtl@replaced\@empty
\else
  \def#1{}%
  \expandafter\@dtl@toks\expandafter{\@dtl@beforepart}%
  \expandafter\toks@\expandafter{#1}%
  \protected@edef#1{\the\toks@\the\@dtl@toks#3}%
  \expandafter\@dtl@toks\expandafter{\@dtl@afterpart}%
  \expandafter\toks@\expandafter{#1}%
  \edef#1{\the\toks@\the\@dtl@toks}%
\fi
}
\newcommand*{\DTLsplitstring}[4]{%
\def\dtl@splitstr##1#2##2\@nil{%
\def#3{##1}%
\def#4{##2}%
\ifx#4\@empty
  \let\@dtl@replaced=\@empty
\else
  \def\@dtl@replaced{#2}%
  \dtl@split@str##2\@nil
\fi
}%
\def\dtl@split@str##1#2\@nil{%
\def#4{##1}}%
\dtl@splitstr#1#2\@nil
}
\newcommand{\DTLsubstituteall}[3]{%
\def\@dtl@splitsubstr{}%
\let\@dtl@afterpart=#1\relax
\@dtl@dosubstitute{#2}{#3}%
\expandafter\toks@\expandafter{\@dtl@splitsubstr}%
\expandafter\@dtl@toks\expandafter{\@dtl@afterpart}%
\edef#1{\the\toks@\the\@dtl@toks}%
}
\def\@dtl@dosubstitute#1#2{%
\expandafter\DTLsplitstring\expandafter
 {\@dtl@afterpart}{#1}{\@dtl@beforepart}{\@dtl@afterpart}%
\expandafter\toks@\expandafter{\@dtl@splitsubstr}%
\expandafter\@dtl@toks\expandafter{\@dtl@beforepart}%
\edef\@dtl@splitsubstr{\the\toks@\the\@dtl@toks}%
\ifx\@dtl@replaced\@empty
  \let\@dtl@dosubstnext=\@dtl@dosubstitutenoop
\else
  \expandafter\toks@\expandafter{\@dtl@splitsubstr}%
  \@dtl@toks{#2}%
  \edef\@dtl@splitsubstr{\the\toks@\the\@dtl@toks}%
  \let\@dtl@dosubstnext=\@dtl@dosubstitute
\fi
\@dtl@dosubstnext{#1}{#2}%
}
\def\@dtl@dosubstitutenoop#1#2{}
\newcommand*{\DTLifinlist}[4]{%
  \def\@dtl@doifinlist##1,#1,##2\end@dtl@doifinlist{%
     \def\@before{##1}%
     \def\@after{##2}%
  }%
  \expandafter\@dtl@doifinlist\expandafter,#2,#1,\@nil
    \end@dtl@doifinlist
  \ifx\@after\@nnil
    #4%
  \else
    #3%
  \fi
}
\newcommand*{\@dtl@currencies}{\$,\pounds}
\newcommand*{\DTLnewcurrencysymbol}[1]{%
\expandafter\toks@\expandafter{\@dtl@currencies}%
\@dtl@toks{#1}%
\edef\@dtl@currencies{\the\@dtl@toks,\the\toks@}%
}
\AtBeginDocument{%
\@ifundefined{texteuro}{}{\DTLnewcurrencysymbol{\texteuro}}%
\@ifundefined{textdollar}{}{\DTLnewcurrencysymbol{\textdollar}}%
\@ifundefined{textstirling}{}{\DTLnewcurrencysymbol{\textstirling}}%
\@ifundefined{textyen}{}{\DTLnewcurrencysymbol{\textyen}}%
\@ifundefined{textwon}{}{\DTLnewcurrencysymbol{\textwon}}%
\@ifundefined{textcurrency}{}{\DTLnewcurrencysymbol{\textcurrency}}%
\@ifundefined{euro}{}{\DTLnewcurrencysymbol{\euro}}%
\@ifundefined{yen}{}{\DTLnewcurrencysymbol{\yen}}%
}
\newcommand{\@dtl@standardize@currency}[1]{%
\def\@dtl@org@currency{}%
\@for\@dtl@thiscurrency:=\@dtl@currencies\do{%
  \expandafter\toks@\expandafter{\@dtl@thiscurrency}%
  \edef\@dtl@dosubs{\noexpand\DTLsubstitute{\noexpand#1}%
   {\the\toks@}{\noexpand\$}}%
  \@dtl@dosubs
  \ifx\@dtl@replaced\@empty
  \else
    \let\@dtl@org@currency=\@dtl@replaced
    \@endfortrue
  \fi
}%
\@endforfalse}
\newcommand*{\@dtl@currency}{\$}
\newcommand*{\DTLsetdefaultcurrency}[1]{%
\renewcommand*{\@dtl@currency}{#1}}
\newcommand{\dtl@ifsingle}[3]{%
\def\@dtl@arg{#1}%
\ifx\@dtl@arg\@empty
  #3%
\else
  \@dtl@ifsingle#1\@nil{#2}{#3}%
\fi
}
\def\@dtl@ifsingle#1#2\@nil#3#4{%
\def\dtl@sg@arg{#2}%
\ifx\dtl@sg@arg\@empty
 #3%
\else
 #4%
\fi
}
\newcommand*{\dtlshowdb}[1]{%
\expandafter\showthe\csname dtldb@#1\endcsname}
\newcommand*{\dtlshowdbkeys}[1]{%
\expandafter\showthe\csname dtlkeys@#1\endcsname}
\newcommand*{\dtlshowtype}[2]{%
  \DTLgetdatatype{\@dtl@type}{#1}{#2}\show\@dtl@type
}
\endinput
%%
%% End of file `datatool.sty'.
