%% mciteplus.sty
%% enhanced mcite
%% Version 1.0, 2008/01/15
%%
%% Copyright (c) 2008 Michael Shell
%% Support site:
%% http://www.michaelshell.org/tex/mciteplus/
%%
%%*************************************************************************
%% Legal Notice:
%% This code is offered as-is without any warranty either expressed or
%% implied; without even the implied warranty of MERCHANTABILITY or
%% FITNESS FOR A PARTICULAR PURPOSE! 
%% User assumes all risk.
%% In no event shall any contributor to this code be liable for any damages
%% or losses, including, but not limited to, incidental, consequential, or
%% any other damages, resulting from the use or misuse of any information
%% contained here.
%%
%% All comments are the opinions of their respective authors.
%%
%% This work is distributed under the LaTeX Project Public License (LPPL)
%% ( http://www.latex-project.org/ ) version 1.3, and may be freely used,
%% distributed and modified. A copy of the LPPL, version 1.3, is included
%% in the base LaTeX documentation of all distributions of LaTeX released
%% 2003/12/01 or later.
%% Retain all contribution notices and credits.
%% ** Modified files should be clearly indicated as such, including  **
%% ** renaming them and changing author support contact information. **
%%**********************************************************************




\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mciteplus}[2008/01/15 v1.0 enhanced mcite]

% package option conditionals
\newif\if@OPTIONmcitenohooks\@OPTIONmcitenohooksfalse
\newif\if@OPTIONmcitechapterbibrootbib\@OPTIONmcitechapterbibrootbibfalse
\newif\if@OPTIONmcitedebug\@OPTIONmcitedebugfalse


\DeclareOption{debug}{\global\@OPTIONmcitedebugtrue}
\DeclareOption{nohooks}{\global\@OPTIONmcitenohookstrue}
% use ds@ for chapterbibrootbib to keep option local
\def\ds@chapterbibrootbib{\global\@OPTIONmcitechapterbibrootbibtrue}

\ProcessOptions

% first entry in citation or bibliography flag
\newif\if@mcitefirstentry
% first head entry in citation or bibliography flag
\newif\if@mcitefirstheadentry
% entry using star (is a tail) flag
\newif\if@mcitestarentry
% head declared more than once flag
\newif\if@mciteheadredeclared
% sublist block is open flag
\newif\if@mcitesublistopen
% bst indicates that end punctuation would normally be used
\newif\ifmciteBstWouldAddEndPunct


% flag to indicate that the label widths have changed
% and that LaTeX has to be rerun
\newif\if@mciteLaTeXrerun\@mciteLaTeXrerunfalse

% flag to indicate the use of the first optional argument of a macro
\newif\ifmciteMacroOptArgI\mciteMacroOptArgIfalse
% flag to indicate the use of the first optional argument of a macro (local, non user, use)
\newif\if@mciteLocalMacroOptArgI\@mciteLocalMacroOptArgIfalse
% flag to indicate the use of the second optional argument of a macro
\newif\ifmciteMacroOptArgII\mciteMacroOptArgIIfalse
% flag to indicate the use of the star form of a macro
\newif\ifmciteMacroStarForm\mciteMacroStarFormfalse
% flag to indicate the use of the star form of the \cite forwarding macro
\newif\ifmciteCiteStarFwdArg\mciteCiteStarFwdArgfalse
% flag to indicate the use of the sec ID argument for the \cite forwarding macro
\newif\if@mciteCiteSecIDArg\@mciteCiteSecIDArgfalse

% flag to indicate the use of the first optional argument of a bibitem
\newif\ifmciteBibitemOptArgI\mciteBibitemOptArgIfalse
% flag to indicate the use of the first optional argument of the current head bibitem
\newif\ifmciteCurheadBibitemOptArgI\mciteCurheadBibitemOptArgIfalse


% temporary token list
\newtoks\@mcitetmptoksA
% macro to add (unexpanded) to token list
\def\@mciteAppendToTmpToksA#1{\@mcitetmptoksA=\expandafter{\the\@mcitetmptoksA#1}}


% temporary dimen registers
\newdimen\@mcitetmpdima
\newdimen\@mcitetmpdimb

% temporary count registers
\newcount\@mcitetmpcnta
\newcount\@mcitetmpcntb

% count of entries
\newcounter{mcitebibitemcount}
\setcounter{mcitebibitemcount}{0}
% count of sub items
\newcounter{mcitesubitemcount}


% the default entry punctuation and separator
\providecommand{\mcitedefaultmidpunct}{;\space}
\providecommand{\mcitedefaultendpunct}{.}
\providecommand{\mcitedefaultseppunct}{\relax}
% the default sublist label, begin and end macros
\providecommand{\mcitedefaultsublistlabel}{\alph{mcitesubitemcount})\space}
\providecommand{\mcitedefaultsublistbegin}{\relax}
\providecommand{\mcitedefaultsublistend}{\relax}
% the default max width forms
\providecommand{\mcitedefaultmaxwidthbibitemform}{\arabic{mcitebibitemcount}}
\providecommand{\mcitedefaultmaxwidthbibitemforminit}{\mciteorgbibsamplelabel}
\providecommand{\mcitedefaultmaxwidthsubitemform}{\alph{mcitesubitemcount})}
\providecommand{\mcitedefaultmaxwidthsubitemforminit}{a)}

% sample label which is forwarded to \thebibliography
\def\mcitebibsamplelabel{\rule{\mcitemaxwidthbibitem sp}{0.2pt}}



% Aux and track handles
%
% aux used by \mcite
\def\mciteauxout{\@auxout}
% aux used within \mcitethebibliography
\def\mcitebibauxout{\@mainaux}
% current auxout in use
\def\@mcitecurauxout{\mciteauxout}

% This is the unique ID string used to track multiple bibliographies.
\def\mcitetrackID{main}
% for \mcitethebibliography
\def\mcitebibtrackID{main}
% current Track ID in use
\def\@mcitecurtrackID{\mcitetrackID}


% macros for letter code and string tests
\def\@mciteMacrod{d}
\def\@mciteMacron{n}
\def\@mciteMacros{s}
\def\@mciteMacrob{b}
\def\@mciteMacrof{f}
\def\@mciteMacroh{h}
\def\@mciteMacrobibitem{bibitem}
\def\@mciteMacrosubitem{subitem}



