%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% This is file 'skeyval.sty', version 1.1a, 2012/10/16.                    %
%                                                                          %
% This package and accompanying files may be distributed and/or            %
% modified under the conditions of the LaTeX Project Public License,       %
% either version 1.3 of this license or 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.                                             %
%                                                                          %
% The LPPL maintenance status of this software is 'author-maintained'.     %
%                                                                          %
% This software is provided 'as it is', without warranty of any kind,      %
% either expressed or implied, including, but not limited to, the          %
% implied warranties of merchantability and fitness for a particular       %
% purpose.                                                                 %
%                                                                          %
% The following files constitute the skeyval bundle and must be            %
% distributed as a whole:                                                  %
%                                                                          %
%  readme, skeyval.sty, skeyval-core.tex, skeyval-for.tex,                 %
%  skeyval-view.sty, skeyval-ltxpatch.sty, skeyval-ltxcmds.tex,            %
%  skeyval-pstkey.sty, skeyval-pstkey.tex, skeyval-testclass.cls,          %
%  and skeyval-testpkg.sty.                                                %
%                                                                          %
% Copyright (c) 2010-2012 Ahmed Musa (amusa22@gmail.com).                  %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\begingroup
\catcode035 06 % #
\catcode064 11 % @
\catcode123 01 % {
\catcode125 02 % }
\catcode044 12 % ,
\def\skv@prova{\endgroup
  \def\do##1,{%
    \ifx\do##1\else
      \catcode##1\string=\the\catcode##1\relax
      \expandafter\do
    \fi
  }%
  \edef\skv@restorecodes{\do35,64,123,125,61,59,13,\do,}%
}
\skv@prova

\edef\skv@restorecodes{%
  \unexpanded\expandafter{\skv@restorecodes}%
  \endlinechar\the\endlinechar\relax
}
\endlinechar13 %
\catcode035 06 % #
\catcode064 11 % @
\catcode123 01 % {
\catcode125 02 % }
\catcode061 12 % =
\catcode044 12 % ,
\def\do#1=#2,{%
  \ifx\do#1\else
    \edef\skv@restorecodes{%
      \unexpanded\expandafter{\skv@restorecodes}%
      \catcode#1=\the\catcode#1\relax
    }%
    \catcode#1=#2\relax
    \expandafter\do
  \fi
}
\do 032=10,033=12,036=03,038=04,040=12,041=12,042=12,043=12,%
  059=12,045=12,047=12,058=12,063=12,091=12,093=12,126=13,\do=,%

\ProvidesPackage{skeyval}[2012/10/16 v1.1a Robust key-value parser (AM)]
\NeedsTeXFormat{LaTeX2e}[2011/06/27]

\input skeyval-core

