\def\filedate{2010/03/17}
\def\docdate{2010/03/17}
\def\fileversion{0.11}
\def\basename{uml}
%
% \iffalse meta-comment
%
%% Package 'uml' to use with LaTeX2e and PSTricks
%% Copyright 2006 by Ellef Fange Gjelstad.
%% http://www.ifi.uio.no/~ellefg/uml.sty/
%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN archives
%% in directory macros/latex/base/lppl.txt.
% 
% \fi
%
% \changes{v0.10}{2006/11/28}{First CTAN release (hv)}
%
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
%
% \GetFileInfo{showexpl.dtx}
%
% \DoNotIndex{\newcommand,\renewcommand,\newenvironment,\renewenvironment}
% \DoNotIndex{\usepackage,\documentclass,\nofiles,\bibliogaphy}
% \DoNotIndex{\tiny,\tableofcontens}
% \DoNotIndex{\newif,\newcounter,\linewidth,\listfiles}
% \DoNotIndex{\providecommand,\def,\edef,\let,\gdef,\xdef,\global,\newtoks}
% \DoNotIndex{\RequirePackage,\DeclareOption,\ProcessOptions,\ExecuteOptions}
% \DoNotIndex{\@nameuse,\value,\input,\InputIfFileExists}
% \DoNotIndex{\@ifdefinable,\@ifundefined,\@percentchar}
% \DoNotIndex{\AtBeginDocument,\AtEndOfPackage,\PassOptionsToPackage}
% \DoNotIndex{\CurrentOption,\jobname}
% \DoNotIndex{\PackageError,\PackageWarning,\PackageWarningNoLine,\PackageInfo}
% \DoNotIndex{\MessageBreak,\typeout}
% \DoNotIndex{\z@,\z@skip,\p@,\@ne,\tw@,\thr@@,\@iv,\two@fourteen,\strip@pt}
% \DoNotIndex{\the,\if,\else,\or,\fi,\ifnum,\ifdim,\ifcase,\ifodd}
% \DoNotIndex{\advance,\multiply,\divide,\ht,\dp,\wd,\catcode}
% \DoNotIndex{\@tfor,\do,\bgroup,\egroup,\ifx,\iftrue,\iffalse}
% \DoNotIndex{\csname,\endcsname,\begingroup,\endgroup}
% \DoNotIndex{\expandafter,\afterassignment,\noexpand}
% \DoNotIndex{\@tempdima,\@tempdimb,\@tempdimc,\@tempcnta,\@tempcntb}
% \DoNotIndex{\@halfwidth,\@wholewidth,\unitlength}
% \DoNotIndex{\@clnwd,\@clnht,\@ovdx,\@ovdy,\@ovro,\@ovri,\@ovxx,\@ovyy}
% \DoNotIndex{\@xarg,\@xdim,\@yarg,\@ydim,\@linelen,\@dashdim,\dimen@}
% \DoNotIndex{\reserved@a,\relax,\protect,\long,\space}
% \DoNotIndex{\if@tempswa,\@tempswatrue,\@tempswafalse,\@tempa}
% \DoNotIndex{\@tempboxa,\@tempboxb,\show}
% \DoNotIndex{\@empty,\%,\typeout,\vspace,\vskip,\the,\hbox,\par}
% \DoNotIndex{\minipage,\endminipage,\trivlist,\endtrivlist}
% \DoNotIndex{\parbox,\setbox,\setlength,\hfill,\item,\number}
% \DoNotIndex{\x}
% \DoNotIndex{\SX@put@a,\SX@put@b,\SX@put@l,\SX@put@r,\SX@put@o,\SX@put@i}
% 
% ^^A\DoNotIndex{\usepackage,\documentclass,\tableofcontens,\printindex}
%
% \RecordChanges
%
%\iffalse
%<*driver>
\documentclass{ltxdoc} 
\usepackage[T1]{fontenc}
\usepackage[dvips,lmargin=4cm]{geometry}
\usepackage{latexsym}
\usepackage[scaled]{luximono}
\usepackage{uml,lscape,varioref,listings}
\RequirePackage{xcolor}
\SpecialCoor
\RequirePackage[linktocpage,colorlinks]{hyperref}
\definecolor{hellgelb}{rgb}{1,1,0.85}
\definecolor{colKeys}{rgb}{0,0,1}
\definecolor{colIdentifier}{rgb}{0,0,0}
\definecolor{colComments}{rgb}{1,0,0}
\definecolor{colString}{rgb}{0,0.5,0}
\lstset{%
     gobble=1,
     frame=single,%
     language=TeX,%
     basicstyle=\small\ttfamily,%
     identifierstyle=\small\ttfamily,%
     keywordstyle=\bfseries,%
     stringstyle=\itshape\color{colComments},%
     commentstyle=\itshape\color{colComments},%
     columns=fixed,
     tabsize=4,%
     frame=single,%
     extendedchars=true,%
     showspaces=false,%
     showstringspaces=false,%
     numbers=left,%
     numberstyle=\tiny\ttfamily,%
     numbersep=1em,%
     breaklines=true,%
     breakindent=10pt,%
     backgroundcolor=\color{hellgelb},%
     breakautoindent=true,%
     xleftmargin=1em
}
\parindent0pt
\input example
\begin{document}
 \DocInput{uml.dtx}
