\RequirePackage{pgfkeys}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% List manipulation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% append a value to a list (either list first or value first) -- for expandafter matters
\newcommand{\pgfoptions@append@to@list}[2]{%#1 -> list (must be a macro) #2 -> value
  \pgfoptions@append{#2}{#1}%
}
\newcommand{\pgfoptions@append}[2]{%#1 -> value #2 -> list (must be a macro) 
  \edef\@tempb{#1}%
  \ifx\@tempb\@empty%
  \else%
    \edef\@tempa{#2}%
    \ifx\@tempa\@empty%
      \edef#2{\@tempb}%
    \else%
      \edef#2{\@tempa,\@tempb}%
    \fi%
  \fi%
}
% catenates the second arg list to the first
\newcommand{\pgfoptions@append@list@to@list}[2]{%#1 -> list1 (must be a macro) #2 -> list2
  \edef\@tempb{#1}%
  \ifx\@tempb\@empty%
    \edef#1{#2}%
  \else%
    \edef\@tempa{#2}%
    \ifx\@tempa\@empty%
      %#1 is unchanged
    \else%
      \edef#1{\@tempb,\@tempa}%
    \fi%
  \fi%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Expand functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% expand (once) the two arguments of a macro before calling it
\def\expandTwoArgs#1#2#3{%#1 -> macro #2 -> first arg #3 -> snd arg
  \expandafter\expandTwoArgs@\expandafter{#2}{#3}{#1}%
}
\def\expandTwoArgs@#1#2#3{%#1 -> first arg (expanded) #2 -> snd arg #3 -> macro
  \expandafter\expandTwoArgs@@\expandafter{#2}{#1}{#3}%
}
\def\expandTwoArgs@@#1#2#3{%#1 -> snd arg (expanded) #2 -> first arg (expanded) #3 -> macro
  #3{#2}{#1}%
}
% expand (once) the three arguments of a macro before calling it
\def\expandThreeArgs#1#2#3#4{%#1 -> macro #2 -> first arg #3 -> snd arg #4 trd arg
  \expandafter\expandThreeArgs@\expandafter{#2}{#3}{#4}{#1}%
}
\def\expandThreeArgs@#1#2#3#4{%#1 -> first arg (expanded) #2 -> snd arg #3 -> trd arg #4 -> macro
  \expandafter\expandThreeArgs@@\expandafter{#2}{#3}{#1}{#4}%
}
\def\expandThreeArgs@@#1#2#3#4{%#1 -> snd arg (expanded) #2 -> trd arg #3 -> first arg (expanded) #4 -> macro
  \expandafter\expandThreeArgs@@@\expandafter{#2}{#3}{#1}{#4}%
}
\def\expandThreeArgs@@@#1#2#3#4{%#1 -> trd arg (expanded) #2 ->  first arg (expanded) #3 -> snd arg (expanded) #4 -> macro
  #4{#2}{#3}{#1}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% pgfkeys extensions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% getting rid of spaces in option name
\def\pgfoptions@withoutspaces#1{%
  \def\pgfoptions@result{}%
  \pgfoptions@withoutspaces@#1 |%
}
\def\pgfoptions@withoutspaces@#1 #2|{%
  \def\pgfoptions@temp{#2}%
  \edef\pgfoptions@result{\pgfoptions@result #1}
  \ifx\pgfoptions@temp\@empty
  \else
    \pgfoptions@withoutspaces@#2|%
  \fi
}
% define a macro that will have options (define an empty list to store init values and a family)
\newcommand*{\pgfoptions@macro@def}[1]{%
  \expandafter\def\csname options@#1@init\endcsname{}%
  \pgfkeys{/pgfuml/#1/.is family}%
}
% create a new boolean option (def the if key, the init at false and the transmit macro)
\newcommand*{\pgfoptions@new@boolean@option}[3]{%#1 -> option name #2 -> macro #3 -> option name without spaces
%  \message{new boolean option '#1' (#3) for '#2'}
  \expandafter\newif\csname if#2@#3\endcsname%
  \pgfqkeys{/pgfuml/#2}{#1/.is if=#2@#3}%
  \expandafter\pgfoptions@append@to@list\expandafter{\csname options@#2@init\endcsname}{#1=false}%
  \expandafter\def\csname getOptionSetup@#2@#3\endcsname{%
    \csname if#2@#3\endcsname%
      #1%
    \else
    \fi
  }%
%  \message{new init list is '\csname options@#2@init\endcsname'}
}
% create a new store option (def the key, the init at the given value and the transmit macro)
\newcommand*{\pgfoptions@new@store@option}[4]{%#1 -> option name #2 -> macro #3 -> macro to store the value #4 -> initial value
%  \message{new store option '#1' (\string#3) for '#2', value '#4'}
  \pgfqkeys{/pgfuml/#2}{#1/.store in=#3}%
  \expandafter\pgfoptions@append@to@list\expandafter{\csname options@#2@init\endcsname}{#1=#4}%
  \expandafter\pgfoptions@withoutspaces\expandafter{#1}%
  \expandafter\def\csname getOptionSetup@#2@\pgfoptions@result\endcsname{%
    #1=#3%
  }%
}
% create a list of boolean options
\newcommand*{\pgfoptions@new@boolean@options}[2]{%#1 -> macro list #2 -> option list
  \@for\@abool:=#2\do{%
    \expandafter\pgfoptions@withoutspaces\expandafter{\@abool}%
    \@for\@amacro:=#1\do{%
      \expandThreeArgs\pgfoptions@new@boolean@option{\@abool}{\@amacro}{\pgfoptions@result}%
    }
  } % 
}
% create a list of store options
\newcommand*{\pgfoptions@new@store@options}[3]{%#1 -> macro list #2 -> option list #3 -> initial value
  \@for\@anoption:=#2\do{%
    \expandafter\pgfoptions@withoutspaces\expandafter{\@anoption}%
    \@for\@amacro:=#1\do{%
      \expandThreeArgs\pgfoptions@new@store@option{\@anoption}{\@amacro}{\csname\@amacro @\pgfoptions@result\endcsname}{#3}%
    }%
  }% 
}
% default options + options given in #2 for macro #1
\newcommand*{\pgfoptions@SetOptions}[2]{% #1 -> macro #2 -> options to set up
  \mypgfqkeys{/pgfuml/#1}{\csname options@#1@init\endcsname}%
  \pgfqkeys{/pgfuml/#1}{#2}%
}
% a setting keys function that take a macro as argument and expand it twice
\def\mypgfqkeys{\expandafter\mypgfkeys@@qset\expandafter{\pgfkeysdefaultpath}}%
\def\mypgfkeys@@qset#1#2#3{\def\pgfkeysdefaultpath{#2/}\expandafter\expandafter\expandafter\pgfkeys@parse#3,\pgfkeys@mainstop\def\pgfkeysdefaultpath{#1}}%
% get a current set up state for a set of options
\newcommand*{\getOptionSetup}[2]{%#1 -> option list #2 -> macro
  \def\optionResult{}%
  \@for\@anoption:=#1\do{%
    \expandafter\pgfoptions@withoutspaces\expandafter{\@anoption}%
    \expandafter\pgfoptions@append\expandafter{\csname getOptionSetup@#2@\pgfoptions@result\endcsname}{\optionResult}%
  }%
}
% create a new store option (def the key, the init at the given value and the transmit macro)
\newcommand*{\pgfoptions@new@style@option}[3]{%#1 -> macro #2 -> option name #3 -> the style
  \pgfqkeys{/pgfuml/#1}{#2/.style={#3}}%
}
\newcommand*{\pgfoptions@new@style@options}[3]{%#1 -> macro list #2 -> option name #3 -> the style
    \@for\@amacro:=#1\do{%
      \expandafter\pgfoptions@new@style@option\expandafter{\@amacro}{#2}{#3}%
    }%
}