% sets the punctuation bst hooks
\long\def\mciteSetBstMidEndSepPunct#1#2#3{\long\def\mcitebstmidpunct{#1}\relax
                                     \long\def\mcitebstendpunct{#2}\long\def\mcitebstseppunct{#3}}
% sets the actual punctuation used
\long\def\mciteSetMidEndSepPunct#1#2#3{\long\def\mcitemidpunct{#1}\relax
                                  \long\def\mciteendpunct{#2}\long\def\mciteseppunct{#3}}

% sets the sublabel bst hooks
\long\def\mciteSetBstSublistLabelBeginEnd#1#2#3{\long\def\mcitebstsublistlabel{#1}\relax
\long\def\mcitebstsublistbegin{#2}\long\def\mcitebstsublistend{#3}}
% sets the actual sublabel used
\long\def\mciteSetSublistLabelBeginEnd#1#2#3{\long\def\mcitesublistlabel{#1}\relax
\long\def\mcitesublistbegin{#2}\long\def\mcitesublistend{#3}}




% sublist mode flags, b and first forms should be set to false unless \@mcitesublistmode is also true
\newif\if@mcitesublistmode\@mcitesublistmodefalse
\newif\if@mcitesublistmodeb\@mcitesublistmodebfalse
\newif\if@mcitesublistmodef\@mcitesublistmodeffalse
\newif\if@mcitesublistmodeh\@mcitesublistmodehfalse
% reset entry counter flag
\newif\ifmciteResetBibitemCount\mciteResetBibitemCounttrue
% error on unknown entries
\newif\ifmciteErrorOnUnknown\mciteErrorOnUnknowntrue


% BST can request a sublist mode using \mciteSetBstSublistMode, but user requests can override it:
% d = default, use current settings
% n = no sublist
% s = sublist
% b = sublistb
% f = sublistfirst
% h = sublistfirst, including single heads
% note that the changes here are local and will not be remembered outside of the \mcitethebibliography environment
\def\mciteSetBstSublistMode#1{\edef\@mcitetemp{#1}\relax
% only make changes if the user mode allows
\ifx\@mcitesublistmode\@mciteMacrod\relax
  \ifx\@mcitetemp\@mciteMacrod
    \def\@mcitebstsublistmode{d}\else
    \ifx\@mcitetemp\@mciteMacron
      \def\@mcitebstsublistmode{n}\@mcitesublistmodefalse\@mcitesublistmodebfalse\@mcitesublistmodeffalse\@mcitesublistmodehfalse\else
      \ifx\@mcitetemp\@mciteMacros
        \def\@mcitebstsublistmode{s}\@mcitesublistmodetrue\@mcitesublistmodebfalse\@mcitesublistmodeffalse\@mcitesublistmodehfalse\else
        \ifx\@mcitetemp\@mciteMacrob
          \def\@mcitebstsublistmode{b}\@mcitesublistmodetrue\@mcitesublistmodebtrue\@mcitesublistmodeffalse\@mcitesublistmodehfalse\else
          \ifx\@mcitetemp\@mciteMacrof
            \def\@mcitebstsublistmode{f}\@mcitesublistmodetrue\@mcitesublistmodebfalse\@mcitesublistmodeftrue\@mcitesublistmodehfalse\else
            \ifx\@mcitetemp\@mciteMacroh
              \def\@mcitebstsublistmode{h}\@mcitesublistmodetrue\@mcitesublistmodebfalse\@mcitesublistmodeftrue\@mcitesublistmodehtrue\else
              \PackageError{mciteplus}{Unknown mode `#1' in argument to \protect\mciteSetBstSublistMode}%
              {Only `d', `n', `s', `b', `f' and `h' are valid.}\relax
            \fi
          \fi
        \fi
      \fi
    \fi
  \fi
\fi}


% User can specify a sublist mode:
% d = default, use current settings, allow BST to choose
% n = no sublist
% s = sublist
% b = sublistb
% f = sublistfirst
% h = sublistfirst, including single heads
\def\mciteSetSublistMode#1{\edef\@mcitetemp{#1}\relax
\ifx\@mcitetemp\@mciteMacrod
  \def\@mcitesublistmode{d}\else
  \ifx\@mcitetemp\@mciteMacron
    \def\@mcitesublistmode{n}\@mcitesublistmodefalse\@mcitesublistmodebfalse\@mcitesublistmodeffalse\@mcitesublistmodehfalse\else
    \ifx\@mcitetemp\@mciteMacros
      \def\@mcitesublistmode{s}\@mcitesublistmodetrue\@mcitesublistmodebfalse\@mcitesublistmodeffalse\@mcitesublistmodehfalse\else
      \ifx\@mcitetemp\@mciteMacrob
        \def\@mcitesublistmode{b}\@mcitesublistmodetrue\@mcitesublistmodebtrue\@mcitesublistmodeffalse\@mcitesublistmodehfalse\else
        \ifx\@mcitetemp\@mciteMacrof
          \def\@mcitesublistmode{f}\@mcitesublistmodetrue\@mcitesublistmodebfalse\@mcitesublistmodeftrue\@mcitesublistmodehfalse\else
          \ifx\@mcitetemp\@mciteMacroh
            \def\@mcitesublistmode{h}\@mcitesublistmodetrue\@mcitesublistmodebfalse\@mcitesublistmodeftrue\@mcitesublistmodehtrue\else
            \PackageError{mciteplus}{Unknown mode `#1' in argument to \protect\mciteSetSublistMode}%
            {Only `d', `n', `s', `b', `f' and `h' are valid.}\relax
          \fi
        \fi
      \fi
    \fi
  \fi
\fi}




% checks to see if valid type in \@mciteformtypeArg (bibitem or subitem), errors if not
% #1 is name of calling macro
\def\@mcitecheckformtypeerror#1{\relax
\ifx\@mciteformtypeArg\@mciteMacrobibitem\relax
\else
  \ifx\@mciteformtypeArg\@mciteMacrosubitem\relax
  \else
    \PackageError{mciteplus}{Unknown form type  `\@mciteformtypeArg' in argument to \protect#1}%
                            {Only `bibitem' and `subitem' are valid.}\relax
  \fi
\fi}


% sets the bst max width forms
% usage: \mciteSetBstMaxWidthForm[init]{type}{form}
% where type is bibitem or subitem
% if [init] not given, uses \mcitedefaultmaxwidth[TYPE]forminit
\def\mciteSetBstMaxWidthForm{\@ifnextchar[{\@mciteLocalMacroOptArgItrue\@mciteSetBstMaxWidthForm}{\@mciteLocalMacroOptArgIfalse\@mciteSetBstMaxWidthForm[\relax]}}
\def\@mciteSetBstMaxWidthForm[#1]#2#3{\edef\@mciteformtypeArg{#2}\relax
\@mcitecheckformtypeerror{\mciteSetBstMaxWidthForm}\relax
\expandafter\def\csname mcitebstmaxwidth\@mciteformtypeArg form\endcsname{#3}\relax
\if@mciteLocalMacroOptArgI
\expandafter\def\csname mcitebstmaxwidth\@mciteformtypeArg forminit\endcsname{#1}\relax
\else
\expandafter\expandafter\expandafter\def\expandafter\expandafter\csname mcitebstmaxwidth\@mciteformtypeArg forminit\endcsname\expandafter{\csname mcitedefaultmaxwidth\@mciteformtypeArg forminit\endcsname}\relax
\fi}

% sets the max width forms
% usage: \mciteSetMaxWidthForm[init]{type}{form}
% where type is bibitem or subitem
% if [init] not given, uses \mcitebstmaxwidth[TYPE]forminit
\def\mciteSetMaxWidthForm{\@ifnextchar[{\@mciteLocalMacroOptArgItrue\@mciteSetMaxWidthForm}{\@mciteLocalMacroOptArgIfalse\@mciteSetMaxWidthForm[\relax]}}
\def\@mciteSetMaxWidthForm[#1]#2#3{\edef\@mciteformtypeArg{#2}\relax
\@mcitecheckformtypeerror{\mciteSetMaxWidthForm}\relax
\expandafter\def\csname mcitemaxwidth\@mciteformtypeArg form\endcsname{#3}\relax
\if@mciteLocalMacroOptArgI
\expandafter\def\csname mcitemaxwidth\@mciteformtypeArg forminit\endcsname{#1}\relax
\else
\expandafter\expandafter\expandafter\def\expandafter\expandafter\csname mcitemaxwidth\@mciteformtypeArg forminit\endcsname\expandafter{\csname mcitebstmaxwidth\@mciteformtypeArg forminit\endcsname}\relax
\fi}




% initialize punctuation, sublist and maxwidth hooks
%
% punctuation controls
% default is to hook into the bst
\mciteSetMidEndSepPunct{\mcitebstmidpunct}{\mcitebstendpunct}{\mcitebstseppunct}
% the default bst setting is to use the package defaults
\mciteSetBstMidEndSepPunct{\mcitedefaultmidpunct}{\mcitedefaultendpunct}{\mcitedefaultseppunct}
%
% sublist controls
% default sublist mode is to use the defaults
\mciteSetBstSublistMode{d}
\mciteSetSublistMode{d}
% the default sublabel bst setting is to use the package defaults
\mciteSetBstSublistLabelBeginEnd{\mcitedefaultsublistlabel}{\mcitedefaultsublistbegin}{\mcitedefaultsublistend}
% default sublabel setting is to hook into the bst settings
\mciteSetSublistLabelBeginEnd{\mcitebstsublistlabel}{\mcitebstsublistbegin}{\mcitebstsublistend}
%
% max width form controls
% the default max width form bst settings is to use the package defaults
\mciteSetBstMaxWidthForm[\mcitedefaultmaxwidthbibitemforminit]{bibitem}{\mcitedefaultmaxwidthbibitemform}
\mciteSetBstMaxWidthForm[\mcitedefaultmaxwidthsubitemforminit]{subitem}{\mcitedefaultmaxwidthsubitemform}
% the default max width form settings is to hook into the bst settings
\mciteSetMaxWidthForm[\mcitebstmaxwidthbibitemforminit]{bibitem}{\mcitebstmaxwidthbibitemform}
\mciteSetMaxWidthForm[\mcitebstmaxwidthsubitemforminit]{subitem}{\mcitebstmaxwidthsubitemform}




% Defines a macro to track the status of entries. An example showing the
% format is \@mciteEntryStatus@1@Smith98
% where the 1 is the tracking ID, and Smith98 is the cite key.
% Possible values for this status macro are:
% 0 = not yet determined
% 1 = tail   (tail entry following a head entry)
% 2 = head   (head entry followed by one or more tails)
% 3 = single (head entry not followed by any tails)
% usage: \@mciteSetEntryStatus{track ID}{cite key}{status}
\def\@mciteSetEntryStatus#1#2#3{\expandafter\xdef\csname @mciteEntryStatus@#1@#2\endcsname{#3}\relax
%\typeout{SetEntryStatus: Track:`#1' Key:`#2' Status:`#3'}\relax
}
% used to obtain status of a given cite key
% usage: \@mciteGetEntryStatus*{track ID}{cite key}{status out}
% star form: no error checking
\def\@mciteGetEntryStatus{\@ifstar{\@mciteGetEntryStatusStar}{\@mciteGetEntryStatusNoStar}}

\def\@mciteGetEntryStatusStar#1#2#3{\expandafter\let\expandafter#3\csname @mciteEntryStatus@#1@#2\endcsname}

\def\@mciteGetEntryStatusNoStar#1#2#3{\expandafter\let\expandafter#3\csname @mciteEntryStatus@#1@#2\endcsname\relax
\ifx#3\relax
\ifmciteErrorOnUnknown
\PackageError{mciteplus}{Entry Status for cite key `#2' under tracking ID `#1' is undefined, treating it as a head entry}{I don't have a
record of the head/tail status of this citation. Possible reasons include the use
of a cite command that is not mciteplus aware, the use of `\string\nocite{*}', or a problem with the
tracking ID and/or aux file handles. `\string\mciteErrorOnUnknownfalse' can be used to disable this error message.}\relax
\fi
\expandafter\def#3{3}\relax
\fi}


% set head key for given tail
% usage: \@mciteSetHeadofTail{track ID}{tail cite key}{head cite key}
\def\@mciteSetHeadofTail#1#2#3{\expandafter\xdef\csname @mciteHeadofTail@#1@#2\endcsname{#3}}
% get head key for given tail
% usage: \@mciteGetHeadofTail{track ID}{tail cite key}{head key out}
% star form: no error checking
\def\@mciteGetHeadofTail{\@ifstar{\@mciteGetHeadofTailStar}{\@mciteGetHeadofTailNoStar}}

\def\@mciteGetHeadofTailStar#1#2#3{\expandafter\let\expandafter#3\csname @mciteHeadofTail@#1@#2\endcsname}

\def\@mciteGetHeadofTailNoStar#1#2#3{\expandafter\let\expandafter#3\csname @mciteHeadofTail@#1@#2\endcsname\relax
\ifx#3\relax
\PackageError{mciteplus}{Head for tail cite key `#2' under tracking ID `#1' is undefined}{I don't have a
record of the head key of this citation.}\relax
\fi}


% for debug status messages
% converts given status number to word description
\def\@mciteStatusNumToWord#1{\expandafter\ifcase#1\relax
Unknown\or Tail\or Head with tails\or Head without tails\else Invalid (#1)\fi}
% form that makes no distinction between status 2 or 3. Used with \cite debug as 
% head status is not finalized till after the entry group
\def\@mciteStatusNumToWordH#1{\expandafter\ifcase#1\relax
Unknown\or Tail\or Head\or Head\else Invalid (#1)\fi}




% usage:\mciteSetMaxWidth{track ID}{type}{width}
% Defines a macro to track the max width of a given label type.
% An example showing the format is \@mciteMaxWidthStore@main@bibitem
% which is set globally
% we don't use @ in the macro name as this cmd appears in the aux
\def\mciteSetMaxWidth#1#2#3{\edef\@mciteformtypeArg{#2}\relax
\@mcitecheckformtypeerror{\mciteSetMaxWidth}\relax
\expandafter\xdef\csname @mciteMaxWidthStore@#1@\@mciteformtypeArg\endcsname{#3}}
%
% usage:\mciteGetMaxWidth{track ID}{type}{out macro}
% reads the stored max width of the given label type into the out macro
% which is set globally
\def\mciteGetMaxWidth#1#2#3{\edef\@mciteformtypeArg{#2}\relax
\@mcitecheckformtypeerror{\mciteGetMaxWidth}\relax
\expandafter\global\expandafter\let\expandafter#3\csname @mciteMaxWidthStore@#1@\@mciteformtypeArg\endcsname}

% usage:\mciteSetMaxCount{track ID}{type}{count}
% Defines a macro to track the max count of a given label type.
% An example showing the format is \@mciteMaxCountStore@main@bibitem
% which is set globally
% we don't use @ in the macro name as this cmd appears in the aux
\def\mciteSetMaxCount#1#2#3{\edef\@mciteformtypeArg{#2}\relax
\@mcitecheckformtypeerror{\mciteSetMaxCount}\relax
\expandafter\xdef\csname @mciteMaxCountStore@#1@\@mciteformtypeArg\endcsname{#3}}
%
% usage:\mciteGetMaxCount{track ID}{type}{out macro}
% reads the stored max count of the given label type into the out macro
% which is set globally
\def\mciteGetMaxCount#1#2#3{\edef\@mciteformtypeArg{#2}\relax
\@mcitecheckformtypeerror{\mciteGetMaxCount}\relax
\expandafter\global\expandafter\let\expandafter#3\csname @mciteMaxCountStore@#1@\@mciteformtypeArg\endcsname}


% sets \mcitemaxcountbibitem and \mcitemaxcountsubitem via \mciteGetMaxCount globally
% sets them to zero if \mciteGetMaxCount returns \relax
% clears \@mcitecorrectmaxcountbibitem and \@mcitecorrectmaxcountsubitem
% uses \@mcitecurtrackID
\def\@mciteMaxCountInitialize{\mciteGetMaxCount{\@mcitecurtrackID}{bibitem}{\mcitemaxcountbibitem}\relax
\ifx\mcitemaxcountbibitem\relax\gdef\mcitemaxcountbibitem{0}\fi
\mciteGetMaxCount{\@mcitecurtrackID}{subitem}{\mcitemaxcountsubitem}\relax
\ifx\mcitemaxcountsubitem\relax\gdef\mcitemaxcountsubitem{0}\fi
\global\let\mcitemaxcountbibitem\mcitemaxcountbibitem
\global\let\mcitemaxcountsubitem\mcitemaxcountsubitem
\xdef\@mcitecorrectmaxcountbibitem{0}\relax
\xdef\@mcitecorrectmaxcountsubitem{0}\relax}
%
% usage: \@mciteMaxCountUpdate
% updates \@mcitecorrectmaxcountsubitem
% no need for \@mcitecorrectmaxcountbibitem as this is carried by the counter itself
\def\@mciteMaxCountUpdate{\relax
\ifnum\@mcitecorrectmaxcountsubitem<\arabic{mcitesubitemcount}\relax
  \xdef\@mcitecorrectmaxcountsubitem{\arabic{mcitesubitemcount}}\relax
\fi}
%
% usage: \@mciteMaxCountAuxWrite uses \@mcitecurauxout and \@mcitecurtrackID
% writes \mciteSetMaxCount{track ID}{type}{count} to \@mcitecurauxout
% and warns if correct values do not match \mcitemaxcountbibitem, \mcitemaxcountsubitem
\def\@mciteMaxCountAuxWrite{\relax
\if@filesw
  \immediate\write\@mcitecurauxout{\string\mciteSetMaxCount{\@mcitecurtrackID}{bibitem}{\arabic{mcitebibitemcount}}}\relax
  \immediate\write\@mcitecurauxout{\string\mciteSetMaxCount{\@mcitecurtrackID}{subitem}{\@mcitecorrectmaxcountsubitem}}\relax
\fi
\ifnum\mcitemaxcountbibitem=\arabic{mcitebibitemcount}\relax
  \ifnum\mcitemaxcountsubitem=\@mcitecorrectmaxcountsubitem\relax\else
    \@latex@warning@no@line{Mciteplus max count has changed}\global\@mciteLaTeXreruntrue
  \fi
\else
  \@latex@warning@no@line{Mciteplus max count has changed}\global\@mciteLaTeXreruntrue
\fi}


% usage: \@mciteMaxWidthInitialize{type}
% sets \mcitemaxwidth[TYPE] via \GetMaxWidth globally
% if \GetMaxWidth returns \relax, sets them to the width (without sp units at end) of \mcitebstmaxwidth[TYPE]forminit
% as evaluated when bibitem and subitem counters are both = 1
% clears \@mcitecorrectmaxwidth[TYPE] globally to 0
% uses \@mcitecurtrackID
\def\@mciteMaxWidthInitialize#1{\edef\@mcitemaxwidthinitializetypeArg{#1}\relax
\expandafter\mciteGetMaxWidth\expandafter{\expandafter\@mcitecurtrackID\expandafter}\expandafter{\expandafter\@mcitemaxwidthinitializetypeArg\expandafter}\expandafter{\csname mcitemaxwidth#1\endcsname}\relax
\expandafter\ifx\csname mcitemaxwidth#1\endcsname\relax
  \begingroup
  % set counters to 1 locally
  \csname c@mcitebibitemcount\endcsname 1\relax
  \csname c@mcitesubitemcount\endcsname 1\relax
  \settowidth{\@mcitetmpdima}{\csname mcitemaxwidth#1forminit\endcsname}\relax
  \@mcitetmpcnta=\@mcitetmpdima\relax
  \expandafter\xdef\csname mcitemaxwidth#1\endcsname{\the\@mcitetmpcnta}\relax
  \endgroup
\fi
\expandafter\xdef\csname @mcitecorrectmaxwidth#1\endcsname{0}}
%
% usage: \@mciteMaxWidthUpdate{type}
% globally updates \@mcitecorrectmaxwidth[TYPE] based on \mcitemaxwidth[TYPE]form
\def\@mciteMaxWidthUpdate#1{\relax
\settowidth{\@mcitetmpdima}{\csname mcitemaxwidth#1form\endcsname}\relax
\@mcitetmpcnta=\@mcitetmpdima\relax
\@mcitetmpcntb=\csname @mcitecorrectmaxwidth#1\endcsname\relax
\ifnum\@mcitetmpcnta>\@mcitetmpcntb\relax
  \expandafter\xdef\csname @mcitecorrectmaxwidth#1\endcsname{\the\@mcitetmpcnta}\relax
\fi}
%
%
% usage: \@mciteMaxWidthAuxWrite uses \@mcitecurauxout and \@mcitecurtrackID
% writes \mciteSetMaxWidth{track ID}{type}{correct width in sp}
% for both bibitem and subitem to \@mcitecurauxout
% and warns if correct values do not match \mcitemaxwidthbibitem, \mcitemaxwidthsubitem
\def\@mciteMaxWidthAuxWrite{\relax
\if@filesw
  \immediate\write\@mcitecurauxout{\string\mciteSetMaxWidth{\@mcitecurtrackID}{bibitem}{\@mcitecorrectmaxwidthbibitem}}\relax
  \immediate\write\@mcitecurauxout{\string\mciteSetMaxWidth{\@mcitecurtrackID}{subitem}{\@mcitecorrectmaxwidthsubitem}}\relax
\fi
\ifnum\mcitemaxwidthbibitem=\@mcitecorrectmaxwidthbibitem\relax
  \ifnum\mcitemaxwidthsubitem=\@mcitecorrectmaxwidthsubitem\relax\else
    \@latex@warning@no@line{Mciteplus max width has changed}\global\@mciteLaTeXreruntrue
  \fi
\else
  \@latex@warning@no@line{Mciteplus max width has changed}\global\@mciteLaTeXreruntrue
\fi}





% empty \mciteheadlist in case someone trys to access it before a \cite
\def\mciteheadlist{}

% default wrappers for \cite and \nocite, package hooks (e.g., multibbl) can change these later
\def\@mciteCiteWrapper{\mciteCiteA{\mciteauxout}{\mcitetrackID}{\relax}{\relax}{\mciteOrgcite}}
\def\@mciteNociteWrapper{\mciteCiteA{\mciteauxout}{\mcitetrackID}{\relax}{\relax}{\mciteOrgnocite}}


% \mcite was undocumented in mcite.sty. We don't need it and it will not work with
% some multibibliography packages. So, we'll not use them.
% mcite version of \cite
%\def\mcite{\mciteCiteA{\mciteauxout}{\mcitetrackID}{\relax}{\relax}{\mciteOrgcite}}
% mcite version of \nocite
%\def\mnocite{\mciteCiteA{\mciteauxout}{\mcitetrackID}{\relax}{\relax}{\mciteOrgnocite}}


% mciteplus \cite wrappers
% usage: \mciteCiteA*{aux out}{track ID}{prehandler}{posthandler}{fwd macro}*[opt1][opt2]{cite list}
%        \mciteCiteB*{aux out}{track ID}{prehandler}{posthandler}{fwd macro}*[opt1][opt2]{sec ID}{cite list}
% B form is for \cite that use two arguments, such as that of multibbl.sty
% processes cite list and fowards arguments and list of heads to specified \cite macro
% star form means no default \mciteDoList processing
\DeclareRobustCommand{\mciteCiteA}{\@mciteCiteSecIDArgfalse\@mciteCiteAB}
\DeclareRobustCommand{\mciteCiteB}{\@mciteCiteSecIDArgtrue\@mciteCiteAB}


\def\@mciteCiteAB{\@ifstar{\mciteMacroStarFormtrue\@@mciteCiteAB}{\mciteMacroStarFormfalse\@@mciteCiteAB}}

\def\@@mciteCiteAB#1#2#3#4#5{\def\mciteCiteAuxArg{#1}\def\mciteCiteTrackArg{#2}\def\mciteCitePrehandlerArg{#3}\relax
                             \def\mciteCitePosthandlerArg{#4}\relax\def\mciteCiteFwdArg{#5}\relax
                             \@ifstar{\mciteCiteStarFwdArgtrue\@@@mciteCiteAB}{\mciteCiteStarFwdArgfalse\@@@mciteCiteAB}}

\def\@@@mciteCiteAB{\@ifnextchar[{\mciteMacroOptArgItrue\@@@@mciteCiteAB}%
{\mciteMacroOptArgIfalse\@@@@mciteCiteAB[\relax]}}

\def\@@@@mciteCiteAB[#1]{\def\mciteCiteOptArgI{#1}\relax
\@ifnextchar[{\mciteMacroOptArgIItrue\@@@@@mciteCiteAB}%
{\mciteMacroOptArgIIfalse\@@@@@mciteCiteAB[\relax]}}

\def\@@@@@mciteCiteAB[#1]{\def\mciteCiteOptArgII{#1}\relax
\if@mciteCiteSecIDArg
\def\@mciteNextMacroChain{\@@@@@mciteCiteB}\relax
\else
\let\mciteCiteSecIDArg\relax
\def\@mciteNextMacroChain{\@@@@@@mciteCiteAB}\relax
\fi
\@mciteNextMacroChain}


\def\@@@@@mciteCiteB#1{\def\mciteCiteSecIDArg{#1}\@@@@@@mciteCiteAB}

\def\@@@@@@mciteCiteAB#1{\def\mciteCiteListArg{#1}\relax
\edef\mciteFwdCiteListArg{}\relax
% execute the user's pre-handler code
\mciteCitePrehandlerArg\relax
\ifmciteMacroStarForm
% star form means no mcite default processing
% the user will have to do all of this in their handler
\else
% otherwise, process the cite list and set the forward cite list to the list of heads
\mciteDoList{\mciteCiteAuxArg}{\mciteCiteTrackArg}{\mciteCiteListArg}\relax
\edef\mciteFwdCiteListArg{\mciteheadlist}\relax
% optional additional calls to do lists for duplicate/global bibliographies
\mciteExtraDoLists\relax
\fi
\relax
% execute the user's post-handler code
\mciteCitePosthandlerArg\relax
% build the forwarding macro and arguments list
\@mcitetmptoksA=\expandafter{\mciteCiteFwdArg}\relax
\ifmciteCiteStarFwdArg
\@mciteAppendToTmpToksA{*}\relax
\fi
\ifmciteMacroOptArgI
\@mciteAppendToTmpToksA{[}\relax
\expandafter\@mciteAppendToTmpToksA\expandafter{\mciteCiteOptArgI}\relax
\@mciteAppendToTmpToksA{]}\relax
\fi
\ifmciteMacroOptArgII
\@mciteAppendToTmpToksA{[}\relax
\expandafter\@mciteAppendToTmpToksA\expandafter{\mciteCiteOptArgII}\relax
\@mciteAppendToTmpToksA{]}\relax
\fi
\if@mciteCiteSecIDArg
\expandafter\@mciteAppendToTmpToksA\expandafter{\expandafter{\mciteCiteSecIDArg}}\relax
\fi
\expandafter\@mciteAppendToTmpToksA\expandafter{\expandafter{\mciteFwdCiteListArg}}\relax
\edef\@mciteCiteFwd{\the\@mcitetmptoksA}\relax
% forward to the "real" \cite
\@mciteCiteFwd}


% mciteplus engine
% processes cite list, records status of keys and writes tail (and head)
% citations to aux file
% list of heads is output to \mciteheadlist for forwarding to \cite
% usage: \mciteDoList{aux out}{track ID}{cite list}
% use noauxwrite for aux out to disable writes to aux
\def\mciteDoList#1#2#3{\edef\@mcitecurauxout{#1}\edef\@mcitecurtrackID{#2}\edef\@mcitetemp{#3}\relax
\expandafter\@mciteDoList\expandafter{\@mcitetemp}}

% flag to determine if mciteDoList should write to aux file
\newif\if@mciteDoListwriteaux \@mciteDoListwriteauxtrue
\def\@mciteMacronoauxwrite{noauxwrite}

\def\@mciteDoList#1{\let\@mcitecurhead\relax % reset current head
\@mciteDoListwriteauxtrue
% disable aux writes if aux parameter is "noauxwrite"
\ifx\@mcitecurauxout\@mciteMacronoauxwrite\@mciteDoListwriteauxfalse\fi
\@mcitefirstentrytrue\@mcitefirstheadentrytrue
\def\mciteheadlist{}\def\@mcitecurstatus{\relax}\relax
\@for\@mcitecurkey:=#1\do{\expandafter\@mciteCheckKey\@mcitecurkey\end\relax
% ignore empty keys
\ifx\@mcitecurkey\@empty
% warn about \nocite{*}
\if@mcitestarentry
  \typeout{** WARNING: mciteplus: Wildcard `*' citation entry declared. BibTeX will add untracked entries to the bibliography.}\relax
  % add * to the head list
  \if@mcitefirstentry
    \@mcitefirstentryfalse
    \edef\mciteheadlist{*}\relax
  \else
    \edef\mciteheadlist{\mciteheadlist,*}\relax
  \fi
\fi
\else % key is not empty
% get entry status
\@mciteGetEntryStatus*{\@mcitecurtrackID}{\@mcitecurkey}{\@mcitecurstatus}\relax
% if entry status is undefined, set status number code to undetermined and update \@mcitecurstatus
\ifx\@mcitecurstatus\relax
  \@mciteSetEntryStatus{\@mcitecurtrackID}{\@mcitecurkey}{0}\relax
  \@mciteGetEntryStatus{\@mcitecurtrackID}{\@mcitecurkey}{\@mcitecurstatus}\relax
\fi
\if@mcitestarentry % if declared to be a tail
  \if@mcitefirstheadentry % tail cannot be declared until after a head
    \PackageError{mciteplus}{Tail `\@mcitecurkey' is declared without a valid head}{You have to
                             declare a head citation before entering tail citations in cite list.}\relax
  \fi
  \ifnum\@mcitecurstatus>1\relax % cannot have been previously declared as a head
    \PackageError{mciteplus}{Tail citation `\@mcitecurkey' has previously been declared as a head}{Declare
                             each citation entry as a head or a tail, but not both.}\relax
  \fi
  \if@mciteheadredeclared % the current head has been redeclared, OK with some restrictions
    \ifnum\@mcitecurstatus=0\relax % cannot add new tails to previous group definitions
    \PackageError{mciteplus}{New tail citation `\@mcitecurkey' cannot be added to the already existing
                             definition of group of head `\@mcitecurhead'}{You cannot define a group,
                             then reissue the head and add new tail citations.}\relax
    \fi
    \ifnum\@mcitecurstatus=1\relax % OK to respecify tails as long as they already belong to this group, this allows for overall (global) bibliographies
      \@mciteGetHeadofTail{\@mcitecurtrackID}{\@mcitecurkey}{\@mciteheadofcurkey}\relax
      \ifx\@mciteheadofcurkey\@mcitecurhead
      \else
        \PackageError{mciteplus}{Tail citation `\@mcitecurkey' is not allowed in group of head
                                 `\@mcitecurhead' as this tail has already been declared in group
                                 of head `\@mciteheadofcurkey'}{You cannot have a tail citation
                                 that appears in more than one citation group.}\relax
      \fi
    \fi
  \else % head not redeclared
    \ifnum\@mcitecurstatus=1\relax % cannot be declared twice as a tail in initial definition, this is an optional error
      \PackageError{mciteplus}{Tail citation `\@mcitecurkey' has been declared more than once in
                               definition of group for head `\@mcitecurhead'}{Each tail
                               citation can only be specified once in the definition
                               of a group.}\relax
    \fi
  \fi% end if head redeclared
  % if not declared before, process as a valid tail
  \ifnum\@mcitecurstatus=0\relax
    % record type as tail
    \@mciteSetEntryStatus{\@mcitecurtrackID}{\@mcitecurkey}{1}\relax
    \@mciteGetEntryStatus{\@mcitecurtrackID}{\@mcitecurkey}{\@mcitecurstatus}\relax
    % write out tail citation to aux as it will not be forwarded to \cite
    \if@mciteDoListwriteaux
      \@mcitewritecurkeytoaux
    \fi
    % record head for this tail
    \@mciteSetHeadofTail{\@mcitecurtrackID}{\@mcitecurkey}{\@mcitecurhead}\relax
    % change current head from code 3 (single) to 2 (one or more tails)
    \@mciteSetEntryStatus{\@mcitecurtrackID}{\@mcitecurhead}{2}\relax
  \fi
\else % is declared to be a head
  \edef\@mcitecurhead{\@mcitecurkey}\relax % this is our new current head
  % add to the head list
  \if@mcitefirstentry
    \@mcitefirstentryfalse
    \edef\mciteheadlist{\@mcitecurkey}\relax
  \else
    \edef\mciteheadlist{\mciteheadlist,\@mcitecurkey}\relax
  \fi
  \@mcitefirstheadentryfalse
  \ifnum\@mcitecurstatus=1\relax % cannot have previously been used as a tail
    \@mciteGetHeadofTail{\@mcitecurtrackID}{\@mcitecurkey}{\@mciteheadofcurkey}\relax
    \PackageError{mciteplus}{Head citation `\@mcitecurkey' has previously been declared
                             as a tail of `\@mciteheadofcurkey'}{Declare each citation
                             entry as a head or a tail, but not both.}\relax
  \fi
  \@mciteheadredeclaredfalse % assume not redeclared
  \ifnum\@mcitecurstatus>1\relax % has already been declared?
    \@mciteheadredeclaredtrue % OK, but do not allow any new future tails for this head
  \fi
  % if not declared before, set as a head, single. Will later change to code 2 if tails are found.
  \if@mciteheadredeclared\else
    \@mciteSetEntryStatus{\@mcitecurtrackID}{\@mcitecurkey}{3}\relax
    \@mciteGetEntryStatus{\@mcitecurtrackID}{\@mcitecurkey}{\@mcitecurstatus}\relax
    % write out head citation to aux.
    % This will result in the entry appearing twice in the aux file as the
    % entry will be part of the \mciteheadlist which will be forwarded to \cite.
    % However, we need to write this out now to preserve the order of the citations.
    \if@mciteDoListwriteaux
      \@mcitewritecurkeytoaux
    \fi
    % this is the new current head
    \let\@mcitecurhead\@mcitecurkey
  \fi % fi not headredeclared
\fi % fi tail or head
% debug report
\if@OPTIONmcitedebug
  \ifnum\@mcitecurstatus=1\relax
  \edef\@mcitedebugheadoftail{Head of this tail: `\@mcitecurhead'}\relax
    \else
  \edef\@mcitedebugheadoftail{}\relax
  \fi
  \typeout{** Mciteplus Debug: Citation Entry: `\@mcitecurkey' TrackID: `\@mcitecurtrackID'
  Auxout: \ifx\@mcitecurauxout\@mciteMacronoauxwrite `none (\@mciteMacronoauxwrite)' \else `\the\@mcitecurauxout' \fi
  Status: `\@mciteStatusNumToWordH{\@mcitecurstatus}' \@mcitedebugheadoftail}\relax
\fi
% end debug report
\fi % only nonempty
}% end do loop
}

% hook to allow for a redo. Useful for global bibliographies
\def\mciteExtraDoLists{\relax}

% determines if an entry starts with an *, removes the * from the start of the entry name
% and sets \@mcitestarentry and \@mcitecurkey accordingly
\def\@mciteCheckKey#1#2\end{\@mcitestarentryfalse
\ifx*#1\@mcitestarentrytrue\edef\@mcitecurkey{#2}\relax
\else
\edef\@mcitecurkey{#1#2}%
\fi}

% writes current key citation to aux. We put this in a macro because some packages
% may fiddle with \if@filesw (making it a macro rather than an if), tripping up
% TeX's parser if \if@filesw is ever within another conditional as is the case
% within \@mciteDoList
\def\@mcitewritecurkeytoaux{\if@filesw\immediate\write\@mcitecurauxout{\string\citation{\@mcitecurkey}}\fi}



% custom \ref command displays \mcitesubrefform when
% \ref'd
% prefix to reference labels to avoid namespace clash
\def\@mcitereflabelprefix{MciteSubReferenceLabel}
\def\@mciteSetSubRefLabel{\begingroup\def\@currentlabel{\mcitesubrefform}\label{\@mcitereflabelprefix:\@mcitecurtrackID:\mciteBibitemArgI}\endgroup}
% default to using the actual sublist form.
\providecommand{\mcitesubrefform}{\arabic{mcitebibitemcount}.\alph{mcitesubitemcount}}
% give user access to sublist \ref and \pageref
% usage: \mciteSubRef[track ID]{cite key}
\def\mciteSubRef{\@ifnextchar[{\@mciteSubRef}{\@mciteSubRef[\mcitetrackID]}}
\def\@mciteSubRef[#1]#2{\ref{\@mcitereflabelprefix:#1:#2}}
\def\mciteSubPageRef{\@ifnextchar[{\@mciteSubPageRef}{\@mciteSubPageRef[\mcitetrackID]}}
\def\@mciteSubPageRef[#1]#2{\pageref{\@mcitereflabelprefix:#1:#2}}


% for debug, head of tail lookup
\def\@mcitecurheadlookup{}




% mciteplus version of \bibitem
% support the optional arg of \bibitem[]{} as well
\def\mcitebibitem{\@ifnextchar[{\global\mciteBibitemOptArgItrue\@mcitebibitem}%
{\global\mciteBibitemOptArgIfalse\@mcitebibitem[\relax]}}

\def\@mcitebibitem[#1]#2{\relax
% build the forwarding macro: \mciteOrgbibitem{#2} or \mciteOrgbibitem[#1]{#2}
\gdef\mciteBibitemOptArgI{#1}\gdef\mciteBibitemArgI{#2}\relax
\@mcitetmptoksA={\mciteOrgbibitem}\relax
\ifmciteBibitemOptArgI
\@mciteAppendToTmpToksA{[}\relax
\expandafter\@mciteAppendToTmpToksA\expandafter{\mciteBibitemOptArgI}\relax
\@mciteAppendToTmpToksA{]}\relax
\fi
\expandafter\@mciteAppendToTmpToksA\expandafter{\expandafter{\mciteBibitemArgI}}\relax
% build the command. we need a global def here so that the changes will persist in spite
% of a later closed sublist
\xdef\@mciteBibitemFwdMacroArgs{\the\@mcitetmptoksA}\relax
% on the very first \bibitem initialize the maxwidths
% we do this here so that the bibstyle can have its say on the forminit
\if@mcitefirstentry
  \@mciteMaxWidthInitialize{bibitem}\relax
  \@mciteMaxWidthInitialize{subitem}\relax
\fi
% get status of entry and process accordingly
\@mciteGetEntryStatus{\@mcitecurtrackID}{#2}{\@mcitecurstatus}\relax
% status get may happen inside a list, so make the changes to \@mcitecurstatus global
\global\let\@mcitecurstatus\@mcitecurstatus
% debug report
\if@OPTIONmcitedebug
  \ifnum\@mcitecurstatus=1\relax
    \@mciteGetHeadofTail{\@mcitecurtrackID}{\mciteBibitemArgI}{\@mcitecurheadlookup}\relax
    \edef\@mcitedebugheadoftail{Head of this tail: `\@mcitecurheadlookup' (from citation),  `\@mcitecurhead' (in bibliography)}\relax
  \else
    \edef\@mcitedebugheadoftail{}\relax
  \fi
  \typeout{** Mciteplus Debug: \string\mcitebibitem\space Entry: `\mciteBibitemArgI' TrackID: `\@mcitecurtrackID'
  Status: `\@mciteStatusNumToWord{\@mcitecurstatus}' \@mcitedebugheadoftail}\relax
\fi
% end debug report
\ifnum\@mcitecurstatus=1\relax % if a tail
  % error if a tail starts the bibliography
  \if@mcitefirstentry
  \PackageError{mciteplus}{Bibliography begins with a tail entry `\mciteBibitemArgI'}{For sorting
                           bibstyles, you must set the `mcitetail' BibTeX database field
                           for each tail entry and use a bibstyle that understands that field.}\relax
  \fi
  \mcitemidpunct\relax
  % open sublist if needed
  \if@mcitesublistmode
    \if@mcitesublistopen\else
      \global\@mcitesublistopentrue
      \relax\mcitesublistbegin\relax
    \fi
    \relax\mcitesublistlabel\relax\@mciteSetSubRefLabel\relax\@mciteMaxWidthUpdate{subitem}\relax
  \fi
  \@mciteMaxCountUpdate
  \addtocounter{mcitesubitemcount}{1}\relax
\else% is head
   \if@mcitefirstentry\else\mciteendpunct\relax\mciteEndOfBibGroupPresubcloseHook\relax\fi
   % close sublist if open
   % watch out with variables as this will close off local changes
   % addtocounter and setcounter make global changes
   \if@mcitesublistopen
     \mcitesublistend\relax
     \global\@mcitesublistopenfalse
   \fi
   \relax\mciteEndOfBibGroupPostsubcloseHook\relax
   % record current head key and argument info
   \xdef\@mcitecurhead{#2}\relax
   \gdef\mciteCurheadBibitemArgI{#2}\relax
   \gdef\mciteCurheadBibitemOptArgI{#1}\relax
   \ifmciteBibitemOptArgI\global\mciteCurheadBibitemOptArgItrue\else\global\mciteCurheadBibitemOptArgIfalse\fi
   % note: with \mcitebibitem mcitebibitemcount advances with heads
   % and holds the current head count until the next \mcitebibitem
   % However, at the end of the \mcitebibitem, mcitesubitemcount
   % is one more than the number of subitems as the label is
   % rendered before updating the counter.
   \setcounter{mcitesubitemcount}{1}\relax
   \addtocounter{mcitebibitemcount}{1}\relax
   \@mciteMaxCountUpdate
   \if@mcitefirstentry\else\relax\mciteseppunct\relax\fi
   \@mciteBibitemFwdMacroArgs\relax\relax\relax
   % check and update the bibitem label width
   \@mciteMaxWidthUpdate{bibitem}\relax
   \ifnum\@mcitecurstatus=2\relax % if head with tails
     \if@mcitesublistmodef
       % open sublist if needed
       \if@mcitesublistopen\else
         \global\@mcitesublistopentrue
         \mcitesublistbegin\relax
       \fi
       \relax\mcitesublistlabel\relax\@mciteSetSubRefLabel\relax\@mciteMaxWidthUpdate{subitem}\relax
       \addtocounter{mcitesubitemcount}{1}\relax
     \fi
   \fi
   \ifnum\@mcitecurstatus=3\relax % if head without tails
     \if@mcitesublistmodeh
       % open sublist if needed
       \if@mcitesublistopen\else
         \global\@mcitesublistopentrue
         \mcitesublistbegin\relax
       \fi
       \relax\mcitesublistlabel\relax\@mciteSetSubRefLabel\relax\@mciteMaxWidthUpdate{subitem}\relax
       \addtocounter{mcitesubitemcount}{1}\relax
     \fi
   \fi
   \if@mcitesublistmodeb
     \addtocounter{mcitesubitemcount}{1}\relax
   \fi
\fi% if tail or head
\global\@mcitefirstentryfalse\ignorespaces}

% End of \bibitem marker from bibstyle
\def\EndOfBibitem{\relax}

% hook inserted at the end of bibitem group, before the sublist is closed
\def\mciteEndOfBibGroupPresubcloseHook{\relax}
% hook inserted at the end of bibitem group, after the sublist is closed
\def\mciteEndOfBibGroupPostsubcloseHook{\relax}

% hook inserted at \mcitethebibliography
\def\mcitethebibliographyHook{\relax}


% hook to allow insertion of custom code at end of mcitethebibliography
\def\mciteBIBdecl{\relax}
% hook to allow insertion of custom code at end of endmcitethebibliography
\def\mciteBIBenddecl{\relax}
% hook to allow insertion of custom code at end of thebibliography
\def\mcitefwdBIBdecl{\relax}




% Bibdecl for package hooks
\def\@mcitepkgBIBdecl{\relax}
% single use internal BIB hook, is automatically reset to \relax at end of \mcitethebibliography
\let\@mciteoneshotBIBdecl\relax


% mciteplus version of \thebibliography
\def\mcitethebibliography#1{\@mcitefirstentrytrue
  \@mcitesublistopenfalse
  \let\@mcitecurauxout\mcitebibauxout
  \let\@mcitecurtrackID\mcitebibtrackID
  \ifmciteResetBibitemCount\setcounter{mcitebibitemcount}{0}\fi
  \setcounter{mcitesubitemcount}{0}\relax
  \xdef\mciteorgbibsamplelabel{#1}\relax
  % set these to something so that init forms that reference them won't choke
  \gdef\mciteBibitemOptArgI{\relax}\relax
  \gdef\mciteBibitemArgI{\relax}\relax
  \global\mciteBibitemOptArgIfalse
  \gdef\mciteCurheadBibitemOptArgI{\relax}\relax
  \gdef\mciteCurheadBibitemArgI{\relax}\relax
  \global\mciteCurheadBibitemOptArgIfalse
  % note: pkg and user hooks may update tracking ID
  \relax\@mcitepkgBIBdecl\relax
  \relax\@mciteoneshotBIBdecl\relax
  \relax\mciteBIBdecl\relax
  \@mciteMaxCountInitialize
  % we initialize here to get a valid \mcitemaxwidthbibitem for \mcitebibsamplelabel
  % but we will reinitialize again at the first \bibitem so that any BST changes can take affect
  \@mciteMaxWidthInitialize{bibitem}\relax
  % debug report
  \if@OPTIONmcitedebug
  \typeout{}\typeout{}\relax
  \typeout{** Mciteplus Debug: \string\mcitethebibliography\space TrackID: `\@mcitecurtrackID' Auxout: `\the\@mcitecurauxout'}\relax
  \fi
  % end debug report
  \thebibliography{\mcitebibsamplelabel}\relax
  \mcitethebibliographyHook\relax
  \relax\mcitefwdBIBdecl\relax
  \let\mciteOrgbibitem\bibitem
  \def\bibitem{\mcitebibitem}}

\def\endmcitethebibliography{\mciteendpunct\relax
  \relax\mciteEndOfBibGroupPresubcloseHook\relax
  % close sublist if open
  \if@mcitesublistopen
    \mcitesublistend\relax
    \@mcitesublistopenfalse
  \fi
  \relax\mciteEndOfBibGroupPostsubcloseHook\relax
  \relax\mciteBIBenddecl\relax
  % globally clear oneshot decl
  \global\let\@mciteoneshotBIBdecl\relax
  % restore original \bibitem as some \endthebibliography tack notes at the end (e.g., REVTeX)
  % we'll add them to the count with mcite's counters and continue to track the bibitem width
  \setcounter{mcitesubitemcount}{1}\relax
  \def\bibitem{\addtocounter{mcitebibitemcount}{1}\@mciteMaxWidthUpdate{bibitem}\relax\mciteOrgbibitem}
  \endthebibliography\relax
  % update max count for possible \endthebibliography tack notes
  \@mciteMaxCountUpdate
  % write correct max counter to aux and warn if changed
  \@mciteMaxCountAuxWrite
  % write correct max widths to aux and warn if changed
  \@mciteMaxWidthAuxWrite
  % debug report
  \if@OPTIONmcitedebug
  \typeout{}\relax
  \typeout{** Mciteplus Debug: \string\endmcitethebibliography^^J
  Current Max bibitem count: `\mcitemaxcountbibitem'^^J
  Correct Max bibitem count: `\arabic{mcitebibitemcount}'^^J^^J
  Current Max subitem count: `\mcitemaxcountsubitem'^^J
  Correct Max subitem count: `\@mcitecorrectmaxcountsubitem'^^J^^J
  Current Max bibitem width: `\mcitemaxwidthbibitem'(sp)^^J
  Correct Max bibitem width: `\@mcitecorrectmaxwidthbibitem'(sp)^^J^^J
  Current Max subitem width: `\mcitemaxwidthsubitem'(sp)^^J
  Correct Max subitem width: `\@mcitecorrectmaxwidthsubitem'(sp)}^^J
  \fi}


% warn at end if any \mcitethebibliography requires a rerun due to a max width/count change
\AtEndDocument{\if@mciteLaTeXrerun\@latex@warning@no@line{Rerun to ensure correct mciteplus label max width/count}\fi}

% always ensure \mciteSetMaxWidth{}{}{} and \mciteSetMaxCount{}{}{} are defined in the .aux,
% lest the package be unloaded and the initial .aux still refers to it.
\AtBeginDocument{\if@filesw\immediate\write\@mainaux{\string\providecommand{\string\mciteSetMaxWidth}[3]{\string\relax}}\relax
\immediate\write\@mainaux{\string\providecommand{\string\mciteSetMaxCount}[3]{\string\relax}}\fi}



% hook into system only after all packages have been loaded
\AtBeginDocument{\let\mciteOrgcite\cite\let\mciteOrgnocite\nocite
\if@OPTIONmcitenohooks\else
% hook into system \cite unless user says otherwise
\def\cite{\@mciteCiteWrapper}
\def\nocite{\@mciteNociteWrapper}
\fi}





% special \if macros needed for PKG hooks
% we've got to define these here to shield the \ifcontinuouslabels
% and and \fi from TeX's scanner when multibib is *not* loaded
% as \ifcontinuouslabels will not be defined and TeX would still
% see the \fi when skipping over the code.
%
% multibib 
\def\@mciteMULTIBIBcontinuouslabelsWarn{\relax
\ifmciteResetBibitemCount
   \ifcontinuouslabels
     \typeout{** WARNING: mciteplus is using \string\mciteResetBibitemCounttrue, but multibib was not invoked with `resetlabels' option.}
   \fi
\else
   \ifcontinuouslabels\else
     \typeout{** WARNING: mciteplus is using \string\mciteResetBibitemCountfalse, but multibib was invoked with `resetlabels' option.}
   \fi
\fi}


% bibunits global copy list handler
\def\@mciteBIBUNITSExtraDoListHandler{\ifglobalcitecopy
\mciteDoList{\mciteauxout}{main}{\mciteCiteListArg}\relax
\else
\ifmciteCiteStarFwdArg
\mciteDoList{\mciteauxout}{main}{\mciteCiteListArg}\relax
\fi
\fi}


% natbib command names
\def\@mciteNatbibCiteCmdList{citep,Citep,citet,Citet,citealp,Citealp,citealt,Citealt,citeauthor,Citeauthor,citeyear,citeyearpar,citepalias,citetalias}

% if natbib loaded, save originals at start
\expandafter\ifx\csname ver@natbib.sty\endcsname\relax\else
\AtBeginDocument{\@for\@mcitecurcmdname:=\@mciteNatbibCiteCmdList\do{\relax
\expandafter\let\expandafter\@mcitetmpA\csname \@mcitecurcmdname\endcsname
\expandafter\let\csname mciteOrg\@mcitecurcmdname\endcsname\@mcitetmpA}}
\fi





% *** External Package Hooks ***
\if@OPTIONmcitenohooks\else% hook into packages



% *** natbib.sty hooks
\expandafter\ifx\csname ver@natbib.sty\endcsname\relax\else
\typeout{** mciteplus: Detected natbib.sty. Invoking hooks.}\relax
\AtBeginDocument{\@for\@mcitecurcmdname:=\@mciteNatbibCiteCmdList\do{\relax
% reroute original cite macro \X through \mciteCiteA
% \X -> \mciteCiteA{\mciteauxout}{\mcitetrackID}{\relax}{\relax}{\mciteOrgX}
\expandafter\@mcitetmptoksA\expandafter=\expandafter{\csname mciteOrg\@mcitecurcmdname\endcsname}\relax
\expandafter\edef\csname \@mcitecurcmdname\endcsname{\noexpand\mciteCiteA{\noexpand\mciteauxout}{\noexpand\mcitetrackID}{\relax}{\relax}{\the\@mcitetmptoksA}}\relax
}}
\fi % if natbib.sty detected




% *** cite.sty hooks
\expandafter\ifx\csname ver@cite.sty\endcsname\relax\else
\typeout{** mciteplus: Detected cite.sty. Invoking hooks.}\relax
\AtBeginDocument{\let\@mciteCITEOrgciten\citen
\def\@mciteCITEciten{\mciteCiteA{\mciteauxout}{\mcitetrackID}{\relax}{\relax}{\@mciteCITEOrgciten}}\relax
% This will still work even though cite.sty routes \citex through \citen.
% The double calls to mciteplus will be OK as the second call to mciteplus
% will only have a head list of already defined entries and so it will do nothing
% other than write the list to the aux again.
% Not the most elegant approach though.
\def\citen{\@mciteCITEciten}\relax
% Handle the aliases as well.
\def\citenum{\@mciteCITEciten}\relax
\def\citeonline{\@mciteCITEciten}}
\fi % if cite.sty detected



% *** drftcite.sty hooks
\expandafter\ifx\csname ver@drftcite.sty\endcsname\relax\else
\typeout{** mciteplus: Detected drftcite.sty. Invoking hooks.}\relax
\AtBeginDocument{\let\@mciteDRFTCITEOrgciten\citen
\def\@mciteDRFTCITEciten{\mciteCiteA{\mciteauxout}{\mcitetrackID}{\relax}{\relax}{\@mciteDRFTCITEOrgciten}}\relax
% As with cite.sty, this will still work even though drftcite.sty
% routes \citex through \citen.
\def\citen{\@mciteDRFTCITEciten}\relax}
\fi % if drftcite.sty detected



% *** chapterbib hooks
\expandafter\ifx\csname ver@chapterbib.sty\endcsname\relax\else
\typeout{** mciteplus: Detected chapterbib.sty. Invoking hooks.}\relax
% one gotcha is that LaTeX closes and reopens \@partaux so aux handle number
% does not change
\def\mcitetrackID{chapterbib\@currentipfile}
\def\mcitebibtrackID{chapterbib\@currentipfile}
% make a second set of entry status macros for the duplicate bibliographies
% produced under the duplicate option. Won't hurt anything if the duplicate
% bibliography is not used. Note that chapterbib uses the .bbl suffix for
% \@currentipfile when reading the duplicate bibliographies.
\def\mciteExtraDoLists{\mciteDoList{noauxwrite}{chapterbib\@currentipfile.bbl}{\mciteCiteListArg}\relax
% create third set only when chapterbib is using the rootbib option.
% We can't just write this out all the time because the rootbib option can
% cause a conflict in the mciteplus status of a key if that same key is
% used in different parts of the document. And we can't test for the use of
% the chapterbib rootbib option because chapterbib is rerun without the
% rootbib option.
\if@OPTIONmcitechapterbibrootbib
  \mciteDoList{noauxwrite}{chapterbib\jobname}{\mciteCiteListArg}\relax
\fi}
\fi % if chapterbib detected




% *** multibib hooks
\expandafter\ifx\csname ver@multibib.sty\endcsname\relax\else
\typeout{** mciteplus: Detected multibib.sty. Invoking hooks.}\relax
\let\@mciteOrgMULTIBIBnewcites\newcites

% internally braced \nocite with \@aux handler as needed by multibib
% usage: \@mciteMULTIBIBgroupedOrgNocite{multibib section name}{cite list}
\def\@mciteMULTIBIBgroupedOrgNocite#1#2{{\expandafter\let\expandafter\@auxout\csname @auxout#1\endcsname
\mciteOrgnocite{#2}}}

\def\@mciteMULTIBIBnewcites#1#2{\relax
% forward to original \newcites and let it do its thing first
\@mciteOrgMULTIBIBnewcites{#1}{#2}%
% now redo some of what it did our way
\@for\@mciteCurRefName:=#1\do{\relax
%
% build auxout names and track ID
\edef\@mcitetempauxout{\csname @auxout\@mciteCurRefName\endcsname}\relax
\edef\@mcitetemptrackID{multibib\@mciteCurRefName}\relax
%
% reroute original \citeX through \mciteCiteA using \@mciteCurRefName in aux and track
% \citeX -> \mciteCiteA{\@auxoutX}{multibibX}{\relax}
%                      {\let\@citex\mb@@citex\let\@newciteauxhandle\@auxoutX}
%                      {\mciteOrgcite}
% basic command name list
\def\@mciteMULTIBIBCiteCmdList{cite}
% add natbib names if natbib is loaded
\expandafter\ifx\csname ver@natbib.sty\endcsname\relax\else
\edef\@mciteMULTIBIBCiteCmdList{\@mciteMULTIBIBCiteCmdList,\@mciteNatbibCiteCmdList}\relax
\fi
\@for\@mcitecurcmdname:=\@mciteMULTIBIBCiteCmdList\do{\relax
\@mcitetmptoksA=\expandafter{\expandafter{\@mcitetempauxout}}\relax
\expandafter\@mciteAppendToTmpToksA\expandafter{\expandafter{\@mcitetemptrackID}{\relax}}\relax
% install multibib \citeX internals into handler
\edef\@mcitetemp{{\let\noexpand\@citex\noexpand\mb@@citex
\let\noexpand\@newciteauxhandle\csname @auxout\@mciteCurRefName\endcsname}}\relax
\expandafter\@mciteAppendToTmpToksA\expandafter{\@mcitetemp}\relax
% forward to standard \cite (\mciteOrgcite), can't go through current \cite
% as that goes through mcite again and would write entries to standard aux
\expandafter\@mciteAppendToTmpToksA\expandafter{\expandafter{\csname mciteOrg\@mcitecurcmdname\endcsname}}\relax
% define new \citeX wrapper
\expandafter\expandafter\expandafter\def\expandafter\expandafter\csname \@mcitecurcmdname\@mciteCurRefName\endcsname
\expandafter{\expandafter\mciteCiteA\the\@mcitetmptoksA}\relax
}% \do for \@mciteMULTIBIBCiteCmdList
%
% reroute original \nociteX through \mciteCiteA using \@mciteCurRefName in aux and track
% \nociteX -> \mciteCiteA{\@auxoutX}{multibibX}{\relax}
%                      {\relax}
%                      {\@mciteMULTIBIBgroupedOrgNocite}
\@mcitetmptoksA=\expandafter{\expandafter{\@mcitetempauxout}}\relax
\expandafter\@mciteAppendToTmpToksA\expandafter{\expandafter{\@mcitetemptrackID}{\relax}{\relax}}\relax
% forward to standard \@mciteMULTIBIBgroupedOrgNocite, can't go through current \nocite
% as that goes through mcite again and would write entries to standard aux also because
% multibib changes \@auxout, we need to use the internally grouped version with
% the \@aux handler in it
\edef\@mcitetemp{{\noexpand\@mciteMULTIBIBgroupedOrgNocite{\@mciteCurRefName}}}
% define new \nociteX wrapper
\expandafter\@mciteAppendToTmpToksA\expandafter{\@mcitetemp}
\expandafter\expandafter\expandafter\def\expandafter\expandafter\csname nocite\@mciteCurRefName\endcsname
\expandafter{\expandafter\mciteCiteA\the\@mcitetmptoksA}\relax
% now reroute \bibliographyX
% save as \@mciteOrgMULTIBIBbibliographyX
\expandafter\let\expandafter\@mcitetemp\csname bibliography\@mciteCurRefName\endcsname
\expandafter\let\csname @mciteOrgMULTIBIBbibliography\@mciteCurRefName\endcsname\@mcitetemp
\@mcitetmptoksA=\expandafter{\csname @mciteOrgMULTIBIBbibliography\@mciteCurRefName\endcsname}\relax
\expandafter\edef\csname bibliography\@mciteCurRefName\endcsname{\def\@mciteoneshotBIBdecl{\def\noexpand\@mcitecurtrackID{\@mcitetemptrackID}}\the\@mcitetmptoksA}\relax
% we depend on the default \mciteauxout and \mcitetrackID for \cite, \nocite and \mcite
}% end ref name do loop
}% end def \@mcitePKGnewcites
%
% setup multibib BIB hooks
% no need to install bibliography wrapper uaing \@auxoutX as multibbl wrapper alters
% \@auxout to point to \@auxoutX before starting \mcitethebibliography
% Thus, the default bibteckID will work.
% 
% warn if a mismatch between the settings of mciteplus entry label counter resets and those of multibib
\expandafter\@mcitetmptoksA\expandafter=\expandafter{\@mcitepkgBIBdecl}
\addto@hook\@mcitetmptoksA{\@mciteMULTIBIBcontinuouslabelsWarn}
\edef\@mcitepkgBIBdecl{\the\@mcitetmptoksA}
% reroute all \newcites calls through \@mciteMULTIBIBnewcites
\let\newcites\@mciteMULTIBIBnewcites
\fi% if multibib detected



% *** multibbl hooks
\expandafter\ifx\csname ver@multibbl.sty\endcsname\relax\else
\typeout{** mciteplus: Detected multibbl.sty. Invoking hooks.}\relax
% for checking that the user has called \newbibliography before \cite.
\def\@mciteMULTIBBLcheckAuxDefined{\expandafter\ifx\csname\mciteCiteSecIDArg @auxfile\endcsname\relax
\PackageError{mciteplus}{multibbl: Bibliography `\mciteCiteSecIDArg' has not been defined}{Use multibbl's \string\newbibliography\space to
 declare this bibliography before using it in \string\cite.}\relax
\fi}
%\cite -> \mciteCiteB{\secID@auxfile}{multibbl\secID}{create aux track arguments}{\relax}{\mciteOrgcite}}
%\cite -> \mciteCiteB{\secID@auxfile}{multibbl\secID}{create aux track arguments}{\relax}{\mciteOrgcite}}
% we use prehandler to set aux and track arguments to use mciteCiteSecIDArg
\def\@mciteCiteWrapper{\mciteCiteB{Bogus auxout}{Bogus trackID}{\relax
\def\mciteCiteAuxArg{\csname \mciteCiteSecIDArg @auxfile\endcsname}\relax
\def\mciteCiteTrackArg{multibbl\mciteCiteSecIDArg}\@mciteMULTIBBLcheckAuxDefined}{\relax}{\mciteOrgcite}}
% nocite
\def\@mciteNociteWrapper{\mciteCiteB{Bogus auxout}{Bogus trackID}{\relax
\def\mciteCiteAuxArg{\csname \mciteCiteSecIDArg @auxfile\endcsname}\relax
\def\mciteCiteTrackArg{multibbl\mciteCiteSecIDArg}\@mciteMULTIBBLcheckAuxDefined}{\relax}{\mciteOrgnocite}}
% hook into bibliography at start of document, use one shot interface for single use setup of the aux and track ID
\AtBeginDocument{\let\mciteOrgbibliography\bibliography
% we need to update \mcitethebibliography's tracking ID, to reflect what multibbl is using,
% multibbl.sty does not read in non-main aux files. We use the one shot so that the definition is cleared
% after each bibliography (but in this case it would be anyway as it is defined inside the
% \bibliography environment).
\def\bibliography#1#2#3{\def\@mciteoneshotBIBdecl{\relax
  \def\@mcitecurtrackID{multibbl#1}}
  \mciteOrgbibliography{#1}{#2}{#3}}}

\fi% if multibbl detected



% *** bibunits hooks
\expandafter\ifx\csname ver@bibunits.sty\endcsname\relax\else
\typeout{** mciteplus: Detected bibunits.sty. Invoking hooks.}\relax

\def\@mciteBIBUNITSbibunit{\def\mcitetrackID{bibunits\@bibunitname}\relax
\def\mcitebibtrackID{bibunits\@bibunitname}\mciteOrgBIBUNITSbibunit}

\def\@mciteBIBUNITSbu@cite{\@startbibunitorrelax\mciteCiteA{\@bibunitaux}{\mcitetrackID}{\relax}{\@mciteBIBUNITSExtraDoListHandler}{\mciteOrgBIBUNITSbu@cite}}
\def\@mciteBIBUNITSbu@nocite{\@startbibunitorrelax\mciteCiteA{\@bibunitaux}{\mcitetrackID}{\relax}{\@mciteBIBUNITSExtraDoListHandler}{\mciteOrgBIBUNITSbu@nocite}}

\AtBeginDocument{\let\mciteOrgBIBUNITSbu@cite\bu@cite
\let\mciteOrgBIBUNITSbu@nocite\bu@nocite
\let\mciteOrgBIBUNITSbibunit\bibunit
\let\mciteOrgBIBUNITSstd@bibliography\std@bibliography
\let\bibunit\@mciteBIBUNITSbibunit
\let\bu@cite\@mciteBIBUNITSbu@cite
\let\bu@nocite\@mciteBIBUNITSbu@nocite
% have to restore main track ID for global bibliography when using \bibliographyunit
\def\std@bibliography{\def\mcitebibtrackID{main}\mciteOrgBIBUNITSstd@bibliography}}

\fi% if bibunits detected


% *** backref.sty (from hyperref) hooks
\expandafter\ifx\csname ver@backref.sty\endcsname\relax\else
\typeout{** mciteplus: Detected backref.sty. Invoking hooks.}\relax
% disable backref's \bibitem intercept within mcitethebibliography
\expandafter\@mcitetmptoksA\expandafter=\expandafter{\mcitethebibliographyHook}
\addto@hook\@mcitetmptoksA{\def\BR@@lbibitem{\@lbibitem}\def\BR@@bibitem{\@bibitem}}
\edef\mcitethebibliographyHook{\the\@mcitetmptoksA}
%\def\BR@bibitem{\BRorg@bibitem}
% and install our own
\def\mciteBACKREFform{{}\ \BR@backref{\@mcitecurhead}}
\expandafter\@mcitetmptoksA\expandafter=\expandafter{\mciteEndOfBibGroupPresubcloseHook}
\addto@hook\@mcitetmptoksA{\mciteBACKREFform}
\edef\mciteEndOfBibGroupPresubcloseHook{\the\@mcitetmptoksA}
\fi % if backref.sty detected


% *** citeref.sty hooks
\expandafter\ifx\csname ver@citeref.sty\endcsname\relax\else
\typeout{** mciteplus: Detected citeref.sty. Invoking hooks.}\relax
% disable citeref's \bibitem intercepts within mcitethebibliography
\expandafter\@mcitetmptoksA\expandafter=\expandafter{\mcitethebibliographyHook}
\addto@hook\@mcitetmptoksA{\def\@@lbibitem{\@lbibitem}\def\@@bibitem{\@bibitem}}
\edef\mcitethebibliographyHook{\the\@mcitetmptoksA}
%\def\@@lbibitem{\@lbibitem}
%\def\@@bibitem{\@bibitem}
% and install our own
\def\mciteCITEREFform{\bibitempages{\@citerefpages{\@mcitecurhead}}}
\expandafter\@mcitetmptoksA\expandafter=\expandafter{\mciteEndOfBibGroupPresubcloseHook}
\addto@hook\@mcitetmptoksA{\mciteCITEREFform}
\edef\mciteEndOfBibGroupPresubcloseHook{\the\@mcitetmptoksA}
\fi % if citeref.sty detected



% *** detect attempts to use incompatible packages ***
% might be best not to lockout amsrefs and biblatex - maybe somebody wants
% and knows how to use them "in parallel" with mciteplus

% *** incompatible with bibtopic.sty
\expandafter\ifx\csname ver@bibtopic.sty\endcsname\relax\else
\PackageError{mciteplus}{Bibtopic.sty cannot be used with mciteplus.sty}{These two packages won't work together.}\relax
\fi

% *** incompatible with inlinebib.sty
\expandafter\ifx\csname ver@inlinebib.sty\endcsname\relax\else
\PackageError{mciteplus}{inlinebib.sty cannot be used with mciteplus.sty}{These two packages won't work together.}\relax
\fi

% *** incompatible with jurabib.sty
\expandafter\ifx\csname ver@jurabib.sty\endcsname\relax\else
\PackageError{mciteplus}{jurabib.sty cannot be used with mciteplus.sty}{These two packages won't work together.}\relax
\fi

% *** incompatible with opcit.sty
\expandafter\ifx\csname ver@opcit.sty\endcsname\relax\else
\PackageError{mciteplus}{opcit.sty cannot be used with mciteplus.sty}{These two packages won't work together.}\relax
\fi

% *** incompatible with splitbib.sty
\expandafter\ifx\csname ver@splitbib.sty\endcsname\relax\else
\PackageError{mciteplus}{Splitbib.sty cannot be used with mciteplus.sty}{These two packages won't work together.}\relax
\fi
\fi % if hooks enabled


\endinput