\skvrobustdef*\skvAfterEndPackage{%
  \skvifcsdefTF{\@currname.\@currext-skv@endpkghook}{}{%
    \@namedef{\@currname.\@currext-skv@endpkghook}{}%
  }%
  \expandafter\g@addto@macro
  \csname\@currname.\@currext-skv@endpkghook\endcsname
}
\skvrobustdef*\skvAfterPackage#1{%
  \skvafterbegindocument{%
    \skvifcsdefTF{ver@#1.\@pkgextension}{}{%
      \skv@warn{Package '#1' was never loaded}%
    }%
  }
  \skvifcsdefTF{ver@#1.\@pkgextension}{%
    \@firstofone
  }{%
    \skvappendtomacro{#1.\@pkgextension-skv@endpkghook}%
  }%
}
\xdef\@popfilename{%
  \unexpanded{%
    \csname\@currname.\@currext-skv@endpkghook\endcsname
    \expandafter\let
    \csname\@currname.\@currext-skv@endpkghook\endcsname\relax
  }%
  \unexpanded\expandafter{\@popfilename}%
}
\skvrobustdef*\skv@getdocumentclass{%
  \skv@swafalse
  \ifx\@filelist\@undefined\else
    \ifx\@filelist\relax\else
      \ifx\@filelist\@gobble\else\skv@swatrue\fi
  \fi\fi
  \ifskv@swa
    \skvcommaparse*\@filelist\skv@tempa{%
      \filename@parse\skv@tempa
      \ifx\filename@ext\@clsextension
        \skvifcsdefFT{opt@\filename@area\filename@base.\filename@ext}{}{%
          \edef\skv@documentclass{%
            \filename@area\filename@base.\filename@ext
          }%
        }%
      \fi
      \ifx\skv@documentclass\@undefined\else\skvbreakloop\fi
    }%
  \fi
}
\skv@getdocumentclass
% Filter class options to remove those with '=':
\skvrobustdef*\skv@filterclassoptions{%
  \skv@swafalse
  \ifx\@classoptionslist\@undefined\else
    \ifx\@classoptionslist\relax\else\skv@swatrue\fi
  \fi
  \ifskv@swa
    \let\skv@filterclassoptions\relax
    \skvkvnormalize\@classoptionslist
    \let\skv@origclassoptlist\@classoptionslist
    \let\skv@classoptionslist\@classoptionslist
    \let\@classoptionslist\@empty
    \skvcommaloop*\skv@origclassoptlist\skv@tempa{%
      \skvxifinTF{=}{\skvexpandonce\skv@tempa}{}{%
        \skvaddtolist*\@classoptionslist\skv@tempa
      }%
    }%
    \def\@fileswith@ptions##1[##2]##3{%
      \edef\skv@tempa{\unexpanded{##3}}%
      \skvcsvnormalize\skv@tempa
      % The following packages need access to the original
      % \@classoptionslist.
      \skvcommaloop{xkeyval,kvoptions,keyval2e,ltxkeys}\skv@prova{%
        \skvxifinTF{,\skv@prova,}{,\skv@tempa,}{%
          \let\@classoptionslist\skv@origclassoptlist
          \skvbreakloop
        }{}%
      }%
      \skvifnextchar[{\@fileswith@pti@ns##1[##2]##3}%
        {\@fileswith@pti@ns##1[##2]##3[]}%
    }%
  \fi
}
\skvifdefFT\skv@documentclass{%
  \let\skv@documentclass\@empty
  \let\skv@classoptionslist\@empty
  \edef\@popfilename{%
    \skvexpandonce\@popfilename\skv@filterclassoptions
  }%
}{%
  \skv@filterclassoptions
}
\skvrobustdef*\skvbeforebegindocument{%
  \skvgappendtomacro\skv@beforebegindoc
}
\skvnewdef*\skv@beforebegindoc{}
\skvprependtomacro\document{%
  \endgroup
  \let\skvbeforebegindocument\@firstofone
  \skv@beforebegindoc
  \gdef\skvbeforebegindocument{\skv@notprerr\skvbeforebegindocument}%
  \global\let\skv@beforebegindoc\relax
  \begingroup
}
\skvrobustdef*\skvafterbegindocument{%
  \skvgappendtomacro\skv@afterbegindoc
}
\skvnewdef*\skv@afterbegindoc{}
\skvgappendtomacro\document{%
  \let\skvafterbegindocument\@firstofone
  \skv@afterbegindoc
  \gdef\skvafterbegindocument{\skv@notprerr\skvafterbegindocument}%
  \global\let\skv@afterbegindoc\relax
  \ignorespaces
}
\skvrobustdef*\skv@notprerr#1{%
  \@latex@error{Command \detokenize{#1} should be used only
    in preamble}\@ehd
}
\skvnewdef*\skv@everypagehook{}
\skvrobustdef*\skvatbegineverypage{\skvgappendtomacro\skv@everypagehook}
\skvafterbegindocument{%
  \let\skv@savedoutputpage\@outputpage
  \def\@outputpage{%
    \let\skv@savedbegindvi\@begindvi
    \def\@begindvi{%
      \skv@everypagehook
      \skv@savedbegindvi
    }%
    \skv@savedoutputpage
    \let\@begindvi\skv@savedbegindvi
  }%
}

\skvnewdef*\skv@preamblecmdhook{}
\skvrobustdef*\skvonlypreamble#1{%
  \def\do##1{%
    \skvxifinTF{\detokenize{\do##1}}{\skvoxdetok\skv@preamblecmdhook}{%
      \skv@warn{Command '\noexpand##1' multiply
        \MessageBreak submitted to \string\skvonlypreamble: ignored}%
    }{%
      \xdef\skv@preamblecmdhook{%
        \skvexpandonce\skv@preamblecmdhook
        \unexpanded{\do##1}%
      }%
    }%
  }%
  \skvcommaparse{#1}\skv@prova{%
    \expandafter\do\expandafter{\skv@prova}%
  }%
}
\AtEndOfPackage{%
  \skvafterbegindocument{%
    \def\do#1{%
      \skvifdefTF#1{%
        \gdef#1{\@latexerr{'\string#1' is a preamble command}\@ehd}%
      }{%
        \@@warning{Undefined command '\unexpanded{#1}'
          appeared in \string\skvonlypreamble}%
      }%
    }%
    \skv@preamblecmdhook
    \let\skv@preamblecmdhook\relax
    \let\do\relax
  }%
}

%%+++++++++++++++++ Utilities for handling options ++++++++++++++++%%

% \skvunknownoptionhandler[<prefixes>]<<families>>{<handler>}
%
\skvrobustdef*\skvunknownoptionhandler{%
  \skv@testopt\skv@unknownoptionhandler\skv@defaultpref
}
\skvrobustdef*\skv@unknownoptionhandler[#1]{%
  \skvifnextchar<{\skv@unkn@wnoptionhandler{#1}}%
    {\skv@unkn@wnoptionhandler{#1}<\@currname.\@currext>}%
}
\skvrobustdef*\skv@unkn@wnoptionhandler#1<#2>{%
  \skv@unknownkeyhandler[#1]{#2}%
}


\skvrobustdef*\skv@testopte#1{\skv@testopta{\skv@t@stopte{#1}}}
\skvrobustdef*\skv@t@stopte#1{\skv@testopt{\skv@t@st@pte{#1}}\skv@defaultpref}
\skvrobustdef*\skv@t@st@pte#1[#2]{%
  % Only one prefix is allowed:
  \skvxifinTF{,}{\detokenize{#2}}{%
    \skv@err{Only one prefix is allowed, but you gave '#2'}\@ehd
  }{%
    \skv@makeprefix{#2}%
    \skvifnextchar<{\skv@@t@st@pte{#1}}%
      {\skv@@t@st@pte{#1}<\@currname.\@currext>}%
  }%
}
\skvrobustdef*\skv@@t@st@pte#1<#2>{%
  \edef\skv@fams{#2}%
  \skvxifinTF{,}{\detokenize{#2}}{%
    \skvcsvnormalize\skv@fams
  }{%
    \skvdespacecontent\skv@fams
  }%
  \skv@testopt{#1}{}%
}

\skvrobustdef*\skveveryunknownoption{\skvdeclareoption*}
% \skvdeclareoption[<pref>]<<fam>>{<key>}[<defa>]{<callback>}
% \skvdeclareoption*{<message>}
\skvrobustdef*\skvdeclareoption{%
  \let\@fileswith@pti@ns\@badrequireerror
  \let\skvdefkey\skvordkey
  \skvifstar\skv@dox\skv@dox@a
}
% \skvdeclarevoidoption[<pref>]<<fam>>{<key>}[<defa>]{<callback>}
\skvrobustdef*\skvdeclarevoidoption{%
  \let\@fileswith@pti@ns\@badrequireerror
  \let\skvdefkey\skvvoidkey
  \skv@dox@a
}
% \skvdeclarebooloption[<pref>]<<fam>>[<mp>]{<key>}[<defa>]{<callback>}
\skvrobustdef*\skvdeclarebooloption{%
  \let\@fileswith@pti@ns\@badrequireerror
  \let\skvdefkey\skvboolkey
  \skv@dox@a
}
% \skvdeclarecmdoption[<pref>]<<fam>>[<mp>]{<key>}[<defa>]{<callback>}
\skvrobustdef*\skvdeclarecmdoption{%
  \let\@fileswith@pti@ns\@badrequireerror
  \let\skvdefkey\skvcmdkey
  \skv@dox@a
}

% Our default action for unknown options is tied to \@currname & \@currext:
\skvrobustdef\skv@dox#1{%
  \skvcsedef{skv@dox@\@currname @\@currext}{%
    \unexpanded{%
      \begingroup
      \ifx\skvcurrentvalue\skv@novaluetoks
        \def\skvcurrentvalue{no value}%
      \fi
      \@onelevel@sanitize\CurrentOption
      \@onelevel@sanitize\skvcurrentvalue
      #1%
      \endgroup
    }%
  }%
}
\skvrobustdef*\skv@dox@a{\skv@testopt\skv@dox@b\skv@defaultpref}
\skvrobustdef*\skv@dox@b[#1]{%
  \skvifnextchar<%
    {\skv@dox@c{#1}}{\skv@dox@c{#1}<\@currname.\@currext>}%
}
\skvrobustdef*\skv@dox@c#1<#2>{\skvdefkey[#1]{#2}}

% Declare options with default values that will be used when the options
% are called without user values.
%
% \skvDeclarePassedOptions[<pref>]{<fam>}{<option>=<default>,...}
%
% Example:
%
%  \skvDeclarePassedOptions[KV]{fam}{%
%    hyperref={colorlinks,breaklinks},xcolor=svgnames
%  }
%
\skvrobustdef*\skvDeclarePassedOptions{%
  \skv@testopt\skv@declarepassedoptions\skv@defaultpref
}
\skvrobustdef*\skv@declarepassedoptions[#1]#2#3{%
  \skvparsekeyvals{#3}\skv@tempa{%
    \skvexpbracenext\skv@kvsplit\skv@tempa{%
      \skvdeclareoption[#1]<#2>{##1}[##2]{%
        \skvifcsdefTF{ver@##1.sty}{%
          \skv@warn{Package '##1' has been loaded and
            \MessageBreak now you're passing options to it.
            \MessageBreak Instruction ignored}%
        }{%
          \skvPassOptionsToPackage{####1}{##1}%
          \AtBeginDocument{%
            \skvifpackageloaded{##1}{}{%
              \skv@warn{Options were passed to package
                \MessageBreak '##1' but it was never loaded}%
            }%
          }%
        }%
      }%
    }%
  }%
}
% \skvPassOptionsToPackage{<opts>}{<pkg>}
\skvrobustdef*\skvPassOptionsToPackage{\skv@passoptions{sty}}
\skvrobustdef*\skvPassOptionsToClass{\skv@passoptions{cls}}
\skvrobustdef*\skv@passoptions#1#2#3{%
  \begingroup
  \edef\@elt{opt@\skvtrimspace{#3}.#1}%
  \skvcsxdef{\@elt}{%
    \skvifcsdefFT{\@elt}{}{\@nameuse{\@elt},}%
    \skvtrimspace{#2}%
  }%
  \endgroup
}

% \skvDeclarePassedOptionsLoadPackage
%    [<pref>]{<fam>}{<option>=<default>,...}
%
\skvrobustdef*\skvDeclarePassedOptionsLoadPackage{%
  \skv@testopt\skv@declarepassedoptions@load\skv@defaultpref
}
\skvrobustdef*\skv@declarepassedoptions@load[#1]#2#3{%
  \skvparsekeyvals{#3}\skv@tempa{%
    \skvexpbracenext\skv@kvsplit\skv@tempa{%
      \skvdeclareoption[#1]<#2>{##1}[##2]{%
        \skvifcsdefTF{ver@##1.sty}{%
          \skv@warn{Package '##1' has been loaded and
            \MessageBreak now you've asked for it to be
            \MessageBreak loaded again. Instruction ignored}%
        }{%
          \skvafterprocessoptions{%
            \RequirePackage[####1]{##1}%
          }%
        }%
      }%
    }%
  }%
}

% \skvexecuteoptions[<pref>]<fams>[<na>]{<kvlist>}
% \skvexecuteoptions+[<pref>]<fams>[<na>]{<kvlist>}
%
% This has no star (*) variant; any star suffix is quietly ignored.
%
\skvrobustdef*\skvexecuteoptions{%
  \skv@testopte{\skv@stfalse\skv@setkeys@a}%
}

% \skvprocessoptions*+[<pref>]{<fams>}[<na>]
%
% 1. If not using LaTeX, then no processing of options.
% 2. The plus (+) variant of \skvprocessoptions will process the options
%    in all the listed families. The star (*) form of \skvprocessoptions
%    -- like in LaTeX2e -- will also copy and use class options.
% 3. Class options are always processed first, but class options that ocurr
%    also as local/package options are dropped from the list of options
%    to be processed. That is, package options always take priority over
%    class options.
% 4. The \ProcessOptionsX of xkeyval package doesn't expect any plus (+)
%    suffix: it processes options only in a single family.
%
\skvrobustdef*\skvprocessoptions{\skv@testopte\skv@pox}
\skvrobustdef*\skv@pox[#1]{%
  \skv@inpoxtrue
  \let\@fileswith@pti@ns\@badrequireerror
  \edef\skv@userclassorpackage{\@currname.\@currext}%
  \begingroup
  \let\skv@clsoptsfound\@empty
  \let\skv@clsorpkgopts\@empty
  \let\skv@exitpoxkeys\@empty
  \skvifxTF\skv@userclassorpackage\skv@documentclass{%
    \let\@unusedoptionlist\skv@classoptionslist
  }{%
    \ifcase0\ifx\skv@classoptionslist\@empty\else
      \ifx\skv@classoptionslist\relax\else\ifskv@st1\fi\fi\fi\relax
      \skv@swafalse
    \else
      \skv@swatrue
    \fi
    \skvifboolFT{skv@swa}{}{%
      \def\ifkeyundef##1##2##3{\skvexpanded{\skvifkeydefFT[##1]{##2}{##3}}}%
      \skvcommaloop*\skv@classoptionslist\CurrentOption{%
        \expandafter\expandafter\expandafter
          \skv@g@tkeyname\CurrentOption=\skv@nil\skvcurrentkey
        % Test if key is defined in one of the families. The search will
        % stop as soon as the key is found in any of the families.
        \ifkeyundef\skvcurrentprefix\skv@fams\skvcurrentkey{}{%
          \edef\skv@clsoptsfound{%
            \skvexpandonce\skv@clsoptsfound
            \ifx\skv@clsoptsfound\@empty\else,\fi
            \skvexpandonce\CurrentOption
          }%
          \expandafter\skv@useoption\expandafter{\CurrentOption}%
        }%
      }%
      \ifx\skv@clsoptsfound\@empty\else\skvafterfi
        \skvexpbracenext\skv@getkeynames\skv@clsoptsfound\skv@tempd
        \skvexpbracenext\skv@getpoxkeys\skv@tempd
      \fi
    }%
  }%
  \skvletcs\skv@clsorpkgopts{opt@\@currname.\@currext}%
  \skvifxTF\skv@clsorpkgopts\@empty{}{%
    \skvifxTF\skv@clsorpkgopts\relax{}{%
      \skvexpbracenext\skv@getkeynames\skv@clsorpkgopts\skv@tempd
      \skvexpbracenext\skv@getpoxkeys\skv@tempd
    }%
  }%
  % Package options have higher priority than class options. Hence
  % filter class options \skv@clsoptsfound that are also present
  % as package options \skv@clsorpkgopts:
  \ifcase0\ifx\skv@clsoptsfound\@empty\else
    \ifx\skv@clsorpkgopts\@empty\else
      \ifx\skv@clsorpkgopts\relax\else1\fi\fi\fi\relax
  \else\skvafterfi
    \skvifxTF\skv@userclassorpackage\skv@documentclass{}{%
      \skvcommaloop*\skv@clsoptsfound\CurrentOption{%
        \expandafter\expandafter\expandafter
          \skv@g@tkeyname\CurrentOption=\skv@nil\skv@tempa
        \skvxifinTF{,\skvoxdetok\skv@tempa,}{,\skvoxdetok\skv@tempd,}{}{%
          \edef\skv@clsorpkgopts{%
            \skvexpandonce\skv@clsorpkgopts,\skvexpandonce\CurrentOption
          }%
        }%
      }%
    }%
  \fi
  \skvexpanded{\endgroup
    \skv@exitpoxkeys
    \skvcmdexit\@unusedoptionlist
    % There may be preset keys even when \skv@clsorpkgopts is empty:
    \skvsetkeys\ifskv@pl+\fi[\skvcurrentprefix]{\skv@fams}[#1]%
      {\skvexpandonce\skv@clsorpkgopts}%
  }%
  \skvcslet{skv@dox@\@currname @\@currext}\relax
  \skvinitializermkeys*\skvcurrentprefix\skv@fams
  \skv@inpoxfalse
  \let\@fileswith@pti@ns\@@fileswith@pti@ns
  \AtEndOfPackage{\let\@unprocessedoptions\relax}%
  \csname skv@\@currname @\@currext @afterprocess@hook\endcsname
  \skvcslet{skv@\@currname @\@currext @afterprocess@hook}\relax
}

% \skvprocessoptionswithclassoptions*+[<pref>]{<fams>}[<na>]
%
% 1. The star (*) suffix is always assumed present, even when the
%    user hasn't put it.
%
\skvrobustdef*\skvprocessoptionswithclassoptions{%
  \skv@testopte\skv@pox@copyclassoptions
}
\skvrobustdef*\skv@pox@copyclassoptions[#1]{\skv@sttrue\skv@pox[#1]}

% \skvprocessoptionswithoutclassoptions*+[<pref>]{<fams>}[<na>]
%
% 1. The star (*) suffix is always assumed absent, even when the
%    user has put it.
%
\skvrobustdef*\skvprocessoptionswithoutclassoptions{%
  \skv@testopte\skv@pox@nocopyclassoptions
}
\skvrobustdef*\skv@pox@nocopyclassoptions[#1]{\skv@stfalse\skv@pox[#1]}

% \skv@getpoxkeys{<keys>}
%
% Get pox keys (ie, keys processed as options) from package or
% class options.
\skvrobustdef*\skv@getpoxkeys#1{%
  \begingroup
  \def\xiftest{%
    \skvexpanded{%
      \noexpand\skvifkeyinfamiliesFT
        [\skvcurrentprefix]{\skv@fams}{\skvcurrentkey}%
    }%
  }%
  \skvcommaloop{#1}\skvcurrentkey{%
    \xiftest{}{%
      % \skv@header is formed in the search for the key:
      \skvletcs\skv@prova{\skv@header.@poxkeys}%
      \skvifdefTF\skv@prova{%
        \skvxifinTF{,\skvoxdetok\skvcurrentkey,}{,\skvoxdetok\skv@prova,}{}{%
          \skvcsedef{\skv@header.@poxkeys}{\skv@prova,\skvcurrentkey}%
        }%
      }{%
        \skvcsedef{\skv@header.@poxkeys}{\skvcurrentkey}%
      }%
      \skvxifinTF{\skvoxdetok\skv@header}{\skvoxdetok\skv@exitpoxkeys}{}{%
        \edef\skv@exitpoxkeys{%
          \skvexpandonce\skv@exitpoxkeys
          \noexpand\skvcsexit{\skv@header.@poxkeys}%
        }%
      }%
    }%
  }%
  \skvexpanded{\endgroup
    \skvcmdexit\skv@exitpoxkeys
    \skv@exitpoxkeys
  }%
}

% +++++++++ Utilities for handling options via \directkeys +++++++++%

\skvrobustdef*\dirkeys@declareoptions@a{%
  \let\@fileswith@pti@ns\@badrequireerror
  \skv@dox
}
\skvrobustdef*\dirkeys@declareoptions@b#1{%
  \let\@fileswith@pti@ns\@badrequireerror
  \skv@inopttrue
  \begingroup
  \edef\skv@tempb{\unexpanded{#1}}%
  \def\skv@tempa{}%
  \def\do##1##2{%
    \edef\skv@tempa{%
      \skvexpandonce\skv@tempa
      \skvdefinekeys\ifskv@handlerswa*\fi[##1]{##2}%
      [\dirkeys@holderprefixtoks]{\skvexpandonce\skv@tempb}%
    }%
  }%
  \dirkeys@getcurrentroots\do
  \expandafter\endgroup\skv@tempa
  \skv@inoptfalse
}
% % \dirkeys@executeoptions{<options>}
%
% 1. Ececute options on all the prevailing paths. If any of
%    the options isn't found on a path, report error (ie,
%    don't save the key to the list of 'remaining keys'). Unknown
%    options should be flagged by an error immediately.
% 2. There is no plus (+) variant for this command/handler.
% 3. It is the user's responsibility to ensure that keys exist on
%    current paths. This is easier to enforce if there is only one
%    current path (prefix and family).
%
\skvrobustdef*\dirkeys@executeoptions#1{%
  \skv@inopttrue
  \begingroup
  % Don't confuse parameter characters in #1 with those of \do:
  \edef\skv@tempb{\unexpanded{#1}}%
  \def\skv@tempa{}%
  \def\do##1##2{%
    \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}%
    \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}%
    \edef\skv@tempa{%
      \skvexpandonce\skv@tempa
      \skvsetkeys[##1]{##2}[\skv@igkeys]{\skvexpandonce\skv@tempb}%
    }%
  }%
  \dirkeys@getcurrentroots\do
  \expandafter\endgroup\skv@tempa
  \skv@inoptfalse
}

% \dirkeys@executeoptions@b{<options>}
%
% 1. Ececute options in all the prevailing families. If any of
%    the options isn't found in at least one family, report error (ie,
%    don't save the key to the list of 'remaining keys'). Unknown options
%    should be flagged immediately.
% 2. The plus (+) variant will execute the option in each family in
%    which the option is found.
% 3. The difference between \dirkeys@executeoptions and
%    \dirkeys@executeoptions@b is that in \dirkeys@executeoptions
%    the prefixes can be more than one. Options will be executed for
%    all combinations of prefixes and families.
% 4. Prevailing prefixes can't be more than one.
%
\skvrobustdef*\dirkeys@executeoptions@b#1{%
  \skv@inopttrue
  \begingroup
  \dirkeys@collectpaths
  \skvexpanded{\endgroup
    \skvsetkeys+[\skv@tempa]{\skv@tempb}[\skv@tempc]%
  }{#1}%
  \skv@inoptfalse
}
\skvrobustdef*\dirkeys@collectpaths{%
  \skvemptify{\do\skv@tempa\do\skv@tempb\do\skv@tempc}%
  \def\do##1##2{%
    \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}%
    \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}%
    \skvxifinTF{,##1,}{,\skv@tempa,}{}{%
      \edef\skv@tempa{\skv@tempa\ifx\skv@tempa\@empty\else,\fi##1}%
    }%
    \skvxifinTF{,##2,}{,\skv@tempb,}{}{%
      \edef\skv@tempb{\skv@tempb\ifx\skv@tempb\@empty\else,\fi##2}%
    }%
    \edef\skv@tempc{%
      \skv@tempc\ifx\skv@tempc\@empty\else,\fi\skv@igkeys
    }%
  }%
  \dirkeys@getcurrentroots\do
  \skvifelementcount*\skv@tempa\tw@
    {\skv@err{You can't submit more than one prefix here}\@ehd}{}
}
\skvrobustdef*\dirkeys@processoptions{%
  \skv@inopttrue
  \begingroup
  \def\skv@tempa{}%
  \def\do##1##2{%
    \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}%
    \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}%
    \edef\skv@tempa{%
      \skvexpandonce\skv@tempa
      \skvprocessoptions\ifskv@handlerswa*\fi
      [##1]<##2>[\skv@igkeys]%
    }%
  }%
  \dirkeys@getcurrentroots\do
  \expandafter\endgroup\skv@tempa
  \skv@inoptfalse
}
\skvrobustdef*\dirkeys@processoptions@b{%
  \skv@inopttrue
  \begingroup
  \dirkeys@collectpaths
  \skvexpanded{\endgroup
    \skvprocessoptions\ifskv@handlerswa*\fi
    +[\skv@tempa]<\skv@tempb>[\skv@tempc]%
  }%
  \skv@inoptfalse
}

% ++++++++ Keys for the handler <.mega process options> +++++++++ %

\directkeys*{%
  .prefix=SKV,
  .family=megapox,
  .holder prefix=dirkeys@pox@,
  .initialize keys after define=true,
  .new keys={
    .ord/.ignore options//
      \def\dirkeys@pox@igkeys{#1}
      \skvstripouterbraces{2}\dirkeys@pox@igkeys
    ,
    .ord/.options prefix/\skv@defaultpref/
      \skvxifinTF{,}{\detokenize{#1}}{
        \skv@err{Only one prefix is allowed in processing options}\@ehd
      }{
        \def\dirkeys@pox@pref{#1}
        \skvstripouterbraces{2}\dirkeys@pox@pref
      }
    ,
    .ord/.options families/\@currname.\@currext/
      \edef\dirkeys@pox@fams{#1}
      \skvstripouterbraces{2}\dirkeys@pox@fams
    ,
    .ord/.copy class options/true/
      \edef\dirkeys@pox@copyclass{\skvifstrcmpTF{#1}{true}{00}{01}}
    ,
  },
  .styles={
    .prefix/.options prefix=#1,
    .options family/.options families=#1,
    .family/.options families=#1,
    .families/.options families=#1,
    .include class options/.copy class options=#1,
  },
}
%\skvshowcs{SKV/megapox/.options family.@cbk}
%\skvshowcs{SKV/megapox/.pref.@cbk}

\skvrobustdef*\dirkeys@megaprocessoptions#1{%
  \skvpushfunctions\dirkeys@megaprocessoptions{%
    \do\dirkeys@pox@pref\do\dirkeys@pox@fams
    \do\dirkeys@pox@igkeys\do\dirkeys@pox@copyclass
  }\skv@gendepth
  \skv@inopttrue
  \skvsetkeys[SKV]{megapox}{#1}%
  \skvexpanded{%
    \skvprocessoptions\if\dirkeys@pox@copyclass*\fi+%
    [\dirkeys@pox@pref]<\dirkeys@pox@fams>[\dirkeys@pox@igkeys]%
  }%
  \skv@inoptfalse
  \skvpopfunctions\dirkeys@megaprocessoptions\skv@gendepth
}

% +++++++++++++ Handlers for processing options ++++++++++++++ %

\directkeys*{%
  .new handlers={
    .action for unknown options=\dirkeys@declareoptions@a{#1},
    .declare options={
      \skv@handlerswafalse\dirkeys@declareoptions@b{#1}
    },
    .new options={
      \skv@handlerswatrue\dirkeys@declareoptions@b{#1}
    },
    .execute options={
      \dirkeys@executeoptions{#1}
    },
    .execute options+={
      \dirkeys@executeoptions@b{#1}
    },
    .execute options*={
      \skv@err
        {Handler <.execute options*> is undefined}
        {Handler <.execute options> has no star (*) variant,
        \MessageBreak since we don't want to ignore unknown
        \MessageBreak options from within package or class file.}%
    },
    .execute options*+={
      \skv@err
        {Handler <.execute options*+> is undefined}
        {Handler <.execute options+> has no star (*) variant,
        \MessageBreak since we don't want to ignore unknown
        \MessageBreak options from within package or class file.}%
    },
    % 1. All <.process options> handlers will filter out ignored keys.
    % 2. <.process options*> will copy class options.
    % 3. <.process options+> will set options in all the active families
    %    in which the options exist.
    % 4. <.process options*+> will copy class options and set options in
    %    all the active families in which the options are found.
    .process options={
      \skv@handlerswafalse\dirkeys@processoptions
    },
    .process options*={
      \skv@handlerswatrue\dirkeys@processoptions
    },
    .process options+={
      \skv@handlerswafalse\dirkeys@processoptions@b
    },
    .process options*+={
      \skv@handlerswatrue\dirkeys@processoptions@b
    },
    % The handler <.mega process options> will:
    % 1. Search all families in its key <families>.
    % 2. Not perform filtering of ignored paths and keys; in fact, will not
    %    use active paths and keys.
    % 3. The handler '.mega process options' has the keys <ignore options>,
    %    <options prefix>, <options families>, and <copy class options>.
    %    These keys have aliases.
    %    See an example later in this file.
    .mega process options={
      \dirkeys@megaprocessoptions{#1}
    },
    .mega process options*={
      \dirkeys@megaprocessoptions{#1,copy class options}
    },
  },
  .handler let={
    .action for unknown option=.action for unknown options,
    .every unknown option=.action for unknown options,
    .define options=.declare options,
    .processoptions=.process options,
    .processoptions*=.process options*,
    .copy class options and process options in all active families=
      .process options*+,
    .copy class options and process options in all families=
      .process options*+,
    .copy class options and process options=.process options*,
    .executeoptions=.execute options,
  },
}
%\skvshowcs{dirkeys@handler@.every unknown option}

% Loading a package while in options section is illegal. The command
% \skvafterprocessoptions can be used to defer the loading of packages
% till after the options section:
\skvrobustdef*\skvafterprocessoptions{%
  \expandafter\skvgappendtomacro
  \csname skv@\@currname @\@currext @afterprocess@hook\endcsname
}
\skvnewlet\skvifpackageloaded\@ifpackageloaded

\def\skv@visiteduseoptions{01}
\skvrobustdef*\skv@useoption#1{%
  \if\skv@visiteduseoptions\else
    \skvcsvnormalize\@unusedoptionlist
    \def\skv@visiteduseoptions{00}%
  \fi
  \begingroup
  \@onelevel@sanitize\@unusedoptionlist
  \skv@kvosplit{\detokenize{#1}}{%
    \edef\CurrentOption{\skvtrimspace{##1}}%
    \def\skv@tempa{}%
    \skvcommaloop*\@unusedoptionlist\skv@prova{%
      \skv@kvosplit\skv@prova{%
        \edef\reserved@a{\skvtrimspace{####1}}%
        \ifx\reserved@a\CurrentOption\else
          \edef\skv@tempa{%
            \skv@tempa\ifx\skv@tempa\@empty\else,\fi\skv@prova
          }%
        \fi
      }%
    }%
    \let\@unusedoptionlist\skv@tempa
  }%
  \skvaftergroupdef\@unusedoptionlist\endgroup
}
\skvonlypreamble{%
  \skvdeclareoption,\skvexecuteoptions,\skvprocessoptions,\skv@useoption,
  \dirkeys@declareoptions@a,\dirkeys@declareoptions@b,
  \dirkeys@megaprocessoptions,\dirkeys@processoptions,
  \dirkeys@processoptions@b,\skvprocessoptionswithclassoptions,
  \skvprocessoptionswithoutclassoptions,\dirkeys@executeoptions,
  \dirkeys@executeoptions@b
}

%+++++++++++++++++ This package's options section ++++++++++++++++++%

\skvrobustdef*\setupskeyval{\skvsetkeys[SKV]{skeyval}}
\skv@inoptionsectrue

%\skvshowcs{dirkeys@handler@.every unknown option}

\directkeys*{%
  .every unknown option={
    \@onelevel@sanitize\CurrentOption
    \PackageWarning{skeyval}{Unknown option '\CurrentOption' ignored}%
  },
  .prefix=SKV,
  .family=skeyval,
  .holder prefix=skv@,
  .new options={
    .bool/verbose/true,
    .bool/tracingkeys/true,
    .ord/{keyparser,key parser}/{,}/
      \def\skv@keyparser{#1}%
      \skvstripouterbraces{2}\skv@keyparser,
    .bool/compatibility/true/
      \ifskv@compatibility
        \skvafterprocessoptions{%
          \skvifpackageloaded{skeyval-bc}{}{%
            \RequirePackage{skeyval-bc}%
          }
        }%
      \fi
    ,
  },
  .execute options={
    tracingkeys=false,keyparser,verbose=false
  },
  .mega process options={
    .options prefix=SKV,
    .options families={skeyval,definekeys},
    .ignore options={},
    .copy class options,
  },
}
%\skvshowcs{SKV/skeyval/keyparser.@cbk}

\skv@inoptionsecfalse

\skv@restorecodes
\endinput