\end{document}
%</driver>
%\fi
%
% \MakeShortVerb{"}
% \DeleteShortVerb{\|}
% \makeatletter
% \def\Codelabel#1{\@bsphack  
%  \protected@write\@auxout{}{\string\newlabel{#1}{{\number\the
%            \c@CodelineNo}{\thepage}}}\@esphack}
% \newcounter{tmpcount}
% \def\Coderef#1#2{\setcounter{tmpcount}{0}\@ifundefined{r@#1}\relax
%           {\setcounter{tmpcount}{\ref{#1}}}\relax
%           \addtocounter{tmpcount}{#2}\arabic{tmpcount}}
% \makeatother

% \title{\texttt{uml.sty}, a package for writing UML diagrams in \LaTeX}
% \author{Ellef Fange Gjelstad}
% \maketitle
%
% \tableofcontents
%
%
% \section{Syntax for all the commands}\label{sec:useSyntax}\label{sec:use}
% 
% Most of the commands in "uml.sty" have the syntax
% "\uml"\meta{Construct}"["\meta{Named options}"]"\meta{Arguments}.
% \begin{description}
% \item[\meta{Construct}] can be "Diagram", "Class", "Method" or other
%   things.
% \item[\meta{Named options}] is a comma-separated list of
%   \meta{key}"="\meta{value} pairs.  This is implemented by
%   "keyval.sty".  The entire "["\meta{Named options}"]" part is
%   optional.\index{keyval.sty}\index{named options}
% 
%   In this documentation, the "=" often is replaced with a
%   "-".  This is due to an error in the index generation process, which
%   does not accept.
% 
% \item[\meta{Arguments}] a number of arguments, typically enclosed in
%   brackets ("{}").  Typical arguments are a name and some interior of
%   a box.
% \end{description}
% 
% 
% \subsection{Lengths}
% 
% \index{lengths}Legal \emph{lengths} are all PSTricks lengths, 
% including \TeX{} lengths.  In
% PSTricks lengths, the unit is optional; if no unit is present, the
% current PSTricks "unit" is used.
% 
% 
% \subsection{Angles}
% \label{sec:angles}
% 
% \index{angles}
% \index{rotations}
% We distinguish between \emph{angles} and \emph{rotations}.  An angle
% should be a number giving the angle in degrees, by default.  You can
% also change the units used for angles with the PSTricks
% "\degrees[num]" command.
% 
% A rotation also expresses a direction, but can have different syntax
% forms:
% \begin{description}
% \item[An angle] i.e.\ a number 
% \item[An angle preceded by an asterisk] This means the angle is to be
%   interpreted absolute (relative to the page) and not to the underling
%   text direction.  This is useful when getting a relation label right
%   up, not in the direction of the relation
% \item[A letter] One of\\
%   \begin{tabular}{lcr|lcr}
%     \emph{letter} & \emph{Short for} & \emph{Equiv. to} &
%     \emph{letter} & \emph{Short for} & \emph{Equiv. to} \\\hline
%     U & Up & 0 & N & North & *0 \\
%     L & Left & 90 & W & West & *90\\
%     D & Down & 180 & S & South & *180\\
%     R & Right & 270 & E & East & *270\\\hline
%   \end{tabular}
% \item[When rotating along lines] e.g.\ relations, you can precede an
%   angle or one of "ULDR" with a colon.  This is to orientate the text
%   relative to the line.  This is useful when getting a relation along
%   the relation, not right up.
% \end{description}
% 
% 
% \subsection{Node names}\label{sec:useNodeNames}
% 
% \index{node names}
% A \emph{node name} is a name of a location on the page.  Such a name 
% must contain only letters and numbers, and must begin with a letter.
% Also, the node names should be unique (at least, to the page).
% 
% Node names are typically placed by means of the "reference" named
% option, but could be placed using any PSTricks node command.
% 
% 
% \subsection{Reference points}
% \label{sec:useReference}
% 
% \index{reference points}A \emph{reference point} is the point in a box
% which is to be placed.  E.g., if the reference point is "tl", meaning
% top left, the top left corner is placed relative to whatever.
% 
% A reference point can be any of "l" (left), "r" (right), "t" (top),
% "b" (bottom) or "B" (baseline) or reasonable combinations of
% them.
% 
% \subsection{Colors}
% \label{sec:useColorsPrimitive}
% 
% \index{colors}This is as in PSTricks.  E.g., you can say
% "\red Red" gives \fbox{{\red Red}} and use the color "red" as
% linecolor or fillcolor.
% 
% See also section \vref{sec:useColors}.
% 
% \subsection{Line styles}
% \label{sec:useLinestyles}
% 
% \index{line styles}As in PSTricks, e.g., solid, dashed, dotted or none.
% 
% \section{uml.sty options}\label{sec:useOptions}
% 
% \subsection{debug}\label{sec:useOptionsDefault}
% \subsection{index}\label{sec:useOptionsIndex}
% 
% By default, every named uml.sty construct (e.g., each Class and
% Attribute) makes an entry in the index of the form
% \meta{name}!\meta{type}.  This feature can be turned off with the
% option "noindex" or on with "index".  The feature can also be turned
% on with "\umlIndexOn"\DescribeMacro\umlIndexOn{} and off with
% "\umlIndexOff"\DescribeMacro\umlIndexOff{}.
% 
% Tip:  It is possible to change the index entry format by changing
% "\umlIndex".  "\umlIndex" should take two arguments: The name and the
% type.  E.g., "\renewcommand\umlIndex[2]{\index{#1 (#2)}}".
% 
% \section{Object-oriented approach}\label{sec:useApproach}
% 
% \index{object oriented LaTeX}When making an uml package for \LaTeX{},
% it seems natural to do the programming object-oriented.  While
% \LaTeX{} has no direct support for object-oriented programming, it can
% be simulated using command calls and keyval.sty.
% 
% {\tiny
%       \umlSchema[box=,posDelta={0,-.5em},refpoint=t,
%                  abstract=, 
%                  comment={Drawable}]{%
%         Drawable}{%
%         \umlAttribute[type=color]{import}%
%         \umlAttribute[type=String,propertyString={quasi-static}]{type}%
%         }{}{%%
%         \umlArgument{[named options]}%%
%         \umlArgument{Contents}}{}{}
% }
% 
% \newlength\saveHeight
% \setlength\saveHeight\umlSymbolHeightDefault
% \setlength\umlSymbolHeightDefault{1ex}
% \newlength\saveWidth
% \setlength\saveWidth\umlSymbolWidthDefault
% \setlength\umlSymbolWidthDefault{.5ex}
% 
% \newcommand\pagesReference[1]{
%   Pages~\pageref{sec:use#1} and \pageref{sec:imp#1}}
% \begin{figure}[htbp]
%   \begin{center}
%     \umlDiagram[grayness=0.92,box=, sizeX=\textwidth,
%     sizeY=9.5cm,innerBorder=2mm,ref=approachDiagram  ]{
%       }{}% End of diagram
%   \end{center}
%   \begin{tiny}
%     \setlength{\umlNodeSep}{1.5em}
%       \umlSchema[pos=\umlTop{approachDiagram},posDelta={0,-.5em},refpoint=t,
%                  abstract=, 
%                  comment=\pagesReference{Drawable}]{
%         Drawable}{
%         \umlAttribute[type=color]{import}
%         \umlAttribute[type=String,propertyString={quasi-static}]{type}
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Contents}}{}{}
%       \umlSchema[pos=\umlBottomSep{Drawable},refpoint=t,
%                  abstract=,
%                  comment=\pagesReference{Element}]{
%         Element}{
%         \umlAttribute{reference}
%         \umlAttribute{stereotype}
%         \umlAttribute{subof}
%         \umlAttribute[type=bool]{abstract}
%         \umlAttribute{importedFrom}
%         \umlAttribute{comment}
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Contents}}{}{}
%       \umlSubclass{Element}{Drawable}
%       \umlSchema[pos=\umlBottomSep{Element},refpoint=t,comment=\pagesReference{Box}]{
%         Box}{
%         \umlAttribute[type=position]{pos[XY ]}
%         \umlAttribute[type=position]{posDelta[XY ]}
%         \umlAttribute{refpoint}
%         \umlAttribute[default=true]{box}
%         \umlAttribute[type=length]{size[XY]}
%         \umlAttribute[type=real 0--1]{grayness}
%         \umlAttribute[type=colorName, default=umlFillColor]{%
%           fillcolorCommand}
%         \umlAttribute[type=length]{border}
%         \umlAttribute[default=solid]{borderLine}
%         \umlAttribute[type=length]{outerBorder}
%         \umlAttribute[type=length]{innerBorder}
%         }{}{}{}{}
%       \umlSubclass{Box}{Element}
%       \umlSchema[pos=\umlTopRight{Box},refpoint=tl,comment=\pagesReference{Diagram},
%                  posDelta={2em,-4em}]{
%         Diagram}{
%         \umlAttribute[colorset=\umlColorsSub,
%           default={\umlColorsDefault\umlColorsAdjust always true}]{%
%             box}
%         }{}{}{Size given\\contents placed\\~~according to size\\}{}
%       \umlSubclass{Diagram}{Box}
%       \umlSchema[pos=\umlTopLeft{Box},refpoint=tr,comment=\pagesReference{Stretchbox},
%                  posDelta={-2em,-4em}]{
%         Stretchbox}{
%         \umlAttribute{name}
%         \umlAttribute[visibility=-]{graphicalName}
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Name}
%         \umlArgument{Contents}}{
%         Size according to contents\\}{}
%       \umlSubclass{Stretchbox}{Box}
%       \umlSchema[pos=\umlBottomRight{Stretchbox},posDelta={0em,-2em},refpoint=tr,
%                  comment=\pagesReference{Package}]{
%         Package}{
%         }{}{}{}{}
%       \umlSubclass{Package}{Stretchbox}
%     \caption{Main commands in uml.sty.  This and the following class
%     diagrams work as a short-form documentation of uml.sty.}
%     \label{fig:useApproach}
%     \label{fig:approachStart}
%   \end{tiny}
% \end{figure}
% 
% Each box in figure \ref{fig:useApproach}--\ref{fig:approachEnd}
% corresponds to one \LaTeX{} command (e.g., "\umlDrawable" and
% "\umlElement").  Each attribute correspond to one \LaTeX{} variable
% (e.g., "\umlReference") and often one named option (e.g., "reference=").
% 
% The arguments of the commands are shown in the fourth compartment.
% Characteristics of each command are shown in the sixth.
% 
% \begin{figure}[thbp]
%   \begin{center}
%     \umlDiagram[grayness=0.92,box=, sizeX=\textwidth,
%     sizeY=10cm,innerBorder=2mm,ref=approachClassifierDiagram  ]{
%       }{}% End of diagram
%   \end{center}
%   \begin{tiny}
%     \setlength{\umlNodeSep}{1.5em}
%       \umlSchema[pos=\umlTopLeft{approachClassifierDiagram},
%                  posDelta={3cm,-.5em},refpoint=tl,
%                  abstract=,import=,importedFrom=main]{
%         Drawable}{
%         \umlAttribute[type=color]{import}
%         \umlAttribute[type=String,propertyString={quasi-static}]{type}
%         \umlAttribute[type=String]{name}
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Contents}}{}{}
%       \umlSchema[pos=\umlTopRight{Drawable},refpoint=tl,
%                  posDelta={\umlNodeSep,0},abstract=,
%                  import=,importedFrom=main]{
%         Element}{
%         \umlAttribute{reference}
%         \umlAttribute{stereotype}
%         \umlAttribute{subof}
%         \umlAttribute[type=bool]{abstract}
%         \umlAttribute{importedFrom}
%         \umlAttribute{comment}
%         }{}{}{}{}
%       \umlPlaceNode[rightside,top=-4em]{Drawable}{DrawableRight}
%       \umlPlaceNode[leftside,top=-4em]{Element}{ElementLeft}
%       \umlSubclass[import=]{ElementLeft}{DrawableRight}
%       \umlSchema[pos=\umlTopRight{Element},refpoint=tl,
%                  import=,importedFrom=main,
%                  posDelta={\umlNodeSep,0}]{
%         Box}{
%         \umlAttribute{pos}
%         \umlAttribute{posDelta}
%         \umlAttribute{refpoint}
%         \umlAttribute{box}
%         \umlAttribute{size}
%         \umlAttribute{grayness}
%         \umlAttribute{border}
%         \umlAttribute{innerBorder}
%         \umlAttribute{borderLine}
%         }{}{}{}{}
%       \umlPlaceNode[rightside,top=-4em]{Element}{ElementRight}
%       \umlPlaceNode[leftside,top=-4em]{Box}{BoxLeft}
%       \umlSubclass[import=]{BoxLeft}{ElementRight}
%       \umlSchema[pos=\umlTopRight{Box},refpoint=lt,
%                  import=,importedFrom=main,
%                  posDelta={\umlNodeSep,0}]{
%         Stretchbox}{
%         \umlAttribute{name}
%         \umlAttribute[visibility=-]{graphicalName}
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Name}
%         \umlArgument{Contents}}{
%         Size according to contents\\}{}
%       \umlPlaceNode[rightside,top=-4em]{Box}{BoxRight}
%       \umlPlaceNode[leftside,top=-4em]{Stretchbox}{StretchboxLeft}
%       \umlSubclass[import=]{StretchboxLeft}{BoxRight}
%       \umlSchema[pos=\umlBottom{Stretchbox},refpoint=t,
%                  posDelta={0,-7em},comment=\pagesReference{Classifier}]{
%         Classifier}{
%         \umlAttribute[type=boolean, default=false]{Object}
%         }{}{}{}{}
%       \umlSubclass{Classifier}{Stretchbox}
%       \umlSchema[pos=\umlTopLeft{Classifier},posDelta={-3em,0},refpoint=tr,
%                  comment=\pagesReference{Compartment}]{
%         Compartment}{
%         \umlAttribute[type=boolean]{suppress}
%         \umlAttribute[type=boolean]{showName}}{}{
%         \umlArgument{[named options]}
%         \umlArgument{Contents}}{}{}
%       \umlSubclass[angleB=270,armB=4em,armAngleB=270
%         ]{Compartment}{Drawable}
%       \umlLabelA{CompartmentDrawable}{<<conceptual>>}
%       \umlAggregation{Compartment}{Classifier}
%       \umlLabelA[offset=1ex]{CompartmentClassifier}{*}
%       \umlLabelB[offset=1ex]{CompartmentClassifier}{1}
%       \umlSchema[pos=\umlTopLeft{Compartment},posDelta={-3em,0},refpoint=tr,
%                  comment=\pagesReference{Compartmentline}]{
%         Compartmentline}{
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Contents}
%         }{}{}
%       \umlSubclass[ref=CompartmentlineDrawable,
%         angleB=270, armB=4em, armAngleB=270]{
%         Compartmentline}{Drawable}
%       \umlAggregation[ref=cline]{Compartmentline}{Compartment}
%       \umlLabelA[offset=1ex]{cline}{*}
%       \umlLabelB[offset=1ex]{cline}{1}
% 
%       \umlSchema[pos=\umlBottomSep{Compartmentline}, refpoint=t,
%                  comment=\pagesReference{Feature}]{
%         Feature}{
%         \umlAttribute{visibility}
%         \umlAttribute{type}
%         \umlAttribute{propertyString}
%         \umlAttribute{initialValue}
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Name}
%         }{}{}
%       \umlSubclass{Feature}{Compartmentline}
% 
%       \umlSchema[pos=\umlBottomSep{Feature},refpoint=t,
%                  comment=\pagesReference{Attribute}]{
%         Attribute}{
%         \umlAttribute{multiplicity}
%         \umlAttribute{ordering}
%         \umlAttribute{/multiplicityOrdering}
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Name}
%         }{}{}
%       \umlSubclass{Attribute}{Feature}
% 
%       \umlSchema[pos=\umlTopLeft{Attribute},refpoint=tr,
%                  posDelta={-\umlNodeSep,0},
%                  comment=\pagesReference{Method}]{
%         Method}{
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Name}
%         \umlArgument{Arguments}
%         }{}{}
%       \umlSubclass{Method}{Feature}
%       \umlSchema[pos=\umlTopRight{Attribute},refpoint=tl,
%                  posDelta={\umlNodeSep,0},
%                  comment=\pagesReference{Argument}]{
%         Argument}{
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Name}
%         }{}{}
%       \umlSubclass{Argument}{Feature}
%       \umlSchema[pos=\umlBottomSep{Classifier},
%                  posDelta={-.5em,-4em},refpoint=tr,
%                  comment=\pagesReference{Class}]{
%         Class}{
%         }{}{
%         \umlArgument{[named Options]}
%         \umlArgument{Name}
%         \umlArgument{Attributes}
%         \umlArgument{Methods}}{}{}{}
%       \umlSubclass{Class}{Classifier}
%       \umlSchema[pos=\umlTopRight{Class},
%                  posDeltaX={1em,0},refpoint=tl,
%                  comment=\pagesReference{Schema}]{
%         Schema}{
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Name}
%         \umlArgument{Attributes}
%         \umlArgument{Methods}
%         \umlArgument{Arguments}
%         \umlArgument{Constraints}
%         \umlArgument{Structure}
%         }{}{}
%       \umlSubclass{Schema}{Classifier}
%     \caption{Classifier commands}
%     \label{fig:useApproachClassifiers}
%   \end{tiny}
% \end{figure}
% 
% 
% \index{subclass!in LaTeX}The subclass relation (e.g., between Box and
% Element) is implemented this way:
% \begin{description}
% \item[Command call] The subclass-commando calls the
%   superclass-commando.  E.g., "\umlBox" calls "\umlElement".
% \item[Variable sharing] The variables of the superclass are also used
%   by the subclass.  "\umlReference" is used by "\umlBox" as well as
%   "\umlElement".  Of course, there is no support for namespaces in
%   \LaTeX{}, so this is easy and requires discipline at the same time.
% \item[Use of named options] A list of named options is sent from the
%   subclass-command to the superclass-command.  Ultimately, it is
%   evaluated in "\umlElement".  Each command on the road can add its
%   own values in the named options; if it is placed last, it takes
%   precedence, if it placed first, it does not.
% 
%   E.g., "\umlClassifier" sets "grayness=0.85" first in its named
%   options, meaning that the default grayness is 0.85.
% \end{description}
% 
% \begin{figure}[htbp]
%   \begin{center}
%     \umlDiagram[grayness=0.92,box=, sizeX=\textwidth,
%     sizeY=12cm,innerBorder=2mm,ref=approachDiagramRelations  ]{
%       }{}% End of diagram
%   \end{center}
%   \begin{tiny}
%       \umlSchema[pos=\umlTop{approachDiagramRelations},
%                  posDelta={-.75em,-.5em},refpoint=tr,
%                  abstract=, importedFrom=main,import=]{
%         Drawable}{
%         \umlAttribute[type=color]{import}
%         \umlAttribute[type=String,propertyString={quasi-static}]{type}
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Contents}}{}{}
%       \umlSchema[pos=\umlTop{approachDiagramRelations},
%                  posDelta={.75em,-.5em},refpoint=tl,
%                  abstract, importedFrom=main,import=]{
%         Element}{
%         \umlAttribute{reference}
%         \umlAttribute{stereotype}
%         \umlAttribute{subof}
%         \umlAttribute[type=bool]{abstract}
%         \umlAttribute{importedFrom}
%         \umlAttribute{comment}
%         }{}{}{}{}
%       \umlSubclass[import=]{Element}{Drawable}
%       \umlSchema[posY=\umlBottomSep{Element},posX=\umlLeft{Element},
%                  refpoint=tl,
%                  comment=\pagesReference{Relation}]{
%         Relation}{
%         \umlAttribute[type=position]{posDelta[AB]}
%         \umlAttribute[type=length]{relationArmA}
%         \umlAttribute[type=angle]{relationAngleA}
%         \umlAttribute[type=angle]{relationArmAngleA}
%         \umlAttribute[default=solid]{umllinestyle}
%         \umlAttribute[type=color]{relationcolor}
%         \umlAttribute[type=color]{/linecolor}
%         \umlAttribute[type=length]{nodesep}
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Node A}
%         \umlArgument{Node B}
%         \umlArgument{Other contents}
%         }{}{}
%       \umlSubclass{Relation}{Element}
%       \umlSchema[posY=\umlTop{Relation},
%         posX=\umlLeft{approachDiagramRelations},
%         refpoint=tl,
%         posDelta={1em,0},abstract=,
%         comment=\pagesReference{AssociationEnd}]{
%         AssociationEnd}{
%         \umlAttribute[type=length,default=0pt]{offset}
%         \umlAttribute[type=real+A+B+C+From+To,default=To]{pos}
%         \umlAttribute[type=length]{height}
%         \umlAttribute[type=angle]{angle}
%         \umlAttribute[type=angle]{posAngle}
%         \umlAttribute[type=?]{refpoint}
%         \umlAttribute[type={Subc.indicator},visibility=-]{type}
%         \umlAttribute[visibility=-]{/noderefClose}
%         \umlAttribute[visibility=-]{/noderefFar}
%         }{}{%
%         \umlArgument{[named options]}
%         \umlArgument{Relation}
%         \umlArgument{Symbol}
%         }{}{
%         \umlDiagram[box=,sizeX=2.5cm, sizeY=1cm,
%                     outerBorder=\umlhsep,innerBorder=\umlhsep,
%                     ref=AssociationEndDiagram]{
%            \umlSchema[pos=\umlBottomLeft{AssociationEndDiagram},
%                       posDelta={1em,1em}, refpoint=bl,ref=AEUsePos]{%
%              A.E.UsePos}{}{}{}{}{}{}{}{}%
%            }\\
%          }
%       \umlAssociation{Relation}{AssociationEnd}
%       \umlLabelA[height=-2ex]{RelationAssociationEnd}{1}
%       \umlLabelB[height=-2ex]{RelationAssociationEnd}{2,*}
% %      \umlSubclass{AssociationEnd}{Drawable}
%        \umlSchema[pos=\umlBottomSep{Relation},
%                   posDelta={-5em,0},refpoint=tr,
%                   comment=\pagesReference{Subclass}]{
%          Subclass}{}{}{
%         \umlArgument{[named options]}
%         \umlArgument{Node A}
%         \umlArgument{Node B}
%         }{}{}{}{}
%        \umlSubclass{Subclass}{Relation}
%        \umlSchema[posY=\umlBottomSep{Subclass},posX=\umlRight{Subclass},
%                   refpoint=tr,
%                   comment=\pagesReference{Generalization}]{
%          Generalization}{}{}{}{}{}{}{}
%        \umlSubclass{Generalization}{Subclass}
%        \umlSchema[pos=\umlTopRight{Relation},
%                   posDelta={3em,7em},refpoint=tl,
%                   comment=\pagesReference{Association}]{
%          Association}{}{}{
%          \umlArgument{[named options]}
%          \umlArgument{Node A}
%          \umlArgument{Node B}
%          }{}{}{}{}
%        \umlSubclass{Association}{Relation}
%        \umlSchema[pos=\umlBottomLeft{Association},
%                   posDelta={0,-1em},refpoint=tl,ref=Inner,
%                   comment=\pagesReference{Inner}]{
%          Inner class}{}{}{
%         \umlArgument{[named options]}
%         \umlArgument{Node A}
%         \umlArgument{Node B}
%         }{}{}{}{}
%        \umlSubclass{Inner}{Relation}
%        \umlSchema[pos=\umlBottomLeft{Inner},
%                   posDelta={0,-1em},refpoint=tl,
%                   comment=\pagesReference{Composition}]{
%          Composition}{}{}{
%         \umlArgument{[named options]}
%         \umlArgument{Node A}
%         \umlArgument{Node B}
%         }{}{}{}{}
%        \umlSubclass{Composition}{Relation}
%        \umlSchema[pos=\umlBottomLeft{Composition},
%                   posDelta={0,-1em},refpoint=tl,
%                   comment=\pagesReference{Aggregation}]{
%          Aggregation}{}{}{
%         \umlArgument{[named options]}
%         \umlArgument{Node A}
%         \umlArgument{Node B}
%         }{}{}{}{}
%        \umlSubclass{Aggregation}{Relation}
%        \umlSchema[pos=\umlBottomSep{Relation},refpoint=tl,posDelta={-4em,0},
%                   comment=\pagesReference{ToRelation}]{
%          ToRelation}{
%          \umlAttribute[type={0--1}, default=0.5]{posMeetLine}}{
%          }{}{
%          \umlArgument{[named options]}
%          \umlArgument{Node}
%          \umlArgument{Relation}}{}{}{}
%        \umlSubclass{ToRelation}{Relation}
%        \umlSchema[posX=\umlLeft{ToRelation},posY=\umlBottomSep{ToRelation},
%                   refpoint=tl,
%                   comment=\pagesReference{AssociationSchema}]{
%          AssociationSchema}{}{}{}{}{}{}{}
%        \umlSubclass{AssociationSchema}{ToRelation}
%        \umlSchema[pos=\umlBottomSep{AssociationSchema},
%                   refpoint=t,
%                   comment=\pagesReference{AssociationClass}]{
%          AssociationClass}{}{}{}{}{}{}{}
%        \umlSubclass{AssociationClass}{AssociationSchema}
%        \umlSchema[pos=\umlTopRight{AssociationSchema},
%                   posDelta={1em,0},refpoint=tl,
%                   comment=\pagesReference{Application}]{
%          Application}{
%          \umlAttribute[type={0--1}, default=0.2]{posMeetLine}}{
%          }{}{}{}{}{}
%        \umlSubclass{Application}{ToRelation}
% 
%       \umlSchema[pos=\umlBottomLeft{AssociationEnd},
%         posDelta={0em,-\umlNodeSep},refpoint=tl,
%                   comment=\pagesReference{Label}]{
%         LabelA}{
%         }{}{}{}{}
%       \umlSubclass{LabelA}{AssociationEnd}
%       \umlSchema[posY=\umlTop{LabelA},posX=\umlRightSep{LabelA},
%         refpoint=tl,
%                   comment=\pagesReference{Symbol}]{
%         SymbolA}{
%         }{}{}{}{}
%       \umlSubclass{SymbolA}{AssociationEnd}
%       \umlSchema[pos=\umlBottomSep{SymbolA}, refpoint=t,
%                   comment=\pagesReference{Navigability}]{
%         NavigabilityA}{
%         }{}{
%         \umlArgument{[named options]}
%         \umlArgument{Relation}
%         }{}{}
%       \umlSubclass{NavigabilityA}{SymbolA}
%     \caption{Relation commands in uml.sty.}
%     \label{fig:useApproachRelations}
%   \end{tiny}
% \end{figure}
% 
% 
% \subsection{Colors}
% 
% 
% Colors are explained in figure \ref{fig:useApproachColors}.  For more
% comments on that figure, see section \vref{sec:useColors}.
% 
% \begin{figure}[htbp]
%   \begin{center}
%     \umlDiagram[grayness=0.92,box=, sizeX=\textwidth,
%     sizeY=13cm,innerBorder=2mm,ref=approachDiagramColors  ]{
%       }{}% End of diagram
%   \end{center}
%   \begin{tiny}
%     \umlSchema[pos=\umlTopLeft{approachDiagramColors},
%       posDelta={1em, -1em}, refpoint=tl,
%       importedFrom={Main},
%     ]{Drawable}{}{}{}{}{}{}
%     \umlSchema[pos=\umlBottom{Drawable},
%       posDelta={0em, -2em}, refpoint=t,
%       importedFrom={Main},
%     ]{Classifier}{}{}{}{}{}{}
%     \umlSchema[pos=\umlBottom{Classifier},
%       posDelta={0em, -2em}, refpoint=t,
%       importedFrom={Main},
%     ]{Diagram}{}{}{}{}{}{}
%     \umlSchema[pos=\umlBottomRight{Diagram},
%       posDelta={2em, -2em}, refpoint=tl,
%       importedFrom={Main},
%     ]{Relation}{}{}{}{}{}{}
%     \umlSchema[pos=\umlTop{approachDiagramColors},
%       posDelta={0em,-1em},refpoint=tr,
%       abstract=, ,
%       comment=\pagesReference{Colorset}
%     ]{Colorset}{
%       \umlAttribute[type=color]{umlColor}
%       \umlAttribute[type=color]{umlLinecolor}
%       \umlAttribute[type=color]{umlFillcolor}
%       \umlAttribute[type=color]{umlClassifierFillcolor}
%       \umlAttribute[type=color]{umlDiagramFillcolor}
%       }{}{}{}{}{}{}{}
%     \umlSchema[pos=\umlTopRight{Colorset},
%       posDelta={2em,-2em}, refpoint=tl,
%       colorset=\umlColorsDefault,
%     ]{ColorsDefault}{
%       \umlAttribute[type=graycolor, default=0]{umlColor}
%       \umlAttribute[type=graycolor, default=0]{umlLinecolor}
%       \umlAttribute[type=graycolor, default=1]{umlFillcolor}
%       \umlAttribute[type=graycolor, default=0.85]{umlClassifierFillcolor}
%       \umlAttribute[type=graycolor, default=0.95]{umlDiagramFillcolor}
%       \umlAttribute[type=graycolor, default=0]{umlRelationColor}
%       }{}{}{}{}{}{}{}
%     \umlSchema[pos=\umlBottomLeft{ColorsDefault},
%       posDelta={0, -2em}, refpoint=tl,
%       colorset=\umlColorsGray,
%     ]{ColorsGray}{
%       \umlAttribute[type=graycolor, default=0.4]{umlColor}
%       \umlAttribute[type=graycolor, default=0.4]{umlLinecolor}
%       \umlAttribute[type=graycolor, default=1]{umlFillcolor}
%       \umlAttribute[type=graycolor, default=0.90]{umlClassifierFillcolor}
%       \umlAttribute[type=graycolor, default=0.98]{umlDiagramFillcolor}
%       \umlAttribute[type=graycolor, default=0]{umlRelationColor}
%       }{}{}{}{}{}{}{}
%     \umlSchema[pos=\umlBottomLeft{ColorsGray},
%       posDelta={0, -2em}, refpoint=tl,
%       colorset=\umlColorsImport,
%     ]{ColorsImport}{
%       \umlAttribute[type=rgbcolor, default={\{1 0 0\}}]{umlColor}
%       \umlAttribute[type=rgbcolor, default={\{1 0 0\}}]{umlLinecolor}
%       \umlAttribute[type=rgbcolor, default={\{1 0.8 0.8\}}]{umlFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{1 0.85 0.85\}}]{umlClassifierFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{1 0.95 0.95\}}]{umlDiagramFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{1 0 0\}}]{umlRelationColor}
%       }{}{}{}{}{}{}{}
%     \umlSchema[pos=\umlBottomLeft{ColorsImport},
%       posDelta={0, -2em}, refpoint=tl,
%       colorset=\umlColorsArgument,
%     ]{ColorsArgument}{
%       \umlAttribute[type=rgbcolor, default={\{0 1 0\}}]{umlColor}
%       \umlAttribute[type=rgbcolor, default={\{0 1 0\}}]{umlLinecolor}
%       \umlAttribute[type=rgbcolor, default={\{0.8 1 0.8\}}]{umlFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{0.85 1 0.85\}}]{umlClassifierFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{0.95 1 0.95\}}]{umlDiagramFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{0 1 0\}}]{umlRelationColor}
%       }{}{}{}{}{}{}{}
%     \umlSchema[pos=\umlBottomLeft{ColorsArgument},
%       posDelta={0, -2em}, refpoint=tl,
%       colorset=\umlColorsRed,
%     ]{ColorsRed}{
%       \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlColor}
%       \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlLinecolor}
%       \umlAttribute[type=rgbcolor, default={\{0.8 0.8 1\}}]{umlFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{0.85 0.85 1\}}]{umlClassifierFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{0.95 0.95 1\}}]{umlDiagramFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlRelationColor}
%       }{}{}{}{}{}{}{}
%     \umlSchema[pos=\umlTopLeft{ColorsRed},
%       posDelta={-1em, 0}, refpoint=tr,
%       colorset=\umlColorsSub,
%     ]{ColorsSub}{
%       \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlColor}
%       \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlLinecolor}
%       \umlAttribute[type=rgbcolor, default={\{0.8 0.8 1\}}]{umlFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{0.85 0.85 1\}}]{umlClassifierFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{0.95 0.95 1\}}]{umlDiagramFillcolor}
%       \umlAttribute[type=rgbcolor, default={\{0 0 1\}}]{umlRelationColor}
%       }{}{}{}{}{}{}{}
%     \umlSubclass[angleA=180,colorset=\umlColorsDefault]{ColorsDefault}{Colorset}
%     \umlSubclass[angleA=180,colorset=\umlColorsImport]{ColorsImport}{Colorset}
%     \umlSubclass[angleA=180,colorset=\umlColorsGray]{ColorsGray}{Colorset}
%     \umlSubclass[angleA=180,colorset=\umlColorsArgument]{ColorsArgument}{Colorset}
%     \umlSubclass[angleA=180,colorset=\umlColorsRed]{ColorsRed}{Colorset}
%     \umlSubclass[colorset=\umlColorsSub]{ColorsSub}{Colorset}
%     \umlSubclass[import=]{Classifier}{Drawable}
%     \umlSubclass[import=,armB=1em,armAngleB=315,angleB=340]{Relation}{Drawable}
%     \umlSubclass[import=]{Diagram}{Classifier}
%     \umlAssociation{Drawable}{Colorset}
%     \umlAssociation{Classifier}{Colorset}
%     \umlAssociation{Diagram}{Colorset}
%     \umlAssociation{Relation}{Colorset}
%     \caption{Color commands in uml.sty.  The colors in this figure is for
%       demonstration, and not necessarily correct.  See also
%       \vref{sec:useColors}.}
%     \label{fig:useApproachColors}
%   \end{tiny}
% \end{figure}
% 
% \subsection{Positions}
% 
% Positions are explained in figure \ref{fig:useApproachPositions}.  For more
% comments on that figure, see section \vref{sec:usePositions}.
% 
% \newcommand\umlPrimitive[5][]{%
%   \umlClassifier[kind=Primitive,#1,stereotype={primitive},suppress]{#2}{%
%     \umlCompartment[name=example]{#3}
%     \umlCompartment[name=arguments]{#5}}}
%     
% \begin{figure}[htbp]
%   \begin{center}
%     \umlDiagram[grayness=0.92,box=, sizeX=\textwidth,
%     sizeY=8cm,innerBorder=2mm,ref=approachDiagramPositions]{}{}% End of diagram
%   \end{center}
%   \begin{tiny}
%     \begin{umlColors}{\umlColorsImport}
%       \umlSchema[pos=\umlTopLeft{approachDiagramPositions},
%         posDelta={1em,-9em}, refpoint=tl,importedFrom=main,
%       ]{Relation}{}{}{}{}{}{}{}
%     \end{umlColors}
%     \begin{umlColors}{\umlColorsRed}
%       \umlCompartmentNamesShowtrue
%     \umlPrimitive[pos=\umlTop{approachDiagramPositions},
%       posDelta={0, -1em}, refpoint=t]{Coordinate}{}{}{}{}{}{}
%     \umlPrimitive[pos=\umlTopRight{Relation},
%       posDelta={3em,0em},
%       refpoint=tl,
%     ]{Node}{\umlCompartmentText{A}}{}{}{}{}{}
%     \umlPrimitive[pos=\umlTopRight{Node},ref=parNode,
%       posDelta={3em,0},refpoint=tl,
%     ]{[par]Node}{\umlCompartmentText{[angle=45]A}}{}{
%       \umlArgument{angle}
%       \umlArgument[type=length]{nodesep}
%       \umlArgument{offset}}{}{}{}
%     \umlPrimitive[pos=\umlTopRight{parNode},posDelta={1em,0},refpoint=tl,
%     ]{Polar}{\umlCompartmentText{3;110}}{}{}{}{}{}
%     \umlPrimitive[pos=\umlTopRight{Polar},ref=ps,posDelta={1em,0},refpoint=tl,
%     ]{!ps}{\umlCompartmentText{!3 110 cos mul 2}}{}{}{}{}{}
%     \umlPrimitive[pos=\umlTopRight{ps},ref=coors,posDelta={1em,0},refpoint=tl,
%     ]{{coor1Icoor2}}{\umlCompartmentText{A|1in;30}}{}{}{}{}{}
%     \umlPrimitive[pos=\umlTopRight{coors},posDelta={1em,0},refpoint=tl,
%       refpoint=tl]{Cartesian}{\umlCompartmentText{3,4}}{}{}{}{}{}
%     \umlSubclass[angleA=90,angleB=350]{Cartesian}{Coordinate}
%     \umlSubclass[angleA=90]{Polar}{Coordinate}
%     \umlSubclass[angleA=90]{Node}{Coordinate}
%     \umlSubclass[angleA=90]{parNode}{Coordinate}
%     \umlSubclass[angleA=90]{ps}{Coordinate}
%     \umlSubclass[angleA=90]{coors}{Coordinate}
%     \umlAggregation[angleA=70,armA=1em,armAngleA=90,
%       angleB=345]{coors}{Coordinate}
%     \umlLabel[height=-1ex,offset=1ex]{coorsCoordinate}{2}
%     \umlAggregation{Node}{parNode}
%     \end{umlColors}
%     \begin{umlColors}{\umlColorsImport}
%       \umlSchema[pos=\umlTopRight{approachDiagramPositions},
%         posDelta={-1em,-1em}, refpoint=tr,
%         importedFrom=main,
%       ]{Box}{}{}{}{}{}{}{}
%       \umlAssociation{Coordinate}{Box}
%       \umlLabelB{CoordinateBox}{pos}
%       \umlAssociation{Cartesian}{Box}
%       \umlLabelB[height=-1ex]{CartesianBox}{posDelta}
%     \end{umlColors}
%     \begin{umlColors}{\umlColorsImport}
%       \umlAssociation{Relation}{Node}
%       \umlLabelA{RelationNode}{Node[AB]}
%     \end{umlColors}
%     \umlSchema[posX=\umlLeft{approachDiagramPositions},
%       posY=\umlBottom{parNode},
%       posDelta={1em,2em}, refpoint=tl,
%       comment=\pagesReference{PlaceNode},
%     ]{PlaceNode}{
%       \umlAttribute[type=length, default=0pt]{leftside}
%       \umlAttribute[type=length, default=0pt]{rightside}
%       \umlAttribute[type=length, default=0pt]{top}
%       \umlAttribute[type=length, default=0pt]{bottom}
%       \umlAttribute[type=length, default=0pt]{left}
%       \umlAttribute[type=length, default=0pt]{right}
%       \umlAttribute[type=length, default=0pt]{up}
%       \umlAttribute[type=length, default=0pt]{down}
%       \umlAttribute[type=angle]{angle[ XY]}
%       \umlAttribute[type=offset]{offset[ XY]}
%       \umlAttribute[type=nodesep]{nodesep[ XY]}
%       }{}{
%       \umlArgument{[named options]}
%       \umlArgument{Node}
%       \umlArgument{New node name}
%       }{}{}{}
%     \umlSubclass{PlaceNode}{Node}
%     \umlSymbol[fraction=0.1,refpoint=b,angle=N]{PlaceNodeNode}{<<places>>}
%     \umlSchema[pos=\umlTopLeft{approachDiagramPositions},
%       posDelta={1em,-1em},refpoint=tl,
%       comment=\pagesReference{TopLeft}
%     ]{TopLeft}{}{}{\umlArgument{node}}{}{}{}{}
%     \umlSubclass{TopLeft}{Coordinate}
%     \caption{Position commands in uml.sty.  See also
%       \vref{sec:usePositions}.}
%     \label{fig:useApproachPositions}
%     \label{fig:approachEnd}
%   \end{tiny}
% \end{figure}
% 
% In figure \ref{fig:useApproachPositions}, the blue stuff is imported
% from diagram \ref{fig:useApproach}.  The red stuff is derived from the
% PSTricks manual.  Only the black classes is defined here.
% 
% \setlength\umlSymbolHeightDefault{2ex}
% \setlength\umlSymbolWidthDefault{1ex}
% 
% 
% \section{Drawable}\label{sec:useDrawable}
% 
% A Drawable is an unspecified UML construct.  It has no graphical
% appearance itself, but is a common superclass for all uml.sty
% constructs.
% 
% 
% The syntax of "\umlDrawable" \DescribeMacro\umlDrawable is, as
% indicated in figure~\vref{fig:useApproach},
% "\umlDrawable["\meta{named options}"]"\meta{Contents}.
% 
% "\umlDrawable" is an ``abstract command'', not ment to be used
% directly by users.  But "\umlDrawable[import=]{Contents}" would yield
% \fbox{\umlDrawable[import=]{Contents}} (the border around is added
% here to emphasize the example).
% 
% 
% 
% \subsection{Named options}
% 
% The named options "import=" and "noimport=" are described under the
% next section.
% 
% 
% 
% 
% \subsubsection{import}
% \label{sec:useImport}
% 
% \newcommand\namedO[1]{$#1$\DescribeMacro{#1-}}
% 
% The named options \namedO{import}{} and \namedO{noimport}{} indicate
% whether this construct are defined in another diagram, and only
% imported here.
% 
% They take no options.
% 
% They make "\umlColorsImport" and "\umlColorsDefault",
% \emph{henholdsvis}, take effect on the construct.
% 
% See also the variable Element.importedFrom
% (section~\ref{sec:useImportedFrom}).
% 
% 
% 
% 
% \section{Element}
% \label{sec:useElement}
% 
% An element is an construct which can be referenced.
% 
% 
% The syntax of "\umlElement" \DescribeMacro\umlElement is exactly the
% same as that of "\umlDrawable".  However, "\umlElement" has more named options.
% 
% "\umlElement" is abstract too.  It does not itself use much of the
% information supplied by the named options.  "\umlElement{Contents}"
% would yield \fbox{\umlElement{Contents}}.
% 
% 
% \subsection{Named options}
% \label{sec:useElementNamed}
% 
% 
% \subsubsection{Reference}
% \label{sec:ref}
% 
% Each element has a \namedO{reference}.  $reference$
% is used among other things when placing nodes.
% 
% Legal values are valid PSTricks node names (\vref{sec:useNodeNames}).
% 
% Default values differ between the constructs.  
% 
% $reference$ is also used by some commands to make several nodes with
% derived names.  E.g.,  "Aa"$reference$ of a relation is one
% of the endpoints.
% 
% \subsubsection{Stereotype}
% \label{sec:useStereotype}
% 
% The variable \namedO{stereotype}{} indicates the
% stereotype of the construct.  The value is not used by every
% construct.  Typically, the name is placed in <<guillements>> around or
% in the construct.
% 
% Legal values is any string.  Default is no stereotype.
% 
% \subsubsection{Subof}
% \label{sec:useSubof}
% 
% \index{generalization}The variable \namedO{subof}{} indicates the
% superconstruct (in standard UML parlance, the \emph{generalization})
% of this construct.  The value is not used by every construct, but is
% typically placed around or in the construct.
% 
% Legal values is any string.  Default is nothing.
% 
% The $subof$ variable and the subclass relation
% (section~\ref{sec:useSubclass}) are different ways of expressing the
% same thing.
% 
% \subsubsection{ImportedFrom}
% \label{sec:useImportedFrom}
% 
% The variable \namedO{importedFrom}{} indicates which package or digram this
% construct is imported from.  The value is not used by every construct,
% but is typically placed around or in the construct.
% 
% Legal values is any string.  Default is nothing.
% 
% \subsubsection{Comment}
% \label{sec:useComment}
% 
% The variable \namedO{comment}{} is a comment.  The value is not used by every
% construct, but is typically placed around or in the construct.
% 
% Legal values is any string.  Default is nothing.
% 
% 
% 
% 
% \section{Box}
% \label{sec:useBox}
% 
% Box is an UML construct drawn as a box, i.e.\ with some areal.  Boxes
% has size, position and possibly a border.
% 
% The syntax is "\umlBox["\meta{Named options}"]{"\meta{Contents}"}".
% 
% "\umlBox[box=,border=2pt,innerBorder=2pt]{Contents}" would be typeset as
% \fbox{\umlBox[box=,border=2pt,innerBorder=2pt]{Contents}} (The inner border is made by
% the box). 
% 
% \subsection{Named options concerning location}
% \label{sec:useBoxesLocation}
% 
% 
% Boxes are positioned by various named options.  The positioning
% mechanism starts at ($pos$), given by the "pos" or "posX" and "posY" named
% potions.  Then, it moves to ($posDelta$), given by the "posDelta" or
% "posDeltaX" and "posDeltaY" keywords.  The $refpoint$ of that class
% (e.g.\ top left corner), given by "refpoint" is placed at this point.
% 
% All the named options with names starting with "pos" have legal values
% coordinate pairs, as described \vpageref{sec:useSyntaxCoordinates}.
% 
% \begin{description}
% \item["pos"] sets \namedO{pos}.  Default is to look at the values set by
%   "posX" and "posY".
% \item["posX"] sets \DescribeMacro{posX-}$pos$ horizontally.  Default is "0,0".
% \item["posY"] sets \DescribeMacro{posY-}$pos$ vertically.  Default is "0,0".
% \item["posDelta"] sets \namedO{posDelta}.  Default is to look at the values set by
%   "posDeltaX" and "posDeltaY".
% \item["posDeltaX"] sets \DescribeMacro{posDeltaX-}$posDelta$ horizontally.  Default is "0,0".
% \item["posDeltaY"] sets \DescribeMacro{posDeltaY-}$posDelta$ vertically.  Default is "0,0".
% \item["refpoint"] \DescribeMacro{refpoint-}which point in the class to be placed.  Can
%   be any of "l", "r", "t", "b" and "B", meaning left, right, top,
%   bottom and baseline, or any reasonable combination of them.
% \end{description}
% 
% E.g., if the named options are "[pos=Car, posDelta={1,-1}, refpoint=tl]",
% the top left corner of the class are placed one unit to the right and
% one down from the node Car.
% 
% \subsection{Boxes in text}
% 
% Default, an box is placed inside a zero size hbox.
% While used in text, you want the class to be put inside a hbox with
% the natural size of the box.  This is done by means of the named
% option "box".  Note that a "=" must be present, even if nothing
% follows it before the next ",".  This option overrides the location
% named options.
% 
% \begin{description}
% \item["box"] \DescribeMacro{box-}normally, the class is put in a hbox
%   of size (0,0), suitable for use in a diagram.  With "box=" set, it
%   is put in a hbox with its natural size, suitable for use in text.
%   The class \umlClass[box=]{Class in text}{}{}, made by
%   "\umlClass[box=]{Class in text}{}{}", can serve as an example.
% \end{description}
% 
% 
% \subsection{Named options concerning visual appearance}
% \label{sec:useBoxesVisual}
% 
% 
% \subsubsection{grayness}
% 
% \DescribeMacro{grayness-}The grayness in the background in the box,
% from "0" (black) to "1" (white).  Default value without named option
% is 1 (white), with named option .85 (still quite bright).
% 
% 
% \subsubsection{border}
% 
% \DescribeMacro{border-}The width of the border.  Legal values are
% lengths.  Default value without named option is 0 (no border), default
% value with named option without value is 0.4~pt.
% 
% \subsubsection{borderLine}
% 
% \DescribeMacro{borderLine-}The style of the border.  Legal values are
% line styles (section~\ref{sec:useLinestyles}).  Default is solid.
% 
% 
% \subsubsection{innerBorder}
% 
% \DescribeMacro{innerBorder-}The inner margin of the box.  Legal values
% are lengths.  Default value is 0.
% 
% 
% \subsection{Named options concerning size}
% \label{sec:useBoxesSize}
% 
% Some boxes (not all) allow the user to specify the size of the
% interior of the box.
% \begin{description}
% \item["sizeX"] \DescribeMacro{sizeX-}The horizontal size of the box.
%   Must be a valid length.
% \item["sizeY"] \DescribeMacro{sizeY-}The vertical size of the box.
%   Must be a valid length.
% \end{description}
% 
% The default size of the box is not specified here, but it normally is
% the natural size of \meta{stuff}.
% 
% 
% 
% \section{Diagram}
% \label{sec:useDiagram}
% \label{sec:useDiagrams}
% 
% 
% \DescribeMacro{\umlDiagram}A diagram is an area, with a coordinate
% system.  Stuff like classes can be placed at the diagram.  The syntax
% of the "\umlDiagram" command
% is "\umlDiagram["\meta{named options}"]{"\meta{stuff}"}".
% 
% \meta{stuff} is placed inside the diagram.  It can be positioned in
% various ways, using mechanisms from \TeX{} or PSTricks or using named
% options in "\umlClass" or "\umlSchema".
% 
% Some positioning mechanisms are very sensitive to ``spurious spaces'',
% \index{spurious spaces}\index{spaces!spurious}pushing some of the
% \meta{stuff} to the right.  Line breaks (without a comment sign
% before) can create such mystical spurious spaces.  Using named options
% like "posX" and "posY" should eliminate this problem.
% 
% "\umlDiagram" is an "\umlBox", and inherits all its named options.  
% 
% Once, I discovered that "\umlDiagram" also works without the "sizeX"
% and "sizeY" options.  Using it that way, you typically want to use
% "innerBorder" on the diagram and "box" on the contents.  You may still
% use "sizeX" and "sizeY" as minimum size.
% 
%   The named option "box=" is always set to true in "\umlDiagram".
% 
% \subsection{Example}
% 
% The diagram in figure \vref{fig:diagram} is made by the code
% 
% \begin{verbatim}
% \umlDiagram[box=,border,sizeX=7cm,sizeY=4cm]{%
%   \umlClass[refpoint=bl, pos={3,3}]{ClassName}{}{}}
% \end{verbatim}
% 
% \begin{figure}[htbp]
%   \begin{center}
%     \umlDiagram[box=,border,sizeX=7cm,sizeY=4cm]{%
%       \umlClass[refpoint=bl, pos={3,3}]{ClassName}{}{}}
%     \caption{Example of a diagram}%
%     \label{fig:diagram}%
%   \end{center}%
% \end{figure}%
% 
% This creates a diagram which is 7~cm wide and 4~cm
% high.  It contains a class, with its bottom left corner positioned at
% position (3,3).  
% 
% Note that the class, as a stretchbox, determines its size
% on the basis of its contents, as opposed to a diagram, which has its
% size given.
% 
% 
% 
% \section{Stretchbox}
% \label{sec:useStretchbox}
% 
% A stretchbox is a box which determines its size on the basis of its
% contents.  It also has a name.
% 
% The syntax\DescribeMacro{\umlStretchbox} is
% "\umlStretchbox["\meta{named options}"]"\meta{name}\meta{contents}.
% 
% 
% \subsection{Name, graphicalName and reference}
% 
% "\umlStretchbox" takes a name as its second argument.  Legal values is
% strings.  The name is a default reference.  If the string contains spaces or something making
% it a non-valid node name, remember to supply a reference with the
% "reference=" named option.
% 
% Subclasses of "\umlStretchBox" may make a
% \DescribeMacro{graphicalName} graphicalName based on the name.  The
% graphical name is typically the string in a large font.
% 
% 
% \section{Classifier}
% \label{sec:useClassifier}
% 
% \DescribeMacro{\umlClassifier}A classifier is a stretchbox which can
% be instantiated.  Classifier is direct superclass to Class.
% 
% It has the same syntax as "\umlStretchbox". However, there is another
% named option:
% 
% \begin{description}
% \item["object"] \DescribeMacro{object-}Makes the graphical name underlined.
% \end{description}
% 
% Classifiers are typically divided in \emph{compartments}, stacked on
% top of each other.  Standard UML classes are divided in three
% compartments.
% 
% 
% \section{Compartment}
% \label{sec:useCompartment}
% 
% \DescribeMacro{\umlCompartment}A compartment is a part (of a
% classifier).  The compartments are stacked on top of each other.  
% 
% The syntax is "\umlCompartment["\meta{Named
%   options}"]"\meta{Contents}.  Compartments are to be placed inside
% classifiers.  In the implementation, "\umlClassifier" is implemented
% as a table and "\umlCompartment" as table lines.
% 
% "\umlCompartment" requires its contents to be ended by a linebreak
% ("\\").  This is typically given by "\umlCompartmentline".
% 
% Example: \fbox{%
%   \umlClassifier[box=]{Name}{%
%     \umlCompartment{First line\\}
%     \umlCompartment{Second line\\}
%     \umlCompartment{
%       \umlCompartmentline{Compartment line}}
%     }} was made by
% \begin{verbatim}
% \umlClassifier[box=]{Name}{%
%   \umlCompartment{First line\\}
%   \umlCompartment{Second line\\}}
%   \umlCompartment{%
%     \umlCompartmentline{Compartment line}}
%  \end{verbatim}
% 
% 
% \subsection{Suppression}
% 
% By default, empty compartments are drawn, indicating that the
% compartment is empty.  The UML specification [UML1.4, 3.22.3]
% states that ``a separator line is not drawn for a missing
% compartment.''
% 
% Suppression is \emph{styrt} by the boolean variable
% "umlCompartmentSuppress".  You can set this to true
% ("\umlCompartmentSuppresstrue") or false
% ("\umlCompartmentSuppressfalse") whenever you wish.
% 
% You can also use the named option
% \DescribeMacro{suppress-}"suppress=" on one compartment or something
% bigger (such as a classifier).  Legal values are "true" and "false"
% when used without value, default is "true".
% 
% 
% \subsection{Name}
% 
% You can set the name with the named option
% \DescribeMacro{name-}"name=".  
% 
% If the boolean value "\umlCompartmentNameShow" are true, the name is
% shown centered bold in the top of the compartment.  You may say
% "\umlCompartmentNameShowtrue" or "\umlCompartmentNameShowfalse" when
% you wish.  
% 
% You can also use the named option \DescribeMacro{showname}"showname="
% on a construct.  Legal values are true and false, default is true.
% 
% 
% \section{Compartmentline}
% \label{sec:useCompartmentline}
% 
% \DescribeMacro{\umlCompartmentline}This is a line in a compartment.
% It ends with a line feed.  Subcommands of "\umlCompartmentline" is
% "\umlAttribute" and "\umlMethod".
% 
% The syntax is as usual "\umlCompartmentline["\meta{named
% options}"]"\meta{Contents}.  For example, see above.  Note the space
% in front of the contents when using "\umlCompartmentline", as opposed
% to raw text.
% 
% All lines in compartments are required to end by a line break.
% "\umlCompartmentline" supplies this.
% 
% 
% 
% \section{Feature}
% \label{sec:useFeature}
% 
% \DescribeMacro{\umlFeature}A feature is a line in a compartment in a
% classifier, such as a method, attribute or argument.
% 
% 
% \subsubsection{visibility}
% 
% \DescribeMacro{visibility-}Legal values for the visibility is
% Visibility is typically one of + (public), \# (protected), -
% (private) or "~" (package).  Default is +.
% 
% The command \DescribeMacro\umlTilde"\umlTilde" writes a \umlTilde.
% \subsubsection{type}
% 
% \DescribeMacro{type-}This is the type of an attribute or an argument,
% or the return type of a method.
% 
% \subsubsection{propertyString}
% 
% \DescribeMacro{propertyString-}An UML property string.
% 
% 
% 
% 
% \section{Method}
% \label{sec:useMethod}
% 
% 
% 
% "\umlMethod" \DescribeMacro\umlMethod is of the form
% "\umlMethod["\meta{options}"]{"\meta{name}"}{"\meta{arguments}"}".  
% 
% "\umlMethod" provides "returntype"\DescribeMacro{returntype-}{} as an
% alias for "type".
% 
% "\umlMethod[visibility=\#, returntype=real]{sqrt}{int arg}"
% makes \begin{tabular}{|c|}\hline\umlMethod[visibility=\#,
% returntype=real]{sqrt}{int arg}\hline\end{tabular}.
% 
% 
% 
% \section{Attribute}
% \label{sec:useAttribute}
% 
% 
% "\umlAttribute" \DescribeMacro\umlAttribute is of the form
% "\umlAttribute["\meta{options}"]{"\meta{name}"}".  
% 
% 
% "\umlAttribute[visibility=\#, default=186, type=int]{height}" 
% makes
% \begin{tabular}{|c|}\hline
% \umlAttribute[visibility=\#, default=186, type=int]{height}\hline
% \end{tabular}.
% 
% 
% \section{Argument}
% \label{sec:useArgument}
% 
% Arguments to classifiers are not a standard UML construct.  However,
% we have included it here.
% 
% "\umlArgument" \DescribeMacro\umlArgument is of the form
% "\umlArgument["\meta{options}"]{"\meta{name}"}".  
% 
% "\umlArgument[type=Class]{nodetype}" 
% would be rendered as
% \begin{tabular}{|c|}\hline
% \umlArgument[type=Class]{nodetype}\hline
% \end{tabular}.
% 
% \section{Class}
% \label{sec:useClass}
% 
% \DescribeMacro{\umlClass}The macro "\umlClass" draws an UML class.  Its
% syntax is "\umlClass["\meta{named
% options}"]"\meta{name}\meta{variables}\meta{methods}.  The
% \meta{variables} and \meta{methods} parts are typically drawn using
% "\umlVariable" and "\umlMethod".
% 
% Graphically, the class is divided in three compartments above each
% other.  The upper compartment contains the class name.  The middle one
% contains the variables, and the lower the methods.
% 
% 
% \index{burger}Example: Figure \vref{fig:useClass} is coded as:
% \begin{verbatim}
% \umlClass[box=,
%           reference=AmericanMan,
%           stereotype=Man,
%           import=,
%           importedFrom=America,
%           comment=A man from America
%          ]{American Man}{%
%            \umlAttribute[visibility=\#, type=State]{State}
%            \umlAttribute[visibility=\#, 
%              default=Mc Donalds]{Favourite burger}}{%
%            \umlMethod[visibility=]{Watch TV}{}
%            \umlMethod[visibility=-, returntype=int]{Vote}{Party party}
% }
% \end{verbatim}
% 
% \begin{figure}[Ht]
%   \begin{center}
% \iftrue
% \umlClass[box=,
%           reference=AmericanMan,
%           stereotype=Man,
%           import=,
%           importedFrom=America,
%           comment=A man from America
%          ]{American Man}{%
%            \umlAttribute[visibility=\#, type=State]{State}
%            \umlAttribute[visibility=\#, 
%              default=Mc Donalds]{Favourite burger}}{%
%            \umlMethod[visibility=]{Watch TV}{}
%            \umlMethod[visibility=-, returntype=int]{Vote}{Party party}
% }
%     \caption{A class}
%     \label{fig:useClass}\label{fig:class}
% \fi
%   \end{center}
% \end{figure}
% 
% Also, see figure \vref{fig:useSchema} for a larger example.
% 
% 
% 
% \section{Schema}
% \label{sec:useSchema}
% 
% \emph{Schema} is not a standard UML construct.  It is a generalization
% of class I find very useful.  A schema is a class which also can
% \begin{itemize}
% \item take arguments
% \item be instantiated freely into other schemas
% \item have an internal structure, typically using its arguments
% \end{itemize}
% Graphically, schemas look pretty much like classes, with attribute and
% method compartments.  In addition, it have more compartments.  Here
% are they all:
% \begin{description}
% \item[Name] compartment contains the name and possibly stereotype and
%   other symbols, just like in the Class symbol.
% \item[Attributes] compartment contains the attributes, like in Class.
% \item[Methods] compartment contains the methods, like in Class.
% \item[Arguments] compartment contains the schema arguments.  Each
%   argument is another schema (possibly an object).
% \item[Constraints] compartment contains constraints.
% \item[Structure] compartment typically contains a class diagram.
% \end{description}
% 
% \DescribeMacro{\umlSchema} This corresponds to more arguments to
% "\umlSchema".  The spec is
% "\umlSchema["\meta{named options}"]{"\meta{Name}"}{"\meta{Attributes}%
% "}{"\meta{Methods}"}\"\\"{"\meta{Arguments}"}{"\meta{Constraints}"}{"\meta{Structure}"}".
% Almost everything said about "\umlClass" is also true about
% "\umlSchema".  The two commands inherit the same named options.
% 
% "\umlSchema" is included for two reasons: Because I use them myself,
% and to show how you can make your own classifiers yourself.
% 
% \subsection{Example (Stack)}
% 
% \index{Node!in stack}\noindent{}\begin{tabular}{@{}lc}
% \noindent{}\parbox{.618\linewidth}{\label{Stack}The figure to the right
%  is a simple stack.  To
% start with the fourth compartment, the schema Stack takes an other
% metaclass as argument (named \emph{type}).  If \emph{type} is set to,
% say, Procedure, we get a Stack of procedures.  Stack has one
% attribute, a private pointer to the first Node.  This first node is of
% type \emph{type}.  There are two procedures, the well-known push and
% pop, both public; push takes an instance of \emph{type} as argument,
% pop returns a \emph{type}.  There is one constraint, that a Stack
% should be equal to itself pushed once and popped once.  
% }
% &
% \parbox[][][t]{.382\linewidth}{
%  \umlSchema[box=]{Stack}{%Attributes
%   \umlAttribute[visibility=-, type=\emph{type}, default=null, ]{firstNode}
%   }{% Methods
%   \umlMethod[visibility]{push}{\emph{type} x}
%   \umlMethod[visibility, type=\emph{type}]{pop}{}
%   }{% Arguments
%   \umlArgument[type=Metaclass]{type}
%   }{% Constraints
%   \umlCompartmentline{S:Stack = S.push(x).pop()}
%   }{% Structure
%   \umlDiagram[box=,innerBorder=2mm, sizeX=11em, sizeY=5em,
%   ref=StackDiagram, outerBorder=2mm]{%
%     \umlClass[pos={.5,.5}, ref=stackNode]{Node}{
%       \umlAttribute[visibility=\#, type=\emph{type}]{data}}{}
%     \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em
%     ]{stackNode}{stackNode}{
%     \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}
%     \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}}
%     }% End of diagram
%   \cr}}% End of Stack
% \end{tabular}
% 
% The seventh compartment describes the internal structure of Stack.
% Here, we do not bother distinguishing between the interface and the
% internal implementation of Stack.
% 
% The \LaTeX{} source is here:
% \begin{verbatim}
% \umlSchema[box=]{Stack}{%Attributes
%   \umlAttribute[visibility=-, type=\emph{type}, default=null, ]{firstNode}
%   }{% Methods
%   \umlMethod[visibility]{push}{\emph{type} x}
%   \umlMethod[visibility, type=\emph{type}]{pop}{}
%   }{% Arguments
%   \umlArgument[type=Metaclass]{type}
%   }{% Constraints
%   \umlCompartmentline{S:Stack = S.push(x).pop()}
%   }{% Structure
%   \umlDiagram[box=,innerBorder=2mm, sizeX=11em, sizeY=5em,
%               ref=StackDiagram, outerBorder=2mm]{%
%     \umlClass[pos={.5,.5}, ref=stackNode]{Node}{
%       \umlAttribute[visibility=\#, type=\emph{type}]{data}}{}%
%     \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em
%                  ]{stackNode}{stackNode}{%
%       \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}%
%       \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}%
%       }
%     }% End of diagram
% \cr}% End of Stack
% \end{verbatim}
% 
% 
% \section{Relation}\label{sec:useRelation}
% 
% \emph{Relations} are all kinds of connections between classifiers (and
% other nodes).  Examples of relations include common associations, the
% subclass (specialization) relation and the aggregation relation.
% While these constructs are semantically very different, they can all
% be drawn as connections between schemas.
% 
%   \DescribeMacro{\umlRelation}"\umlRelation" itself, like most of its
%   subclasses, is of the form "\umlRelation["\meta{Named
%     options}"]"\meta{From}\meta{To}\meta{Other contents}, where
%   \meta{From} and \meta{To} are references to nodes (e.g.\ classes and
%   nodes).  \meta{Other contents} typically contains labels etc which
%   should have the same colors etc as the relation.  The argument
%   \meta{Other contents} are new since version 0.09.  This may cause
%   errors if one tries to use "\umlRelation" with the old arguments.
% 
% Figure \vref{fig:generalRelation} shows some of the capabilities of
% "uml.sty" relations.  
% 
% The source of figure \ref{fig:generalRelation} is:
% \begin{verbatim}
% \umlDiagram[box=,sizeX=7cm, sizeY=7cm, ref=relation]{%
%   \umlClass[pos=\umlBottomLeft{relation}, posDelta={1,1}, refpoint=bl,
%             reference=A]{Class A}{}{}%
%   \umlClass[pos=\umlTopRight{relation}, posDelta={-1,-1}, refpoint=tr, 
%             reference=B]{Class B}{}{}%
%   \umlRelation{A}{B}{
%     \umlLabelA{AB}{*}
%     \umlLabelB{AB}{1}}
%   \umlLabel[fraction=.5,offset=0]{AB}{center}
%   \umlAssociationEnd[fraction=A, angle=U]{AB}{A}
%   \umlAssociationEnd[fraction=B, angle=R]{AB}{B}
%   \umlSubclass[ref=ABsub, angleA=0, armA=5, armAngleA=0,
%     angleB=300, linecolor=blue,nodesep=1ex]{A}{B}
%   \umlComposition[reference=ABComp,
%     angleA=120, arm=4, armAngleA=80,
%     angleB=180, armAngleB=190]{A}{B}
%   \umlNavigabilityA{ABComp}
%   }
% \end{verbatim}
% 
% \begin{figure}[htbp]
%   \begin{center}
%     \umlDiagram[box=,sizeX=7cm, sizeY=7cm, ref=relation]{
%       \umlClass[pos=\umlBottomLeft{relation}, posDelta={1,1}, refpoint=bl,
%                 reference=A]{Class A}{}{}
%       \umlClass[pos=\umlTopRight{relation}, posDelta={-1,-1}, refpoint=tr, 
%                 reference=B]{Class B}{}{}
%       \umlRelation{A}{B}{
%         \umlLabelA{AB}{*}
%         \umlLabelB{AB}{1}}
%       \umlLabel[fraction=.5,offset=0]{AB}{center}
%       \umlAssociationEnd[fraction=A, angle=U]{AB}{A}
%       \umlAssociationEnd[fraction=B, angle=R]{AB}{B}
%       \umlSubclass[ref=ABsub, angleA=0, armA=5, armAngleA=0,
%         angleB=300, linecolor=blue,nodesep=1ex]{A}{B}
%       \umlComposition[reference=ABComp,
%         angleA=120, arm=4, armAngleA=80,
%         angleB=180, armAngleB=190]{A}{B}
%       \umlNavigabilityA{ABComp}
%       }
%     \caption{Some relations (silly relations, but good example)}
%     \label{fig:generalRelation}
%   \end{center}
% \end{figure}
% 
% 
% 
% \subsection{Appearance of the connector}
% 
% The visual appearance of the connector is influenced by the following
% named option:
% 
% \begin{description}
% \item["umllinestyle"] A\DescribeMacro{umllinestyle-} umllinestyle to draw the
%   connector.  Default is "solid".
% \item["linecolor"] The color of the line.\DescribeMacro{linecolor-}
% \end{description}
% 
% \subsection{Geometry of the connector}
% 
% The connector consists of three line segments: A main part in the
% middle and two arms.  By default, the arms have zero length.  The arms
% are sometimes referred to as "A" and "B".
% 
% In the example, figure \ref{fig:generalRelation}, the both arms of
% the middle relation and one of the blue one have lengths zero.
% 
% \paragraph{Where the connector hits the node}
% 
% By default, the connector tries to be as short as possible.  With no
% named options, the connector will be a straight line between the
% nodes.  This can be overridden by the named option
% \begin{description}
% \item["angle", "angleA" and "angleB"] \DescribeMacro{angle-}Angle at
%   which the connector hits the node.  "angleA" affects \meta{From},
%   "angleB" \meta{To} and "angle" both of them.
% \end{description}
% 
% 
% \paragraph{The arms}
% 
% By default, there are no arms (they have lengths zero).  This can be
% overridden by the named options
% \begin{description}
% \item["arm", "armA" and "armB"] The \DescribeMacro{arm-}length of the
%   arm.  Default is 0pt, which means there is no arm at all.
% \item["armAngle", "armAngleA" and "armAngleB"] The
%   \DescribeMacro{armAngle-}direction of the arm.  Default is 0
%   (meaning right).
% \end{description}
% 
% 
% \paragraph{Nodesep}
% 
% It is possible to make a separation between the nodes and the
% connector by the named options
% \begin{description}
% \item["nodesep", "nodesepA" and "nodesepB"] Legal values are lengths,
%   default is 0.
% \end{description}
% 
% \subsection{Reference and placement of nodes}
% 
% 
% \index{nodes!in Relation}As "\umlElement"s, relations have references.  Default is
% \index{reference!default!in Relation}
% the concatenation of the references of \meta{From} and
% \meta{To}.  This can as usual be overridden by the named option "reference".
% 
% \begin{figure}[htbp]
%   \begin{center}
%     \umlDiagram[box=,sizeX=\textwidth, sizeY=5cm, ref=nodePlacement]{
%       \umlClass[pos=\umlBottomLeft{nodePlacement}, posDelta={1,1}, refpoint=bl,
%                 reference=A]{Class A}{}{}
%       \umlClass[pos=\umlTopRight{nodePlacement}, posDelta={-1,-1}, refpoint=tr, 
%                 reference=B]{Class B}{}{}
%       \umlRelation[ref=ABnode, angleA=0, armA=5, armAngleA=0]{A}{B}{}
%       \rput{0}(AaABnode){\rput(1ex,0){Aa}}
%       \rput{0}(BaABnode){\rput(-6ex,.5ex){Ba and Bc}}
%       \rput{0}(AcABnode){Ac}
%       \rput{0}(BcABnode){Bc}
%       }
%     \caption{Placement of relation nodes.  In this case, Both SymbolAb
%       and SymbolBb is where Ac is (one line segment from resp.\ nodes).}
%     \label{fig:relationNodes}
%   \end{center}
% \end{figure}
% 
% \noindent{}With the reference set as \meta{reference}, the following nodes are
% set:
% \begin{itemize}
% \item "Aa"\meta{reference} Where the connector hits node A (\meta{From})
% \item "Ba"\meta{reference} Where the connector hits node B (\meta{To})
% \item "Ab"\meta{reference} One line segment from "Aa"\meta{reference}.
% \item "Bb"\meta{reference} One line segment from "Ba"\meta{reference}.
% \item "Ac"\meta{reference} Where the main line segment hits arm or
%   node A
% \item "Bc"\meta{reference} Where the main line segment hits arm or
%   node B
% \end{itemize}
% 
% The clever reader will understand that "Ab"\meta{reference} will be
% the same location as "Ac"\meta{reference} (if there is an arm A) or as
% "Bc"\meta{reference} (if there is not).  In the latter case,
% "Ac"\meta{reference} will be the same location as
% "Aa"\meta{reference}.  Similarly in the opposite direction.
% 
% Tip: The connector is drawn with "\ncdiag".  Just after making the
% relation, you can make your own "\pnode" with something like
% "\lput{:R}("\meta{a number 0--3}"){\pnode{"\meta{your reference}"}}".
% 
% 
% \section{AssociationEnd}
% \label{sec:useAssociationEnd}
% 
% An relation may have different attachments attached to it.  It may
% have labels specifying multiplicities and a end-symbol (such as a
% triangle in the subclass case).  All this can be made with
% "\umlAssociationEnd".
% 
% Its syntax is \DescribeMacro\umlAssociationEnd
% "\umlAssociationEnd["\meta{named
% options}"]"\meta{relation}\meta{Symbol}, where \meta{relation} is the
% reference of a relation and \meta{symbol} is the symbol to be placed
% (e.g., an asterisk or a triangle).
% 
% 
% \subsection{Placing of the symbol}
% \label{sec:useAssociationEndPlacing}
% 
% The location of the symbol is determined this way:
% \begin{itemize}
% \item You pick the direction along the relation
% \item Relative\DescribeMacro{posAngle} to this direction, you pick the direction determined by
%   "posAngle".  But, since this direction is
%   ":U", up, by default, you probably still move in the direction along
%   the relation.  You probably don't want to modify posAngle.
% \item In this direction, move the fraction specified by
%   "pos"\DescribeMacro{pos-} of the relation.  This is default 0.  But
%   if you specify "fraction=0.2", you move 20~\% along the line.  Legal
%   values, in addition to real numbers, are "A" and "From", meaning
%   near node A, and "B" and "To", meaning you move from node B to A.
% \item Still in this direction, \DescribeMacro{offset-}move the length
%   specified by "offset".  If you say "offset=2ex", you are 20~\% of
%   the line + 2~ex away from the node now.
% \item To \DescribeMacro{height-}the right of this direction, move the length specified by
%   "height".  
% \item Here, \DescribeMacro{refpoint-}place the point on the symbol
%   specified by "refpoint".  This is default "B" (baseline).
% \item Rotate \DescribeMacro{angle-}the symbol in the direction
%   specified by "angle".  This is default "U" (up).
% \end{itemize}
% 
% Much of the point in "\umlLabel" and "\umlSymbol" is to provide other
% defaults for different uses.
% 
% Common relations have their specialized commands (like "\umlSubclass"
% and "\umlAggregation"), to be explained later on.  These commands call
% "\umlRelation" and then "\umlSymbol" with the appropriate
% symbol.
% 
% 
% \section{Label}
% \label{sec:useLabel}
% 
% \DescribeMacro{\umlLabel}This is an association end which new defaults:
% offset is 4~ex, height is 4~ex and direction is N (north, absolute
% up).  This is good defaults for label.
% 
% In labels, if pos is "B" or "To", the height is inverted.
% 
% The command\DescribeMacro\umlLabelA "\umlLabelA" is an "\umlLabel"
% with fraction=A.  "\umlLabelB" is an "\umlLabel" with fraction=B.
% 
% In figure \ref{fig:generalRelation}, there are three labels: 1, * and
% ``center''.  ``A'' and ``B'' is implemented directly by means of
% "\umlAssociationEnd".
% 
% \section{Symbol}
% \label{sec:useSymbol}
% 
% This\DescribeMacro\umlSymbol is an association end with new defaults.
% Refpoint is "t" (top).
% 
% The command\DescribeMacro\umlSymbolA "\umlSymbolA" is an "\umlSymbol"
% with fraction=A.  "\umlSymbolB" is an "\umlSymbol" with fraction=B.
% 
% In figure \ref{fig:generalRelation}, there are two symbols (the diamond
% in the left one and the triangle in the right)
% 
% \section{Navigability}
% \label{sec:useNavigability}
% 
% 
% 
% Navigability indicates which direction the relation can be followed.
% Graphically, it looks like an open arrow.  
% 
% The syntax is "\umlNavigability["\meta{named
%   options}"]"\meta{Relation}.  The symbol is predefined.  Navigability
% can also be drawn with the commands \DescribeMacro\umlNavigabilityA"\umlNavigabilityA" and
% "\umlNavigabilityB".
% 
% In figure \ref{fig:generalRelation}, there is one navigability symbol
% (towards Class A).
% 
% 
% \section{The different relations}
% 
% There are several different relations; being semantically very
% different, they all are connectors between nodes, and they all are
% implemented as subcommands of "\umlRelation", with various end symbols.
% 
% \subsubsection{Association}
% \label{sec:useAssociation}
% 
% \rput{0}(-1cm, -1ex){\pnode{AssociationA}}
% \DescribeMacro{\umlAssociation}
% "\umlAssociation" is only a wrapper to "\umlReference".  Graphically,
% an association is a reference without any fuzz.  An example of an
% association (between nothing, though) is shown
% in the left margin of this text.
% \rput{0}(AssociationA|-1cm, 0){\pnode{AssociationB}}
% \umlAssociation{AssociationB}{AssociationA}
% 
% \subsubsection{Subclass (generalization)}
% \label{sec:useSubclass}
% \label{sec:useGeneralization}
% 
% \rput{0}(-1cm, -4ex){\pnode{SubclassA}}
% \DescribeMacro{\umlSubclass}
% \DescribeMacro{\umlGeneralization}
% This relation is in UML named \emph{generalization}.  We prefer to
% name it the \emph{subclass relation} (really, more relations are about
% generalization).  However, for the sake of compatibility, the commands
% "\umlSubclass" and "\umlGeneralization" are offered as equals.
% 
% The relation goes from the most special node to the most general one.
% Graphically, it is a solid line with a triangle at the general end.
% \rput{0}(SubclassA|-1cm, 0){\pnode{SubclassB}}
% \umlSubclass{SubclassB}{SubclassA}
% 
% 
% \subsubsection{Inner class}
% \label{sec:useInner}
% 
% \rput{0}(-1cm, -1ex){\pnode{InnerA}}
% \DescribeMacro{\umlInner}
% The graphical notation for this is not part of standard UML, and not
% very well worked through either.  However, I find it very useful to
% have a notation for this (without drawing the classes inside each
% other).
% 
% Bug: I have not been able to get rid of the gray thing borders made by
% "\psClip".
% 
% I have not investigated the differences and similarities in the
% semantics of what I call Inner Class, Java Inner Classes, Schemas
% which contain other classes and traditional UML composition.
% 
% The command is "\umlInner".
% \rput{0}(InnerA|-1cm, 0){\pnode{InnerB}}
% \umlInner{InnerB}{InnerA}
% 
% 
% \subsubsection{Instance}
% \label{sec:useInstance}
% 
% \rput{0}(-1cm, -1ex){\pnode{InstanceA}}
% \DescribeMacro{\umlInstance}
% This is the relation between a class and its metaclass.  This is the
% real ``is-a'' relation.  It is the strongest kind of a generalization
% relationship, even if it is not called generalization in standard
% UML.  Its symbol is an open arrow on a dashed line.
% 
% The command is "\umlInstance".
% \rput{0}(InstanceA|-1cm, 0){\pnode{InstanceB}}
% \umlInstance{InstanceB}{InstanceA}
% 
% 
% 
% \subsubsection{Aggregation}
% \label{sec:useAggregation}
% 
% \rput{0}(-1cm, -1ex){\pnode{AggregationA}}
% \DescribeMacro{\umlAggregation}
% The target class (the upper class in the left margin) is an aggregate; therefore, the source class is a
% part.  This is the weak form of aggregation, indicated by a hollow
% diamond.  The part may be contained in other aggregates.  The
% aggregation is optional, but not suppressible.
% \rput{0}(AggregationA|-1cm, 0){\pnode{AggregationB}}
% \umlAggregation{AggregationB}{AggregationA}
% 
% 
% \subsubsection{Composition}
% \label{sec:useComposition}
% 
% \rput{0}(-1cm, -1ex){\pnode{CompositionA}}
% \DescribeMacro{\umlComposition}
% The strong form of aggregation, which requires that a part instance be
% included in at most one composite at a time and that the composite
% object has sole responsibility for the disposition of its parts.  In
% other words, a part can be part of at most one composite.
% \rput{0}(CompositionA|-1cm, 0){\pnode{CompositionB}}
% \umlComposition{CompositionB}{CompositionA}
% 
% \subsubsection{Application}
% \label{sec:useApplication}
% 
% \rput{0}(-1cm, -1ex){\pnode{ApplicationA}}
% \DescribeMacro{\umlApplication}
% This is the relation between an abstraction (a schema taking
% arguments) and the application (the schema with the arguments).
% Application, and the entire argument idea, is not part of standard
% UML.  For example, see the section about Argument
% \vpageref{sec:useArgument}.
% 
% "\umlApplication" places a node "argument"\meta{reference} in addition
% to the usual ones.
% \rput{0}(ApplicationA|-1cm, 0){\pnode{ApplicationB}}
% \umlApplication{ApplicationB}{ApplicationA}
% 
% \subsection{Relations to Relations}
% \label{sec:relationsTernary}
% \label{sec:useToRelation}
% 
% Some constructs can be viewed as relations between a classifier and a
% relation.  They are implemented as subcommands of
% "\umlToRelation".\DescribeMacro\umlToRelation
% 
% "\umlToRelation"\DescribeMacro{posMeetLine-} takes the named option
% "posMeetLine", a real number between 0.0 and 1.0, which determines
% where at the target relation the relation shall hit.  Default is 0.5,
% in the middle of the relation.
% 
% The node "ToRelation"\meta{reference of this relation} is placed where
% the lines meet.
% 
% \subsubsection{AssociationClass}
% \label{sec:useAssociationClass}
% \label{sec:useAssociationSchema}
% 
% \rput{0}(-2ex, -4ex){\pnode{AssociationClassA}}
% \DescribeMacro{\umlAssociationClass}
% \DescribeMacro{\umlAssociationSchema}
% An association class is an association which also has attributes and
% methods.  Similarly, we can speak about an association schema.
% Graphically, the schema is drawn as an usual schema with a dashed
% connector to the association.
% \rput{0}(AssociationClassA|-2ex, 0){\pnode{AssociationClassB}}
% \umlAssociation{AssociationClassB}{AssociationClassA}
% \ncline[linecolor=red, linestyle=\umlDebugLinestyle]{%
%   AcAssociationClassB}{BcAssociationClassA}%
%   \lput{:R}(.5){\pnode{AssociationClassHeight}}%
% \small{\umlSchema[pos=AssociationClassHeight, refpoint=r,
%            posDelta={-3ex, 0}, reference=AssCl]{Ass.Cl.}{}{}{}{}{}}
% \umlAssociationClass{AssCl}{AssociationClassBAssociationClassA}
% 
% 
% \subsubsection{ArgumentRelation}
% \label{sec:useArgumentRelation}
% 
% \rput{0}(-2ex, -1ex){\pnode{ArgumentA}}
% \DescribeMacro{\umlArgument}
% In this construct, we speak about three differenc classifiers: 
% \begin{itemize}
% \item The \index{abstraction}\emph{abstraction} (Stack in figure \ref{fig:stack})
%   is the schema which can take argument.  
% \item The \index{application}\emph{application} (Stack of books) is
%   the abstraction after applying the argument.  The application is
%   more special than the abstraction.
% \item The \index{argument!and application}\emph{argument} (Book) is
%   what is filled in.
% \end{itemize}
% 
% Graphically, this is shown as two connectors:  One solid with an arrow
% from the application to the abstraction.  It is made by
% "\umlApplication".  Then, a dotted from this line to the argument.
% It is made by "\umlArgument".
% 
% By default, the dotted line hits the solid one quite near the
% application, at about 20\% of the main line segment (position 1.2). 
% \rput{0}(ArgumentA|-2ex, 0){\pnode{ArgumentB}}
% \umlApplication{ArgumentB}{ArgumentA}
% \ncline[linecolor=red, linestyle=\umlDebugLinestyle]{%
%   AcArgumentB}{BcArgumentA}%
%   \lput{:R}(.5){\pnode{ArgumentHeight}}%
% \small{\umlSchema[pos=ArgumentHeight, refpoint=r,
%            posDelta={-3ex, 0}, ]{Argument}{}{}{}{}{}}
% \umlArgumentRelation{Argument}{ArgumentBArgumentA}
% 
% \begin{figure}[htbp]
%   \begin{center}
%     \begin{footnotesize}
%     \umlDiagram[sizeX=10cm, sizeY=12cm,
%     ref=argumentDiagram,box=,border]{
%       \umlSchema[pos=\umlTopLeft{argumentDiagram}, posDelta={2ex, -2ex}, 
%                 refpoint=tl]{Stack}{%Attributes
%         \umlAttribute[visibility=-, type=\emph{type}, default=null
%                       ]{firstNode}
%         }{% Methods
%         \umlMethod[visibility=+]{push}{\emph{type} x}
%         \umlMethod[visibility=+, type=\emph{type}]{pop}{}
%         }{% Arguments
%         \umlArgument[type=Metaclass]{type}
%         }{% Constraints
%         \umlCompartmentline{S:Stack = S.push(x).pop()}
%         }{% Structure
%         \umlDiagram[ref=StackDiagramA, outerBorder,innerBorder=2mm,box=]{%
%            \umlClass[pos=\umlBottomLeft{StackDiagramA},
%                      posDelta={1ex, 1ex}, box=,
%                      ref=stackNode]{Node}{
%               \umlAttribute[visibility, type=\emph{type}]{data}}{}
%           \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em]{stackNode}{stackNode}{
%             \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}
%             \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}}
%           }\cr% End of diagram
%         }% End of Stack
%       \umlSchema[refpoint=br, posY=\umlBottom{Stack}, 
%                  posX=\umlRight{argumentDiagram},
%                  posDelta={-2ex,0}]{
%         Book}{% Attributes
%         \umlAttribute[visibility, type=Integer]{pages}
%         }{% Methods
%         \umlMethod[visibility]{read}{}
%         }{% Arguments
%         }{% Constraints
%         }{% Structure
%         }% End of Book
%       \umlSchema[pos=\umlBottomLeft{argumentDiagram}, posDelta={2ex, 2ex}, refpoint=bl,
%                  reference=StackofBooks]{Stack of books}{%Attributes
%         \umlAttribute[visibility=-, type=Book, default=null, ]{firstNode}
%         }{% Methods
%         \umlMethod[visibility=+]{push}{Book x}
%         \umlMethod[visibility=+, type=Book]{pop}{}
%         }{% Arguments
%         \umlCompartmentline{\emph{type} = Book}
%         }{% Constraints
%         }{% Structure
%         \umlDiagram[innerBorder=2mm,box=,innerBorder=2mm,outerBorder]{%
%           \umlClass[posDelta={1ex, 1ex}, ref=stackNode,box=]{Node}{
%             \umlAttribute[visibility, type=Book]{data}}{}
%           \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em]{stackNode}{stackNode}{
%             \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}
%             \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}}
%           }\cr% End of diagram
%         }% End of Stack
%       \umlApplication[reference=ssb]{StackofBooks}{Stack}
%       \umlArgumentRelation{Book}{ssb}
%       \umlLabel[fraction=0.7]{Bookssb}{\emph{type}}
%       }% End of main diagram
%     \caption{Example of abstraction and application}
%     \label{fig:abstraction}\label{fig:stack}\label{fig:Stack}
%     \end{footnotesize}
%   \end{center}
% \end{figure}
% 
% \index{Stack!and abstraction}\index{Stack!of books}%
% An example of this construct is shown in figure~\vref{fig:stack}.  The
% \LaTeX{} source is here:
% \begin{verbatim}
% \umlDiagram[sizeX=10cm, sizeY=12cm,
%             ref=argumentDiagram,box=,border]{
%   \umlSchema[pos=\umlTopLeft{argumentDiagram}, posDelta={2ex, -2ex}, 
%             refpoint=tl]{Stack}{%Attributes
%     \umlAttribute[visibility=-, type=\emph{type}, default=null
%                   ]{firstNode}%
%     }{% Methods
%     \umlMethod[visibility=+]{push}{\emph{type} x}
%     \umlMethod[visibility=+, type=\emph{type}]{pop}{}
%     }{% Arguments
%     \umlArgument[type=Metaclass]{type}%
%     }{% Constraints
%     \umlCompartmentline{S:Stack = S.push(x).pop()}
%     }{% Structure
%     \umlDiagram[ref=StackDiagramA, outerBorder,innerBorder=2mm,box=]{%
%        \umlClass[pos=\umlBottomLeft{StackDiagramA},
%                  posDelta={1ex, 1ex}, box=,
%                  ref=stackNode]{Node}{%
%           \umlAttribute[visibility, type=\emph{type}]{data}}{}%
%       \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em]{stackNode}{stackNode}{%
%         \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}%
%         \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}}%
%       }\cr% End of diagram
%     }% End of Stack
%   \umlSchema[refpoint=br, posY=\umlBottom{Stack}, 
%              posX=\umlRight{argumentDiagram},
%              posDelta={-2ex,0}]{%
%     Book}{% Attributes
%     \umlAttribute[visibility, type=Integer]{pages}
%     }{% Methods
%     \umlMethod[visibility]{read}{}
%     }{% Arguments
%     }{% Constraints
%     }{% Structure
%     }% End of Book
%   \umlSchema[pos=\umlBottomLeft{argumentDiagram}, posDelta={2ex, 2ex}, refpoint=bl,
%              reference=StackofBooks]{Stack of books}{%Attributes
%     \umlAttribute[visibility=-, type=Book, default=null, ]{firstNode}
%     }{% Methods
%     \umlMethod[visibility=+]{push}{Book x}
%     \umlMethod[visibility=+, type=Book]{pop}{}
%     }{% Arguments
%     \umlCompartmentline{\emph{type} = Book}
%     }{% Constraints
%     }{% Structure
%     \umlDiagram[innerBorder=2mm,box=,innerBorder=2mm,outerBorder]{%
%       \umlClass[posDelta={1ex, 1ex}, ref=stackNode,box=]{Node}{
%         \umlAttribute[visibility, type=Book]{data}}{}%
%       \umlRelation[angleA=20, angleB=-20, armA=1em, armB=1em]{stackNode}{stackNode}{%
%         \umlLabelA[height=-1ex, fraction=1.5]{stackNodestackNode}{1}%
%         \umlLabelB[height=-1ex, fraction=1.5]{stackNodestackNode}{1}}%
%       }\cr% End of diagram
%     }% End of Stack
%   \umlApplication[reference=ssb]{StackofBooks}{Stack}
%   \umlArgumentRelation{Book}{ssb}
%   \umlLabel[fraction=0.7]{Bookssb}{\emph{type}}
%   }% End of main diagram
% \end{verbatim}
% 
% 
% \section{Package}
% \label{sec:usePackage}
% 
% A package is a collection of classes, relations and other elements.
% It is simply a grouping of different elements.
% 
% The graphic symbol consists of two rectangles above each other: The
% upper one is small and contains the name.  The lower one is typically
% large and contains the elements.  The lower rectangle typically
% contains an "\umlDiagram".
% 
% In uml.sty, packages are drawn by the command "\umlPackage["\meta{named
% options}"]{"\meta{name}"}{"\meta{stuff}"}".  "\umlPackage" is an
% "\umlBox", and inherits all its named options.  
% 
% 
% 
% \subsection{Example}
% 
% In figure \vref{fig:usePackage}, the package ``Package'' contains four
% classes, four usual associations and one subclass relation.
% 
% \begin{figure}[htbp]
%   \begin{center}
%       \umlPackage[box=,
%       subof=subof, stereotype=stereo, importedFrom=From, 
%       comment=comment]{Package}{%
%         \umlDiagram[sizeX=7cm, sizeY=5cm,box=,ref=pack]{
%           \umlClass[pos=\umlBottomLeft{pack}, posDelta={2ex, 2ex}, refpoint=bl]{Book}{}{}
%           \umlClass[pos=\umlTopLeft{pack}, posDelta={2ex, -2ex},  refpoint=tl]{House}{}{}
%           \umlClass[pos=\umlTopRight{pack}, posDelta={-2ex,-2ex}, refpoint=tr]{Person}{}{}
%           \umlClass[pos=\umlBottomRight{pack}, posDelta={-2ex, 2ex}, refpoint=br]{Author}{}{}
%           \umlAssociation[]{Book}{House}
%           \umlLabelB{BookHouse}{is in}
%           \umlAssociation[]{Book}{Person}
%           \umlLabelA{BookPerson}{reads}
%           \umlSubclass{Author}{Person}
%           \umlAssociation{Book}{Author}
%           \umlLabelA[height=.5ex]{BookAuthor}{written}
%           \umlAssociation{House}{Person}
%           \umlLabelA{HousePerson}{lives in}
%           }% End of diagram
%       }% End of package
%     \caption{Example of package}
%     \label{fig:usePackages}
%     \label{fig:usePackage}
%   \end{center}
% \end{figure}
% 
% 
% The source:
% \begin{small}
% \begin{verbatim}
% \umlPackage[border=,box=,
%       subof=subof, stereotype=stereo, importedFrom=From, 
%       comment=comment]{Package}{%
%    \umlDiagram[sizeX=7cm, sizeY=5cm,box=,ref=pack]{
%      \umlClass[pos=\umlBottomLeft{pack}, posDelta={2ex, 2ex}, 
%                refpoint=bl]{Book}{}{}
%      \umlClass[pos=\umlTopLeft{pack}, posDelta={2ex, -2ex},  
%                refpoint=tl]{House}{}{}
%      \umlClass[pos=\umlTopRight{pack}, posDelta={-2ex,-2ex}, 
%                refpoint=tr]{Person}{}{}
%      \umlClass[pos=\umlBottomRight{pack}, posDelta={-2ex, 2ex}, 
%                refpoint=br]{Author}{}{}
%      \umlAssociation[]{Book}{House}
%      \umlLabelB{BookHouse}{is in}
%      \umlAssociation[]{Book}{Person}
%      \umlLabelA{BookPerson}{reads}
%      \umlSubclass{Author}{Person}
%      \umlAssociation{Book}{Author}
%      \umlLabelA[height=.5ex]{BookAuthor}{written}
%      \umlAssociation{House}{Person}
%      \umlLabelA{HousePerson}{lives in}
%      }% End of diagram
%  }% End of package
% \end{verbatim}
% \end{small}
% 
% 
% \subsection{Connecting packages}
% 
% 
% Two packages can be connected in the same way, and using the same
% function, as two classes.  Symbols, labels etc.\ work the same way,
% and you can even connect a package and a class.  Not all these
% possibilities make sense semantically.
% 
% However, due to the geometrical shape of packages, there is some
% problems with the connections.  I have found no good solution to this.
% Now, default, relations is connected to an imaginary rectangle
% covering the entire package.  The problem occur if the node hits the
% package in the upper right corner, where the package does not fill out
% the rectangle.
% 
% To solve this problem preliminarily, two more nodes are placed: The
% upper rectangle is given the name "small"\meta{reference}, and the
% lower "big"\meta{reference}.  You can make the connector connect to
% one of these if desired.
% 
% \section{Colors}
% \label{sec:useColors}
% 
% The metamodel for this is in figure \vref{fig:useApproachColors}.
% 
% \subsection{Colorset}
% \label{sec:useColorset}
% \label{sec:useColorsColorset}
% 
% 
% In uml.sty, there is always an \emph{color set}\index{color set} in
% action.  There are currently six defined color sets:
% \begin{description}
% \item[ColorsDefault] \index{ColorsDefault}uses normal black and white
%   colors.
% \item[ColorsGray] \index{ColrosGray}uses more gray colors.  Typically
%   used for constructs which not is to be emphazised.
% \item[ColorsImport] \index{ColorsImport}uses blue colors.  Typically
%   used for constructs which are defined in another document, and only
%   are imported here.
% \item[ColorsArgument] \index{ColorsArgument}uses green colors.
%   Typically used for constructs given as arguments.
% \item[ColorsRed] \index{ColorsRed}uses red colors.  Use it as you
%   like.
% \item[ColorsSub] \index{ColorsSub} is intended to be used on material
%   inherited from other material.
% \end{description}
% Demonstrations of this color sets is in figure
% \ref{fig:useApproachColors}.
% 
% If you want to make your own color set, you may say something like
% 
% \noindent{\newcommand\myColorset{%
%   \umlColorset{%
%     \newrgbcolor{umlColor}{0 .4 .4}%
%     \newrgbcolor{umlLinecolor}{0.5 1 1}%
%     \newrgbcolor{umlFillcolor}{.8 1 1}%
%     \newrgbcolor{umlClassifierFillcolor}{.85 1 1}%
%     \newrgbcolor{umlDiagramFillcolor}{.95 1 1}%
%     \newrgbcolor{umlRelationColor}{0 1 1}%
%     }%
% }%  
% \footnotesize%
% \umlClass[colorset=\myColorset,
%   pos={-1em, -3em},posDelta={-1ex,0},refpoint=tr,
%   ]{Class}{\umlAttribute[default=myColorset]{Color set}}{}}%
% \begin{verbatim}
% \newcommand\myColorset{%
%   \umlColorsSet{%
%     \newrgbcolor{umlColor}{0 .4 .4}%
%     \newrgbcolor{umlLinecolor}{0.5 1 1}%
%     \newrgbcolor{umlFillcolor}{.8 1 1}%
%     \newrgbcolor{umlClassifierFillcolor}{.85 1 1}%
%     \newrgbcolor{umlDiagramFillcolor}{.95 1 1}%
%     \newrgbcolor{umlRelationColor}{0 1 1}%
%     }%
% }  
% \end{verbatim}
% You may want to use the commands
% "\newrgbcolor{"\meta{name}"}{"\meta{red} \meta{green} \meta{blue}"}",
% "\newgray{"\meta{name}"}{"\meta{grayness}"}",
% "\newhsbcolor{"\meta{name}"}{"\meta{hue} \meta{saturation}
%   \meta{brightness}"}" or
% "\newcmykcolor{"\meta{name}"}{"\meta{cyan} \meta{magenta}
%   \meta{yellow} \meta{black}"}", where
% all the parameters except \meta{name} are real numbers between 0 and
% 1.
% 
% \subsection{Using the color sets}
% \label{sec:useColorsets}
% 
% You can use the color sets in different ways:
% \begin{itemize}
% \item You \DescribeMacro{\umlColors\dots}can use the command directly (e.g., say
%   "\umlColorsDefault"), and the color set will take effect on the
%   following constructs.
% \item You can use the environment \DescribeEnv{umlColorset}, which
%   takes the color set as argument
%   (e.g. "\begin{umlColors}{\umlColorsDefault}"). 
% \item In\DescribeMacro{colorSet-} drawables, (i.e., most constructs)
%   you can use the named option "colorSet" (e.g.,
%   "\umlClass[colorSet=\umlColorsDefault,...").
% \item Some color sets are also implied in other named options
%   ("import=") and otherwise.
% \end{itemize}
% 
% Colors are primarily handled by Drawable.  However, due to some
% technical obscurities in \TeX{}, the implementation is done in the
% known subclasses ("\umlElement", "\umlCompartment" and
% "\umlCompartmentline").
% 
% Technically, the commands only define another command
% ("\umlColorsAdjust"), which is called in every construct.  The value
% of "\umlColorsAdjust" \emph{til enhver tid} is the color set in
% action.  See \ref{sec:impColorset} for more details on this.
% 
% 
% \section{Positions}
% \label{sec:usePositions}
% \label{sec:useTopLeft}
% 
% The metamodel for this is in figure \vref{fig:useApproachPositions}.
% 
% In PSTricks, a Node can serve as a Coordinate.  There exist other
% types of coordinates too.  Box.pos uses "\rput", and is a coordinate.
% Box.posDelta should be a relative coordinate (a cartesian number
% pair), but could really be any coordinate.  
% 
% Relation.NodeA and Relation.NodeB, however, uses "\ncdiag", and must
% be Nodes.  This is confusing.  It is also confusing that coordinates
% in PSTricks are written in parenthesis, while nodes are not.  In
% uml.sty, no parenthesis are used.
% 
% This imply that relation only can be between Nodes, and not between
% other coordinates.  But sometimes, we want to use the power of other
% coordinate kinds while placing relations.  
% 
% 
% \subsection{PlaceNode}
% \label{sec:usePlaceNode}
% 
% To do that, use the command
% "\umlPlaceNode", which has a lot of
% power, and places a node.  Note that "\umlPlaceNode" only places a new
% node (named after its third argument); it is no node itself.
% 
% One may want to do something like
% \begin{verbatim}
% \umlPlaceNode[top=-2em,rightside]{A}{Aright}
% \umlPlaceNode[top=-2em,leftside]{B}{Bleft}
% \umlSubclass[ref=AB]{Aright}{Bleft}
% \end{verbatim}
% 
% Why should it not be legal to say something like
% \begin{verbatim}
% \umlSubclass[top=-2em,rightsideA, leftsideB]{A}{B}
% \end{verbatim}
% ?
% 
% It is possible to implement the latter syntax, but that would require
% a great amount of new nodes.  It is already a problem that uml.sty
% relations uses so many nodes, so I have chosen to keep the first
% syntax.  After all, I do not expect "\umlPlaceNode" to be used often.
% 
% "\umlPlacenode"\DescribeMacro{\umlPlaceNode} takes three arguments:
% Its named options, a node and a name to be used as a name of the new
% node.
% 
% It takes several named options:
% \begin{description}
% \item["leftside", "rightside", "top" and "bottom"]
%   \DescribeMacro{leftside-} \DescribeMacro{rightside-}
%   \DescribeMacro{top-} \DescribeMacro{bottom-} makes "\umlPlaceNode"
%   start at one side of the node.  They all can take one length as
%   argument.  One horizontal and one vertical of these can be combined.
% \item["left", "right", "up" and "down"] \DescribeMacro{left-}
%   \DescribeMacro{right-} \DescribeMacro{up-} \DescribeMacro{down-}
%   These makes "\umlPlaceNode" go in one of the four directions.
%   Several (even of the same type) can be combined.  Legal values are
%   lengths.
% \item["angle", "angleX" and "angleY"] \DescribeMacro{angle-}angle from the node to start
%   with.
% \item["offset", "offsetX" and "offsetY"] \DescribeMacro{offset-}
% \item["nodesep", "nodesepX" and "nodesepY"] \DescribeMacro{nodesep-}separation from the node.
% \end{description}
% 
% \subsection{Coordinates}
% \label{sec:useSyntaxCoordinates}
% 
% \index{coordinates}Legal \emph{coordinates} are:
% \begin{description}
% \item \textbf{\meta{x}"," \meta{y}} The usual Cartesian coordinate.  E.g.,
%   "3,4".
% \item \textbf{\meta{r}";"\meta{a}} Polar coordinate, with radius \meta{r} and
%   angle \meta{a}.  The default unit for \meta{r} is the PSTricks
%   "unit".  E.g., "3;110".
% \item \index{node!as coordinate}\textbf{\meta{node}} The center of
%   \meta{node}.  \meta{node} can be any valid PSTricks node.  Various
%   commands in "uml.sty" places a number of nodes, which can be used as
%   reference points.
%   \begin{itemize}
%   \item Most constructs can be given a node name using the
%     "reference=" named option.
%   \item For classes and schemas, default node name (when "reference="
%     is not used) is the Class name or Schema name itself.
%   \item Relations place nodes, see documentation in \vref{sec:useRelation}.
%   \end{itemize}
% \item \textbf{"["\meta{par}"]"\meta{node}} The position relative to
%   \meta{node} determined using the "angle", "nodesep" and "offset"
%   parameters.  E.g., "([angle=90]Car)".
% \item \textbf{\meta{coor1}"|"\meta{coor2}} The $x$ coordinate from
%   \meta{coor1} and the $y$ coordinate from \meta{coor2}. \meta{coor1}
%   and \meta{coor2} can be any other coordinates.  For example,
%   "(Car|1in;30)".  However, you may instead want to use named options
%   such as "posX" and "deltaPosY" to achieve this.
% \item[Position commands] take a node as parameter and return an
%   coordinate.  The different position commands are shown below.  E.g.,
%   "\umlClass[pos=\umlBottomRight{Car}]{Wheel}{}{}".
% \end{description}
% 
% Note that you should usually omit the parentheses in "uml.sty".  This
% is due to the fact that the "("\meta{coor1}"|"\meta{coor2}")"
% construct requires two parts without parentheses.
% 
% Also note that coordinate pairs containing parentheses as values to
% named options my cause problems.  You have to enclose them in braces.
% E.g., "\umlClass[pos={3,3}]{Car}{}{}".
% 
% \subsubsection{Coordinate commands}
% 
%   This is kept for backward compatibility.  However, only the first
%   group of Coordinate commands should be useful now.  The others are
%   deprecated. 
% 
% A coordinate command takes an node (and possibly other things) as
% argument, and return a coordinate.
% 
% Several groups of coordinate commands exist:
% 
% 
% \DescribeMacro{\umlTop}
% \DescribeMacro{\umlRight}
% \DescribeMacro{\umlBottom}
% \DescribeMacro{\umlLeft}
% \DescribeMacro{\umlTopRight}
% \DescribeMacro{\umlBottomRight}
% \DescribeMacro{\umlBottomLeft}
% \DescribeMacro{\umlTopLeft}
% \begin{description}
% \item[Simple commands] The
%  commands "\umlTop", "\umlRight", "\umlBottom",
%   "\umlLeft", "\umlTopRight", "\umlBottomRight", "\umlBottomLeft" and
%   "\umlTopLeft" all take one argument: the node
% \DescribeMacro{\umlTopSep}
% \DescribeMacro{\umlRightSep}
% \DescribeMacro{\umlBottomSep}
% \DescribeMacro{\umlLeftSep}
% \DescribeMacro{\umlTopRightSep}
% \DescribeMacro{\umlBottomRightSep}
% \DescribeMacro{\umlBottomLeftSep}
% \DescribeMacro{\umlTopLeftSep}
% \DescribeMacro{\umlNodeSep}
% \item[Commands with separation] The commands "\umlTopSep",
%   "\umlRightSep", "\umlBottomSep", "\umlLeftSep", "\umlTopRightSep",
%   "\umlBottomRightSep", "\umlBottomLeftSep" and "\umlTopLeftSep" 
%   returns a position "\umlNodeSep" from the position of the argument.
%   "\umlNodeSep" is default 1em, but may be changed by the user.
% \DescribeMacro{\umlTopOpt}
% \DescribeMacro{\umlRightOpt}
% \DescribeMacro{\umlBottomOpt}
% \DescribeMacro{\umlLeftOpt}
% \DescribeMacro{\umlTopRightOpt}
% \DescribeMacro{\umlBottomRightOpt}
% \DescribeMacro{\umlBottomLeftOpt}
% \DescribeMacro{\umlTopLeftOpt}
% \item[Commands taking options] The commands "\umlTopOpt", "\umlRightOpt", "\umlBottomOpt",
%   "\umlLeftOpt", "\umlTopRightOpt", "\umlBottomRightOpt", "\umlBottomLeftOpt" and
%   "\umlTopLeftOpt" takes two arguments, both mandatory: a
%   comma-separated list of \meta{key}"="\meta{value} pairs, where
%   \meta{key} can be "angle" (value: number), "nodesep" (value: length)
%   or "offset" (value: length).  The second argument is the node
% \DescribeMacro{\umlTopSepOpt}
% \DescribeMacro{\umlRightSepOpt}
% \DescribeMacro{\umlBottomSepOpt}
% \DescribeMacro{\umlLeftSepOpt}
% \DescribeMacro{\umlTopRightSepOpt}
% \DescribeMacro{\umlBottomRightSepOpt}
% \DescribeMacro{\umlBottomLeftSepOpt}
% \DescribeMacro{\umlTopLeftSepOpt}
% \DescribeMacro{\umlNodeSepOpt}
% \item[Commands with separation taking options] The commands "\umlTopSepOpt",
%   "\umlRightSepOpt", "\umlBottomSepOpt", "\umlLeftSepOpt", "\umlTopRightSepOpt",
%   "\umlBottomRightSepOpt", "\umlBottomLeftSepOpt" and "\umlTopLeftSepOpt" 
%   takes two arguments and do just what you expect them to.
% \end{description}
% 
% \label{useSchemaSourceEnd}
%
% \section{A large example (Abstract Data Structures)}
%
% \index{Abstract Data Structure}Figure \vref{fig:useSchema}
% is a more large model of some standard ADTs.  It is an example of both
% "\umlSchema" and some relations.  It also is an example of the Schema
% construct itself, but is primarily intended to be a "uml.sty" example,
% and is not intended to be a good ADT model.
%
% \begin{figure}[htbp]
%   \centering
%     \footnotesize
%     \umlADTExample
%     \caption{ADT model.  Bad model, good uml.sty example.}\label{fig:ADTExample}
%     \label{fig:useSchema}
%  \end{figure}
%
% \paragraph{The command}
% Technically, the following source defines a command
% "\umlADTExample", which is used in figure \vref{fig:ADTExample}.
%\begin{lstlisting}
% \providecommand\umlADTExample{
%\end{lstlisting}
%
% \paragraph{The diagram}
% The diagram is a box which uses room.  It is 15~cm wide and 16~cm
% high, and has the reference "ADTdiagram".  It has a grayness of
% 92~\%.  If we did not supply a grayness, it would get the
% "umlDiagramFillcolor" of the current color set.
%
% Note that, technically, it is not necessary to have the semantical
% contents of the diagram inside its \LaTeX{} argument.
%\begin{lstlisting}
%    \umlDiagram[box=,sizeX=15cm, sizeY=16cm,ref=ADTdiagram,
%                grayness=0.92]{}% End of diagram
%\end{lstlisting}
%
% \paragraph{ADT}
% The schema (or class) ADT is located in the top right corner of
% the diagram (which had reference "ADTdiagram".  More accurately, its
% top right ("tr") corner is placed half an unit left and half an unit
% down relative the the top right corner.
%\begin{lstlisting}
%      \umlSchema[pos=\umlTopRight{ADTdiagram}, posDelta={-.5,-.5},
%        refpoint=tr]{ADT}{% Attributes
%        \umlAttribute[visibility,type=String]{name}}{}{}{}{}
%\end{lstlisting}
%
% \paragraph{ADT-example}
% The schema ADT-example is located in the upper left corner of the
% diagram.
% It is an abstract schema, giving italics name in the diagram.
% Because the class name contains a dash, a reference ("ADTexample")
% must be supplied.
%
% This schema also takes an \emph{argument} (type).  This is not the
% place to fully explain the semantics of arguments, but \emph{type} can
% be given any Metaclass as value.  

% Everywhere in the schemas an argument is
% used, {\umlColorsArgument\umlColorsAdjust this color} is used.  
% Here, the code is getting a bit \emph{clogged up} with color
% code.  If you read this the first time, please ignore the commands
% starting with "\umlColor".
%\begin{lstlisting}
%      \umlSchema[pos=\umlTopLeft{ADTdiagram}, posDelta={.5,-1},
%                 refpoint=lt, abstract,
%                 ref=ADTexample]{ADT-example}{%
%        \umlAttribute[visibility=-, 
%          type=\emph{\umlColorsArgument\umlColorsAdjust type},default=null]{%
%          firstNode}
%        }{ %Methods
%        }{ %Arguments
%        \umlArgument[type=Metaclass]{type}
%        }{ %Constraints
%        }{ %Structure
%          \umlDiagram[box=,innerBorder=2mm,outerBorder]{%
%            \umlClass[pos={.5,.5}, ref=adtNode,box=]{Node}{%
%              \umlAttribute[visibility, 
%                type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
%                data}}{}%
%            \umlAssociation[angleA=20, angleB=-20, 
%                         arm=1em, arm=1em]{adtNode}{adtNode}%
%         }\cr% End of Diagram
%       }% End of ADT-example
%\end{lstlisting}
%
% Then the isInstance relation between ADT-example and ADT.  
% This is shown as a dashed arrown with an arrowhead towards ADT.
%\begin{lstlisting}
%      \umlInstance{ADTexample}{ADT}%
%\end{lstlisting}
%
% \paragraph{Graph}
% Graph is a subclass (subschema) of ADT-example.  Thus, it is
% implicitly inheriting the attribute firstNode, the argument
% \emph{type}, the structure Node (with the relation), and the
% isInstance-relationwhip to ADT.  
%
% What is added, is four well-known procedures, the *--*-specification
% of the Node--Node-relation, and the association class Edge.
%
% What is inherited from ADT-example (Node and the
% Node--Node-relation) is drawn with the "\umlColorsSub" color set.
% Note that the relation is brown, while the relation multiplicities is black.
%
% All the nodes are given references, in order to separate them from each
% other (they have equal class names).  However, it might work to let "Node"
% mean the last defined Node all the time.
%\begin{lstlisting}
%      \umlSchema[pos=\umlRight{ADTexample}, posDelta={3,-1},
%                 refpoint=tl, ]{Graph}{% Attributes
%        }{% Methods
%        \umlMethod[visibility,]{%
%          insert}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
%        \umlMethod[visibility,
%            type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
%          dijkstra}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
%        \umlMethod[visibility, type=boolean]{%
%          insertEdge}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
%        \umlMethod[visibility, ]{%
%          delete}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
%        }{% Arguments
%        }{% Constraints
%        }{% Structure
%          \umlDiagram[box=,innerBorder=2mm, outerBorder,
%                      sizeX=11em,sizeY=3.5em,ref=GraphDiagram]{%
%               \begin{umlColors}{\umlColorsSub}
%            \umlClass[pos=\umlBottomLeft{GraphDiagram},
%                      posDelta={1,1}, ref=graphNode]{Node}{}{}%
%            \umlAssociation[angleA=20, angleB=-20, armA=1em, armB=1em
%                         ]{graphNode}{graphNode}%
%               \end{umlColors}
%              \umlLabelA[height=0mm,offset=1ex]{graphNodegraphNode}{*}%
%              \umlLabelB[height=0mm,offset=1ex,refpoint=t
%                         ]{graphNodegraphNode}{*}%
%            \umlSymbol[fraction=.5]{graphNodegraphNode}{\pnode{gngn}}
%            \umlClass[pos=gngn, posDelta={2,0}, 
%                               ref=graphEdge, refpoint=l]{Edge}{%
%            \umlAttribute[type=real]{cost}}{}%
%          \umlAssociationClass[]{graphEdge}{gngn}%
%          }\cr% End of diagram
%        }% End of Graph
%\end{lstlisting}
% Graph is an subschema of ADT-example.
%\begin{lstlisting}
%      \umlSubclass{Graph}{ADTexample}
%\end{lstlisting}
%
% \paragraph{Search Tree}
% This schema is vertically positioned relative to ADT-example,
% and horizontally below Graph.
%
% It has four well-known methods.  It has two arguments (in addition
% to \emph{type}); \emph{arity} is an integer which default to 2, giving
% a binary tree.  \emph{sort} is a function itself taking as arguments
% two instances of \emph{type} and returning true or false.  It defaults
% to ``greater than''.
%
%\begin{lstlisting}
%      \umlSchema[posX=\umlLeft{ADTexample}, posDelta={3em,-1em},
%                 posY=\umlBottom{Graph}, 
%                 refpoint=tl, ref=searchTree]{Search Tree}{% Attributes
%        }{% Methods
%        \umlMethod[visibility,]{%
%          insert}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
%        \umlMethod[visibility, 
%             type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
%          search}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
%        \umlMethod[visibility, type=boolean]{%
%          search}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
%        \umlMethod[visibility, ]{%
%          delete}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
%        }{% Arguments
%        \umlArgument[type=Integer, initialValue=2]{arity}
%        \umlArgument[type={${\umlColorsArgument\umlColorsAdjust type}
%          \times {\umlColorsArgument\umlColorsAdjust type}\rightarrow$
%            boolean}, default=>]{sort}
%        }{% Constraints
%        }{% Structure
%          \umlDiagram[box=, sizeX=14em, sizeY=4em,
%                      innerBorder=2mm, outerBorder]{%
%            \begin{umlColors}{\umlColorsSub}
%            \umlClass[pos={.5, .5}, ref=treeNode]{Node}{}{}%
%            \umlAssociation[angleA=30, angleB=-30, armA=1em, armB=1em
%                         ]{treeNode}{treeNode}%
%             \end{umlColors}
%              \umlLabelA[height=1mm, offset=4mm,refpoint=l
%                ]{treeNodetreeNode}{%
%                \emph{\umlColorsArgument\umlColorsAdjust arity}}%
%              \umlLabelB[refpoint=tl,height=-1mm, offset=4mm,
%                         ]{treeNodetreeNode}{1}%
%            }\cr% End of diagram
%        }%
%      \umlSubclass{searchTree}{ADTexample}%
%\end{lstlisting}
% \paragraph{List}
% There is not much new here.
%\begin{lstlisting}
%      \umlSchema[pos=\umlBottomLeft{searchTree},posDelta={0,-1},
%                 refpoint=lt]{List}{%Attributes
%        }{% Methods
%        }{% Arguments
%        }{% Constraints
%        }{% Structure
%          \umlDiagram[box=, sizeX=6em, sizeY=4em,
%                      innerBorder=2mm, outerBorder]{%
%            \begin{umlColors}{\umlColorsSub}
%              \umlClass[pos={.5, .5}, ref=listNode]{Node}{}{}%
%              \umlAssociation[angleA=30, angleB=-30, armA=1em, armB=1em
%                           ]{listNode}{listNode}%
%            \end{umlColors}
%              \umlLabelA[height=1mm, offset=5mm, refpoint=l
%                         ]{listNodelistNode}{1}%
%              \umlLabelB[refpoint=tl, height=-1mm,offset=5mm
%                         ]{listNodelistNode}{1}%
%            }\cr% End of diagram
%        }% End of Schema List
%\end{lstlisting}
% Before making the actual subclass relation from List to ADT-example,
% we place node to point to and from.
% This is in order to better control the placement of the end
% points. (Really, it is to demonstrate "\umlPlaceNode" :-)
%
% The first one is called "Listtl", and is placed 1~em below the top
% left corner of List.
% The second  is named "ADTexamplebl", and placed
% 2~em to the right of the bottom left corner of ADT-example.
%
% The subclass relation itself has an arm A of 1~em sticking out from List.
%\begin{lstlisting}
%      \umlPlaceNode[leftside, top, down=1em]{List}{Listtl}
%      \umlPlaceNode[leftside,right=2em,bottom]{ADTexample}{ADTexamplebl}
%      \umlSubclass[armA=1.4142em, armAngleA=135]{Listtl}{ADTexamplebl}%
%\end{lstlisting}
% \paragraph{Queue}
% A Queue inherits pretty much from List, ADT-example and ADT.
% Only two methods and one constraint (in natural language) is added explicitly.
%\begin{lstlisting}
%      \umlSchema[pos=\umlTopRight{List},posDelta={1em,-2em},
%                 refpoint=tl]{Queue}{% Attributes
%        }{\umlMethod[visibility]{%
%          enqueue}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
%        \umlMethod[visibility, type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
%          dequeue}{}}{%Arguments
%        }{%Constraints
%        \umlCompartmentline{First come, first served.}
%        }{% Structure
%        }% End of Queue
%      \umlPlaceNode[rightside, top, down=1em]{List}{Listtr}
%      \umlSubclass[angleA=90, armAngleA=135, armA=1.4142em]{Queue}{Listtr}%
%\end{lstlisting}
% \paragraph{Stack}
% Remember, Stack is still a subclass of List and of ADT-example, and an
% instance of ADT.  Thus, Stack really resembles figure \vref{fig:Stack}
% closely.
%\begin{lstlisting}
%      \umlSchema[pos=\umlTopRight{Queue},posDelta={\umlNodeSep,0em},
%                 refpoint=tl]{Stack}{%Attributes
%        }{% Methods
%        \umlMethod[visibility]{
%          push}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
%        \umlMethod[visibility, type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
%          pop}{}
%        }{% Arguments
%        }{% Constraints
%        \umlCompartmentline{S:Stack = S.push(x).pop()}
%        }{% Structure
%        }% End of Stack
%      \umlSubclass[angleA=90, armAngleA=135, armA=1.4142em]{Stack}{Listtr}%
%}
%\end{lstlisting}
%
%
% \section{Typesetting the implementation}
%
% I want the line numbers and the macro names to be right-aligned
% together, close to the text.  It is important to make a virtual
% vertical line in order to make some order in the pages.  

% However, "doc.sty" contains a spurious space (in "\m@cro@", where
% "\PrintMacroName" and where "\PrintEnvName" are used).  This space
% shows up after the macro name.  To overcome this, I make a length
% "\minusSpace" of length one negative space in the right font, and make
% a "\hspace" of this length.
%
% \setlength\MacroIndent{0pt}
% \newlength\minusSpace
% \settowidth\minusSpace{\rmfamily\scriptsize \ }
% \setlength\minusSpace{-\minusSpace}
% \def\PrintMacroName#1{\strut \MacroFont \string #1\hspace*\minusSpace}
% \def\PrintDescribeMacro#1{\strut \MacroFont \string #1\hspace*\minusSpace}
% \def\PrintDescribeEnv#1{\strut \MacroFont #1\hspace*\minusSpace}
% \def\PrintEnvName#1{\strut \MacroFont #1\hspace*\minusSpace}
% \def\packageName#1{\texttt{#1}}
%
% \subsection{The documentation driver file}
%
% The next bit of code contains the documentation driver file for
% \TeX{}, i.e., the file that will produce the documentation you are
% currently reading. It will be extracted from this file by the
% \texttt{docstrip} program. Since it is the first code in the file
% one can alternatively process this file directly with \LaTeXe{} to
% obtain the documentation.
%
% \setcounter{CodelineNo}{0}
%<*package>
% \section{Introductory code}\label{sec:implementationIntroduction}
% \subsection{Identification}\label{sec:impIdentification}

%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{uml}
%    \end{macrocode}

% \subsection{Processing of options}\label{sec:impOptions}

% \subsubsection{debug}

% \begin{macro}{debug}
% The option "debug" is used if you want some extra lines shown.
% Intended for debugging of this package.
%    \begin{macrocode}
\DeclareOption{debug}{
  \def\umlDebugLineStyle{dashed}
  \def\umlDebugLength{1pt}
  }
\DeclareOption{nodebug}{
  \def\umlDebugLineStyle{none}
  \def\umlDebugLength{0pt}
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlDebugLinestyle}
% A linestyle normally none.  The linestyle of invisible leading lines.
%    \begin{macrocode}
\def\umlDebugLinestyle{none}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlDebugLength}
% A length normally 0pt.  E.g., the breadth of invisible lines.
%    \begin{macrocode}
\def\umlDebugLength{0pt}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{index}
% \begin{macro}{index}
% The option "index" makes all Stretchboxes and Features (all
% Drawables with names make an index entry of the form
% \meta{name}!\meta{type}.
%    \begin{macrocode}
\newcommand\umlIndexOn{\renewcommand\umlIndex[2]{\index{##1!##2}}}
\newcommand\umlIndexOff{\renewcommand\umlIndex[2]{}}
\DeclareOption{index}{\umlIndexOn}
\DeclareOption{noindex}{\umlIndexOff}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlIndex}
% Takes two arguments: Type and Name.
%    \begin{macrocode}
\newcommand\umlIndex[2]{\index{#1!#2}}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Processing the options}
% \noindent{}Default is the "index"\index{nodebug option} option.
%    \begin{macrocode}
\ExecuteOptions{nodebug}
\ProcessOptions
%    \end{macrocode}
%
% \subsection{Using other packages}\label{sec:impUsing}
%
% \packageName{uml.sty} relies heavily on the \LaTeX{} packages
% \index{PSTricks}
% \packageName{pstricks} and \packageName{pst-node} [PSTricks].
% Most of the graphics is displayed using \packageName{pstricks}.
%    \begin{macrocode}
\RequirePackage{pstricks}
\RequirePackage{pst-node}
%    \end{macrocode}

% \noindent\packageName{pst-xkey} [xKeyval] is the package which handles
% \index{keyval}\index{xkeyval} Keys can be set as usual for PStricks related
% package with "\psset[uml]{...}", where the family name "uml" is optional. 
% named options (like \verb+[name=Name, reference=Ref]+).
%    \begin{macrocode}
\RequirePackage{pst-xkey}
\pst@addfams{uml,umlAE,umlPlaceNode}
%    \end{macrocode}

% \noindent\packageName{relsize} [Relsize] handles relative sizes, with
% macros like "\Larger" and "\relsize{-1}".
% \index{relsize}
%    \begin{macrocode}
\RequirePackage{relsize}
%    \end{macrocode}

% We also need the \packageName{color} package, which is already loaded by the
% \verb+pstricks+ package.% \index{color}

% \section{General syntax}\label{sec:impSyntax}

% Users used to \LaTeX{} and PSTricks will recognize a lot of syntax.
%
% An important implementation point is that any contents (which can
% affect variables) is typeset after all the variables is used.  If it
% is not,
% the different boxes inside each other get intertwined with strange
% results.  
% "\umlDiagram" uses "\expandafter" to assert this.
% \index{intertwined boxes}\index{evaluation sequence}

%    \begin{macrocode}
\def\umlTrueVariable{true}
%    \end{macrocode}
%
% \subsection{Lengths}
% \label{sec:impSyntaxLengths}

%    \begin{macrocode}
\psset{unit=1em}
%    \end{macrocode}
%
% \subsection{Angles}\label{sec:impSyntaxAngles}
%
% \section{Drawable}\label{sec:impDrawable}
%
% Each main "uml.sty" command (those drawn as schemas at pages
% \pageref{fig:approachStart}--\pageref{fig:approachEnd}) is implemented
% in the same pattern.  
%
% \begin{macro}{\umlDrawableNull}
% First, all the variables (in the "\umlDrawable" case, just one) are
% set to their default values.
%    \begin{macrocode}
\def\umlDrawableNull{%
   \def\umlImport{}%
   \def\umlKind{Drawable}%
   \gdef\umlName{DrawableNameDefault}%
   \def\umlNameDefault{DrawableNameDefault}% 
   %\ifx\umlName\umlNameDefault\else umlName is changed
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Named options}
%
% Of course, it would be more elegant to treat one variable at a time,
% setting it to its default value and handling its named options at the
% same place.  However, I have not found any way to do so.

% Then, the named options are handled.  Most of them modify the
% variables.  In this case, there is only one named option ("import")
% which modify one variable ("\umlColor").  In most cases, the named
% option and the variable has corresponding names.
%
% \begin{macro}{kind-}
% The kind (type, metaclass) of the Drawable, e.g., "Class".
%    \begin{macrocode}
\define@key[psset]{uml}{kind}{\def\umlKind{#1}}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{name-}
% The name of the Drawable, e.g., "Car".
%    \begin{macrocode}
\define@key[psset]{uml}{name}{\gdef\umlName{#1}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Colors}
%
% As said in section \ref{sec:useDrawableColors}, colors are primarily
% handled by Drawable.  However, due to some technical obscurities in
% \TeX{}, the implementation is done in the known subclasses
% ("\umlElement", "\umlCompartment" and "\umlCompartmentline").

% The technical obscurities in \TeX{} is this:  The brackets ("{}")
% needed to limit the scope of colors, cannot contain table line breaks.
% "\umlCompartmentline", which uses to be placed inside a table
% ("\umlClassifier"), must put the line break outside the brackets.

% \begin{macro}{import-}
%    \begin{macrocode}
\define@key[psset]{uml}{import}{\umlColorsImport}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{noimport-}
%    \begin{macrocode}
\define@key[psset]{uml}{noimport}{\umlColorsDefault}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{argument-}
%    \begin{macrocode}
\define@key[psset]{uml}{argument}{\umlColorsArgument}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{argument-}
%    \begin{macrocode}
\define@key[psset]{uml}{colorset}[\umlColorsDefault]{#1}
%    \end{macrocode}
% \end{macro}
%
% \subsection{The command}
% And then the command itself.
% \begin{macro}{\umlDrawable}
% This command does not do much work.  It just process the nmed options.
%    \begin{macrocode}
\newcommand\umlDrawable[2][]{%
%    \end{macrocode}
% It sets its variables to default values,
%    \begin{macrocode}
  \umlDrawableNull%
%    \end{macrocode}
% process the named options
%    \begin{macrocode}
  \psset[uml]{kind=Drawable,#1}%
%    \end{macrocode}
% and typesets it second argument.  This argument, the contents,
% typically uses some of the variables.
%    \begin{macrocode}
  #2%
}
%    \end{macrocode}
% \end{macro}
%
% \section{Element}\label{sec:impElement}
% \begin{macro}{\umlElementNull}
% "\umlElement" follows the same pattern as "\umlDrawable" and the other
% main commands; first, it sets its variables to the default values,
% then handles the named options, and least define the command itself to
% call its ``supercommand''.
%    \begin{macrocode}
\def\umlElementNull{%
  \def\umlReference{refdef}%
  \def\umlStereotype{}%
  \def\umlSubof{}%
  \def\umlImportedFrom{}%
  \def\umlComment{}%
  \def\umlAbstract{}%
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{reference-}
% "ref" is provided as an short-form for "reference".
%    \begin{macrocode}
\define@key[psset]{uml}{reference}{\def\umlReference{#1}}
\define@key[psset]{uml}{ref}{\def\umlReference{#1}}
%    \end{macrocode}
% \end{macro}
%
%\begin{macro}{stereotype-}
% The \LaTeX{} variable itself sometimes contains not only the 
% value itself, but some grahical stuff around.
%    \begin{macrocode}
\define@key[psset]{uml}{stereotype}{%
  \def\umlStereotype{{\hfil\phantom{x}<<#1>>\phantom{x}\hfil}\\}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{subof-}
%    \begin{macrocode}
\define@key[psset]{uml}{subof}{\def\umlSubof{{~Sub of: #1}\\}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{abstract-}
% The "abstract" named option also affects the graphical name in "\umlStretchbox".
%    \begin{macrocode}
\define@key[psset]{uml}{abstract}[]{\def\umlAbstract{\emph}}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{importedFrom-}
%    \begin{macrocode}
\define@key[psset]{uml}{importedFrom}{%
  \def\umlImportedFrom{{~From: #1}\\}%
  \umlColorsImport%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{comment-}
%    \begin{macrocode}
\define@key[psset]{uml}{comment}{\def\umlComment{{~#1}\\}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlElement}
% The command itself just calls "\umlDrawable".
%    \begin{macrocode}
\newcommand\umlElement[2][]{%
  \umlElementNull%
  {\umlDrawable[kind=Element,#1]{%
      \umlColorsAdjust%
      #2}}}
%    \end{macrocode}
% \end{macro}
%
% \section{Box}\label{sec:impBox}
%
% \subsection{Positioning}\label{sec:implementationClassPositions}
% One of the main responsibilities of "\umlBox" is to place the box in
% the right position.  In order to achieve this, "\umlBox" uses two
% macros, "\umlBoxPosCommand" and "\umlBoxPosDeltaCommand".  Each of
% these, in turn, uses other macros, which ultimately are set to default
% values.  How this happends is indicated in figure \ref{fig:impBoxPos}.
%
% The user can modify this tree by the named options "pos", "posX",
% "posY", "posDelta", "posDeltaX", "posDeltaY" and "refpoint".
%
% \newcommand\myBox[4]{
%    \rput(#1,#2){\rnode{#3}{
%         \begin{tabular}{c}#4\end{tabular}}}}
%   \begin{figure}[htbp]
%    \begin{center}
%      \rule{0mm}{7cm}% Why does not \pspicture make the space itself?
%      \hspace*{-1cm}
%     \pspicture(-3cm,-5cm)(8cm,1.5cm)
%       \begin{small}
%       \myBox{2.5cm}{1.5cm}{Box}{"\bslash{}umlBox"}
%       \myBox{0cm}{0cm}{Command}{"\bslash{}umlBoxPosCommand"}
%       \myBox{-2cm}{-2cm}{Refpoint}{"\bslash{}umlRefpoint"\\"refpoint="}
%       \myBox{-2cm}{-4cm}{RefpointValue}{"bl"}
%       \myBox{2cm}{-2cm}{Pos}{"\bslash{}umlPos"\\"pos="}
%       \myBox{1cm}{-4cm}{XPos}{"\bslash{}umlPosX"\\"posX="}
%       \myBox{3cm}{-4cm}{YPos}{"\bslash{}umlPosY"\\"posY="}
%       \myBox{1cm}{-5cm}{XPosValue}{"(0,"{\gray "0"}")"}
%       \myBox{3cm}{-5cm}{YPosValue}{"("{\gray "0"}",0)"}
%       \ncline{<-}{Command}{Box}
%       \ncline{<-}{Refpoint}{Command}
%       \ncline{<-}{RefpointValue}{Refpoint}
%       \ncline{<-}{Pos}{Command}
%       \ncline{<-}{XPos}{Pos}
%       \ncline{<-}{YPos}{Pos}
%       \ncline{<-}{YPosValue}{YPos}
%       \ncline{<-}{XPosValue}{XPos}
%       \myBox{7cm}{0cm}{DCommand}{"\bslash{}umlBoxPosDeltaCommand"}
%       \myBox{7cm}{-2cm}{PosDelta}{"\bslash{}umlPosDelta"\\"posDelta="}
%       \myBox{6cm}{-4cm}{XPosDelta}{"\bslash{}umlPosDeltaX"\\"posDeltaX="}
%       \myBox{8cm}{-4cm}{YPosDelta}{"\bslash{}umlPosDeltaY"\\"posDeltaY="}
%       \myBox{6cm}{-5cm}{XPosDeltaValue}{"(0,"{\gray "0"}")"}
%       \myBox{8cm}{-5cm}{YPosDeltaValue}{"("{\gray "0"}",0)"}
%       \ncline{<-}{DCommand}{Box}
%       \ncline{<-}{Refpoint}{DCommand}
%       \ncline{<-}{RefpointValue}{Refpoint}
%       \ncline{<-}{PosDelta}{DCommand}
%       \ncline{<-}{XPosDelta}{PosDelta}
%       \ncline{<-}{YPosDelta}{PosDelta}
%       \ncline{<-}{YPosDeltaValue}{YPosDelta}
%       \ncline{<-}{XPosDeltaValue}{XPosDelta}
%       \end{small}
%       \endpspicture
%       \caption{Positioning of boxes.  The arrows here means
%                ``calls''.  The user can affects this tree by 
%                several named options.}
%       \label{fig:impBoxPos}
%     \end{center}
%   \end{figure}
%
% \begin{macro}{\umlBoxNullPositions}
% First, the variables are set to their null values.  This command is
% called from "\umlBox" via "\umlBoxNull".
%
%    \begin{macrocode}
\def\umlBoxNullPositions{%
  \def\umlPosCommand{%
    \rput[\umlRefpoint](\umlPos)}%
  \def\umlPos{\umlPosX|\umlPosY}%
  \def\umlPosX{0,0}%
  \def\umlPosY{0,0}%
  \def\umlPosDeltaCommand{%
    \rput[\umlRefpoint](\umlPosDelta)}%
  \def\umlPosDelta{\umlPosDeltaX|\umlPosDeltaY}%
  \def\umlPosDeltaX{0,0}%
  \def\umlPosDeltaY{0,0}%
  \def\umlRefpoint{bl}%
  }%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{pos-}
% Note that all the named options starting with "pos"
% takes legal values as arguments.  You
% must write "posX={1em,0}" even if he zero is ignored.
% \label{pos}
%
%    \begin{macrocode}
\define@key[psset]{uml}{pos}[0,0]{\def\umlPos{#1}}
\define@key[psset]{uml}{posX}[0,0]{\def\umlPosX{#1}}
\define@key[psset]{uml}{posY}[0,0]{\def\umlPosY{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{posDelta-}
% The reference point of the box is placed at $pos + posDelta$.
%    \begin{macrocode}
\define@key[psset]{uml}{posDelta}[0,0]{\def\umlPosDelta{#1}}
\define@key[psset]{uml}{posDeltaX}[0,0]{\def\umlPosDeltaX{#1}}
\define@key[psset]{uml}{posDeltaY}[0,0]{\def\umlPosDeltaY{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{refpoint-}
% Legal values are \emph{reference points} (sec.\ \ref{sec:useReference})
%    \begin{macrocode}
\define@key[psset]{uml}{refpoint}{\def\umlRefpoint{#1}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Boxes in text}
%
% \begin{macro}{\umlBoxNullBoxes}
% Normally, a box is an empty hbox.  This can be changed using 
% the named option "box=".  It takes no values (i.e.\
% possible values are ignored).  It makes the box taking
% the natural size of its contents.
%    \begin{macrocode}
\def\umlBoxNullBoxes{%
%    \end{macrocode}
% This is how the box is made a zero size hbox then the "box=" named
% option are not in effect.
%    \begin{macrocode}
  \def\umlBoxH{\hbox to 0cm}%
  \def\umlBoxV{\smash}%
  }%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{box-}
% This gives the box its natural size.
%    \begin{macrocode}
\define@key[psset]{uml}{box}{%
  \def\umlBoxH{}% no \hbox to 0cm
  \def\umlBoxV{}% no \smash anymore
  \def\umlPosCommand{}% no \rput... anymore
  \def\umlPosDeltaCommand{}}% Ditto
%    \end{macrocode}
% \end{macro}
%
% \subsection{The visual appeareance}
% \begin{macro}{\umlBoxNullVisual}
%    \begin{macrocode}
\def\umlBoxNullVisual{%
  \def\umlGrayness{1}%
  \def\umlBorder{0mm}%
  \def\umlInnerBorder{0mm}%
  \def\umlOuterBorder{0mm}%
  \def\umlFillcolorCommand{umlFillcolor}%
  }%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{grayness-}
% The grayness of the background in the box.  
% Legal values are real numbers between 0 (black) and 1 (white).
% Default without named option is 1.  Default with named option
% is 0.85.
%    \begin{macrocode}
\define@key[psset]{uml}{grayness}[.85]{\definecolor{umlFillcolor}{gray}{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{fillcolorCommand-}
% "\umlFillcolorCommand" returns the name of the current fill color.
%    \begin{macrocode}
\define@key[psset]{uml}{fillcolorCommand}[umlFillcolor]{%
  \def\umlFillcolorCommand{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{border-}
% The thickness of the outer border.  Default without named option is
% 0~mm, with 0.4~pt.  Legal values are lengths.
%    \begin{macrocode}
\define@key[psset]{uml}{border}[0.4pt]{\gdef\umlBorder{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{outerBorder-}
% The margin around the border.  
% Default is "\umlhsep".
%    \begin{macrocode}
\define@key[psset]{uml}{outerBorder}[1pt]{\def\umlOuterBorder{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{innerBorder-}
% The space left between the edge of the box and its contents.
% Default is "\umlhsep".
%    \begin{macrocode}
\define@key[psset]{uml}{innerBorder}[\umlhsep]{\def\umlInnerBorder{#1}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Size}
% \begin{macro}{\umlBoxNullSize}
% The minimum size of the box (or rather, the space left for the contents).
% Different boxes (i.e., "\umlStretchBox" and "\umlDiagram" use
% different algorithms for sizeing the box.
%    \begin{macrocode}
\def\umlBoxNullSize{%
%    \end{macrocode}
%    \begin{macrocode}
  \def\umlSizeX{5mm}%
  \def\umlSizeY{7mm}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{size-}
% Minimum values, used mostly by "\umlDiagram".  
% Legal values are lengths.
%    \begin{macrocode}
\define@key[psset]{uml}{sizeX}{\def\umlSizeX{#1}}
\define@key[psset]{uml}{sizeY}{\def\umlSizeY{#1}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Holding together all the named options}
% \begin{macro}{\umlBoxNull}
% Just to invoke the other macros.
%    \begin{macrocode}
\def\umlBoxNull{%
  \umlBoxNullPositions%
  \umlBoxNullBoxes%
  \umlBoxNullVisual%
  \umlBoxNullSize%
  }%
%    \end{macrocode}
% \end{macro}
%
% \subsection{The command}\label{sec:impBoxCommand}
% \begin{macro}{\umlBox}
% A box is a rectangle with position and size.
% "\umlBox" takes two arguments: The named options and the contents.
%    \begin{macrocode}
\newcommand\umlBox[2][]{\leavevmode%
%    \end{macrocode}
% The variables are set to default
%    \begin{macrocode}
  \umlBoxNull%
%    \end{macrocode}
% and "\umlElement" is invoked, with new contents.
%    \begin{macrocode}
  \umlElement[kind=Box,#1]{%
%    \end{macrocode}
% Determines how large hbox \LaTeX{} should think this is
%    \begin{macrocode}
    \umlBoxH{% \hbox to 0cm or nothing
      \umlBoxV{% \smash or nothing
%    \end{macrocode}
% rputs the stuff the right place
%    \begin{macrocode}
        \umlPosCommand{%
          \umlPosDeltaCommand{%
%    \end{macrocode}
% the box is a node
%    \begin{macrocode}
          \rnode{\umlReference}{%
%    \end{macrocode}
% with outer margin
%    \begin{macrocode}
              \setlength{\fboxrule}{0mm}%
              \setlength{\fboxsep}{\umlOuterBorder}%
              \fbox{%
%    \end{macrocode}
% border
%    \begin{macrocode}
%                 \setlength{\fboxrule}{\umlBorder}%
%                 \setlength{\fboxsep}{0mm}%
%                 \fbox{%
%    \end{macrocode}
% and some color and inner margin
%    \begin{macrocode}
                \psframebox[framesep=\umlInnerBorder,
                    linewidth=\umlBorder,
                    fillcolor=\umlFillcolorCommand, fillstyle=solid]{%
%    \end{macrocode}
% around the contents.
%    \begin{macrocode}
                    #2}%
%                  }%
                }% 
              }%
            }%
          }%
        }%
      }%
    }%
  }
%    \end{macrocode}
% \end{macro}
%
% \section{Diagram}\label{sec:impDiagram}
%
% A diagram determines its size before typesetting the contents.  This in
% order to be able to place the contents relative to the borders of the diagram.

% \begin{macro}{\umlDiagramNull}
% The macro "\umlDiagramNull" sets the variables to their
% default variables.
%    \begin{macrocode}
\newcommand\umlDiagramNull{%
  \def\umlGrid{}%
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{grid-}
%    \begin{macrocode}
\define@key[psset]{uml}{grid}[1]{\message{named option grid is deprecated and of no use}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{The command}\label{sec:impDiagramCommand}
% \begin{macro}{\umlDiagram}
%    \begin{macrocode}
\newcommand\umlDiagram[2][]{%
%    \end{macrocode}
% First, the variables are set to their default values.
%    \begin{macrocode}
  \umlDiagramNull%
%    \end{macrocode}
% For some reason, "\umlDiagram" without the "box=" named option gives
% an error.  I do not understand why, but it appears to be an illegal
% paragraph break at "\umlBoxV" in "\umlBox".
%    \begin{macrocode}
  \umlBox[kind=Diagram, fillcolorCommand=umlDiagramFillcolor,
          box=,#1]{%
%    \end{macrocode}
% \index{grayness-!default in Diagram}
% \#2 is the contents.  The rules are to make sure the diagram is big
% enough.  The rules are normally invisible, because "\umlDebugLength"
% normally is 0~pt.

% However, the rules must be evaluated before the contents,
% so possible "\umlBox"es does not inflict on "\umlSizeX"
% and "\umlSizeY".  Thus, the "\expandafter", which assert that "#2"
% is typeset before, but expanded after, the rules.
%    \begin{macrocode}
      \expandafter{#2}{%
        \rule{\umlDebugLength}{\umlSizeY}%
        \rule{\umlSizeX}{\umlDebugLength}}%
    }%
  }%
%    \end{macrocode}
% \end{macro}

% \section{Stretchbox}\label{sec:impStretchbox}
%
% "\umlStretchbox" is the first command to take three arguments: The
% optional named options, a name and some contents.

% \begin{macro}{\umlStretchboxNull}
%    \begin{macrocode}
\newcommand\umlStretchboxNull{%
  \def\umlGraphicalName{StrechboxDefault{\umlAbstract\umlName}\\}%
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\umlGraphicalName}
% "\umlGraphicalName" is a name, possibly with some graphical fuzz, to
% be printed in the box.
% \end{macro}

% \begin{macro}{\umlStretchbox}
% The macro itself just handles the name.  The reference is by default
% set to the name.

% A stretchbox first typesets its contents, 
% and then take size depending on the contents.  
% This as opposed to a diagram, which determine the size first.
%    \begin{macrocode}
\newcommand\umlStretchbox[3][]{%
  \umlStretchboxNull%
  \umlBox[kind=Stretchbox, name={#2}, ref={#2}, #1]{%
    \umlIndex{\umlName}{\umlKind}%
    \rnode{\umlReference}{#3}%
    }%
  }%
%    \end{macrocode}
% \index{reference-!default in Stretchbox}
% \end{macro}

% \section{Package}\label{sec:impPackage}
% \begin{macro}{\umlPackage}
%    \begin{macrocode}
\newcommand\umlPackage[3][]{%
  % Null unneccessary
  \def\umlName{#1}%
  \begin{tabular}{@{}l@{}}%
%    \end{macrocode}
% \index{border-!default in Package}
% The upper rectangle.  It may seem natural to make this a
% "\umlStretchbox", but then we risk variable interference between the
% two instances of "\umlStretchbox".  It does not work in practice either.
%    \begin{macrocode}
    \umlStretchbox[kind=Package, border=0.4pt,#1]{#2}{%
      \def\umlGraphicalName{%
        {\umlhspace\hfill\relsize{2}\textbf{\umlName}%
          \rule{0mm}{2.3ex}\hfill\umlhspace}\\%
        }%
      \rnode{small\umlReference}{%
        \begin{tabular}{@{}l@{}}%
          \umlStereotype%
          \umlGraphicalName%
          \umlImportedFrom%
          \umlComment%
          \umlSubof%
        \end{tabular}}}%
%    \end{macrocode}
% There is no need for double width border between the parts
% of the package, so we step back a bit.
%    \begin{macrocode}
    \cr\noalign{\vskip -\umlBorder}%
%    \end{macrocode}
% The lower rectangle
%    \begin{macrocode}
    \umlStretchbox[kind=Package,border=0.4pt,#1]{#2}{%
      \rnode{big\umlReference}{%
        \begin{tabular}{@{}l@{}}%
%    \end{macrocode}
% Start the boxes in the lower rectangle
%    \begin{macrocode}
%    \end{macrocode}
% Insert the contents
%    \begin{macrocode}
          #3%
          \cr%
%    \end{macrocode}
% Here (in the "\cr"?), there is some vertical space.  I still have
% some work to do to understand the vertical lengths in tabular.
%    \begin{macrocode}
        \end{tabular}}}% End of lower rectangle
  \end{tabular}%
  }%
%    \end{macrocode}
% \end{macro}

% \section{Classifier}
% \label{sec:impClassifier}
%
% A classifier is a stretchbox which contains compartments.  
% A classifier can be instanciated, or be an instance.

% \begin{macro}{\umlClassifierNull}
%    \begin{macrocode}
\newcommand\umlClassifierNull{%
  \def\umlObject{}%
  \umlClassifierEmptytrue%
}
\newif\ifumlClassifierEmpty%
%    \end{macrocode}
% \end{macro}

% \begin{macro}{object-}
% This makes the classifier be an instance (object).
% Graphically, this is shown by an line under the classifier name.
% Note that instances cannot be abstract.
%    \begin{macrocode}
\define@key[psset]{uml}{object}{\def\umlObject{\underbar}}
%    \end{macrocode}
% \end{macro}


% \begin{macro}{suppress-}
% Makes "\umlSuppressionOn" active in the classifier
% (empty compartments are not shown).  For implementation: see
% \vpageref{suppress}.
% \end{macro}


% \begin{macro}{instance-}
% "instance" is provided as an equivalent to "object".
%    \begin{macrocode}
\define@key[psset]{uml}{instance}{\def\umlObject{\underbar}}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\umlClassifier}
% "\umlClassifier" is implemented as a table inside a "\umlStretchbox".
% The contents must be able to be inside a table.
% The contents is typically "\umlCompartment"s.
%    \begin{macrocode}
\newcommand\umlClassifier[3][]{%
%    \end{macrocode}
% Variables set to default values
%    \begin{macrocode}
  \umlClassifierNull%
%    \end{macrocode}
% Names fixed.  Uses "\umlAbstract".
%    \begin{macrocode}
  \def\umlName{#2}%
%    \end{macrocode}
% Grayness and border are given default values,
% possible to override.
%    \begin{macrocode}
  \umlStretchbox[kind=Classifier,border=.4pt,
    fillcolorCommand=umlClassifierFillcolor,#1]{#2}{%
%    \end{macrocode}
%\index{grayness-!default in Classifier}\index{border-!default in Classifier}
% "\umlGraphicalName" must be defined here not to be overridden by
% "\umlStretchboxNull".
% Note the invisible rule to make some space.
%    \begin{macrocode}
      \def\umlGraphicalName{%
        \rule{0mm}{2.8ex}%
        \umlhspace\larger\hfill\textbf{%
          \umlAbstract{\umlObject{\umlName}}}\hfill\umlhspace\\}%
      \begin{tabular}[tl]{@{}l@{}}%
        \umlStereotype%
        \umlGraphicalName%
        \umlImportedFrom%
        \umlComment%
        \umlSubof%
        #3%
%        \ifhmode hmode\else not\fi
%        \\\noalign{\vskip -15pt}%
        \ifumlClassifierEmpty\\\noalign{\vskip -2.5ex}\fi
      \end{tabular}%
    }%
  }%
%    \end{macrocode}
% \end{macro}

% \section{Class}\label{sec:impClass}

% \begin{macro}{\umlClass}
% A class is a classifier with the three usual compartments.
%
% There is not much work left for "\umlClass":
%    \begin{macrocode}
\newcommand\umlClass[4][]{%
%    \end{macrocode}
% A "\umlClassNull" is unneccessary, as there is no variables here.
%    \begin{macrocode}
  \umlClassifier[kind=Class,#1]{#2}{%
    \umlCompartment[name=attributes]{#3}%
    \umlCompartment[name=operations]{#4}%
    }%
  }%
%    \end{macrocode}
% \end{macro}

% \section{Schema}
% \label{sec:impSchema}

% \begin{macro}{\umlSchema}
% A schema is a classifier with some more compartments.
%    \begin{macrocode}
\newcommand\umlSchema[7][]{%
%    \end{macrocode}
% "Null" unneccessary here too.
%    \begin{macrocode}
  \umlClassifier[kind=Schema,#1]{#2}{%
    \umlCompartment[name=attributes]{#3}% Attributes
    \umlCompartment[name=operations]{#4}% Methods
    \umlCompartment[name=arguments]{#5}% Arguments
    \umlCompartment[name=constraints]{#6}% Constraints
    \umlCompartment[name=structure]{#7}% Structure
    }%
  }%
%    \end{macrocode}

% \end{macro}

% \section{Compartment}
% \label{sec:impCompartment}

% Classifiers (e.g., classes) are drawn as compartments (boxes) below each other.  

% "\umlCompartment" takes two arguments: a optional list of named
% options, and the contents.

% \begin{macro}{\umlCompartmentNull}
%    \begin{macrocode}
\newcommand\umlCompartmentNull{%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifisnull}
% A handy command stolen from [AdvancedTeX, p.126].
% If first argument is empty, execute the second; else execute the third.
%    \begin{macrocode}
\def\ifisnull#1#2#3{\def\inner{#1}%
  \ifx\inner\empty%
  #2\else{}#3%
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{last-}
%    \begin{macrocode}
\define@key[psset]{uml}{last}[]{%
  \message{The named option last= is deprecated and of no use.}%
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Suppression}
% \label{suppress}

%\SpecialMainIndex{\umlCompartmentSuppresstrue}
%\SpecialMainIndex{\umlCompartmentSuppressfalse}
% \begin{macro}{\ifumlCompartmentSuppress}
% The boolean variable "umlCompartmentSuppress" affects whether empty
% compartments should be suppressed or not.

% You can set the variable (saying "\umlCompartmentSuppresstrue" or
% "\umlCompartmentSuppressfalse") whenever you like.
%    \begin{macrocode}
\newif\ifumlCompartmentSuppress
%    \end{macrocode}
% \end{macro}

% \begin{macro}{suppress-}
% You can also set it for a construct (e.g., one compartment or an
% entire classifier) with the named option suppress.  When used, it is
% default true.
%    \begin{macrocode}
\define@key[psset]{uml}{suppress}[true]{%
  \def\arg{#1}%
  \ifx\arg\umlTrueVariable\umlCompartmentSuppresstrue%
  \else\umlCompartmentSuppressfalse%
  \fi%
}
%    \end{macrocode}
% \end{macro}

% \subsection{Compartment names}

%\SpecialMainIndex{\umlCompartmentNamesShowtrue}
%\SpecialMainIndex{\umlCompartmentNamesShowfalse}
% \begin{macro}{\ifumlCompartmentNamesShow}
% The boolean variable "umlCompartmentNamesShow" affects whether
% compartment names should be shown or not.

% Compartment names are shown top centered in a distinct font in the compartment.

% You can set the variable (saying "\umlCompartmentNamesShowtrue" or
% "\umlCompartmentNamesShowfalse") when you like.
%    \begin{macrocode}
\newif\ifumlCompartmentNamesShow
%    \end{macrocode}
% \end{macro}


% \begin{macro}{showname-}
% You may also use the named option "showname" for one compartment or
% another construct.
%    \begin{macrocode}
\define@key[psset]{uml}{showname}[true]{%
  \def\arg{#1}%
  \ifx\arg\umlTrueVariable\umlCompartmentNamesShowtrue%
  \else\umlCompartmentNamesShowfalse%
}
%    \end{macrocode}
% \end{macro}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \subsection{The implementation}

% The implementation of "\umlCompartment" caused me some trouble.  This
% is partly due to the many different possibilities, partly due to the
% funny scope rules in \LaTeX{} tables (in "\halign").

% In tables, it seems like every line is a scope.  A variable modified
% with "\def" in one line gets its old value when passing a line break.

% Also, we cannot place the line break inside the body of an if
% sentence.

% This is very, very odd, took me some time to detect, and destroys much
% beauty.

% In short: \TeX{} is a \emph{scanalous} bad programming language,
% but you can make absolutely everyting in it (including object oriented
% programs :-)

% A compartment composes classifiers, and is itself composed
% of compartment lines.  Every compartment line ends with a line break.
% Every compartment starts with a "\hline" and ends with a line break.

% \begin{macro}{\umlCompartmentCommon}
%     \begin{macrocode}
\newcommand\umlCompartmentCommon[2][]{%
%    \end{macrocode}
% Even if every compartment should be preceded by a line break,
% we assert this is really true.

% Of couse, the following line is an ad hoc hack, but I have no 
% better solution right now.
%    \begin{macrocode}
  \ifhmode \vspace*{-2.5ex}\\\fi%
%    \end{macrocode}
% The actual line between this and the following compartment.
%    \begin{macrocode}
  \hline%
%    \end{macrocode}
% The compartment name (if it should be shown).
% I miss an and operator in \TeX.
%    \begin{macrocode}
  \ifumlCompartmentNamesShow%
    \ifx\umlName\umlNameDefault\else%
      \omit\hfil\textbf{\umlName}\hfil\\%
    \fi%
  \fi%
%    \end{macrocode}
% This is really not neccesary, as it is defined in "\umlCompartment".
%    \begin{macrocode}
  \def\umlCompartmentContents{#2}%
%    \end{macrocode}
% If the compartment is empty (but not suppressed),
% It looks better to make it shorter.
% (But why isn't this like "\hline\hline" in the first place?
%    \begin{macrocode}
  \ifx\umlCompartmentContents\empty%
    \vspace*{-1.5ex}%
  \else% There is contents
    \umlClassifierEmptyfalse%
    #2%
  \fi%
%    \end{macrocode}
% Assuring we end with a line break.
%    \begin{macrocode}
  \ifhmode\\\fi%
  }
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\umlCompartment}
% "\umlCompartment" itself mainly calls "\umlCompartmentCommon".
%    \begin{macrocode}
\newcommand\umlCompartment[2][]{%
  \umlCompartmentNull%
  \def\umlCompartmentContents{#2}%
  \umlDrawable[kind=Compartment,#1]{%
    \umlColorsAdjust%
    \ifumlCompartmentSuppress%
      \ifx\umlCompartmentContents\empty\else%
        \umlCompartmentCommon[#1]{#2}%
      \fi%
    \else%
      \umlClassifierEmptyfalse%
      \umlCompartmentCommon[#1]{#2}%
    \fi}}%
%    \end{macrocode}
% \end{macro}

% \section{Compartmentline}\label{sec:impCompartmentline}

% A compartmentline is a line of text designed to be in a compartment.
% Such a line should have some room before and after it, in order not
% to touch the compartment border.

% \begin{macro}{\umlhspace}
% This make some horizontal space.
%    \begin{macrocode}
\def\umlhsep{.5ex}
\newcommand\umlhspace{\hspace*{\umlhsep}}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\umlCompartmentline}
% This should be straight-forward\dots
%    \begin{macrocode}
\newcommand\umlCompartmentline[2][]{%
  \umlDrawable[kind=Compartmentline,#1]{%
    {\umlColorsAdjust\umlhspace{}#2{}\umlhspace}\\}}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\umlCompartmentText}
% Provided for backward compatibility.
%    \begin{macrocode}
\newcommand\umlCompartmentText[1]{%
  \umlhspace#1\umlhspace}
%    \end{macrocode}
% \end{macro}


% \section{Feature}
% \label{sec:impFeature}
%
% A feature is something attached  to a classifier.

% \begin{macro}{\umlVisibilityLength}
% This is the hspace in front of the attribute name, where the
% visibility is placed.
%    \begin{macrocode}
\def\umlVisibilityLength{2ex}
%    \end{macrocode}
%\end{macro}

% \begin{macro}{\umlFeatureNull}
%    \begin{macrocode}
\newcommand\umlFeatureNull{%
  \def\umlVisibility{}%
  \def\umlType{}%
  \def\umlPropertyString{}%
  \def\umlInitialValue{}%
  \def\umlName{FeatureNameDefault}%
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{visibility-}
%    \begin{macrocode}
\define@key[psset]{uml}{visibility}[+]{%
  \def\umlVisibility{\hbox to \umlVisibilityLength{#1\hfil}}}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\umlTilde}
% Prints a tilde.
%    \begin{macrocode}
\newcommand\umlTilde{\ensuremath{\sim}}
%    \end{macrocode}
% \end{macro}

%
% \begin{macro}{propertyString-}
%    \begin{macrocode}
\define@key[psset]{uml}{propertyString}{%
  \def\umlPropertyString{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{type-}
% The data type returned from the feature.
%    \begin{macrocode}
\define@key[psset]{uml}{type}{%
  \def\umlType{: #1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{initialValue-}
%    \begin{macrocode}
\define@key[psset]{uml}{initialValue}{%
  \def\umlInitialValue{= #1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlFeature}
% "\umlFeature" is implemented as a table inside a "\umlStretchbox".
% The contents must be able to be inside a table.
% The contents is typically "\umlCompartment"s.
%    \begin{macrocode}
\newcommand\umlFeature[2][]{%
  \umlFeatureNull%
  \umlCompartmentline[kind=Feature, #1]{%
    \umlIndex{\umlName}{\umlKind}%
    #2}%
  }%
%    \end{macrocode}
% \end{macro}
%
% \subsection{Attribute}\label{sec:impAttribute}
%
% \begin{macro}{\umlAttributeNull}
%    \begin{macrocode}
\def\umlAttributeNull{%
  \def\umlMultiplicity{}%
  \def\umlOrdering{}%
  \def\umlMultiplicityOrdering{}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{default-}
% This is provided as an alias to "initialValue" for the sake
% of backward compatibility.  Use is deprecated.
%    \begin{macrocode}
\define@key[psset]{uml}{default}{%
  \def\umlInitialValue{ = #1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{multiplicity-}
% Examples of legal values are "{[1]}", "{[1..*]}" and "{[1..3,5..]}".
%    \begin{macrocode}
\define@key[psset]{uml}{multiplicity}{%
  \def\umlMultiplicity{#1}%
  \def\umlMultiplicityOrdering{[\umlMultiplicity{} \umlOrdering]}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{ordering-}
% Legal values are "ordered" and "unordered".  
% Absent value imply unordered.  Default value with named option is ordered.
%    \begin{macrocode}
\define@key[psset]{uml}{ordering}[ordered]{%
  \def\umlOrdering{#1}%
  \def\umlMultiplicityOrdering{[\umlMultiplicity{} \umlOrdering]}}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\umlAttribute}
%    \begin{macrocode}
\newcommand\umlAttribute[2][]{%
  \umlAttributeNull%
  \umlFeature[kind=Attribute, name={#2}, #1]{%
    \umlVisibility #2 \umlType \umlMultiplicityOrdering
    \umlInitialValue \umlPropertyString}}
%    \end{macrocode}
% \end{macro}

% \subsection{Method}\label{sec:impMethod}


% \begin{macro}{\umlMethodNull}
%    \begin{macrocode}
\newcommand\umlMethodNull{%
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{returntype-}
% Alias to "type=".
%    \begin{macrocode}
\define@key[psset]{uml}{returntype}{%
  \def\umlType{: #1}}
%    \end{macrocode}
% \end{macro}


% \begin{macro}{\umlMethod}
%    \begin{macrocode}
\newcommand\umlMethod[3][]{%
  \umlMethodNull%
  \def\umlName{#2}%
  \umlFeature[kind=Method, name={#2}, #1]{%
    \umlVisibility #2(#3) \umlType \umlPropertyString}} 
%    \end{macrocode}
% \end{macro}

% \subsection{Argument}\label{sec:impArgument}


% \begin{macro}{\umlArgumentNull}
%    \begin{macrocode}
\newcommand\umlArgumentNull{%
}
%    \end{macrocode}
% \end{macro}



% \begin{macro}{\umlArgument}
%    \begin{macrocode}
\newcommand\umlArgument[2][]{%
  \umlArgumentNull%
  \def\umlName{#2}%
  \umlFeature[kind=Argument, name={#2}, #1]{%
    \emph{#2} \umlType \umlInitialValue}}
%    \end{macrocode}
% \end{macro}

% \section{Relation}\label{sec:impRelation}

% \subsection{Node connection points}


% \begin{macro}{\umlRelationNullConnection}
%    \begin{macrocode}
\newcommand\umlRelationNullConnection{%
  \def\umlNodesepA{0pt}%
  \def\umlNodesepB{0pt}%
  \def\umlOffsetA{0pt}%
  \def\umlOffsetB{0pt}%
  \def\umlAngleA{}%
  \def\umlAngleB{}%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{angle-}
% This is the angle at which the connector hits the node
%    \begin{macrocode}
\define@key[psset]{uml}{angleA}{\def\umlAngleA{#1}}
\define@key[psset]{uml}{angleB}{\def\umlAngleB{#1}}
\define@key[psset]{uml}{angle}{\def\umlAngleA{#1}\def\umlAngleB{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{nodesep-}
% The distance from the node to the connector end.
% Legal values are lengths.
%    \begin{macrocode}
\define@key[psset]{uml}{nodesepA}{\def\umlNodesepA{#1}}
\define@key[psset]{uml}{nodesepB}{\def\umlNodesepB{#1}}
\define@key[psset]{uml}{nodesep}{\def\umlNodesepA{#1}\def\umlNodesepB{#1}}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{offset-}
% After the connection point is calculated, it is shift right (assumed
% direction onto node) by this value.  Legal values are lengths.
%    \begin{macrocode}
\define@key[psset]{uml}{offsetA}{\def\umlOffsetA{#1}}
\define@key[psset]{uml}{offsetB}{\def\umlOffsetB{#1}}
\define@key[psset]{uml}{offset}{\def\umlOffsetA{#1}\def\umlOffsetB{#1}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Arm geometry}
%
% \begin{macro}{\umlRelationNullArmGeometry}
%    \begin{macrocode}
\newcommand\umlRelationNullArmGeometry{%
  \pssetlength\umlArmA{0pt}%
  \pssetlength\umlArmB{0pt}%
  \def\umlArmAngleA{0}%
  \def\umlArmAngleB{0}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{armA-}
% This is the lengths of the arms.
%    \begin{macrocode}
\newlength\umlArmA
\newlength\umlArmB
\define@key[psset]{uml}{armA}{\pssetlength\umlArmA{#1}}
\define@key[psset]{uml}{armB}{\pssetlength\umlArmB{#1}}
\define@key[psset]{uml}{arm}{%
  \pssetlength\umlArmA{#1}%
  \pssetlength\umlArmB{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{armAngle-}
% This is the angle of the arm.
%    \begin{macrocode}
\define@key[psset]{uml}{armAngleA}{\def\umlArmAngleA{#1}}
\define@key[psset]{uml}{armAngleB}{\def\umlArmAngleB{#1}}
\define@key[psset]{uml}{armAngle}{%
  \def\umlArmAngleA{#1}%
  \def\umlArmAngleB{#1}%
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Visual appeareance}
%
% \begin{macro}{\umlRelationNullVisual}
%    \begin{macrocode}
\newcommand\umlRelationNullVisual{%
  \def\umlLinestyle{solid}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{umllinestyle-}
% Legal values are "none", "solid", "hashed" and "dotted".
%    \begin{macrocode}
\define@key[psset]{uml}{umllinestyle}{\def\umlLinestyle{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{relationColor-}
% The color of the line.
%    \begin{macrocode}
\define@key[psset]{uml}{relationColor}[black]{\pst@getcolor{#1}\pslinecolor}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{lineColor-}
% Alias for "relationColor=".
%    \begin{macrocode}
\define@key[psset]{uml}{linecolor}{\pst@getcolor{#1}\pslinecolor}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlRelationNull}
%    \begin{macrocode}
\newcommand\umlRelationNull{%
  \umlRelationNullConnection%
  \umlRelationNullArmGeometry%
  \umlRelationNullVisual%
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{The macro}
% \begin{macro}{\umlRelation}
% The command itself:
%    \begin{macrocode}
\newcommand\umlRelation[4][]{%
  \umlRelationNull%
%    \end{macrocode}
% The default reference is the concatenation of the two references
%    \begin{macrocode}
  \umlElement[kind=Relation,ref={#2#3}, #1]{%
%    \end{macrocode}
% Putting the "Aa" and "Ba" nodes, default (without "angle=") first
%    \begin{macrocode}
  \ncline[linecolor=green, linestyle=\umlDebugLinestyle,
          offsetA=\umlOffsetA, nodesepA=\umlNodesepA,
          offsetB=\umlOffsetB, nodesepB=\umlNodesepB]{#2}{#3}%
  \lput{:R}(0){\pnode{Aa\umlReference}}%
  \lput{:R}(1){\pnode{Ba\umlReference}}%
%    \end{macrocode}
% Then modifying "Aa", if "angleA=" or "angle=" is used
%    \begin{macrocode}
  \ifx\umlAngleA\empty \else
     \ncdiag[linestyle=\umlDebugLinestyle, linecolor=magenta, %
             angleA=\umlAngleA,
             offsetA=\umlOffsetA, nodesepA=\umlNodesepA,
             offsetB=\umlOffsetB, nodesepB=\umlNodesepB
            ]{#2}{#2}%
     \lput{:R}(0){\pnode{Aa\umlReference}}\fi%
%    \end{macrocode}
% And "Ba".
%    \begin{macrocode}
  \ifx\umlAngleB\empty \else
     \ncdiag[linestyle=\umlDebugLinestyle, linecolor=magenta, %
             angleA=\umlAngleB,
             offsetA=\umlOffsetA, nodesepA=\umlNodesepA,
             offsetB=\umlOffsetB, nodesepB=\umlNodesepB
            ]{#3}{#3}%
     \lput{:R}(0){\pnode{Ba\umlReference}}\fi%
%    \end{macrocode}
% Now, we can draw the line, from the "Aa" to the "Ba" node.
%    \begin{macrocode}
    \ncdiag[linestyle=\umlLinestyle,  linecolor=umlLinecolor,
            angleA=\umlArmAngleA, angleB=\umlArmAngleB,
            armA=\umlArmA, armB=\umlArmB
            ]{%
              Aa\umlReference}{%
              Ba\umlReference}%
%    \end{macrocode}
% Placing nodes "Ab" and "Bb".
% If there is no arm A,
%    \begin{macrocode}
  \ifdim \umlArmA=0pt \lput{:R}(2){\pnode{Ab\umlReference}}%
%    \end{macrocode}
% Else, if there is 
%    \begin{macrocode}
  \else \lput{:R}(1){\pnode{Ab\umlReference}} \fi%
%    \end{macrocode}
% If there is no arm B,
%    \begin{macrocode}
  \ifdim \umlArmB=0pt \lput{:R}(1){\pnode{Bb\umlReference}}%
%    \end{macrocode}
% Else, if there is 
%    \begin{macrocode}
  \else \lput{:R}(2){\pnode{Bb\umlReference}} \fi%
%    \end{macrocode}
% Final nodes
%    \begin{macrocode}
   \lput{:R}(1){\pnode{Ac\umlReference}}%
   \lput{:R}(2){\pnode{Bc\umlReference}}%
%    \end{macrocode}
% Other contents
%    \begin{macrocode}
   #4}% of \umlElement
}
%    \end{macrocode}
% \end{macro}

% \subsection{About the spesific relations}

% The different relations are specialized relations; they typically call
% "\umlRelation" and "\umlSymbol" with an appropriate symbol.


% \label{lengths}
% \begin{macro}{\umlSymbolHeightDefault}
% All the symbols are drawn with "0" as the upper border,
% "-\umlSymbolHeightDefault" as the lower,
% "-\umlSymbolWidthDefault" as the left and
% "\umlSymbolWidthDefault" as the right one.  These lengths can
% be changed by the user.  See, however, section \vref{sec:impInner}.
%    \begin{macrocode}
\newlength\umlSymbolHeightDefault
\setlength\umlSymbolHeightDefault{1em}
\newlength\umlSymbolWidthDefault
\setlength\umlSymbolWidthDefault{.5em}
%    \end{macrocode}
% \end{macro}

% \subsection{Association}\label{sec:impAssociation}

% \label{sec:association}
% \begin{macro}{\umlAssociation}
% "\umlAssociation" is a relation without any other contents.
%    \begin{macrocode}
\newcommand\umlAssociation[3][]{%
  \umlRelation[kind=Association, #1]{#2}{#3}{}%
}
%    \end{macrocode}
% \end{macro}


% \subsection{Subclass (generalization)}
% \label{sec:impSubclass}
% \label{sec:impGeneralization}

% \begin{macro}{\umlSubclass}
% A simple relation with a triangle as an endsymbol.
%    \begin{macrocode}
\newcommand\umlSubclass[3][]{%
  \def\umlEndSymbol{%
     \pspolygon*[linecolor=white](0,0)%
       (-\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
       (\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
     \pspolygon[](0,0)% Why does not dimen=inner work?
       (-\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
       (\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
      }%
%   \def\umlEndSymbol{% Alternative \umlEndSymbol
%     \pstriangle[dimen=inner](0,-\umlSymbolHeightDefault)%
%     (\umlSymbolWidthDefault,\umlSymbolHeightDefault)}
%    \end{macrocode}
%    \begin{macrocode}
  \umlRelation[kind=Subclass, #1]{#2}{#3}{%
    \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}%
  }
\def\umlGeneralization{\umlSubclass}
%    \end{macrocode}
% \end{macro}

% \subsection{Inner class}
% \label{sec:impInner}
% \label{sec:inner}

% The making of this symbol gave some problems.  After experimenting
% with different interpolations and Bézier curves, I defined it to
% consist of two clipped wedges.  Each should of course have width $w
% = $ "\umlWidthDefault" and height 
% $h = $"\umlHeightDefault".
% \index{circle}
%  The radius of the circle is $r$, and $r
% = v + w$.  This gives figure \vref{fig:innerSymbol}.
% \begin{figure}[htbp]
% This figure is drawn with an angle of 60 degrees.
%   \begin{center}{%
%     \psset{unit=1.5cm}
%     \begin{pspicture}(-2,-2)(2,.25)%
%       %\psgrid[subgriddiv=0,griddots=10](0,0)(-2,-2)(1,.25)
%       \psline(-2,0)(2,0)
%       \pswedge(0,-.866){1}{120}{180}
%       \pscircle[](0,-.866){1}
%       \psarc[linewidth=2.4pt](0,-.866){1}{120}{180}
%       \psline(-.5,0)(-.5,-.866)
% The symbols
%       \psbezier(-1,-.866)(-1,-.933)(-.75,-.933)(-.75,-1)
%       \psbezier(-.5,-.866)(-.5,-.933)(-.75,-.933)(-.75,-1)
%       \rput[t](-.75,-1){\rput(0,-1ex){$v$}}
%       \psbezier(-.5,-.866)(-.5,-.933)(-.25,-.933)(-.25,-1)
%       \psbezier(-0,-.866)(-0,-.933)(-.25,-.933)(-.25,-1)
%       \rput[t](-.25,-1){\rput(0,-1ex){$w$}}
%       \psbezier(0,0)(0.067,0)(0.067,-.433)(0.134,-.433)
%       \psbezier(0,-.866)(0.067,-.866)(0.067,-.433)(0.134,-.433)
%       \rput[l](.134,-.433){~$h$}
%     \end{pspicture}
%     \hspace{1cm}
%     \begin{pspicture}(-2,-2)(1,.25)%
%       \psline(-2,0)(1,0)
%       \psarc[linewidth=2.4pt](0,-.866){1}{120}{180}
%       \psarc[linewidth=2.4pt](-1,-.866){1}{0}{60}
%       \psline[linewidth=2.4pt](-1,-.866)(0,-.866)
%       \psline[linewidth=2.4pt](-.5,-1.75)(-.5,-.866)
%     \end{pspicture}
%     \caption{The inner class symbol}
%     \label{fig:innerSymbol}}
%   \end{center}
% \end{figure}

% \index{Pythagoras}
% We have $$r = v + w$$ and, from Pythagoras, $$r^2 = h^2 + w^2$$
% This gives $$r=\frac{h^2}{2v} + \frac{v}{2}$$ and
% $$w=\frac{h^2}{2v}-\frac{v}{2}$$ and we know where to locate the
% wedge.
%
% \index{addition!of lengths}\index{subtraction!of lengths}
% \index{multiplication!of lengths}\index{division!of lengths}
% However, while addition and subtraction of lengths is easy in
% PSTricks (only stepping back and forth), multiplication  and division
% of lengths is difficult, if not impossible.  I really haven't found a
% good solution to this problem.
%
% The not-so-good problem is to define $w$ and $r$ as \TeX{} lengths
% ("\umlInnerWidthDefault" and
% "\umlInnerRadiusDefault")
% and then assign them values manually.  We
% have to remember, then, that Pythagoras still should work.  
%
% Page \pageref{lengths} assign the default values $h=1$ em, $v=.5$ em.
% This gives
%
% \begin{macro}{\umlInnerWidthDefault}
% $w=0.75$ em
%    \begin{macrocode}
\newlength\umlInnerWidthDefault
\setlength\umlInnerWidthDefault{0.75em}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\umlInnerRadiusDefault}
%   and $r=1.25$ em.
%    \begin{macrocode}
\newlength\umlInnerRadiusDefault
\setlength\umlInnerRadiusDefault{1.25em}
%    \end{macrocode}
% \end{macro}
%
% If we should implement the symbol by "\umlArc", we had to know some
% angles.  They would be easy to compute using trigonometry,
% but that is difficult within \TeX.  Then, we use "\umlCircle" and
% "\psclip" instead.
%
% Maybe this could be done easily using raw  postscript?
%
% \begin{macro}{\umlInner}
% On some systems, the clipping makes some borders.  
%    \begin{macrocode}
\newcommand\umlInner[3][]{%
  \def\umlEndSymbol{%
     \pspolygon*[linecolor=white](0,0)%
       (-\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
       (\umlSymbolWidthDefault,-\umlSymbolHeightDefault)%
    \psclip{%
      \psframe[linewidth=0pt]%
        (-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)(0,0)}
      \pscircle(\umlInnerWidthDefault,-\umlSymbolHeightDefault)%
        {\umlInnerRadiusDefault}
    \endpsclip
    \psclip{%
      \psframe[linewidth=0pt]%
        (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)(0,0)}
      \pscircle(-\umlInnerWidthDefault,-\umlSymbolHeightDefault)%
        {\umlInnerRadiusDefault}
    \endpsclip
    \psline(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
      (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)}
  \umlRelation[kind=Inner, #1]{#2}{#3}{%
    \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}
  }}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Instance}\label{sec:instance}\label{sec:impInstance}
%
% \begin{macro}{\umlInstance}
% The only new thing about "\umlInstance" is the addition of one named
% option, the linestyle.
%    \begin{macrocode}
\newcommand\umlInstance[3][]{%
  \def\umlEndSymbol{%
    \psline(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
      (0,0)%
      (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)}%
  \umlRelation[kind={Instance-of}, umllinestyle=dashed, #1]{#2}{#3}{%
    \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
  }
%    \end{macrocode}
% \index{umllinestyle-!dashed in Instance}
% \end{macro}
%
% \subsection{Aggregation}\label{sec:aggregation}\label{sec:impAggregation}
%
% \begin{macro}{\umlAggregation}
% Endpoint is a diamond.\index{diamond}
%    \begin{macrocode}
\newcommand\umlAggregation[3][]{%
  \def\umlEndSymbol{%
%    \end{macrocode}
% Anyone said addition of lengths in PSTricks was difficult?
%    \begin{macrocode}
    \rput(0,-\umlSymbolHeightDefault){%
      \psline*[linecolor=white](-\umlSymbolWidthDefault, 0)%
        (0,-\umlSymbolHeightDefault)%
        (\umlSymbolWidthDefault, 0)}
    \psline*[linecolor=white]%
      (-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
      (0,0)%
      (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)
    \rput(0,-\umlSymbolHeightDefault){%
      \psline(-\umlSymbolWidthDefault, 0)%
        (0,-\umlSymbolHeightDefault)%
        (\umlSymbolWidthDefault, 0)}
    \psline(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
      (0,0)%
      (\umlSymbolWidthDefault,
      -\umlSymbolHeightDefault)}
  \umlRelation[kind=Aggregation, #1]{#2}{#3}{%
    \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Composition}\label{sec:composition}\label{sec:impComposition}
%
% \begin{macro}{\umlComposition}
% End symbol is a filled diamond. \index{diamond!filled}\index{filled diamond}
%    \begin{macrocode}
\newcommand\umlComposition[3][]{%
  \def\umlEndSymbol{%
    \rput(0,-\umlSymbolHeightDefault){%
      \psline*(-\umlSymbolWidthDefault, 0)%
        (0,-\umlSymbolHeightDefault)%
        (\umlSymbolWidthDefault, 0)}
    \psline*(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
      (0,0)%
      (\umlSymbolWidthDefault,
      -\umlSymbolHeightDefault)}
  \umlRelation[kind=Composition, #1]{#2}{#3}{%
    \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Application}\label{sec:application}\label{sec:impApplication}
%
% \begin{macro}{\umlApplication}
% End symbol is a filled arrow.\index{arrow!endpoint in Application}
%    \begin{macrocode}
\newcommand\umlApplication[3][]{%
  \def\umlEndSymbol{%
    \pspolygon*(-\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
      (0,0)%
      (\umlSymbolWidthDefault, -\umlSymbolHeightDefault)%
      (0,-\umlSymbolWidthDefault)}%
  \umlRelation[kind=Application, #1]{#2}{#3}{%
    \lput(1.2){\pnode{argument\umlReference}}%
    \umlSymbol[fraction=B]{\umlReference}{\umlEndSymbol}}
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{ToRelation}\label{sec:impToRelation}
%
% \begin{macro}{\umlToRelationNull}
%    \begin{macrocode}
\newcommand\umlToRelationNull{%
  \def\umlPosMeetLine{.5}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{posMeetLine-}
% Where this relation shall meet the relation.
%    \begin{macrocode}
\define@key[psset]{uml}{posMeetLine}[.5]{\def\umlPosMeetLine{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlAssociationClass}
% Relation from a relation to a classifier
%    \begin{macrocode}
\newcommand\umlToRelation[3][]{%
  \umlToRelationNull%
%    \end{macrocode}
%   We have to process the "posMeetLine" option before the "\lput".
%   This introduces some overhead, as "\psset" is run twice.
%   However, I expect this to be used relatively few times.
%    \begin{macrocode}
  \psset[uml]{kind=ToRelation, #1}%
  \ncline[linecolor=red, linestyle=\umlDebugLinestyle]{Ac#3}{Bc#3}%
  \lput{:R}(\umlPosMeetLine){\pnode{ToRelation#3}}%
  \umlRelation[ref={#2#3}, #1]{#2}{ToRelation#3}{}%
}
%    \end{macrocode}
% \index{reference-!default in ToRelation}
% \end{macro}
%
% \subsection{AssociationClass and AssociationSchema}\label{sec:associationClass}
% \label{sec:impAssociationClass}
% \label{sec:impAssociationSchema}
%
% \begin{macro}{\umlAssociationClass}
% Relation from a relation to a schema symbol.
%\index{umllinestyle!dashed in AssociationClass}
% \index{posMeetLine!AssociationClass}
%    \begin{macrocode}
\newcommand\umlAssociationSchema[3][]{%
  \umlToRelation[kind=AssociationSchema,
    posMeetLine=.5, umllinestyle=dashed,#1]{#2}{#3}%
}
\newcommand\umlAssociationClass[3][]{%
  \umlAssociationSchema[kind=AssociationClass,#1]{#2}{#3}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{ArgumentRelation}\label{sec:argument}
% \label{sec:impArgumentRelation}
%
% \begin{macro}{\umlArgumentRelation}
% Relation from an application to an argument.
%\index{umllinestyle!dottedin ArgumentRelation}
% \index{posMeetLine!ArgumentRelation}
%    \begin{macrocode}
\newcommand\umlArgumentRelation[3][]{%
  \umlToRelation[kind=ArgumentRelation,
    posMeetLine=.2,umllinestyle=dotted,#1]{#2}{#3}%
  }
%    \end{macrocode}
% \end{macro}
%
% \section{AssociationEnd}\label{sec:impAssociationEnd}
%
% \begin{macro}{\umlAssociationEndNull}
%    \begin{macrocode}
\newcommand\umlAssociationEndNull{%
  \def\umlAEOffset{\umlAEOffsetDefault}%
  \def\umlAEOffsetDefault{0pt}%
  \def\umlAEFraction{0}%
  \def\umlAEFractionAngle{\umlAEFractionAngleDefault}%
  \def\umlAEFractionAngleDefault{:U}%
  \def\umlAEAngle{\umlAEAngleDefault}%
  \def\umlAEAngleDefault{U}%
  \def\umlAERefpoint{B}%
  \def\umlAEHeight{\umlAEHeightDefault}%
  \def\umlAEHeightDefault{0pt}%
  \def\umlAENoderefClose{Ac}%
  \def\umlAENoderefFar{Bc}%
  \def\umlAEType{AssociationEnd}%
  \def\umlAEKind{AssociationEnd}
}
%    \end{macrocode}  
% \end{macro}
%
% \begin{macro}{import-}
%    \begin{macrocode}
\define@key[psset]{umlAE}{import}{\def\umlAEColor{red}}
%    \end{macrocode}  
% \end{macro}
% \begin{macro}{type-}
%    \begin{macrocode}
\define@key[psset]{umlAE}{type}{\def\umlType{#1}}
%    \end{macrocode}  
% \end{macro}
% \begin{macro}{kind-}
% E.g., AssociationEnd.
%    \begin{macrocode}
\define@key[psset]{umlAE}{kind}{\def\umlKind{#1}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{offset-}
%    \begin{macrocode}
\define@key[psset]{umlAE}{offset}{\def\umlAEOffset{#1}}
%    \end{macrocode}  
% \end{macro}
% \begin{macro}{angle-}
% Angle used to rotate the symbol itself.
%    \begin{macrocode}
\define@key[psset]{umlAE}{angle}{\def\umlAEAngle{#1}}
%    \end{macrocode}  
% \end{macro}
%
% \begin{macro}{fractionAngle-}
% The angle used when positioning the symbol.
% Legal values includes angles preceded by a colon (:),
% indicting positioning relative to the relation.
% This is expected to be used by subcommands, but
% seldom by users.
%    \begin{macrocode}
\define@key[psset]{umlAE}{fractionAngle}{\def\umlAEFractionAngle{#1}}
%    \end{macrocode}  
% \end{macro}
% \begin{macro}{height-}
%    \begin{macrocode}
\define@key[psset]{umlAE}{height}{\def\umlAEHeight{#1}}
%    \end{macrocode}  
% \end{macro}
% \begin{macro}{refpoint-}
%    \begin{macrocode}
\define@key[psset]{umlAE}{refpoint}{\def\umlAERefpoint{#1}}
%    \end{macrocode}  
% \end{macro}
% \begin{macro}{refpoint-}
%    \begin{macrocode}
%% \define@key[psset]{umlAE}{type}{\def\umlAEType{#1}}%   %%%%%%%%%%%%
%    \end{macrocode}  
% \end{macro}
%
% \subsection{Fraction}
%
% \begin{macro}{fraction-}
% This value is used by "\umlAEFixFractionLabel" and "\umlAEFixFractionSymbol".
%    \begin{macrocode}
\define@key[psset]{umlAE}{fraction}{\def\umlAEFraction{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlFromTo}
% A handy little procedure.  If its first argument is "A" or "From", it
% executes the second argument.  If it is "B" or "To", it executes the
% third.  Used in the procedures like "\umlAssociationEndMakeA",
% "\umlLabelMakeA" and "\umlSymbolMakeA".
%    \begin{macrocode}
\newcommand\umlFromTo[3]{%
  \edef\umlAEFractionArgument{#1}%
  \def\umlAEFractionTmp{From}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#2\fi%
  \def\umlAEFractionTmp{A}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#2\fi%
  \def\umlAEFractionTmp{To}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#3\fi%
  \def\umlAEFractionTmp{B}\ifx\umlAEFractionArgument\umlAEFractionTmp{}#3\fi%
}
%
%    \end{macrocode}  
% \end{macro}
%
% \begin{macro}{\umlAssociationEndUseFraction}
% If "\umlFraction" is "A" or something (i.e., if "fraction=A" or sth),
% adjust some other parameters.
%    \begin{macrocode}
\newcommand\umlAssociationEndUseFraction{%
%    \begin{macrocode}
  \umlFromTo{\umlAEFraction}{% If A or From
    \def\umlAENoderefClose{Aa}%
    \def\umlAENoderefFar{Ab}%
    \def\umlAEFraction{0}%
    }{%
    \def\umlAENoderefClose{Ba}% If B or To
    \def\umlAENoderefFar{Bb}%
    \def\umlAEFraction{0}%
%    \end{macrocode}
% If this is a ``"B"'' type association end, 
% and this is an Label type association end,
% invert the height.
%    \begin{macrocode}
    \def\umlTmp{Label}%
    \ifx\umlTmp\umlAEType% 
      \edef\umlAEHeight{-\umlAEHeight}\fi%
    }%
  }
%    \end{macrocode}  
% \end{macro}
%
% \subsection{The command}
%
% \begin{macro}{\umlAssociationEnd}
% This places a symbol (third argument) on the \meta{From} end of 
% the relation (indicated by the second argument).
%    \begin{macrocode}
\newcommand\umlAssociationEnd[3][]{%
  \umlAssociationEndNull%
  \psset[umlAE]{kind=AssociationEnd,#1}%
  \umlAssociationEndUseFraction%
%  AE:#2:\umlAENoderefClose:\umlAENoderefFar:
  \ncline[linecolor=red, linestyle=\umlDebugLinestyle]{%
    \umlAENoderefClose#2}{\umlAENoderefFar#2}%
  {\umlColorsAdjust%
    \lput[\umlAERefpoint]{\umlAEFractionAngle}(\umlAEFraction){%
      \rput[\umlAERefpoint]{\umlAEAngle}(\umlAEOffset, \umlAEHeight){%
        #3}%
      }%
    }%
  }%
%    \end{macrocode}
% \end{macro}
%
% \subsection{Label}\label{Labels}\label{sec:labels}
% \label{sec:impLabel}
%
% \begin{macro}{\umlLabel}
% A label is a symbol with default height and offset.
%    \begin{macrocode}
\newcommand\umlLabel[3][]{% Null unneccesary
  \umlAssociationEnd[kind=Label,offset=4ex,height=2ex,angle=N, #1]{#2}{#3}%
}
%    \end{macrocode}
%\end{macro}
%
% \begin{macro}{\umlLabelA}
% "\umlLabelA" and "\umlLabelB" are
% provided for convenience and backward compatibility.
%    \begin{macrocode}
\newcommand\umlLabelA[2][]{\umlLabel[#1,fraction=A]{#2}}
\newcommand\umlLabelB[2][]{\umlLabel[#1,fraction=B]{#2}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Symbol}\label{Symbols}\label{sec:symbols}
% \label{sec:impSymbol}
%
% \begin{macro}{\umlSymbol}
% A symbol is a symbol with default height and offset.
%    \begin{macrocode}
\newcommand\umlSymbol[3][]{%  Null unneccesary
  \umlAssociationEnd[kind=Symbol,offset=0ex,height=0ex,
                     fractionAngle=:L,refpoint=t,#1]{%
    #2}{\umlSymbolUseFraction%
    #3}}
%    \end{macrocode}
%\end{macro}
%
% \begin{macro}{\umlAssociationEndUseFraction}
%    \begin{macrocode}
\newcommand\umlSymbolUseFraction{%
  \umlFromTo{\umlAEFraction}{%
    }{%
    }%
  }
%    \end{macrocode}  
% \end{macro}
%
% \begin{macro}{\umlSymbolA}
% "\umlSymbolA" and "\umlSymbolB" are
% provided for convenience and backward compatibility.
%    \begin{macrocode}
\newcommand\umlSymbolA[2][]{\umlSymbol[#1,fraction=A]{#2}}
\newcommand\umlSymbolB[2][]{\umlSymbol[#1,fraction=B]{#2}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Navigability}\label{sec:impNavigability}
%
% \begin{macro}{\umlNavigability}
% A specialized version of "\umlAssociationEnd".
% Takes two arguments: a list of named options, and the relation reference.
%    \begin{macrocode}
\newcommand\umlNavigability[2][]{
  \def\umlEndSymbol{\psline%
    (-1ex, -1.618ex)%
    (0,0)%
    (1ex, -1.618ex)}%
  \umlSymbol[kind=Navigability, #1]{#2}{\umlEndSymbol}%
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlNavigabilityA}
% "\umlNavigabilityA" and "\umlNavigabilityB" are
% provided for convenience and backward compatibility.
%    \begin{macrocode}
\newcommand\umlNavigabilityA[2][]{\umlNavigability[#1,fraction=A]{#2}}
\newcommand\umlNavigabilityB[2][]{\umlNavigability[#1,fraction=B]{#2}}
%    \end{macrocode}
% \end{macro}
%
% \section{Colors}\label{sec:impColors}
%
% \subsection{Colorset}\label{sec:impColorset}
%
% \begin{macro}{\umlColorset}
% Every "\umlDrawable" (really, every instance of a subcommand) calls
% "\umlColorsAdjust".  Then, the colors is set anew for the Drawable.
% The effect then depends on the value of "\umlColorsAdjust".  This
% value is set by "\umlColorsDefault", "\umlColorsImport" etc.
%    \begin{macrocode}
\newcommand\umlColorset[1]{%
  \def\umlColorsAdjust{#1%
  \psset{linecolor=umlLinecolor, fillcolor=umlFillcolor}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlColorsDefault}
%    \begin{macrocode}
\newcommand\umlColorsDefault{%
  \umlColorset{%
    \definecolor{umlColor}{gray}{0}%
    \definecolor{umlLinecolor}{gray}{0}%
    \definecolor{umlFillcolor}{gray}{1}%
    \definecolor{umlClassifierFillcolor}{gray}{0.85}%
    \definecolor{umlDiagramFillcolor}{gray}{0.95}%
    \definecolor{umlRelationColor}{gray}{0}%
}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlColorsGray}
%    \begin{macrocode}
\newcommand\umlColorsGray{%
  \umlColorset{%
    \definecolor{umlColor}{gray}{0.4}%
    \definecolor{umlLinecolor}{gray}{0.4}%
    \definecolor{umlFillcolor}{gray}{1}%
    \definecolor{umlClassifierFillcolor}{gray}{0.90}%
    \definecolor{umlDiagramFillcolor}{gray}{0.98}%
    \definecolor{umlRelationColor}{gray}{0.4}%
}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlColorsImport}
% The import color set makes the boxes blue.
%    \begin{macrocode}
\newcommand\umlColorsImport{%
  \umlColorset{%
    \definecolor{umlColor}{rgb}{0, 0, 0.4}%
    \definecolor{umlLinecolor}{rgb}{0, 0, 0.4}%
    \definecolor{umlFillcolor}{rgb}{.8, .8, 1}%
    \definecolor{umlClassifierFillcolor}{rgb}{.85, .85, 1}%
    \definecolor{umlDiagramFillcolor}{rgb}{.95, .95, 1}%
    \definecolor{umlRelationColor}{rgb}{0, 0, 0.4}%
}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlColorsArgument}
% This color set makes the boxes green.
%    \begin{macrocode}
\newcommand\umlColorsArgument{%
  \umlColorset{%
    \definecolor{umlColor}{rgb}{0, 0.4, 0}%
    \definecolor{umlLinecolor}{rgb}{0, 0.4, 0}%
    \definecolor{umlFillcolor}{rgb}{.8, 1, .8}%
    \definecolor{umlClassifierFillcolor}{rgb}{.85, 1, .85}%
    \definecolor{umlDiagramFillcolor}{rgb}{.95, 1, .95}%
   \definecolor{umlRelationColor}{rgb}{0, 0.7, 0}%
}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlColorsRed}
%    \begin{macrocode}
\newcommand\umlColorsRed{%
  \umlColorset{%
    \definecolor{umlColor}{rgb}{0.4, 0, 0}%
    \definecolor{umlLinecolor}{rgb}{0.4, 0, 0}%
    \definecolor{umlFillcolor}{rgb}{1, .8, .8}%
    \definecolor{umlClassifierFillcolor}{rgb}{1, .85, .85}%
    \definecolor{umlDiagramFillcolor}{rgb}{1, .95, .95}%
    \definecolor{umlRelationColor}{rgb}{0.4, 0, 0}%
}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlColorsSub}
%    \begin{macrocode}
\newcommand\umlColorsSub{%
  \umlColorset{%
    \definecolor{umlColor}{rgb}{.6, .2, .2}%
    \definecolor{umlLinecolor}{rgb}{.6, .2, .2}%
    \definecolor{umlFillcolor}{rgb}{.9, .8, .8}%
    \definecolor{umlClassifierFillcolor}{rgb}{.9, .8, .8}%
    \definecolor{umlDiagramFillcolor}{rgb}{.97, .95, .95}%
    \definecolor{umlRelationColor}{rgb}{.6, .2, .2}%
}}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\umlColorsDefault
\umlColorsAdjust
%    \end{macrocode}
%
% \subsection{Using color sets}
% \begin{macro}{\umlColors}
%    \begin{macrocode}
\newenvironment{umlColors}[1]{\bgroup#1}{\egroup}
%    \end{macrocode}
% \end{macro}
%
% \section{Positions}\label{sec:impSyntaxPositions}
%
%    \begin{macrocode}
\SpecialCoor
\newlength{\umlNodeSep}
\setlength{\umlNodeSep}{1em}
%    \end{macrocode}
%
% A historical note here: First, "\umlBox" used to throw lots of pnodes
% around.  However, this used huge memory space.  This way works much
% better.  However, I have not found any way to do the corresponding
% thing in the relations.
%
%\subsection{PlaceNode}\label{sec:impPlaceNode}
%
%    \begin{macrocode}
\newlength\umlPlaceNodeX
\newlength\umlPlaceNodeY
%    \end{macrocode}
%
% \begin{macro}{\umlPlaceNodeNull}
%    \begin{macrocode}
\newcommand\umlPlaceNodeNull{%
  \def\umlPlaceNodeNodesepX{0pt}%
  \def\umlPlaceNodeNodesepY{0pt}%
  \def\umlPlaceNodeAngleX{}%
  \def\umlPlaceNodeAngleY{}%
  \def\umlPlaceNodeOffsetX{}%
  \def\umlPlaceNodeOffsetY{}%
  \setlength\umlPlaceNodeX{0pt}%
  \setlength\umlPlaceNodeY{0pt}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{leftside-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{leftside}[0pt]{%
  \def\umlPlaceNodeAngleX{,angle=180}%
  \def\umlPlaceNodeNodesepX{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{rightside-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{rightside}[0pt]{%
  \def\umlPlaceNodeAngleX{,angle=0}%
  \def\umlPlaceNodeNodesepX{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{up-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{top}[0pt]{%
  \def\umlPlaceNodeAngleY{,angle=90}%
  \def\umlPlaceNodeNodesepY{#1}}%
%    \end{macrocode}% 
% \end{macro}
% \begin{macro}{bottom-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{bottom}[0pt]{%
  \def\umlPlaceNodeAngleY{,angle=270}%
  \def\umlPlaceNodeNodesepY{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{left-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{left}[0pt]{%
  \addtolength\umlPlaceNodeX{-#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{right-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{right}[0pt]{\addtolength\umlPlaceNodeX{#1}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{up-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{up}[0pt]{\addtolength\umlPlaceNodeY{#1}}
%    \end{macrocode}% 
% \end{macro}
% \begin{macro}{down-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{down}[0pt]{\addtolength\umlPlaceNodeY{-#1}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{angle-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{angle}{%
  \def\umlPlaceNodeAngleX{,angle=#1}%
  \def\umlPlaceNodeAngleY{,angle=#1}}%
\define@key[psset]{umlPlaceNode}{angleX}{\def\umlPlaceNodeAngleX{,angle=#1}}%
\define@key[psset]{umlPlaceNode}{angleY}{\def\umlPlaceNodeAngleY{,angle=#1}}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{offset-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{offset}{
  \def\umlPlaceNodeOffsetX{,offset=#1}%
  \def\umlPlaceNodeOffsetY{,offset=#1}}%
\define@key[psset]{umlPlaceNode}{offsetX}{\def\umlPlaceNodeOffsetX{,offset=#1}}%
\define@key[psset]{umlPlaceNode}{offsetY}{\def\umlPlaceNodeOffsetY{,offset=#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{nodesep-}
%    \begin{macrocode}
\define@key[psset]{umlPlaceNode}{nodesep}{%
  \def\umlPlaceNodeNodesepX{#1}%
  \def\umlPlaceNodeNodesepY{#1}}%
\define@key[psset]{umlPlaceNode}{nodesepX}{\def\umlPlaceNodeNodesepX{#1}}%
\define@key[psset]{umlPlaceNode}{nodesepY}{\def\umlPlaceNodeNodesepY{#1}}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlPlaceNode}
%    \begin{macrocode}
\newcommand\umlPlaceNode[3][]{%
  \umlPlaceNodeNull%
  \psset[umlPlaceNode]{#1}%
%    \end{macrocode}
% Placement relative to the node
%    \begin{macrocode}
  \rput(%
    [nodesep=\umlPlaceNodeNodesepX\umlPlaceNodeOffsetX\umlPlaceNodeAngleX]#2|%
    [nodesep=\umlPlaceNodeNodesepY\umlPlaceNodeOffsetY\umlPlaceNodeAngleY]#2){%
%    \end{macrocode}
% Placement relative to that
%    \begin{macrocode}
%    \rput(\umlPlaceNodeX, \umlPlaceNodeY){%
%    \end{macrocode}
% The new node is placed
%    \begin{macrocode}
      \pnode(\umlPlaceNodeX, \umlPlaceNodeY){#3}}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlRight}
% \label{sec:impTopLeft}
% The first coordinate commands are very simple.  
% They takes as argument  node.
%    \begin{macrocode}
\newcommand\umlRight[1]{[angle=0]#1}
\newcommand\umlTop[1]{[angle=90]#1}
\newcommand\umlLeft[1]{[angle=180]#1}
\newcommand\umlBottom[1]{[angle=270]#1}
\newcommand\umlTopRight[1]{[angle=0]#1|[angle=90]#1}
\newcommand\umlBottomRight[1]{[angle=0]#1|[angle=270]#1}
\newcommand\umlTopLeft[1]{[angle=180]#1|[angle=90]#1}
\newcommand\umlBottomLeft[1]{[angle=180]#1|[angle=270]#1}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlRightSep}
% The "Sep" coordinate commands use "\umlNodeSep" to make 
% some space between  the nodes.
%    \begin{macrocode}
\newcommand\umlRightSep[1]{[angle=0, nodesep=\umlNodeSep]#1}
\newcommand\umlTopSep[1]{[angle=90, nodesep=\umlNodeSep]#1}
\newcommand\umlLeftSep[1]{[angle=180, nodesep=\umlNodeSep]#1}
\newcommand\umlBottomSep[1]{[angle=270, nodesep=\umlNodeSep]#1}
\newcommand\umlTopRightSep[1]{%
    [angle=0, nodesep=\umlNodeSep]#1|[angle=90, nodesep=\umlNodeSep]#1}
\newcommand\umlBottomRightSep[1]{%
  [angle=0, nodesep=\umlNodeSep]#1|[angle=270, nodesep=\umlNodeSep]#1}
\newcommand\umlTopLeftSep[1]{%
  [angle=180, nodesep=\umlNodeSep]#1|[angle=90, nodesep=\umlNodeSep]#1}
\newcommand\umlBottomLeftSep[1]{%
  [angle=180, nodesep=\umlNodeSep]#1|[angle=270, nodesep=\umlNodeSep]#1}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlRightOpt}
% This takes two mandatory arguments: Named options and the usual
% node.
%
% Of course, it would be nice to make the first argument optional, thus
% combining "\umlRight" and "\umlRightOpt".  However,
% this does not work together with mandatory argument in "\umlBox".  I
% have found no elegant solution to this (despite some nights\dots)
%    \begin{macrocode}
\newcommand\umlRightOpt[2]{[angle=0, #1]#2}
\newcommand\umlTopOpt[2]{[angle=90, #1]#2}
\newcommand\umlLeftOpt[2]{[angle=180, #1]#2}
\newcommand\umlBottomOpt[2]{[angle=270, #1]#2}
\newcommand\umlTopRightOpt[2]{[angle=0, #1]#2|[angle=90, #1]#2}
\newcommand\umlBottomRightOpt[2]{[angle=0, #1]#2|[angle=270, #1]#2}
\newcommand\umlTopLeftOpt[2]{[angle=180, #1]#2|[angle=90, #1]#2}
\newcommand\umlBottomLeftOpt[2]{[angle=180, #1]#2|[angle=270, #1]#2}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\umlRightSep}
%    \begin{macrocode}
\newcommand\umlRightSepOpt[2]{[angle=0, nodesep=\umlNodeSep, #1]#2}
\newcommand\umlTopSepOpt[2]{[angle=90, nodesep=\umlNodeSep, #1]#2}
\newcommand\umlLeftSepOpt[2]{[angle=180, nodesep=\umlNodeSep, #1]#2}
\newcommand\umlBottomSepOpt[2]{[angle=270, nodesep=\umlNodeSep, #1]#2}
\newcommand\umlTopRightSepOpt[2]{[angle=0, nodesep=\umlNodeSep, #1]#2|[angle=90, nodesep=\umlNodeSep, #1]#2}
\newcommand\umlBottomRightSepOpt[2]{[angle=0, nodesep=\umlNodeSep, #1]#2|[angle=270, nodesep=\umlNodeSep, #1]#2}
\newcommand\umlTopLeftSepOpt[2]{%
  [angle=180, nodesep=\umlNodeSep, #1]#2|[angle=90, nodesep=\umlNodeSep, #1]#2}
\newcommand\umlBottomLeftSepOpt[2]{%
  [angle=180, nodesep=\umlNodeSep, #1]#2|[angle=270, nodesep=\umlNodeSep, #1]#2}
%    \end{macrocode}
% \end{macro}
%
%\iffalse
%</package>
%\fi
% \GlossaryPrologue{}
%
% \IfFileExists{uml.gls}{\PrintChanges}
% {\begin{quote}You should create the list of changes by 
% 
% ~~~ \texttt{makeindex -s gglo.ist -o uml.gls uml.glo}
%
% and running \texttt{latex uml.drv} again.\end{quote}}
%
%\iffalse
%<*example>
\newcommand\umlADTExample{%
    \umlDiagram[box=,sizeX=15cm, sizeY=16cm,ref=ADTdiagram,
                grayness=0.92]{}% End of diagram
      \umlSchema[pos=\umlTopRight{ADTdiagram}, posDelta={-.5,-.5},
        refpoint=tr]{ADT}{% Attributes
        \umlAttribute[visibility,type=String]{name}}{}{}{}{}
      \umlSchema[pos=\umlTopLeft{ADTdiagram}, posDelta={.5,-1},
                 refpoint=lt, abstract,
                 ref=ADTexample]{ADT-example}{%
        \umlAttribute[visibility=-, 
          type=\emph{\umlColorsArgument\umlColorsAdjust type},default=null]{%
          firstNode}
        }{%Methods
        }{%Arguments
        \umlArgument[type=Metaclass]{type}
        }{%Constraints
        }{%Structure
          \umlDiagram[box=,innerBorder=2mm,outerBorder]{%
            \umlClass[pos={.5,.5}, ref=adtNode,box=]{Node}{%
              \umlAttribute[visibility, 
                type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
                data}}{}%
            \umlAssociation[angleA=20, angleB=-20, 
                         arm=1em, arm=1em]{adtNode}{adtNode}%
         }\cr% End of Diagram
       }% End of ADT-example
      \umlInstance{ADTexample}{ADT}%
      \umlSchema[pos=\umlRight{ADTexample}, posDelta={3,-1},
                 refpoint=tl, ]{Graph}{% Attributes
        }{% Methods
        \umlMethod[visibility,]{%
          insert}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
        \umlMethod[visibility,
            type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
          dijkstra}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
        \umlMethod[visibility, type=boolean]{%
          insertEdge}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
        \umlMethod[visibility, ]{%
          delete}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
        }{% Arguments
        }{% Constraints
        }{% Structure
          \umlDiagram[box=,innerBorder=2mm, outerBorder,
                      sizeX=11em,sizeY=3.5em,ref=GraphDiagram]{%
               \begin{umlColors}{\umlColorsSub}
            \umlClass[pos=\umlBottomLeft{GraphDiagram},
                      posDelta={1,1}, ref=graphNode]{Node}{}{}%
            \umlAssociation[angleA=20, angleB=-20, armA=1em, armB=1em
                         ]{graphNode}{graphNode}%
               \end{umlColors}
              \umlLabelA[height=0mm,offset=1ex]{graphNodegraphNode}{*}%
              \umlLabelB[height=0mm,offset=1ex,refpoint=t
                         ]{graphNodegraphNode}{*}%
            \umlSymbol[fraction=.5]{graphNodegraphNode}{\pnode{gngn}}
            \umlClass[pos=gngn, posDelta={2,0}, 
                               ref=graphEdge, refpoint=l]{Edge}{%
            \umlAttribute[type=real]{cost}}{}%
          \umlAssociationClass[]{graphEdge}{gngn}%
          }\cr% End of diagram
        }% End of Graph
      \umlSubclass{Graph}{ADTexample}
      \umlSchema[posX=\umlLeft{ADTexample}, posDelta={3em,-1em},
                 posY=\umlBottom{Graph}, 
                 refpoint=tl, ref=searchTree]{Search Tree}{% Attributes
        }{% Methods
        \umlMethod[visibility,]{%
          insert}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
        \umlMethod[visibility, 
             type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
          search}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
        \umlMethod[visibility, type=boolean]{%
          search}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
        \umlMethod[visibility, ]{%
          delete}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
        }{% Arguments
        \umlArgument[type=Integer, initialValue=2]{arity}
        \umlArgument[type={${\umlColorsArgument\umlColorsAdjust type}
          \times {\umlColorsArgument\umlColorsAdjust type}\rightarrow$
            boolean}, default=>]{sort}
        }{% Constraints
        }{% Structure
          \umlDiagram[box=, sizeX=14em, sizeY=4em,
                      innerBorder=2mm, outerBorder]{%
            \begin{umlColors}{\umlColorsSub}
            \umlClass[pos={.5, .5}, ref=treeNode]{Node}{}{}%
            \umlAssociation[angleA=30, angleB=-30, armA=1em, armB=1em
                         ]{treeNode}{treeNode}%
             \end{umlColors}
              \umlLabelA[height=1mm, offset=4mm,refpoint=l
                ]{treeNodetreeNode}{%
                \emph{\umlColorsArgument\umlColorsAdjust arity}}%
              \umlLabelB[refpoint=tl,height=-1mm, offset=4mm,
                         ]{treeNodetreeNode}{1}%
            }\cr% End of diagram
        }%
      \umlSubclass{searchTree}{ADTexample}%
      \umlSchema[pos=\umlBottomLeft{searchTree},posDelta={0,-1},
                 refpoint=lt]{List}{%Attributes
        }{% Methods
        }{% Arguments
        }{% Constraints
        }{% Structure
          \umlDiagram[box=, sizeX=6em, sizeY=4em,
                      innerBorder=2mm, outerBorder]{%
            \begin{umlColors}{\umlColorsSub}
              \umlClass[pos={.5, .5}, ref=listNode]{Node}{}{}%
              \umlAssociation[angleA=30, angleB=-30, armA=1em, armB=1em
                           ]{listNode}{listNode}%
            \end{umlColors}
              \umlLabelA[height=1mm, offset=5mm, refpoint=l
                         ]{listNodelistNode}{1}%
              \umlLabelB[refpoint=tl, height=-1mm,offset=5mm
                         ]{listNodelistNode}{1}%
            }\cr% End of diagram
        }% End of Schema List
      \umlPlaceNode[leftside, top, down=1em]{List}{Listtl}
      \umlPlaceNode[leftside,right=2em,bottom]{ADTexample}{ADTexamplebl}
      \umlSubclass[armA=1.4142em, armAngleA=135]{Listtl}{ADTexamplebl}%
      \umlSchema[pos=\umlTopRight{List},posDelta={1em,-2em},
                 refpoint=tl]{Queue}{% Attributes
        }{\umlMethod[visibility]{%
          enqueue}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
        \umlMethod[visibility, type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
          dequeue}{}}{%Arguments
        }{%Constraints
        \umlCompartmentline{First come, first served.}
        }{% Structure
        }% End of Queue
      \umlPlaceNode[rightside, top, down=1em]{List}{Listtr}
      \umlSubclass[angleA=90, armAngleA=135, armA=1.4142em]{Queue}{Listtr}%
      \umlSchema[pos=\umlTopRight{Queue},posDelta={\umlNodeSep,0em},
                 refpoint=tl]{Stack}{%Attributes
        }{% Methods
        \umlMethod[visibility]{
          push}{\emph{\umlColorsArgument\umlColorsAdjust type} x}
        \umlMethod[visibility, type=\emph{\umlColorsArgument\umlColorsAdjust type}]{%
          pop}{}
        }{% Arguments
        }{% Constraints
        \umlCompartmentline{S:Stack = S.push(x).pop()}
        }{% Structure
        }% End of Stack
      \umlSubclass[angleA=90, armAngleA=135, armA=1.4142em]{Stack}{Listtr}%
}
%</example>
%\fi
%
%
% \Finale
\endinput
