diff --git a/documentation/meetings/meeting ayday raisaro youssef 20140608.docx b/documentation/meetings/meeting ayday raisaro youssef 20140608.docx
new file mode 100644
index 0000000..7710f10
Binary files /dev/null and b/documentation/meetings/meeting ayday raisaro youssef 20140608.docx differ
diff --git a/documentation/meetings/meeting ayday raisaro youssef 20140608.pdf b/documentation/meetings/meeting ayday raisaro youssef 20140608.pdf
new file mode 100644
index 0000000..ad2e82d
Binary files /dev/null and b/documentation/meetings/meeting ayday raisaro youssef 20140608.pdf differ
diff --git a/project/PPPCommons/src/test/FieldSizeTest.java b/project/PPPCommons/src/test/FieldSizeTest.java
new file mode 100644
index 0000000..c659dfc
--- /dev/null
+++ b/project/PPPCommons/src/test/FieldSizeTest.java
@@ -0,0 +1,40 @@
+package test;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.asn1.nist.NISTNamedCurves;
+import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.math.ec.ECPoint;
+
+public class FieldSizeTest {
+
+	public static void main(String[] args) {
+		X9ECParameters curve = NISTNamedCurves.getByName("P-384");
+		ECPoint g = curve.getG();
+		BigInteger fieldSize = curve.getN();
+		
+		// Test 1: numbers correctly wrapped
+		ECPoint pOutOfField = g.multiply(fieldSize.add(BigInteger.valueOf(1L)));
+		ECPoint pWithinField = g;
+		
+		if (pOutOfField.equals(pWithinField)) {
+			System.out.println("Equal");
+		}
+		else {
+			System.out.println("Not equal");
+		}
+		
+		// Test 2: numbers adding and substracting correctly
+		ECPoint p1Small = g.multiply(BigInteger.valueOf(8));
+		ECPoint p1Large = g.multiply(fieldSize.multiply(BigInteger.valueOf(100L)));
+		ECPoint sum = p1Small.add(p1Large);
+		ECPoint p1SmallPrime = sum.subtract(p1Large);
+		
+		if (p1Small.equals(p1SmallPrime)) {
+			System.out.println("Points are equal");
+		}
+		else {
+			System.out.println("Points are the same");
+		}
+	}
+}
diff --git a/report/biblio/research.bib b/report/biblio/research.bib
index 951a52c..83de344 100644
--- a/report/biblio/research.bib
+++ b/report/biblio/research.bib
@@ -1,299 +1,364 @@
 % This file was created with JabRef 2.10.
 % Encoding: Cp1252
 
 
-@Online{amazon-s3-pricing,
-  Title                    = {Amazon S3 Pricing},
-  Author                   = {Amazon Web Services, Inc.},
-  Url                      = {http://aws.amazon.com/s3/pricing/},
+@Online{lib-ucanaccess,
+  Title                    = {UCanAccess},
+  Author                   = {Amadei, Marco},
+  Url                      = {http://ucanaccess.sourceforge.net/site.html},
   Year                     = {2014},
-  Urldate                  = {2014-06-05},
+  Urldate                  = {2014-06-11},
 
   Owner                    = {Franck},
-  Timestamp                = {2014.06.04}
+  Timestamp                = {2014.06.11}
 }
 
 @Techreport{EPFL-REPORT-186866,
   Title                    = {The {C}hills and {T}hrills of {W}hole {G}enome {S}equencing},
   Author                   = {Ayday, Erman and De Cristofaro, Emiliano and Hubaux,
  Jean-Pierre and Tsudik, Gene},
   Year                     = {2013},
 
   Abstract                 = {In recent years, whole genome sequencing (WGS) evolved
  from a futuristic-sounding research project to an
  increasingly affordable technology for determining
  complete genome sequences of complex organisms, including
  humans. This prompts a wide range of revolutionary
  applications, as WGS is a promising means for improving
  modern healthcare and providing a better understanding of
  the human genome, in particular its relation to diseases
  and response to treatments. However, this progress raises
  worrisome privacy and ethical issues, since, besides
  uniquely identifying its owner, the genome contains a
  treasure trove of highly personal and sensitive
  information. In this article, after summarizing recent
  advances in genomics, we discuss some important privacy
  issues associated with human genomic information and
  identify a number of particularly relevant research
  challenges.},
   Affiliation              = {EPFL},
   Details                  = {http://infoscience.epfl.ch/record/186866},
   Documenturl              = {http://infoscience.epfl.ch/record/186866/files/survey.pdf},
   Keywords                 = {Privacy; Genomics},
   Oai-id                   = {oai:infoscience.epfl.ch:186866},
   Oai-set                  = {driver},
   Pagecount                = {9},
   Submitter                = {217726; 217726},
   Unit                     = {LCA1}
 }
 
 @Inproceedings{EPFL-CONF-188284,
   Title                    = {Protecting and {E}valuating {G}enomic {P}rivacy in
  {M}edical {T}ests and {P}ersonalized {M}edicine},
   Author                   = {Ayday, Erman and Raisaro, Jean Louis and Rougemont,
  Jacques and Hubaux, Jean-Pierre},
   Booktitle                = {{ACM} {W}orkshop on {P}rivacy in the {E}lectronic {S}ociety ({WPES})},
   Year                     = {2013},
   Location                 = {Berlin, Germany},
 
   Abstract                 = {In this paper, we propose privacy-enhancing technologies
  for medical tests and personalized medicine methods that
  use patients' genomic data. Focusing on genetic
  disease-susceptibility tests, we develop a new
  architecture (between the patient and the medical unit)
  and propose a "privacy-preserving disease susceptibility
  test" (PDS) by using homomorphic encryption and proxy
  re-encryption. Assuming the whole genome sequencing to be
  done by a certified institution, we propose to store
  patients' genomic data encrypted by their public keys at
  a "storage and processing unit" (SPU). Our proposed
  solution lets the medical unit retrieve the encrypted
  genomic data from the SPU and process it for medical
  tests and personalized medicine methods, while preserving
  the privacy of patients' genomic data. We also quantify
  the genomic privacy of a patient (from the medical unit's
  point of view) and show how a patient's genomic privacy
  decreases with the genetic tests he undergoes due to (i)
  the nature of the genetic test, and (ii) the
  characteristics of the genomic data. Furthermore, we show
  how basic policies and obfuscation methods help to keep
  the genomic privacy of a patient at a high level. We also
  implement and show, via a complexity analysis, the
  practicality of PDS.},
   Affiliation              = {EPFL},
   Details                  = {http://infoscience.epfl.ch/record/188284},
   Documenturl              = {http://infoscience.epfl.ch/record/188284/files/wpes018-ayday.pdf},
   Keywords                 = {Privacy; Genomics; Personalized medicine; Security},
   Oai-id                   = {oai:infoscience.epfl.ch:188284},
   Oai-set                  = {conf},
   Review                   = {REVIEWED},
   Status                   = {PUBLISHED},
   Submitter                = {217726},
   Unit                     = {LCA1}
 }
 
 @Online{bc-ref,
   Title                    = {Bouncy Castle Crypto APIs},
   Author                   = {Legion of the Bouncy Castle Inc.},
   Url                      = {https://www.bouncycastle.org/java.html},
   Urldate                  = {2014-05-27},
 
   Owner                    = {Franck},
   Timestamp                = {2014.05.27}
 }
 
+@Online{bc-jira,
+  Title                    = {BouncyCastle JIRA Issue Tracker},
+  Author                   = {The Legion of Bouncy Castle Inc.},
+  Url                      = {http://www.bouncycastle.org/jira},
+  Year                     = {2014},
+  Urldate                  = {2014-06-06},
+
+  Owner                    = {Franck},
+  Timestamp                = {2014.06.06}
+}
+
 @Incollection{chevallier2006encoding,
   Title                    = {Encoding-free ElGamal encryption without random oracles},
   Author                   = {Chevallier-Mames, Beno{\^\i}t and Paillier, Pascal and Pointcheval, David},
   Booktitle                = {Public Key Cryptography-PKC 2006},
   Year                     = {2006},
   Pages                    = {91--104},
   Publisher                = {Springer}
 }
 
 @Online{jca-ref-guide,
   Title                    = {Java Cryptography Architecture (JCA) Reference Guide},
   Author                   = {Oracle Corporation},
   Url                      = {http://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html},
   Urldate                  = {2014-05-27},
 
   Owner                    = {Franck},
   Timestamp                = {2014.05.27}
 }
 
 @Online{glassfish-doc,
   Title                    = {GlassFish Documentation},
   Author                   = {Oracle Corporation},
   Url                      = {https://glassfish.java.net/documentation.html},
   Year                     = {2014},
   Urldate                  = {2014-06-05},
 
   Owner                    = {Franck},
   Timestamp                = {2014.06.05}
 }
 
+@Online{jdbc-odbc-remove,
+  Title                    = {JDBC-ODBC Bridge},
+  Author                   = {Oracle Corporation},
+  Url                      = {http://docs.oracle.com/javase/7/docs/technotes/guides/jdbc/bridge.html},
+  Year                     = {2014},
+  Urldate                  = {2014-06-11},
+
+  Owner                    = {Franck},
+  Timestamp                = {2014.06.11}
+}
+
 @Report{NIST-800-57,
   Title                    = {Recommendation for Key
 Management � Part 1: General (Revision 3)},
   Author                   = {Elaine Barker, William Barker, William Burr, William Polk, and Miles Smid},
   Date                     = {July},
   Institution              = {National Institute of Standards and Technology (NIST)},
   Type                     = {Special Publication},
   Year                     = {2012},
 
   Owner                    = {Franck},
   Timestamp                = {2014.06.04}
 }
 
 @Online{apache-ws,
   Title                    = {Apache Web Services� Project},
   Author                   = {The Apache Software Foundation},
   Url                      = {https://ws.apache.org/},
   Year                     = {2014},
   Urldate                  = {2014-06-05},
 
   Owner                    = {Franck},
   Timestamp                = {2014.06.05}
 }
 
 @Inproceedings{fouque2013injective,
   Title                    = {Injective encodings to elliptic curves},
   Author                   = {Fouque, Pierre-Alain and Joux, Antoine and Tibouchi, Mehdi},
   Booktitle                = {Information Security and Privacy},
   Year                     = {2013},
   Organization             = {Springer},
   Pages                    = {203--218}
 }
 
+@Online{git-bc-activity,
+  Title                    = {Commit Activity of BouncyCastle Java},
+  Author                   = {Github},
+  Url                      = {https://github.com/bcgit/bc-java/graphs/commit-activity},
+  Year                     = {2014},
+
+  Owner                    = {Franck},
+  Timestamp                = {2014.06.06}
+}
+
 @Book{hankerson2004guide,
   Title                    = {Guide to Elliptic Curve Cryptography},
   Author                   = {Hankerson, D. and Vanstone, S. and Menezes, A.J.},
   Year                     = {2004},
   ISBN                     = {9780387952734},
   Publisher                = {Springer},
   Series                   = {Springer Professional Computing},
   Url                      = {http://books.google.ch/books?id=bhMPt3I3J\_UC},
 
   Lccn                     = {2003059137}
 }
 
+@Online{amazon-s3-pricing,
+  Title                    = {Amazon S3 Pricing},
+  Author                   = {Amazon Web Services Inc.},
+  Url                      = {http://aws.amazon.com/s3/pricing/},
+  Year                     = {2014},
+  Urldate                  = {2014-06-05},
+
+  Owner                    = {Franck},
+  Timestamp                = {2014.06.04}
+}
+
 @Article{king2009mapping,
   Title                    = {Mapping an Arbritrary Message to an Elliptic Curve When Defined over GF(2 n).},
   Author                   = {King, Brian},
   Year                     = {2009},
   Month                    = {March},
   Note                     = {(Received Sept. 8, 2006; revised Nov. 8, 2006; and accepted Apr. 4, 2007)},
   Number                   = {2},
   Pages                    = {169-176},
   Volume                   = {8},
 
   Journal                  = {International Journal of Network Security}
 }
 
 @Article{Koblitz1987,
   Title                    = {Elliptic curve cryptosystems},
   Author                   = {Koblitz, Neal},
   Year                     = {1987},
   Number                   = {177},
   Pages                    = {203--209},
   Volume                   = {48},
 
   __markedentry            = {[Franck:6]},
   Journal                  = {Mathematics of computation},
   Owner                    = {Franck},
   Timestamp                = {2014.03.13}
 }
 
+@Article{lin04,
+  Title                    = {{Genomic research and human subject privacy}},
+  Author                   = {Lin, Z. and Owen, A. B. and Altman, R. B. },
+  Year                     = {2004},
+  Month                    = {Jul},
+  Number                   = {5681},
+  Pages                    = {183},
+  Volume                   = {305},
+
+  Journal                  = {Science}
+}
+
+@Techreport{lca1-report,
+  Title                    = {Technical report on genomic data privacy},
+  Author                   = {Raisaro, Jean Louis and Ayday, Erman and Hubaux, Jean-Pierre},
+  Institution              = {LCA1, EPFL},
+  Year                     = {2014},
+
+  Owner                    = {Franck},
+  Timestamp                = {2014.06.10}
+}
+
 @Article{Ruan2012,
   Title                    = {Elliptic curve ElGamal Threshold-based Key Management Scheme against Compromise of Distributed RSUs for VANETs},
   Author                   = {Na Ruan and Takashi Nishide and Yoshiaki Hori},
   Year                     = {2012},
   Number                   = {4},
   Pages                    = {846-853},
   Volume                   = {20},
 
   __markedentry            = {[Franck:]},
   Journal                  = {Journal of Information Processing},
   Owner                    = {Franck},
   Timestamp                = {2014.03.13}
 }
 
 @Unpublished{swisscom-dcs-sales,
   Title                    = {Swisscom Dynamic Storage},
   Author                   = {Swisscom Sales},
   Year                     = {2014},
 
   Owner                    = {Franck},
   Timestamp                = {2014.06.04}
 }
 
 @Book{fips-dss,
   Title                    = {FIPS PUB 180-1: Digital Signature Standard (DSS)},
   Author                   = {National Institute of Standards and Technology},
   Date                     = {July},
   Year                     = {2013},
 
   Owner                    = {Franck},
   Timestamp                = {2014.06.04}
 }
 
 @Online{shcs-intro,
   Title                    = {Introduction},
   Author                   = {Swiss HIV Cohort Study},
   Url                      = {http://www.shcs.ch/},
   Year                     = {2014},
   Urldate                  = {2014-06-01},
 
   Owner                    = {Franck},
   Timestamp                = {2014.06.01}
 }
 
 @Online{shcs-obj,
   Title                    = {Objectives},
   Author                   = {Swiss HIV Cohort Study},
   Url                      = {http://www.shcs.ch/29-objectives},
   Year                     = {2014},
   Urldate                  = {2014-06-01},
 
   Owner                    = {Franck},
   Timestamp                = {2014.06.01}
 }
 
 @Inproceedings{Ugus_performanceof,
   Title                    = {Performance of Additive Homomorphic EC-ElGamal Encryption for TinyPEDS, Under submission at 6},
   Author                   = {Osman Ugus},
   Booktitle                = {GI/ITG KuVS Fachgespr�ch �Drahtlose Sensornetze�, RWTH Aachen, 2007}
 }
 
 @Mastersthesis{MA_Ugus,
   Title                    = {Asymmetric Homomorphic Encryption Transformation for Securing Distributed Data Storage in Wireless Sensor Networks},
   Author                   = {Osman Ugus},
   Year                     = {2007},
   Month                    = {April},
 
   Address                  = {Integrated Circuits and Systems Laboratory
 Department of Computer Science
 Technical University of Darmstadt
 and
 NEC Europe Network Laboratories},
   Owner                    = {Franck},
   School                   = {TU Darmstadt},
   Timestamp                = {2014.03.13}
 }
 
 @Article{DBLP:journals/corr/abs-0903-3900,
   Title                    = {Optimized Implementation of Elliptic Curve Based Additive
  Homomorphic Encryption for Wireless Sensor Networks},
   Author                   = {Osman Ugus and
  Dirk Westhoff and
  Ralf Laue and
  Abdulhadi Shoufan and
  Sorin A. Huss},
   Year                     = {2009},
   Volume                   = {abs/0903.3900},
 
   Bibsource                = {DBLP, http://dblp.uni-trier.de},
   Ee                       = {http://arxiv.org/abs/0903.3900},
   Journal                  = {CoRR}
 }
 
diff --git a/report/external_sty/tikz-uml.sty b/report/external_sty/tikz-uml.sty
new file mode 100644
index 0000000..2ea87df
--- /dev/null
+++ b/report/external_sty/tikz-uml.sty
@@ -0,0 +1,4429 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Start of tikz-uml.sty
+%
+% Some macros for UML Diagrams.
+% Home page of project : 
+% Author: Nicolas Kielbasiewicz
+% Style from : 
+% Fixed by Nicolas Kielbasiewicz (nicolas.kielbasiewicz@ensta-paristech.fr) in dec 2010 to compile with pgf 2.00
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]%
+\ProvidesPackage{tikz-uml}[2011/01/26]%
+
+\RequirePackage{ifthen}%
+\RequirePackage{tikz}%
+\RequirePackage{xstring}%
+\RequirePackage{calc}%
+\RequirePackage{pgfopts}%
+\usetikzlibrary{backgrounds,arrows,shapes,fit,shadows,decorations.markings}%
+
+\def\tikzumlPackageLayersNum{3}%
+\pgfkeys{/tikzuml/options/.cd, packageLayers/.initial=3}%
+\pgfkeys{/tikzuml/options/.cd, packageLayers/.store in=\tikzumlPackageLayersNum}%
+\def\tikzumlStateLayersNum{3}%
+\pgfkeys{/tikzuml/options/.cd, stateLayers/.initial=3}%
+\pgfkeys{/tikzuml/options/.cd, stateLayers/.store in=\tikzumlStateLayersNum}%
+\def\tikzumlFragmentLayersNum{3}%
+\pgfkeys{/tikzuml/options/.cd, fragmentLayers/.initial=3}%
+\pgfkeys{/tikzuml/options/.cd, fragmentLayers/.store in=\tikzumlFragmentLayersNum}%
+\def\tikzumlComponentLayersNum{3}%
+\pgfkeys{/tikzuml/options/.cd, componentLayers/.initial=3}%
+\pgfkeys{/tikzuml/options/.cd, componentLayers/.store in=\tikzumlComponentLayersNum}%
+
+\ProcessPgfOptions{/tikzuml/options}%
+
+\def\pgfsetlayersArg{background}%
+\pgfdeclarelayer{background}%
+\newcounter{tikzumlPackageLayers}%
+\loop \pgfdeclarelayer{package\thetikzumlPackageLayers}%
+  \xdef\pgfsetlayersArg{\pgfsetlayersArg,package\thetikzumlPackageLayers}%
+  \ifnum\tikzumlPackageLayersNum>\thetikzumlPackageLayers%
+    \stepcounter{tikzumlPackageLayers}%
+\repeat%
+%
+\newcounter{tikzumlFragmentLayers}%
+\loop \pgfdeclarelayer{fragment\thetikzumlFragmentLayers}%
+  \xdef\pgfsetlayersArg{\pgfsetlayersArg,fragment\thetikzumlFragmentLayers}%
+  \ifnum\tikzumlFragmentLayersNum>\thetikzumlFragmentLayers%
+    \stepcounter{tikzumlFragmentLayers}%
+\repeat%
+%
+\newcounter{tikzumlStateLayers}%
+\loop \pgfdeclarelayer{state\thetikzumlStateLayers}%
+  \xdef\pgfsetlayersArg{\pgfsetlayersArg,state\thetikzumlStateLayers}%
+  \ifnum\tikzumlStateLayersNum>\thetikzumlStateLayers%
+    \stepcounter{tikzumlStateLayers}%
+\repeat%
+%
+\newcounter{tikzumlComponentLayers}%
+\loop \pgfdeclarelayer{component\thetikzumlComponentLayers}%
+  \xdef\pgfsetlayersArg{\pgfsetlayersArg,component\thetikzumlComponentLayers}%
+  \ifnum\tikzumlComponentLayersNum>\thetikzumlComponentLayers%
+    \stepcounter{tikzumlComponentLayers}%
+\repeat%
+%
+\pgfdeclarelayer{lifelines}%
+\pgfdeclarelayer{activity}%
+\pgfdeclarelayer{connections}%
+\xdef\pgfsetlayersArg{\pgfsetlayersArg,lifelines,activity,connections,main}%
+\pgfsetlayers{\pgfsetlayersArg}%
+
+\pgfkeys{/tikzuml/.cd,%
+         text/.initial=black, draw/.initial=black, font/.initial=\small,%
+         fill class/.initial=yellow!20, fill template/.initial=yellow!2,%
+         fill package/.initial=blue!20, fill note/.initial=green!20,%
+         fill usecase/.initial=blue!20, fill system/.initial=white,%
+         fill state/.initial=yellow!20, fill object/.initial=yellow!20,%
+         fill call/.initial=white, fill fragment/.initial= none,%
+         fill component/.initial= yellow!20, fill port/.initial= yellow!20,%
+         fill assembly connector/.initial= white,%
+         .unknown/.code={%
+           \let\keyname=\pgfkeyscurrentname%
+           \errmessage{TIKZUML ERROR : in tikzuml global, invalid option \keyname}%
+         }}%
+\pgfkeys{/tikzuml/.cd,%
+         text/.get=\tikzumltextcolor, draw/.get=\tikzumldrawcolor, font/.get=\tikzumlfont,%
+         fill class/.get=\tikzumlfillclasscolor,%
+         fill template/.get=\tikzumlfilltemplatecolor,%
+         fill package/.get=\tikzumlfillpackagecolor, fill note/.get=\tikzumlfillnotecolor,%
+         fill usecase/.get=\tikzumlfillusecasecolor,%
+         fill system/.get=\tikzumlfillsystemcolor,%
+         fill state/.get=\tikzumlfillstatecolor, fill object/.get=\tikzumlfillobjectcolor,%
+         fill call/.get=\tikzumlfillcallcolor,%
+         fill fragment/.get=\tikzumlfillfragmentcolor,%
+         fill component/.get=\tikzumlfillcomponentcolor,%
+         fill port/.get=\tikzumlfillportcolor,%
+         fill assembly connector/.get=\tikzumlfillassemblyconnectorcolor}%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                       class diagrams                    %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\pgfkeys{/tikzuml/relation/.cd,%
+         attr1/.style args={#1|#2}{arg1=#1, mult1=#2},%
+         attr2/.style args={#1|#2}{arg2=#1, mult2=#2},%
+         attr/.style args={#1|#2}{arg=#1, mult=#2},%
+         recursive/.style args={#1|#2|#3}{angle1=#1, angle2=#2, loopsize=#3},%
+         anchors/.style args={#1 and #2}{anchor1=#1, anchor2=#2},%
+         recursive direction/.style args={#1 to #2}{recursive direction start=#1, recursive direction end=#2}}%
+\pgfkeys{/tikzuml/note/.cd,%
+         anchors/.style args={#1 and #2}{anchor1=#1, anchor2=#2}}%
+
+\tikzstyle{tikzuml simpleclass style}=[rectangle, minimum height=2em, node distance=2em]%
+\tikzstyle{tikzuml class style}=[rectangle split, rectangle split parts=3, rectangle split part align={center, left, left}, minimum height=2em, node distance=2em]%
+\tikzstyle{tikzuml narynode style}=[diamond]%
+\tikzstyle{tikzuml template style}=[dashed, inner ysep=0.5em, inner xsep=1ex]%
+\tikzstyle{tikzuml control nodes style}=[fill=black, inner sep=1.5pt, circle]%
+%
+\tikzstyle{tikzuml association style}=[color=\tikzumldrawcolor, -]%
+\tikzstyle{tikzuml bidirectional association style}=[color=\tikzumldrawcolor, angle45-angle45]%
+\tikzstyle{tikzuml unidirectional association style}=[color=\tikzumldrawcolor, -angle 45]%
+\tikzstyle{tikzuml aggregation style}=[color=\tikzumldrawcolor, open diamond-]%
+\tikzstyle{tikzuml unidirectional aggregation style}=[color=\tikzumldrawcolor, open diamond-angle 45]%
+\tikzstyle{tikzuml composition style}=[color=\tikzumldrawcolor, diamond-]%
+\tikzstyle{tikzuml unidirectional composition style}=[color=\tikzumldrawcolor, diamond-angle 45]%
+\tikzstyle{tikzuml dependency style}=[color=\tikzumldrawcolor, -angle 45, dashed]%
+\tikzstyle{tikzuml import style}=[color=\tikzumldrawcolor, -angle 45, dashed]%
+\tikzstyle{tikzuml inherit style}=[color=\tikzumldrawcolor, -open triangle 45]%
+\tikzstyle{tikzuml implements style}=[color=\tikzumldrawcolor, -open triangle 45, dashed]%
+
+\pgfkeys{/tikzuml/assemblyconnectorrelation/.cd, anchors/.style args={#1 and #2}{anchor1=#1, anchor2=#2}}%
+
+\newcounter{tikzumlPackageClassNum}%
+\newcounter{tikzumlPackageSubPackageNum}%
+\newcounter{tikzumlRelationNum}%
+\setcounter{tikzumlRelationNum}{1}%
+\newcounter{tikzumlNoteNum}%
+\setcounter{tikzumlNoteNum}{1}%
+
+\newcounter{pos}%
+\newcounter{posT}%
+\newcounter{posStereo}%
+
+\newcounter{tikzumlPackageLevel}%
+\setcounter{tikzumlPackageLevel}{0}%
+
+\newif\ifumlclassSimpleStyle%
+
+% utility : change default colors
+\newcommand{\tikzumlset}[1]{%
+  \pgfkeys{/tikzuml/.cd,#1}%
+  \pgfkeys{/tikzuml/.cd,%
+           text/.get=\tikzumltextcolor, draw/.get=\tikzumldrawcolor,%
+           font/.get=\tikzumlfont,%
+           fill class/.get=\tikzumlfillclasscolor,%
+           fill template/.get=\tikzumlfilltemplatecolor,%
+           fill package/.get=\tikzumlfillpackagecolor,%
+           fill note/.get=\tikzumlfillnotecolor,%
+           fill usecase/.get=\tikzumlfillusecasecolor,%
+           fill system/.get=\tikzumlfillsystemcolor,%
+           fill state/.get=\tikzumlfillstatecolor,%
+           fill object/.get=\tikzumlfillobjectcolor,%
+           fill call/.get=\tikzumlfillcallcolor,%
+           fill fragment/.get=\tikzumlfillfragmentcolor,%
+           fill component/.get=\tikzumlfillcomponentcolor,%
+           fill port/.get=\tikzumlfillportcolor,%
+           fill assembly connector/.get=\tikzumlfillassemblyconnectorcolor}%
+}%
+
+% define a point
+% arg : node/coordinates of the point
+\newcommand{\umlpoint}[1]{%
+  \begin{pgfonlayer}{connections}%
+  \node[tikzuml control nodes style] at (#1) {};%
+  \end{pgfonlayer}%
+}%
+
+\newcommand{\tikzumlskipescape}[3][_]{%
+\begingroup%
+  \def\_{#1}\edef\x{\endgroup%
+    \def\noexpand\csname #3\endcsname{#2}}\x%
+}%
+
+% define a uml package
+%  arg : package name
+%  optional : x, y coordinates of the package
+%             draw, fill, text colors
+\newenvironment{umlpackage}[2][]{%
+  \pgfkeys{/tikzuml/package/.cd,%
+           x/.initial=0, y/.initial=0,%
+           name/.initial=tikzumlEmpty, draw/.initial=\tikzumldrawcolor,% 
+           fill/.initial=\tikzumlfillpackagecolor, text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlpackage, invalid option \keyname}%
+                                }}%
+  \pgfkeys{/tikzuml/package/.cd, #1}%
+  \pgfkeys{/tikzuml/package/.cd,%
+           x/.get=\xshift, y/.get=\yshift, name/.get=\tikzumlpackagename,%
+           draw/.get=\tikzumlpackagedraw, fill/.get=\tikzumlpackagefill,%
+           text/.get=\tikzumlpackagetext}%
+  %
+  \ifnum\thetikzumlPackageLevel>0%
+    \let\tikzumlPackage@nameold\tikzumlPackage@fitname%
+    \def\tikzumlPackage@name{#2}%
+    \begingroup%
+      \def\_{@}\edef\x{\endgroup%
+        \def\noexpand\tikzumlPackage@fitname{\tikzumlPackage@name}}\x%
+    \let\tikzumlPackage@parentold\tikzumlPackage@parent%
+    \edef\tikzumlPackage@parent{\tikzumlPackage@parentold @@\tikzumlPackage@nameold}%
+  \else%
+    \def\tikzumlPackage@parent{}%
+    \def\tikzumlPackage@name{#2}%
+    \begingroup%
+      \def\_{@}\edef\x{\endgroup%
+        \def\noexpand\tikzumlPackage@fitname{\tikzumlPackage@name}}\x%
+  \fi%
+  %
+  \let\tikzumlPackage@nodeNameold\tikzumlPackage@nodeName%
+  %  
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlPackage@nodeName{\tikzumlPackage@name}}\x%
+  %
+  \ifthenelse{\equal{\tikzumlpackagename}{tikzumlEmpty}}{}{%
+    \def\tikzumlPackage@nodeName{\tikzumlpackagename}%
+  }%
+  %
+  \StrSubstitute{\tikzumlPackage@nodeName}{.}{@POINT@}{\tikzumlPackage@nodeName}%
+  %
+  \expandafter\gdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{}%
+  %
+  \setcounter{tikzumlPackageClassNum}{0}%
+  \setcounter{tikzumlPackageSubPackageNum}{0}%
+  \stepcounter{tikzumlPackageLevel}%
+  %
+  \begin{scope}[xshift=\xshift cm, yshift=\yshift cm]%
+}{%
+  \addtocounter{tikzumlPackageLevel}{-1}%
+  \begin{pgfonlayer}{package\thetikzumlPackageLevel}%
+  %
+  % if contains no class, one define a fictive node to enable the fit option
+  \ifnum\c@tikzumlPackageClassNum=0%
+    \ifnum\c@tikzumlPackageSubPackageNum=0%
+      \node[inner sep=1.5ex] (\tikzumlPackage@nodeName-root) at (0,0) {\phantom{\tikzumlPackage@nodeName}};%
+      \expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{(\tikzumlPackage@nodeName-root)}%
+      %
+    \fi%
+  \fi%
+  %
+  \ifnum\c@tikzumlPackageLevel>0%
+    \def\tikzumlPackageFitTmp{\csname tikzumlPackageFit\tikzumlPackage@parent\endcsname}%
+    \expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent\endcsname{\tikzumlPackageFitTmp (\tikzumlPackage@nodeName) (\tikzumlPackage@nodeName-caption)}%
+    \stepcounter{tikzumlPackageSubPackageNum}%
+  \fi%
+  %
+  \node[draw=\tikzumlpackagedraw, fill=\tikzumlpackagefill, text=\tikzumlpackagetext, font=\tikzumlfont, inner sep=1.5ex, fit = \csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname] (\tikzumlPackage@nodeName) {};%
+  \node[draw=\tikzumlpackagedraw, fill=\tikzumlpackagefill, text=\tikzumlpackagetext, font=\tikzumlfont, minimum height=1.5em, outer ysep=-0.3, anchor=south west] (\tikzumlPackage@nodeName-caption) at (\tikzumlPackage@nodeName.north west) {\tikzumlPackage@name};%
+  \end{pgfonlayer}%
+  \end{scope}%
+}%
+
+% shortcut to define an empty package
+\newcommand{\umlemptypackage}[2][]{\begin{umlpackage}[#1]{#2} \end{umlpackage}}%
+
+% define a uml class
+% args : name of the class
+%        attributes of the class
+%        operations of the class
+% optional : x,y coordinates of the class
+%            width of the class node
+%            type of class (class, interface, typedef, enum)
+%            template parameters
+%            draw, fill, text colors
+\newcommand{\umlclass}[4][]{%
+  \pgfkeys{/tikzuml/class/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=10ex, type/.initial=class,%
+           tags/.initial={}, simple/.is if=umlclassSimpleStyle,%
+           template/.initial={}, name/.initial={tikzumlEmpty},%
+           draw/.initial=\tikzumldrawcolor,%
+           fill template/.initial=\tikzumlfilltemplatecolor,%
+           fill/.initial=\tikzumlfillclasscolor,%
+           text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlclass, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/class/.cd,#1}%
+  \pgfkeys{/tikzuml/class/.cd,%
+           x/.get=\umlclassX, y/.get=\umlclassY, width/.get=\umlclassMinimumWidth,% 
+           type/.get=\umlclassType, tags/.get=\umlclasstags, template/.get=\umlclassTemplateParam,%
+           name/.get=\umlclassName,%
+           draw/.get=\tikzumlclassdraw, fill/.get=\tikzumlclassfill,%
+           text/.get=\tikzumlclasstext, fill template/.get=\tikzumlclasstemplate}%
+  %
+  \ifthenelse{\equal{\umlclassType}{class}\OR\equal{\umlclassType}{abstract}}{%
+    \def\tikzumlClassType{}%
+  }{%
+    \def\tikzumlClassType{\guillemotleft\umlclassType\guillemotright \\}%
+  }%
+  %
+  \ifthenelse{\equal{\umlclasstags}{}}{%
+    \def\tikzumlClassTags{}%
+  }{%
+    \def\tikzumlClassTags{\\ \{\umlclasstags\}}%
+  }%
+  %
+  \ifthenelse{\equal{\umlclassTemplateParam}{}}{%
+    \def\tikzumlClassVPadding{}%
+    \def\tikzumlClassHPadding{}%
+  }{%
+    \def\tikzumlClassVPadding{\vspace{0.1em} \\}%
+    \def\tikzumlClassHPadding{\hspace{0.5ex} $ $}%
+  }%
+  %
+  \def\tikzumlClassName{#2}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlClassNodeName{\tikzumlClassName}}\x%
+  %
+  \ifthenelse{\equal{\umlclassName}{tikzumlEmpty}}{}{%
+    \def\tikzumlClassNodeName{\umlclassName}%
+  }%
+  %
+  \StrSubstitute{\tikzumlClassNodeName}{:}{@COLON@}[\tikzumlClassNodeName]
+  %
+  \ifthenelse{\equal{\umlclassType}{abstract}}{%
+    \let\tikzumlClassNameOld\tikzumlClassName%
+    \def\tikzumlClassName{{\it \tikzumlClassNameOld}}%
+  }{}%
+  %
+  \def\tikzumlClassPos{\umlclassX,\umlclassY}%
+  \def\tikzumlClassAttributes{#3}%
+  \def\tikzumlClassOperations{#4}%
+  %
+  \ifumlclassSimpleStyle%
+    \node[tikzuml simpleclass style, draw=\tikzumlclassdraw, fill=\tikzumlclassfill, text=\tikzumlclasstext, font=\tikzumlfont, minimum width=\umlclassMinimumWidth] (\tikzumlClassNodeName) at (\tikzumlClassPos) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
+    };%
+  \else%
+    \node[tikzuml class style, draw=\tikzumlclassdraw, fill=\tikzumlclassfill, text=\tikzumlclasstext, font=\tikzumlfont, minimum width=\umlclassMinimumWidth] (\tikzumlClassNodeName) at (\tikzumlClassPos) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
+    \nodepart{second}%
+    \begin{tabular}{l}%
+    \tikzumlClassAttributes%
+    \end{tabular}%
+    \nodepart{third}%
+    \begin{tabular}{l}%
+    \tikzumlClassOperations%
+    \end{tabular}%
+    };%
+  \fi%
+  %
+  \ifthenelse{\equal{\umlclassTemplateParam}{}}{}{%
+    \draw (\tikzumlClassNodeName.north east) node[tikzuml template style, name=\tikzumlClassNodeName-template, draw=\tikzumlclassdraw, fill=\tikzumlclasstemplate, text=\tikzumlclasstext, font=\tikzumlfont] {\umlclassTemplateParam};%
+  }%
+  %
+  % add to fit
+  \ifnum\c@tikzumlPackageLevel>0%
+    \edef\tikzumlPackageFitOld{\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname}%
+    \ifthenelse{\equal{\umlclassTemplateParam}{}}{%
+      \expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlClassNodeName)}%
+    }{%
+      \expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlClassNodeName) (\tikzumlClassNodeName-template)}%
+    }%
+    \stepcounter{tikzumlPackageClassNum}%
+  \fi%
+  \ifnum\c@tikzumlComponentLevel>0%
+    \message{class \tikzumlComponent@parent{} @@@@ \tikzumlComponent@fitname}
+    \def\tikzumlComponentFitTmp{\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname}%
+    \ifthenelse{\equal{\umlclassTemplateParam}{}}{%
+      \expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{\tikzumlComponentFitTmp (\tikzumlClassNodeName)}%
+    }{%
+      \expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{\tikzumlComponentFitTmp (\tikzumlClassNodeName) (\tikzumlClassNodeName-template)}%
+    }%
+    \stepcounter{tikzumlComponentSubComponentNum}%
+  \fi%
+}%
+
+% shortcuts for interface, enum and typedef environments
+\newcommand{\umlabstract}[4][]{\umlclass[type=abstract,#1]{#2}{#3}{#4}}%
+\newcommand{\umlinterface}[4][]{\umlclass[type=interface,#1]{#2}{#3}{#4}}%
+\newcommand{\umltypedef}[4][]{\umlclass[type=typedef,#1]{#2}{#3}{#4}}%
+\newcommand{\umlenum}[4][]{\umlclass[type=enum,#1]{#2}{#3}{#4}}%
+
+% shortcut to define an empty class
+\newcommand{\umlemptyclass}[2][]{\umlclass[#1]{#2}{}{}}%
+\newcommand{\umlsimpleclass}[2][]{%
+  \pgfkeys{/tikzuml/friendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlCNfriend, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/friendrelation/.cd, #1}%
+  \umlemptyclass[simple, #1]{#2}%
+}%
+
+% underline the text for static arg
+\newcommand{\umlstatic}[1]{\underline{#1}}%
+\newcommand{\umlvirt}[1]{\textit{#1}}%
+
+% define node for n-ary association
+\newcommand{\umlNarynode}[2][]{%
+  \def\tikzumlNaryNodeAnchor{.north}
+  \def\tikzumlNaryNodeLabelPos{above}
+  \pgfkeys{/tikzuml/narynode/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=6ex, name/.initial={tikzumlEmpty},%
+           draw/.initial=\tikzumldrawcolor,  fill/.initial=\tikzumlfillclasscolor,%
+           text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{above}}{%
+               \def\tikzumlNaryNodeAnchor{.north}%
+               \def\tikzumlNaryNodeLabelPos{above}%
+             }{%
+               \ifthenelse{\equal{\keyname}{above left}}{%
+                 \def\tikzumlNaryNodeAnchor{.north west}%
+                 \def\tikzumlNaryNodeLabelPos{above left}%
+               }{%
+                 \ifthenelse{\equal{\keyname}{left}}{%
+                   \def\tikzumlNaryNodeAnchor{.west}%
+                   \def\tikzumlNaryNodeLabelPos{left}%
+                 }{%
+                   \ifthenelse{\equal{\keyname}{below left}}{%
+                     \def\tikzumlNaryNodeAnchor{.south west}%
+                     \def\tikzumlNaryNodeLabelPos{below left}%
+                   }{%
+                     \ifthenelse{\equal{\keyname}{below}}{%
+                       \def\tikzumlNaryNodeAnchor{.south}%
+                       \def\tikzumlNaryNodeLabelPos{below}%
+                     }{%
+                       \ifthenelse{\equal{\keyname}{below right}}{%
+                         \def\tikzumlNaryNodeAnchor{.south east}%
+                         \def\tikzumlNaryNodeLabelPos{below right}%
+                       }{%
+                         \ifthenelse{\equal{\keyname}{right}}{%
+                           \def\tikzumlNaryNodeAnchor{.east}%
+                           \def\tikzumlNaryNodeLabelPos{right}%
+                         }{%
+                           \ifthenelse{\equal{\keyname}{above right}}{%
+                             \def\tikzumlNaryNodeAnchor{.north east}%
+                             \def\tikzumlNaryNodeLabelPos{above right}%
+                           }{%
+                             \errmessage{TIKZUML ERROR : in umlNarynode, invalid option \keyname}%
+                           }%
+                         }%
+                       }%
+                     }%
+                   }%
+                 }%
+               }%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/narynode/.cd,#1}%
+  \pgfkeys{/tikzuml/narynode/.cd,%
+           x/.get=\umlnarynodeX, y/.get=\umlnarynodeY, width/.get=\umlnarynodeMinimumWidth,%
+           name/.get=\umlnaryName,%
+           draw/.get=\tikzumlnarynodedraw, fill/.get=\tikzumlnarynodefill,%
+           text/.get=\tikzumlnarynodetext}%
+  %
+  \def\tikzumlNaryName{#2}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlNaryNodeName{\tikzumlNaryName}}\x%
+  %
+  \ifthenelse{\equal{\umlnaryName}{tikzumlEmpty}}{}{%
+    \def\tikzumlNaryNodeName{\umlnaryName}%
+  }%
+  %
+  \StrSubstitute{\tikzumlNaryNodeName}{:}{@COLON@}[\tikzumlNaryNodeName]
+  %
+  \def\tikzumlNarynodePos{\umlnarynodeX,\umlnarynodeY}%
+  %
+  \node[tikzuml narynode style, draw=\tikzumlnarynodedraw, fill=\tikzumlnarynodefill, text=\tikzumlnarynodetext, font=\tikzumlfont, minimum width=\umlnarynodeMinimumWidth, minimum height=\umlnarynodeMinimumWidth] (\tikzumlNaryNodeName) at (\tikzumlNarynodePos) {};%
+  \draw (\tikzumlNaryNodeName\tikzumlNaryNodeAnchor) node[\tikzumlNaryNodeLabelPos] {\tikzumlNaryName};
+  %
+  % add to fit
+  \ifnum\c@tikzumlPackageLevel>0%
+    \edef\tikzumlPackageFitOld{\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlNaryNodeName)}%
+    \stepcounter{tikzumlPackageClassNum}%
+  \fi%
+}%
+
+% main command to define a relation between two classes
+% args : src class
+%        dest class
+% optional : geometry of the line
+%            barycentric weight
+%            name of the src class type attribute defined by the relation
+%            multiplicity of the src class type attribute defined by the relation
+%            position on the relation
+%            text justification on the relation
+%            name of the dest class type attribute defined by the relation
+%            multiplicity of the dest class type attribute defined by the relation
+%            position on the relation
+%            anchors on linked classes
+%            text justification on the relation
+%            start angle, end angle and size of the relation (only if recursive)
+%            stereotype of the relation
+%            style of the relation (association, aggregation, composition, inherit, ...)
+\newcommand{\umlrelation}[3][]{%
+  \pgfkeys{/tikzuml/relation/.cd,%
+           geometry/.initial=--, weight/.initial=0.5,%
+           arm1/.initial={auto}, arm2/.initial={auto},%
+           arg1/.initial={}, arg2/.initial={}, arg/.initial={},%
+           mult1/.initial={}, mult2/.initial={}, mult/.initial={},%
+           pos1/.initial=0.2, pos2/.initial=0.8, pos/.initial={tikzumlEmpty},%
+           align1/.initial={}, align2/.initial={}, align/.initial={},%
+           anchor1/.initial={tikzumlEmpty}, anchor2/.initial={tikzumlEmpty},%
+           angle1/.initial=-30, angle2/.initial=30, loopsize/.initial=3em,%
+           stereo/.initial={}, pos stereo/.initial=0.5,%
+           style/.initial=->, name/.initial=relation-\thetikzumlRelationNum,%
+           recursive mode/.initial=default, recursive direction start/.initial=right,%
+           recursive direction end/.initial=bottom,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{with port}%
+                      \OR\equal{\keyname}{interface}%
+                      \OR\equal{\keyname}{padding}%
+                      \OR\equal{\keyname}{width}%
+                      \OR\equal{\keyname}{first arm}%
+                      \OR\equal{\keyname}{second arm}%
+                      \OR\equal{\keyname}{middle arm}%
+                      \OR\equal{\keyname}{last arm}%
+                      \OR\equal{\keyname}{distance}}{}{%
+                        \errmessage{TIKZUML ERROR : in umlrelation, invalid option \keyname}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/relation/.cd,#1}%
+  \pgfkeys{/tikzuml/relation/.cd,%
+           geometry/.get=\geometry, weight/.get=\weight, arm1/.get=\armO, arm2/.get=\armT,%
+           arg1/.get=\attrName, arg2/.get=\attrNameTO, arg/.get=\attrNameTT,%
+           mult1/.get=\multiplicity, mult2/.get=\multiplicityTO, mult/.get=\multiplicityTT,%
+           pos1/.get=\position, pos2/.get=\positionTO, pos/.get=\positionTT,%
+           align1/.get=\align, align2/.get=\alignTO, align/.get=\alignTT,%
+           anchor1/.get=\tikzumlSrcAnchor, anchor2/.get=\tikzumlDestAnchor,%
+           angle1/.get=\startangle, angle2/.get=\endangle, loopsize/.get=\loopsize,%
+           stereo/.get=\stereo, pos stereo/.get=\positionStereotype,%
+           style/.get=\style, name/.get=\relationName,%
+           recursive mode/.get=\tikzumlrecmode,%
+           recursive direction start/.get=\tikzumlrecdirstart,%
+           recursive direction end/.get=\tikzumlrecdirend}%
+  %
+  \def\tikzumlSrcClassName{#2}%
+  %
+  % managing \_ in class names for node names
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlSrcClassNodeName{\tikzumlSrcClassName}}\x%
+  %
+  \StrSubstitute{\tikzumlSrcClassNodeName}{:}{@COLON@}[\tikzumlSrcClassNodeName]
+  %
+  \def\tikzumlDestClassName{#3}%
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlDestClassNodeName{\tikzumlDestClassName}}\x%
+  %
+  \StrSubstitute{\tikzumlDestClassNodeName}{:}{@COLON@}[\tikzumlDestClassNodeName]
+  %
+  % managing alias keys
+  \def\attrNameT{\attrNameTO\attrNameTT}%
+  \def\multiplicityT{\multiplicityTO\multiplicityTT}%
+  \def\alignT{\alignTO\alignTT}%
+  \def\posAttrName{}%
+  \def\posMultiplicity{}%
+  \def\posAttrNameT{}%
+  \def\posMultiplicityT{}%
+  %
+  \ifthenelse{\equal{\positionTT}{tikzumlEmpty}}{%
+    \def\positionT{\positionTO}%
+  }{%
+    \def\positionT{\positionTT}%
+  }%
+  %
+  \def\attrAlign{}%
+  \def\multAlign{}%
+  \def\attrAlignT{}%
+  \def\multAlignT{}%
+  %
+  \ifthenelse{\equal{\align}{left}}{%
+    \def\attrAlign{above right}%
+    \def\multAlign{below right}%
+  }{%
+    \ifthenelse{\equal{\align}{right}}{%
+      \def\attrAlign{above left}%
+      \def\multAlign{below left}%
+    }{}%
+  }%
+  %
+  \ifthenelse{\equal{\alignT}{left}}{%
+    \def\attrAlignT{above right}%
+    \def\multAlignT{below right}%
+  }{%
+    \ifthenelse{\equal{\alignT}{right}}{%
+      \def\attrAlignT{above left}%
+      \def\multAlignT{below left}%
+    }{}%
+  }%
+  %
+  % def stereotype
+  \ifthenelse{\equal{\stereo}{}}{%
+    \def\stereotype{}%
+  }{%
+    \def\stereotype{\guillemotleft\stereo\guillemotright}%
+  }%
+  
+  % def anchors macros
+  \ifthenelse{\equal{\tikzumlSrcAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlSrcAnchor{}%
+  }{%
+    \let\tikzumlSrcAnchorold\tikzumlSrcAnchor%
+    \def\tikzumlSrcAnchor{.\tikzumlSrcAnchorold}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlDestAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlDestAnchor{}%
+  }{%
+    \let\tikzumlDestAnchorold\tikzumlDestAnchor%
+    \def\tikzumlDestAnchor{.\tikzumlDestAnchorold}%
+  }%
+  %
+  \setcounter{pos}{100*\real{\position}}%
+  \setcounter{posT}{100*\real{\positionT}}%
+  \setcounter{posStereo}{100*\real{\positionStereotype}}%
+  %
+  \pgfmathsetmacro{\weightT}{1-\real{\weight}}%
+  %
+  \def\tikzumlControlNodesNum{0}%
+  %
+  \def\pos{\position}%
+  \def\posT{\positionT}%
+  \def\posStereo{\positionStereotype}%
+  %
+  \node[inner sep=0] (\relationName-middle) at (barycentric cs:\tikzumlSrcClassNodeName=\weightT,\tikzumlDestClassNodeName=\weight) {};%
+  %
+  % straight line
+  \ifthenelse{\equal{\geometry}{--}}{%
+    \ifthenelse{\equal{\tikzumlSrcClassNodeName}{\tikzumlDestClassNodeName}}{%
+      \def\arcNum{1}%
+      \def\arcNumT{1}%
+      %
+      \ifthenelse{\equal{\tikzumlrecmode}{default}}{%
+        \xdef\tikzumlLastArc{node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                             node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity}%
+                             node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                             node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT}%
+                             node[pos=\positionStereotype, anchor=center] {\stereotype} }%
+        \xdef\tikzumlPath{(\tikzumlSrcClassNodeName) edge[in=\endangle, out=\startangle, distance=\loopsize] \tikzumlLastArc%
+                                                          node[midway, inner sep=0, name=\relationName-1, anchor=center] {} (\tikzumlDestClassNodeName) }%
+      }{%
+        \ifthenelse{\equal{\tikzumlrecmode}{transition}}{%
+          \xdef\tikzumlFirstArc{node[midway, inner sep=0, name=\relationName-1, anchor=center] {}}%
+          \xdef\tikzumlMidOneArc{node[midway, inner sep=0, name=\relationName-3, anchor=center] {}}%
+          %
+          \ifthenelse{\equal{\tikzumlrecdirstart}{\tikzumlrecdirend}}{%
+            \def\numArcs{3}%
+            \xdef\tikzumlLastArc{node[midway, inner sep=0, name=\relationName-5, anchor=center] {}}%
+            %
+            \begin{pgfonlayer}{connections}%
+            \draw (\tikzumlSrcClassNodeName) edge[in=\endangle, out=\startangle, distance=\loopsize, draw=none] %
+                                                  node[midway, inner sep=0, name=\relationName-tmp, anchor=center] {} (\tikzumlDestClassNodeName);%
+            \ifthenelse{\equal{\tikzumlrecdirstart}{right}\OR\equal{\tikzumlrecdirstart}{left}}{%
+              \node[inner sep=0, name=\relationName-2] at (\tikzumlSrcClassNodeName.\startangle -| \relationName-tmp) {};%
+              \node[inner sep=0, name=\relationName-4] at (\tikzumlDestClassNodeName.\endangle -| \relationName-tmp) {};%
+            }{%
+              \node[inner sep=0, name=\relationName-2] at (\tikzumlSrcClassNodeName.\startangle |- \relationName-tmp) {};%
+              \node[inner sep=0, name=\relationName-4] at (\tikzumlDestClassNodeName.\endangle |- \relationName-tmp) {};%
+            }%
+            \end{pgfonlayer}%
+          }{%
+            \def\numArcs{4}%
+            \xdef\tikzumlMidTwoArc{node[midway, inner sep=0, name=\relationName-5, anchor=center] {}}%
+            \xdef\tikzumlLastArc{node[midway, inner sep=0, name=\relationName-7, anchor=center] {}}%
+            %
+            \begin{pgfonlayer}{connections}%
+            \draw (\tikzumlSrcClassNodeName) edge[in=\endangle, out=\startangle, distance=\loopsize, draw=none] %
+                                                  node[midway, name=\relationName-4, anchor=center] {} (\tikzumlDestClassNodeName);%
+            \ifthenelse{\equal{\tikzumlrecdirstart}{right}\OR\equal{\tikzumlrecdirstart}{left}}{%
+              \node[inner sep=0, name=\relationName-2] at (\tikzumlSrcClassNodeName.\startangle -| \relationName-4) {};%
+              \node[inner sep=0, name=\relationName-6] at (\tikzumlDestClassNodeName.\endangle |- \relationName-4) {};%
+            }{%
+              \node[inner sep=0, name=\relationName-2] at (\tikzumlSrcClassNodeName.\startangle |- \relationName-4) {};%
+              \node[inner sep=0, name=\relationName-6] at (\tikzumlDestClassNodeName.\endangle -| \relationName-4) {};%
+            }%
+            \end{pgfonlayer}%
+          }%
+          %
+          \ifnum\numArcs=4%
+            \ifnum\theposStereo>300%
+              \pgfmathsetmacro{\posStereo}{(\theposStereo-300)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posStereo, anchor=center] {\stereotype}}%
+            \else%
+              \ifnum\theposStereo<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posStereo, anchor=center] {\stereotype}}%
+              \else%
+                \ifnum\theposStereo>200%
+                  \pgfmathsetmacro{\posStereo}{(\theposStereo-200)/100}%
+                  \xdef\tikzumlMidTwoArc{\tikzumlMidTwoArc node[pos=\posStereo, anchor=center] {\stereotype}}%
+                \else%
+                  \pgfmathsetmacro{\posStereo}{(\theposStereo-100)/100}%
+                  \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\posStereo, anchor=center] {\stereotype}}%
+                \fi%
+              \fi%
+            \fi%
+            %
+            \ifthenelse{\thepos=300\OR\thepos=100}{%
+              \ifthenelse{\equal{\tikzumlrecdirstart}{right}}{%
+                \ifthenelse{\equal{\tikzumlrecdirend}{bottom}}{%
+                  \def\posAttrName{above right}%
+                  \def\posMultiplicity{below left}%
+                }{%
+                  \def\posAttrName{above left}%
+                  \def\posMultiplicity{below right}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlrecdirstart}{left}}{%
+                  \ifthenelse{\equal{\tikzumlrecdirend}{bottom}}{%
+                    \def\posAttrName{above left}%
+                    \def\posMultiplicity{below right}%
+                  }{%
+                    \def\posAttrName{above right}%
+                    \def\posMultiplicity{below left}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlrecdirstart}{top}}{%
+                    \ifthenelse{\equal{\tikzumlrecdirend}{left}}{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }%
+                  }{%
+                    \ifthenelse{\equal{\tikzumlrecdirend}{left}}{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifthenelse{\thepos=200}{%
+              \ifthenelse{\equal{\tikzumlrecdirstart}{right}}{%
+                \ifthenelse{\equal{\tikzumlrecdirend}{bottom}}{%
+                  \def\posAttrName{above left}%
+                  \def\posMultiplicity{below right}%
+                }{%
+                  \def\posAttrName{above right}%
+                  \def\posMultiplicity{below left}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlrecdirstart}{left}}{%
+                  \ifthenelse{\equal{\tikzumlrecdirend}{bottom}}{%
+                    \def\posAttrName{above right}%
+                    \def\posMultiplicity{below left}%
+                  }{%
+                    \def\posAttrName{above left}%
+                    \def\posMultiplicity{below right}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlrecdirstart}{top}}{%
+                    \ifthenelse{\equal{\tikzumlrecdirend}{left}}{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }%
+                  }{%
+                    \ifthenelse{\equal{\tikzumlrecdirend}{left}}{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifnum\thepos>300%
+              \pgfmathsetmacro{\pos}{(\thepos-300)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                   node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity}%
+                                   }%
+            \else%
+              \ifnum\thepos<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                     node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity}%
+                                     }%
+              \else%
+                \ifnum\thepos>200%
+                  \pgfmathsetmacro{\pos}{(\thepos-200)/100}%
+                  \xdef\tikzumlMidTwoArc{\tikzumlMidTwoArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                         node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity}%
+                                        }%
+                \else%
+                  \pgfmathsetmacro{\pos}{(\thepos-100)/100}%
+                  \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                         node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity}%
+                                        }%
+                \fi%
+              \fi%
+            \fi%
+            %
+            \ifthenelse{\theposT=300\OR\theposT=100}{%
+              \ifthenelse{\equal{\tikzumlrecdirstart}{right}}{%
+                \ifthenelse{\equal{\tikzumlrecdirend}{bottom}}{%
+                  \def\posAttrNameT{above right}%
+                  \def\posMultiplicityT{below left}%
+                }{%
+                  \def\posAttrNameT{above left}%
+                  \def\posMultiplicityT{below right}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlrecdirstart}{left}}{%
+                  \ifthenelse{\equal{\tikzumlrecdirend}{bottom}}{%
+                    \def\posAttrNameT{above left}%
+                    \def\posMultiplicityT{below right}%
+                  }{%
+                    \def\posAttrNameT{above right}%
+                    \def\posMultiplicityT{below left}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlrecdirstart}{top}}{%
+                    \ifthenelse{\equal{\tikzumlrecdirend}{left}}{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }%
+                  }{%
+                    \ifthenelse{\equal{\tikzumlrecdirend}{left}}{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            \ifthenelse{\theposT=200}{%
+              \ifthenelse{\equal{\tikzumlrecdirstart}{right}}{%
+                \ifthenelse{\equal{\tikzumlrecdirend}{bottom}}{%
+                  \def\posAttrNameT{above left}%
+                  \def\posMultiplicity{below right}%
+                }{%
+                  \def\posAttrNameT{above right}%
+                  \def\posMultiplicityT{below left}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlrecdirstart}{left}}{%
+                  \ifthenelse{\equal{\tikzumlrecdirend}{bottom}}{%
+                    \def\posAttrNameT{above right}%
+                    \def\posMultiplicityT{below left}%
+                  }{%
+                    \def\posAttrNameT{above left}%
+                    \def\posMultiplicityT{below right}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlrecdirstart}{top}}{%
+                    \ifthenelse{\equal{\tikzumlrecdirend}{left}}{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }%
+                  }{%
+                    \ifthenelse{\equal{\tikzumlrecdirend}{left}}{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifnum\theposT>300%
+              \pgfmathsetmacro{\posT}{(\theposT-300)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                   node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT}%
+                                   }%
+            \else%
+              \ifnum\theposT<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                     node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT}%
+                                     }%
+              \else%
+                \ifnum\theposT>200%
+                  \pgfmathsetmacro{\posT}{(\theposT-200)/100}%
+                  \xdef\tikzumlMidTwoArc{\tikzumlMidTwoArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                         node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT}%
+                                        }%
+                \else%
+                  \pgfmathsetmacro{\posT}{(\theposT-100)/100}%
+                  \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                         node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT}%
+                                        }%
+                \fi%
+              \fi%
+            \fi%
+          \else%
+            \ifnum\theposStereo>200%
+              \pgfmathsetmacro{\posStereo}{(\theposStereo-200)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+            \else%
+              \ifnum\theposStereo<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+              \else%
+                \pgfmathsetmacro{\posStereo}{(\theposStereo-100)/100}%
+                \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+              \fi%
+            \fi%
+            %
+            \ifthenelse{\thepos=100}{%
+              \ifthenelse{\equal{\tikzumlrecdirstart}{right}}{%
+                \ifthenelse{\endangle<\startangle}{%
+                  \def\posAttrName{above right}%
+                  \def\posMultiplicity{below left}%
+                }{%
+                  \def\posAttrName{above left}%
+                  \def\posMultiplicity{below right}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlrecdirstart}{left}}{%
+                  \ifthenelse{\endangle<\startangle}{%
+                    \def\posAttrName{above left}%
+                    \def\posMultiplicity{below right}%
+                  }{%
+                    \def\posAttrName{above right}%
+                    \def\posMultiplicity{below left}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlrecdirstart}{top}}{%
+                    \ifthenelse{\endangle<\startangle}{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }%
+                  }{%
+                    \ifthenelse{\endangle<\startangle}{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifthenelse{\thepos=200}{%
+              \ifthenelse{\equal{\tikzumlrecdirstart}{right}}{%
+                \ifthenelse{\endangle<\startangle}{%
+                  \def\posAttrName{above left}%
+                  \def\posMultiplicity{below right}%
+                }{%
+                  \def\posAttrName{above right}%
+                  \def\posMultiplicity{below left}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlrecdirstart}{left}}{%
+                  \ifthenelse{\endangle<\startangle}{%
+                    \def\posAttrName{above right}%
+                    \def\posMultiplicity{below left}%
+                  }{%
+                    \def\posAttrName{above left}%
+                    \def\posMultiplicity{below right}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlrecdirstart}{top}}{%
+                    \ifthenelse{\endangle<\startangle}{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }%
+                  }{%
+                    \ifthenelse{\endangle<\startangle}{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifnum\thepos>200%
+              \pgfmathsetmacro{\pos}{(\thepos-200)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                   node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity}%
+                                   }%
+            \else%
+              \ifnum\thepos<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                     node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity}%
+                                     }%
+              \else%
+                \pgfmathsetmacro{\pos}{(\thepos-100)/100}%
+                \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                       node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity}%
+                                      }%
+              \fi%
+            \fi%
+            %
+            \ifthenelse{\theposT=100}{%
+              \ifthenelse{\equal{\tikzumlrecdirstart}{right}}{%
+                \ifthenelse{\endangle<\startangle}{%
+                  \def\posAttrNameT{above right}%
+                  \def\posMultiplicityT{below left}%
+                }{%
+                  \def\posAttrNameT{above left}%
+                  \def\posMultiplicityT{below right}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlrecdirstart}{left}}{%
+                  \ifthenelse{\endangle<\startangle}{%
+                    \def\posAttrNameT{above left}%
+                    \def\posMultiplicityT{below right}%
+                  }{%
+                    \def\posAttrNameT{above right}%
+                    \def\posMultiplicityT{below left}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlrecdirstart}{top}}{%
+                    \ifthenelse{\endangle<\startangle}{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }%
+                  }{%
+                    \ifthenelse{\endangle<\startangle}{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifthenelse{\theposT=200}{%
+              \ifthenelse{\equal{\tikzumlrecdirstart}{right}}{%
+                \ifthenelse{\endangle<\startangle}{%
+                  \def\posAttrNameT{above left}%
+                  \def\posMultiplicityT{below right}%
+                }{%
+                  \def\posAttrNameT{above right}%
+                  \def\posMultiplicityT{below left}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlrecdirstart}{left}}{%
+                  \ifthenelse{\endangle<\startangle}{%
+                    \def\posAttrNameT{above right}%
+                    \def\posMultiplicityT{below left}%
+                  }{%
+                    \def\posAttrNameT{above left}%
+                    \def\posMultiplicityT{below right}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlrecdirstart}{top}}{%
+                    \ifthenelse{\endangle<\startangle}{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }%
+                  }{%
+                    \ifthenelse{\endangle<\startangle}{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifnum\theposT>200%
+              \pgfmathsetmacro{\posT}{(\theposT-200)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                   node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT}%
+                                   }%
+            \else%
+              \ifnum\theposT<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                     node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT}%
+                                     }%
+              \else%
+                \pgfmathsetmacro{\posT}{(\theposT-100)/100}%
+                \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                       node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT}%
+                                      }%
+              \fi%
+            \fi%
+          \fi%
+          %
+          \ifthenelse{\equal{\tikzumlrecdirstart}{\tikzumlrecdirend}}{%
+            \xdef\tikzumlPath{(\tikzumlSrcClassNodeName.\startangle) -- \tikzumlFirstArc (\relationName-2.center) -- \tikzumlMidOneArc (\relationName-4.center) -- \tikzumlLastArc (\tikzumlDestClassNodeName.\endangle) }%
+            \ifnum\thetikzumlStateLevel>0%
+              \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+              \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\relationName-1) (\relationName-2) (\relationName-3) (\relationName-4) (\relationName-5)}%
+            \fi%
+          }{%
+            \xdef\tikzumlPath{(\tikzumlSrcClassNodeName.\startangle) -- \tikzumlFirstArc (\relationName-2.center) -- \tikzumlMidOneArc (\relationName-4.center) -- \tikzumlMidTwoArc (\relationName-6.center) -- \tikzumlLastArc (\tikzumlDestClassNodeName.\endangle) }%
+            \ifnum\thetikzumlStateLevel>0%
+              \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+              \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\relationName-1) (\relationName-2) (\relationName-3) (\relationName-4) (\relationName-5) (\relationName-6) (\relationName-7)}%
+            \fi%
+          }%
+        }{}%
+      }%
+    }{%
+      \def\arcNum{1}%
+      \def\arcNumT{1}%
+      %
+      \node[inner sep=0] (\relationName-1) at (\relationName-middle) {};%
+      \xdef\tikzumlLastArc{node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                           node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity}%
+                           node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                           node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT}%
+                           node[pos=\positionStereotype, anchor=center] {\stereotype} }%
+      \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlSrcAnchor) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlDestAnchor) }%
+      \ifnum\thetikzumlStateLevel>0%
+        \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+        \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\relationName-1) }%
+      \fi%
+    }%
+  }{%
+    % first vertical then horizontal line
+    \ifthenelse{\equal{\geometry}{|-}}%
+    {%
+      \def\tikzumlControlNodesNum{1}%
+      %
+      \def\tikzumlFirstArc{node[midway, inner sep=0, name=\relationName-1, anchor=center] {} }%
+      \def\tikzumlLastArc{node[midway, inner sep=0, name=\relationName-3, anchor=center]{} }%
+      %
+      \begin{pgfonlayer}{connections}%
+      \node[inner sep=0] (\relationName-2) at (\tikzumlSrcClassNodeName\tikzumlSrcAnchor |- \tikzumlDestClassNodeName\tikzumlDestAnchor) {};%
+      \end{pgfonlayer}%
+      %
+      \ifnum\theposStereo>100%
+        \pgfmathsetmacro{\posStereo}{(\theposStereo-100)/100}%
+        \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+      \else%
+        \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+      \fi%
+      %
+      \ifnum\thepos>100%
+        \pgfmathsetmacro{\pos}{(\thepos-100)/100}%
+        \def\arcNum{2}%
+      \else%
+        \def\arcNum{1}%
+        \ifnum\thepos=100%
+          \def\posAttrName{above left}%
+          \def\posMultiplicity{below right}%
+        \fi%
+      \fi%
+      %
+      \ifnum\arcNum=1%
+        \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                               node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+      \fi%
+      \ifnum\arcNum=2%
+        \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                             node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+      \fi%
+      %
+      \ifnum\theposT>100%
+        \pgfmathsetmacro{\posT}{(\theposT-100)/100}%
+        \def\arcNumT{2}%
+      \else%
+        \def\arcNumT{1}%
+        \ifnum\theposT=100%
+          \def\posAttrNameT{above left}%
+          \def\posMultiplicityT{below right}%
+        \fi%
+      \fi%
+      %
+      \ifnum\arcNumT=1%
+        \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                               node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+      \fi%
+      \ifnum\arcNumT=2%
+        \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                             node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+      \fi%
+      %
+      \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlSrcAnchor) -- \tikzumlFirstArc (\relationName-2.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlDestAnchor) }%
+      \ifnum\thetikzumlStateLevel>0%
+        \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+        \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\relationName-1) (\relationName-2) (\relationName-3) }%
+      \fi%
+    }{%
+      % first horizontal then vertical line
+      \ifthenelse{\equal{\geometry}{-|}}{%
+        \def\tikzumlControlNodesNum{1}%
+        %
+        \def\tikzumlFirstArc{node[midway, inner sep=0, name=\relationName-1, anchor=center]{} }%
+        \def\tikzumlLastArc{node[midway, inner sep=0, name=\relationName-3, anchor=center] {} }%
+        %
+        \begin{pgfonlayer}{connections}%
+        \node[inner sep=0] (\relationName-2) at (\tikzumlSrcClassNodeName\tikzumlSrcAnchor -| \tikzumlDestClassNodeName\tikzumlDestAnchor) {};%
+        \end{pgfonlayer}%
+        %
+        \ifnum\theposStereo>100%
+          \pgfmathsetmacro{\posStereo}{(\theposStereo-100)/100}%
+          \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+        \else%
+          \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+        \fi%
+        %
+        \ifnum\thepos>100%
+          \pgfmathsetmacro{\pos}{(\thepos-100)/100}%
+          \def\arcNum{2}%
+        \else%
+          \def\arcNum{1}%
+          \ifnum\thepos=100%
+            \def\posAttrName{above left}%
+            \def\posMultiplicity{below right}%
+          \fi%
+        \fi%
+        %
+        \ifnum\arcNum=1%
+          \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                                 node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+        \fi%
+        \ifnum\arcNum=2%
+          \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                               node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+        \fi%
+        %
+        \ifnum\theposT>100%
+          \pgfmathsetmacro{\posT}{(\theposT-100)/100}%
+          \def\arcNumT{2}%
+        \else%
+          \def\arcNumT{1}%
+          \ifnum\theposT=100%
+            \def\posAttrNameT{above left}%
+            \def\posMultiplicityT{below right}%
+          \fi%
+        \fi%
+        %
+        \ifnum\arcNumT=1%
+          \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                                 node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+        \fi%
+        \ifnum\arcNumT=2%
+          \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                               node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+        \fi%
+        %
+        \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlSrcAnchor) -- \tikzumlFirstArc (\relationName-2.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlDestAnchor) }%
+        \ifnum\thetikzumlStateLevel>0%
+          \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+          \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\relationName-1) (\relationName-2) (\relationName-3) }%
+        \fi%
+      }{%
+        % first vertical, then horizontal, finally vertical line
+        \ifthenelse{\equal{\geometry}{|-|}}{%
+          \def\tikzumlControlNodesNum{2}%
+          %
+          \def\tikzumlFirstArc{node[midway, inner sep=0, name=\relationName-1, anchor=center] {} }%
+          \def\tikzumlLastArc{node[midway, inner sep=0, name=\relationName-5, anchor=center] {} }%
+          \def\tikzumlMidOneArc{ }%
+          %
+          \begin{pgfonlayer}{connections}%
+          %
+          \ifthenelse{\equal{\armO}{auto}}{%
+            \ifthenelse{\equal{\armT}{auto}}{%
+              \node[inner sep=0] (\relationName-3) at (\relationName-middle) {};%
+              \node[inner sep=0] (\relationName-2) at (\tikzumlSrcClassNodeName\tikzumlSrcAnchor |- \relationName-3) {};%
+              \node[inner sep=0] (\relationName-4) at (\relationName-3 -| \tikzumlDestClassNodeName\tikzumlDestAnchor) {};%
+            }{%
+              \draw (\tikzumlDestClassNodeName\tikzumlDestAnchor)+(0,\armT) node[inner sep=0, name=\relationName-4] {};%
+              \node[inner sep=0] (\relationName-2) at (\relationName-4 -| \tikzumlSrcClassNodeName\tikzumlSrcAnchor) {};%
+              \node[inner sep=0] (\relationName-3) at (barycentric cs:\relationName-2=0.5,\relationName-4=0.5) {};%
+            }%
+          }{%
+            \draw (\tikzumlSrcClassNodeName\tikzumlSrcAnchor)+(0,\armO) node[inner sep=0, name=\relationName-2] {};%
+            \node[inner sep=0] (\relationName-4) at (\relationName-2 -| \tikzumlDestClassNodeName\tikzumlDestAnchor) {};%
+            \node[inner sep=0] (\relationName-3) at (barycentric cs:\relationName-2=0.5,\relationName-4=0.5) {};%
+          }%
+          \end{pgfonlayer}%
+          %
+          \ifnum\theposStereo>200%
+            \pgfmathsetmacro{\posStereo}{(\theposStereo-200)/100}%
+            \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+          \else%
+            \ifnum\theposStereo<100%
+              \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+            \else%
+              \pgfmathsetmacro{\posStereo}{(\theposStereo-100)/100}%
+              \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+            \fi%
+          \fi%
+          %
+          \ifthenelse{\thepos=200\OR\thepos=100}{%
+            \def\posAttrName{above left}%
+            \def\posMultiplicity{below right}%
+          }{}%
+          %
+          \ifthenelse{\thepos>200}{%
+            \pgfmathsetmacro{\pos}{(\thepos-200)/100}%
+            \def\arcNum{3}%
+          }{%
+            \ifthenelse{\thepos<100}{%
+              \def\arcNum{1}%
+            }{%
+              \pgfmathsetmacro{\pos}{(\thepos-100)/100}%
+              \def\arcNum{2}%
+            }%
+          }%
+          %
+          \ifnum\arcNum=1%
+            \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                                   node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+          \fi%
+          \ifnum\arcNum=2%
+            \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                                     node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+          \fi%
+          \ifnum\arcNum=3%
+            \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                                 node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+          \fi%
+          %
+          \ifthenelse{\theposT=200\OR\theposT=100}{%
+            \def\posAttrNameT{above left}%
+            \def\posMultiplicityT{below right}%
+          }{}%
+          %
+          \ifthenelse{\theposT>200}{%
+            \pgfmathsetmacro{\posT}{(\theposT-200)/100}%
+            \def\arcNumT{3}%
+          }{%
+            \ifthenelse{\theposT<100}{%
+              \def\arcNumT{1}%
+            }{%
+              \pgfmathsetmacro{\posT}{(\theposT-100)/100}%
+              \def\arcNumT{2}%
+            }%
+          }%
+          %
+          \ifnum\arcNumT=1%
+            \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                                   node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+          \fi%
+          \ifnum\arcNumT=2%
+            \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                                     node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+          \fi%
+          \ifnum\arcNumT=3%
+            \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                                 node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+          \fi%
+          %
+          \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlSrcAnchor) -- \tikzumlFirstArc (\relationName-2.base) -- \tikzumlMidOneArc (\relationName-4.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlDestAnchor) }%
+          \ifnum\thetikzumlStateLevel>0%
+            \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+            \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\relationName-1) (\relationName-2) (\relationName-3) (\relationName-4) (\relationName-5) }%
+          \fi%
+        }{%
+          % first horizontal, then vertical, finally horizontal line
+          \ifthenelse{\equal{\geometry}{-|-}}{%
+            \def\tikzumlControlNodesNum{2}%
+            %
+            \def\tikzumlFirstArc{node[midway, inner sep=0, name=\relationName-1, anchor=center] {} }%
+            \def\tikzumlLastArc{node[midway, inner sep=0, name=\relationName-5, anchor=center] {} }%
+            \def\tikzumlMidOneArc{}%
+            %
+            \begin{pgfonlayer}{connections}%
+            %
+            \ifthenelse{\equal{\armO}{auto}}{%
+              \ifthenelse{\equal{\armT}{auto}}{%
+                \node[inner sep=0] (\relationName-3) at (\relationName-middle) {};%
+                \node[inner sep=0] (\relationName-2) at (\tikzumlSrcClassNodeName\tikzumlSrcAnchor -| \relationName-3) {};%
+                \node[inner sep=0] (\relationName-4) at (\relationName-3 |- \tikzumlDestClassNodeName\tikzumlDestAnchor) {};%
+              }{%
+                \draw (\tikzumlDestClassNodeName\tikzumlDestAnchor)+(\armT,0) node[inner sep=0, name=\relationName-4] {};%
+                \node[inner sep=0] (\relationName-2) at (\relationName-4 |- \tikzumlSrcClassNodeName\tikzumlSrcAnchor) {};%
+                \node[inner sep=0] (\relationName-3) at (barycentric cs:\relationName-2=0.5,\relationName-4=0.5) {};%
+              }%
+            }{%
+              \draw (\tikzumlSrcClassNodeName\tikzumlSrcAnchor)+(\armO,0) node[inner sep=0, name=\relationName-2] {};%
+              \node[inner sep=0] (\relationName-4) at (\relationName-2 |- \tikzumlDestClassNodeName\tikzumlDestAnchor) {};%
+              \node[inner sep=0] (\relationName-3) at (barycentric cs:\relationName-2=0.5,\relationName-4=0.5) {};%
+            }%
+            \end{pgfonlayer}%
+            %
+            %
+            \ifnum\theposStereo>200%
+              \pgfmathsetmacro{\posStereo}{(\theposStereo-200)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+            \else%
+              \ifnum\theposStereo<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+              \else%
+                \pgfmathsetmacro{\posStereo}{(\theposStereo-100)/100}%
+                \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+              \fi%
+            \fi%
+            %
+            \ifthenelse{\thepos=200\OR\thepos=100}{%
+              \def\posAttrName{above left}%
+              \def\posMultiplicity{below right}%
+            }{}%
+            %
+            \ifthenelse{\thepos>200}{%
+              \pgfmathsetmacro{\pos}{(\thepos-200)/100}%
+              \def\arcNum{3}%
+            }{%
+              \ifthenelse{\thepos<100}{%
+                \def\arcNum{1}%
+              }{%
+                \pgfmathsetmacro{\pos}{(\thepos-100)/100}%
+                \def\arcNum{2}%
+              }%
+            }%
+            %
+            \ifnum\arcNum=1%
+              \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                                     node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+            \fi%
+            \ifnum\arcNum=2%
+              \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                                       node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+            \fi%
+            \ifnum\arcNum=3%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                                   node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+            \fi%
+            %
+            \ifthenelse{\theposT=200\OR\theposT=100}{%
+              \def\posAttrNameT{above left}%
+              \def\posMultiplicityT{below right}%
+            }{}%
+            %
+            \ifthenelse{\theposT>200}{%
+              \pgfmathsetmacro{\posT}{(\theposT-200)/100}%
+              \def\arcNumT{3}%
+            }{%
+              \ifthenelse{\theposT<100}{%
+                \def\arcNumT{1}%
+              }{%
+                \pgfmathsetmacro{\posT}{(\theposT-100)/100}%
+                \def\arcNumT{2}%
+              }%
+            }%
+            %
+            \ifnum\arcNumT=1%
+              \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                                     node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+            \fi%
+            \ifnum\arcNumT=2%
+              \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                                       node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+            \fi%
+            \ifnum\arcNumT=3%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                                   node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+            \fi%
+            %
+            \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlSrcAnchor) -- \tikzumlFirstArc (\relationName-2.base) -- \tikzumlMidOneArc (\relationName-4.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlDestAnchor) }%
+            \ifnum\thetikzumlStateLevel>0%
+              \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+              \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\relationName-1) (\relationName-2) (\relationName-3) (\relationName-4) (\relationName-5) }%
+            \fi%
+          }{%
+            \errmessage{TIKZUML ERROR : Unknown geometry value !!! It should be in the following list : --, |-, -|, |-|, -|-}%
+          }%
+        }%
+      }%
+    }%
+  }%
+  %
+  \begin{pgfonlayer}{connections}%
+  \draw[auto, \style, font=\tikzumlfont] \tikzumlPath ;%
+  \end{pgfonlayer}%
+  %
+  \stepcounter{tikzumlRelationNum}%
+}%
+
+% shortcuts of \umlrelation
+\newcommand{\umlHVrelation}[3][]{%
+  \pgfkeys{/tikzuml/HVrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlHVrelation, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/HVrelation/.cd, #1}%
+  \umlrelation[geometry=-|, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlVHrelation}[3][]{%
+  \pgfkeys{/tikzuml/VHrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlVHrelation, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/VHrelation/.cd, #1}%
+  \umlrelation[geometry=|-, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlHVHrelation}[3][]{%
+  \pgfkeys{/tikzuml/HVHrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlHVHrelation, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/HVHrelation/.cd, #1}%
+  \umlrelation[geometry=-|-, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlVHVrelation}[3][]{%
+  \pgfkeys{/tikzuml/VHVrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlVHVrelation, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/VHVrelation/.cd, #1}%
+  \umlrelation[geometry=|-|, #1]{#2}{#3}%
+}%
+
+% shortcuts for relations
+\newcommand{\umlinherit}[3][]{\umlrelation[style={tikzuml inherit style}, #1]{#2}{#3}}%
+\newcommand{\umlimpl}[3][]{\umlrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
+\newcommand{\umlreal}[3][]{\umlrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
+\newcommand{\umlassoc}[3][]{\umlrelation[style={tikzuml association style}, #1]{#2}{#3}}%
+\newcommand{\umlbiassoc}[3][]{\umlrelation[style={tikzuml bidirectional association style}, #1]{#2}{#3}}%
+\newcommand{\umluniassoc}[3][]{\umlrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}}%
+\newcommand{\umlaggreg}[3][]{\umlrelation[style={tikzuml aggregation style}, #1]{#2}{#3}}%
+\newcommand{\umluniaggreg}[3][]{\umlrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}}%
+\newcommand{\umlcompo}[3][]{\umlrelation[style={tikzuml composition style}, #1]{#2}{#3}}%
+\newcommand{\umlunicompo}[3][]{\umlrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}}%
+\newcommand{\umlimport}[3][]{\umlrelation[style={tikzuml import style}, #1]{#2}{#3}}%
+\newcommand{\umldep}[3][]{\umlrelation[style={tikzuml dependency style}, #1]{#2}{#3}}%
+\newcommand{\umlfriend}[3][]{%
+  \pgfkeys{/tikzuml/friendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlfriend, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/friendrelation/.cd, #1}%
+  \umlrelation[stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlHVinherit}[3][]{\umlHVrelation[style={tikzuml inherit style}, #1]{#2}{#3}}%
+\newcommand{\umlHVimpl}[3][]{\umlHVrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
+\newcommand{\umlHVreal}[3][]{\umlHVrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
+\newcommand{\umlHVassoc}[3][]{\umlHVrelation[style={tikzuml association style}, #1]{#2}{#3}}%
+\newcommand{\umlHVuniassoc}[3][]{\umlHVrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}}%
+\newcommand{\umlHVaggreg}[3][]{\umlHVrelation[style={tikzuml aggregation style}, #1]{#2}{#3}}%
+\newcommand{\umlHVuniaggreg}[3][]{\umlHVrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}}%
+\newcommand{\umlHVcompo}[3][]{\umlHVrelation[style={tikzuml composition style}, #1]{#2}{#3}}%
+\newcommand{\umlHVunicompo}[3][]{\umlHVrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}}%
+\newcommand{\umlHVimport}[3][]{\umlHVrelation[style={tikzuml import style}, #1]{#2}{#3}}%
+\newcommand{\umlHVdep}[3][]{\umlHVrelation[style={tikzuml dependency style}, #1]{#2}{#3}}%
+\newcommand{\umlHVfriend}[3][]{%
+  \pgfkeys{/tikzuml/friendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlHVfriend, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlHVfriend, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/friendrelation/.cd, #1}%
+  \umlrelation[geometry=-|, stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlVHinherit}[3][]{\umlVHrelation[style={tikzuml inherit style}, #1]{#2}{#3}}%
+\newcommand{\umlVHimpl}[3][]{\umlVHrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
+\newcommand{\umlVHreal}[3][]{\umlVHrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
+\newcommand{\umlVHassoc}[3][]{\umlVHrelation[style={tikzuml association style}, #1]{#2}{#3}}%
+\newcommand{\umlVHuniassoc}[3][]{\umlVHrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}}%
+\newcommand{\umlVHaggreg}[3][]{\umlVHrelation[style={tikzuml aggregation style}, #1]{#2}{#3}}%
+\newcommand{\umlVHuniaggreg}[3][]{\umlVHrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}}%
+\newcommand{\umlVHcompo}[3][]{\umlVHrelation[style={tikzuml composition style}, #1]{#2}{#3}}%
+\newcommand{\umlVHunicompo}[3][]{\umlVHrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}}%
+\newcommand{\umlVHimport}[3][]{\umlVHrelation[style={tikzuml import style}, #1]{#2}{#3}}%
+\newcommand{\umlVHdep}[3][]{\umlVHrelation[style={tikzuml dependency style}, #1]{#2}{#3}}%
+\newcommand{\umlVHfriend}[3][]{%
+  \pgfkeys{/tikzuml/friendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlVHfriend, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlVHfriend, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/friendrelation/.cd, #1}%
+  \umlrelation[geometry=|-, stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlHVHinherit}[3][]{\umlHVHrelation[style={tikzuml inherit style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHimpl}[3][]{\umlHVHrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHreal}[3][]{\umlHVHrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHassoc}[3][]{\umlHVHrelation[style={tikzuml association style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHuniassoc}[3][]{\umlHVHrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHaggreg}[3][]{\umlHVHrelation[style={tikzuml aggregation style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHuniaggreg}[3][]{\umlHVHrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHcompo}[3][]{\umlHVHrelation[style={tikzuml composition style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHunicompo}[3][]{\umlHVHrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHimport}[3][]{\umlHVHrelation[style={tikzuml import style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHdep}[3][]{\umlHVHrelation[style={tikzuml dependency style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHfriend}[3][]{%
+  \pgfkeys{/tikzuml/friendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlHVHfriend, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlHVHfriend, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/friendrelation/.cd, #1}%
+  \umlrelation[geometry=-|-, stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlVHVinherit}[3][]{\umlVHVrelation[style={tikzuml inherit style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVimpl}[3][]{\umlVHVrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVreal}[3][]{\umlVHVrelation[style={tikzuml implements style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVassoc}[3][]{\umlVHVrelation[style={tikzuml association style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVuniassoc}[3][]{\umlVHVrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVaggreg}[3][]{\umlVHVrelation[style={tikzuml aggregation style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVuniaggreg}[3][]{\umlVHVrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVcompo}[3][]{\umlVHVrelation[style={tikzuml composition style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVunicompo}[3][]{\umlVHVrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVimport}[3][]{\umlVHVrelation[style={tikzuml import style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVdep}[3][]{\umlVHVrelation[style={tikzuml dependency style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVfriend}[3][]{%
+  \pgfkeys{/tikzuml/friendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlVHVfriend, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlVHVfriend, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/friendrelation/.cd, #1}%
+  \umlrelation[geometry=|-|, stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+
+% define a node
+\newcommand{\umlnode}[2]{%
+  \node (#2) at (#1) {};%
+}%
+
+% main command to define a relation between two classes through a control node
+% args : src class
+%        control node
+%        dest class
+% optional : geometry of the line
+%            barycentric weight
+%            name of the src class type attribute defined by the relation
+%            multiplicity of the src class type attribute defined by the relation
+%            position on the relation
+%            text justification on the relation
+%            name of the dest class type attribute defined by the relation
+%            multiplicity of the dest class type attribute defined by the relation
+%            position on the relation
+%            border anchors 
+%            text justification on the relation
+%            start angle, end angle and size of the relation (only if recursive)
+%            stereotype of the relation
+%            style of the relation (association, aggregation, composition, inherit, ...)
+\newcommand{\umlCNrelation}[4][]%
+{%
+  \pgfkeys{/tikzuml/relation/.cd,%
+           arg1/.initial={}, arg2/.initial={}, arg/.initial={},%
+           mult1/.initial={}, mult2/.initial={}, mult/.initial={},%
+           pos1/.initial=0.2, pos2/.initial=0.8, pos/.initial={tikzumlEmpty},%
+           align1/.initial={}, align2/.initial={}, align/.initial={},%
+           anchor1/.initial={tikzumlEmpty}, anchor2/.initial={tikzumlEmpty},%
+           stereo/.initial={}, pos stereo/.initial=1,%
+           style/.initial=->, name/.initial=relation-\thetikzumlRelationNum,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlCNrelation, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/relation/.cd,#1}%
+  \pgfkeys{/tikzuml/relation/.cd,%
+           arg1/.get=\attrName, arg2/.get=\attrNameTO, arg/.get=\attrNameTT,%
+           mult1/.get=\multiplicity, mult2/.get=\multiplicityTO, mult/.get=\multiplicityTT,%
+           pos1/.get=\position, pos2/.get=\positionTO, pos/.get=\positionTT,%
+           align1/.get=\align, align2/.get=\alignTO, align/.get=\alignTT,%
+           anchor1/.get=\tikzumlSrcAnchor, anchor2/.get=\tikzumlDestAnchor,%
+           stereo/.get=\stereo, pos stereo/.get=\positionStereotype,%
+           style/.get=\style, name/.get=\relationName}%
+  %
+  % managing \_ in class names for node names
+  \def\tikzumlSrcClassName{#2}%
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlSrcClassNodeName{\tikzumlSrcClassName}}\x%
+  %
+  \StrSubstitute{\tikzumlSrcClassNodeName}{:}{@COLON@}[\tikzumlSrcClassNodeName]
+  %
+  \def\tikzumlDestClassName{#4}%
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlDestClassNodeName{\tikzumlDestClassName}}\x%
+  %
+  \StrSubstitute{\tikzumlDestClassNodeName}{:}{@COLON@}[\tikzumlDestClassNodeName]
+  %
+  % managing alias keys
+  \def\attrNameT{\attrNameTO\attrNameTT}%
+  \def\multiplicityT{\multiplicityTO\multiplicityTT}%
+  \def\alignT{\alignTO\alignTT}%
+  \def\orientationT{\orientationTO\orientationTT}%
+  %
+  \ifthenelse{\equal{\positionTT}{tikzumlEmpty}}{%
+    \def\positionT{\positionTO}%
+  }{%
+    \def\positionT{\positionTT}%
+  }%
+  %
+  \def\attrAlign{}%
+  \def\multAlign{}%
+  \def\attrAlignT{}%
+  \def\multAlignT{}%
+  %
+  \ifthenelse{\equal{\align}{left}}{%
+    \def\attrAlign{above right}%
+    \def\multAlign{below right}%
+  }{%
+    \ifthenelse{\equal{\align}{right}}{%
+      \def\attrAlign{above left}%
+      \def\multAlign{below left}%
+    }{}%
+  }%
+  %
+  \ifthenelse{\equal{\alignT}{left}}{%
+    \def\attrAlignT{above right}%
+    \def\multAlignT{below right}%
+  }{%
+    \ifthenelse{\equal{\alignT}{right}}{%
+      \def\attrAlignT{above left}%
+      \def\multAlignT{below left}%
+    }{}%
+  }%
+  %
+  % def stereotype
+  \ifthenelse{\equal{\stereo}{}}{%
+    \def\stereotype{}%
+  }{%
+    \def\stereotype{\guillemotleft\stereo\guillemotright}%
+  }%
+  %
+  % def anchors macros
+  \ifthenelse{\equal{\tikzumlSrcAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlSrcAnchor{}%
+  }{%
+    \let\tikzumlSrcAnchorold\tikzumlSrcAnchor%
+    \def\tikzumlSrcAnchor{.\tikzumlSrcAnchorold}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlDestAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlDestAnchor{}%
+  }{%
+    \let\tikzumlDestAnchorold\tikzumlDestAnchor%
+    \def\tikzumlDestAnchor{.\tikzumlDestAnchorold}%
+  }%
+  %
+  \setcounter{pos}{100*\real{\position}}%
+  \setcounter{posT}{100*\real{\positionT}}%
+  \setcounter{posStereo}{100*\real{\positionStereotype}}%
+  %
+  \def\pos{\position}%
+  \def\posT{\positionT}%
+  \def\posStereo{\positionStereotype}%
+  %
+  % straight line
+  \def\tikzumlControlNodesNum{1}%
+  %
+  \def\tikzumlFirstArc{node[midway, name=\relationName-1, anchor=center] {} }%
+  \def\tikzumlLastArc{node[midway, name=\relationName-3, anchor=center]{} }%
+  \def\posAttrName{}%
+  \def\posMultiplicity{}%
+  \def\posAttrNameT{}%
+  \def\posMultiplicityT{}%
+  %
+  \begin{pgfonlayer}{connections}%
+  \node (\relationName-2) at (#3) {};%
+  \end{pgfonlayer}%
+  %
+  \ifnum\theposStereo>100%
+    \pgfmathsetmacro{\posStereo}{(\theposStereo-100)/100}%
+    \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+  \else%
+    \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posStereo, anchor=center] {\stereotype} }%
+  \fi%
+  %
+  \ifnum\thepos>100%
+    \pgfmathsetmacro{\pos}{(\thepos-100)/100}%
+    \def\arcNum{2}%
+  \else%
+    \def\arcNum{1}%
+    \ifnum\thepos=100%
+      \def\posAttrName{above left}%
+      \def\posMultiplicity{below right}%
+    \fi%
+  \fi%
+  %
+  \ifnum\arcNum=1%
+    \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                           node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+  \fi%
+  \ifnum\arcNum=2%
+    \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\pos, \posAttrName, \attrAlign] {\attrName}%
+                                         node[pos=\pos, swap, \posMultiplicity, \multAlign] {\multiplicity} }%
+  \fi%
+  %
+  \ifnum\theposT>100%
+    \pgfmathsetmacro{\posT}{(\theposT-100)/100}%
+    \def\arcNumT{2}%
+  \else%
+    \def\arcNumT{1}%
+    \ifnum\theposT=100%
+      \def\posAttrNameT{above left}%
+      \def\posMultiplicityT{below right}%
+    \fi%
+  \fi%
+  %
+  \ifnum\arcNumT=1%
+    \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                           node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+  \fi%
+  \ifnum\arcNumT=2%
+    \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\posT, \posAttrNameT, \attrAlignT] {\attrNameT}%
+                                         node[pos=\posT, swap, \posMultiplicityT, \multAlignT] {\multiplicityT} }%
+  \fi%
+  %
+  \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlSrcAnchor) -- \tikzumlFirstArc (\relationName-2.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlDestAnchor) }%
+  
+  \begin{pgfonlayer}{connections}%
+  \draw[auto, \style, font=\tikzumlfont] \tikzumlPath ;%
+  \end{pgfonlayer}%
+  %
+  \stepcounter{tikzumlRelationNum}%
+}%
+
+% shortcuts for cnrelations
+\newcommand{\umlCNinherit}[4][]{\umlCNrelation[style={tikzuml inherit style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNimpl}[4][]{\umlCNrelation[style={tikzuml implements style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNreal}[4][]{\umlCNrelation[style={tikzuml implements style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNassoc}[4][]{\umlCNrelation[style={tikzuml association style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNuniassoc}[4][]{\umlCNrelation[style={tikzuml unidirectional association style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNaggreg}[4][]{\umlCNrelation[style={tikzuml aggregation style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNuniaggreg}[4][]{\umlCNrelation[style={tikzuml unidirectional aggregation style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNcompo}[4][]{\umlCNrelation[style={tikzuml composition style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNunicompo}[4][]{\umlCNrelation[style={tikzuml unidirectional composition style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNimport}[4][]{\umlCNrelation[style={tikzuml import style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNdep}[4][]{\umlCNrelation[style={tikzuml dependency style}, #1]{#2}{#3}{#4}}%
+\newcommand{\umlCNfriend}[4][]{%
+  \pgfkeys{/tikzuml/friendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlCNfriend, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/friendrelation/.cd, #1}%
+  \umlCNrelation[stereo=friend, style={tikzuml dependency style}, #1]{#2}{#3}{#4}%
+}%
+
+% define a note
+% arg : attached class
+%       label of the note
+% optional : x,y coordinates of the note
+%            width of the note
+%            draw, fill, text colors
+\newcommand{\umlnote}[3][]{
+  \pgfkeys{/tikzuml/note/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=3cm, geometry/.initial=--,%
+           weight/.initial=0.5, arm/.initial={auto},%
+           anchor1/.initial={tikzumlEmpty}, anchor2/.initial={tikzumlEmpty},%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillnotecolor,%
+           text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlnote, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/note/.cd, #1}%
+  \pgfkeys{/tikzuml/note/.cd,%
+           x/.get=\tikzumlnoteX, y/.get=\tikzumlnoteY, width/.get=\notetextwidth,%
+           geometry/.get=\tikzumlnotegeometry,%
+           weight/.get=\tikzumlnoteweight, arm/.get=\tikzumlnotearm,%
+           anchor1/.get=\tikzumlnoteSrcAnchor, anchor2/.get=\tikzumlnoteDestAnchor,%
+           draw/.get=\tikzumlnotedraw, fill/.get=\tikzumlnotefill,%
+           text/.get=\tikzumlnotetext}%
+  %
+  \def\tikzumlClassName{#2}%
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlClassNodeName{\tikzumlClassName}}\x%
+  %
+  % def anchors macros
+  \ifthenelse{\equal{\tikzumlnoteSrcAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlnoteSrcAnchor{}%
+  }{%
+    \let\tikzumlnoteSrcAnchorold\tikzumlnoteSrcAnchor%
+    \def\tikzumlnoteSrcAnchor{.\tikzumlnoteSrcAnchorold}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlnoteDestAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlnoteDestAnchor{}%
+  }{%
+    \let\tikzumlnoteDestAnchorold\tikzumlnoteDestAnchor%
+    \def\tikzumlnoteDestAnchor{.\tikzumlnoteDestAnchorold}%
+  }%
+  %
+  \node[text=\tikzumlnotetext, text width=\notetextwidth, font=\tikzumlfont, outer sep=0, inner xsep=1ex, inner ysep=3ex] (note-\thetikzumlNoteNum-coord) at (\tikzumlnoteX, \tikzumlnoteY) {#3};%
+  \draw (note-\thetikzumlNoteNum-coord.north east) node[name=note-\thetikzumlNoteNum-right-top, below=2ex, coordinate] {};%
+  \draw (note-\thetikzumlNoteNum-coord.north east) node[name=note-\thetikzumlNoteNum-top-right, left=2ex, coordinate] {};%
+  \draw[draw=\tikzumlnotedraw, fill=\tikzumlnotefill] (note-\thetikzumlNoteNum-coord.south west) -- (note-\thetikzumlNoteNum-coord.south east) -- (note-\thetikzumlNoteNum-right-top.base) -- (note-\thetikzumlNoteNum-top-right.base) -- (note-\thetikzumlNoteNum-coord.north west) -- cycle;%
+  \node[text=\tikzumlnotetext, text width=\notetextwidth, outer sep=0, inner xsep=1ex, inner ysep=3ex, font=\tikzumlfont] (note-\thetikzumlNoteNum) at (note-\thetikzumlNoteNum-coord) {#3};%
+    \draw[draw=\tikzumlnotedraw] (note-\thetikzumlNoteNum-right-top) -| (note-\thetikzumlNoteNum-top-right);%
+  %
+  \pgfmathsetmacro{\tikzumlnoteweightT}{1-\tikzumlnoteweight}%
+  \node (note-\thetikzumlNoteNum-middle) at (barycentric cs:note-\thetikzumlNoteNum-coord=\tikzumlnoteweight,\tikzumlClassNodeName=\tikzumlnoteweightT) {};%
+  %
+  \ifthenelse{\equal{\tikzumlnotegeometry}{--}%
+           \OR\equal{\tikzumlnotegeometry}{-|}%
+           \OR\equal{\tikzumlnotegeometry}{|-}}{%
+    \edef\tikzumlnotepath{\tikzumlnotegeometry}
+  }{%
+    \ifthenelse{\equal{\tikzumlnotegeometry}{-|-}}{%
+      \ifthenelse{\equal{\tikzumlnotearm}{auto}}{%
+        \edef\tikzumlnotepath{-- (note-\thetikzumlNoteNum-coord\tikzumlnoteSrcAnchor -| note-\thetikzumlNoteNum-middle.center) -- (note-\thetikzumlNoteNum-middle.center) -- (note-\thetikzumlNoteNum-middle.center |- \tikzumlClassNodeName\tikzumlnoteDestAnchor) --}%
+      }{%
+        \draw (note-\thetikzumlNoteNum-coord\tikzumlnoteSrcAnchor)+(\tikzumlnotearm,0) node[name=note-\thetikzumlNoteNum-tmp] {};
+        \edef\tikzumlnotepath{-- (note-\thetikzumlNoteNum-tmp.center) |-}%
+      }%
+    }{%
+      \ifthenelse{\equal{\tikzumlnotegeometry}{|-|}}{%
+        \ifthenelse{\equal{\tikzumlnotearm}{auto}}{%
+        \edef\tikzumlnotepath{-- (note-\thetikzumlNoteNum-coord\tikzumlnoteSrcAnchor |- note-\thetikzumlNoteNum-middle.center) -- (note-\thetikzumlNoteNum-middle.center) -- (note-\thetikzumlNoteNum-middle.center -| \tikzumlClassNodeName\tikzumlnoteDestAnchor) --}%
+      }{%
+        \draw (note-\thetikzumlNoteNum-coord\tikzumlnoteSrcAnchor)+(0,\tikzumlnotearm) node[name=note-\thetikzumlNoteNum-tmp] {};
+        \edef\tikzumlnotepath{-- (note-\thetikzumlNoteNum-tmp.center) -|}%
+      }%
+      
+      }{%
+        \errmessage{TIKZUML ERROR : Unknown geometry value !!! It should be in the following list : --, |-, -|, |-|, -|-}%
+      }%
+    }%
+  }%
+  %
+  \begin{pgfonlayer}{connections}%
+  \draw[dashed] (note-\thetikzumlNoteNum-coord\tikzumlnoteSrcAnchor) \tikzumlnotepath (\tikzumlClassNodeName\tikzumlnoteDestAnchor);%
+  \end{pgfonlayer}%
+  %
+  \stepcounter{tikzumlNoteNum}%
+}%
+
+% shortcuts for note with geometry
+\newcommand{\umlHVnote}[3][]{%
+  \pgfkeys{/tikzuml/note/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlHVnote, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/note/.cd, #1}%
+  \umlnote[geometry=-|, #1]{#2}{#3}%
+}%
+\newcommand{\umlVHnote}[3][]{%
+  \pgfkeys{/tikzuml/note/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlVHnote, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/note/.cd, #1}%
+  \umlnote[geometry=|-, #1]{#2}{#3}%
+}%
+\newcommand{\umlVHVnote}[3][]{%
+  \pgfkeys{/tikzuml/note/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlVHVnote, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/note/.cd, #1}%
+  \umlnote[geometry=|-|, #1]{#2}{#3}%
+}%
+\newcommand{\umlHVHnote}[3][]{%
+  \pgfkeys{/tikzuml/note/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlHVHnote, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/note/.cd, #1}%
+  \umlnote[geometry=-|-, #1]{#2}{#3}%
+}%
+
+% define a uml association class (command)
+% args : name of the class
+%        attributes of the class
+%        operations of the class
+% optional : x,y coordinates of the class
+%            width of the class node
+%            type of class (class, interface, typedef, enum)
+%            template parameters
+%            draw, fill, text colors
+\newcommand{\umlassocclass}[5][]{%
+  \pgfkeys{/tikzuml/assocclass/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=10ex, type/.initial=class,%
+           template/.initial={}, name/.initial={tikzumlEmpty}, geometry/.initial=--,%
+           weight/.initial=0.5, arm/.initial={auto},%
+           anchor1/.initial={tikzumlEmpty}, anchor2/.initial={tikzumlEmpty},%
+           draw/.initial=\tikzumldrawcolor,%
+           fill template/.initial=\tikzumlfilltemplatecolor,%
+           fill/.initial=\tikzumlfillclasscolor,%
+           text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlassocclass, invalid option \keyname}%
+           }}%
+  %
+  \pgfkeys{/tikzuml/assocclass/.cd,#1}%
+  \pgfkeys{/tikzuml/assocclass/.cd,%
+           x/.get=\umlassocclassX, y/.get=\umlassocclassY,%
+           width/.get=\umlassocclassMinimumWidth, type/.get=\umlassocclassType,%
+           template/.get=\umlassocclassTemplateParam,%
+           name/.get=\umlassocclassName, geometry/.get=\tikzumlassocclassgeometry,%
+           weight/.get=\tikzumlassocclassweight, arm/.get=\tikzumlassocclassarm,%
+           anchor1/.get=\tikzumlassocclassSrcAnchor,%
+           anchor2/.get=\tikzumlassocclassDestAnchor,%
+           draw/.get=\tikzumlassocclassdraw, fill/.get=\tikzumlassocclassfill,%
+           text/.get=\tikzumlassocclasstext, fill template/.get=\tikzumlassocclasstemplate}%
+  %
+  \ifthenelse{\equal{\umlassocclassType}{class}\OR\equal{\umlassocclassType}{abstract}}{%
+    \def\tikzumlAssocClassType{}%
+  }{%
+    \def\tikzumlAssocClassType{\guillemotleft\umlassocclassType\guillemotright \\}%
+  }%
+  %
+  \ifthenelse{\equal{\umlassocclassTemplateParam}{}}{%
+    \def\tikzumlAssocClassVPadding{}%
+    \def\tikzumlAssocClassHPadding{}%
+  }{%
+    \def\tikzumlAssocClassVPadding{\vspace{0.1em} \\}%
+    \def\tikzumlAssocClassHPadding{\hspace{0.5ex} $ $}%
+  }%
+  %
+  \def\tikzumlAssocClassName{#2}%
+  \def\tikzumlAssocClassRelationName{#3}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlAssocClassNodeName{\tikzumlAssocClassName}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlAssocClassRelationNodeName{\tikzumlAssocClassRelationName}}\x%
+  %
+  \ifthenelse{\equal{\umlassocclassName}{tikzumlEmpty}}{}{%
+    \def\tikzumlAssocClassNodeName{\umlassocclassName}%
+  }%
+  %
+  \StrSubstitute{\tikzumlAssocClassNodeName}{:}{@COLON@}[\tikzumlAssocClassNodeName]
+  %
+  \ifthenelse{\equal{\umlassocclassType}{abstract}}{%
+    \let\tikzumlAssocClassNameOld\tikzumlAssocClassName%
+    \def\tikzumlAssocClassName{{\it \tikzumlAssocClassNameOld}}%
+  }{}%
+  %
+  \def\tikzumlAssocClassPos{\umlassocclassX,\umlassocclassY}%
+  \def\tikzumlAssocClassAttributes{#4}%
+  \def\tikzumlAssocClassOperations{#5}%
+  %
+  % def anchors macros
+  \ifthenelse{\equal{\tikzumlassocclassSrcAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlassocclassSrcAnchor{}%
+  }{%
+    \let\tikzumlassocclassSrcAnchorold\tikzumlassocclassSrcAnchor%
+    \def\tikzumlassocclassSrcAnchor{.\tikzumlassocclassSrcAnchorold}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlassocclassDestAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlassocclassDestAnchor{}%
+  }{%
+    \let\tikzumlassocclassDestAnchorold\tikzumlassocclassDestAnchor%
+    \def\tikzumlassocclassDestAnchor{.\tikzumlassocclassDestAnchorold}%
+  }%
+  %
+  \node[tikzuml class style, draw=\tikzumlassocclassdraw, fill=\tikzumlassocclassfill, text=\tikzumlassocclasstext, font=\tikzumlfont, minimum width=\umlassocclassMinimumWidth] (\tikzumlAssocClassNodeName) at (\tikzumlAssocClassPos) {\begin{tabular}{c}\tikzumlAssocClassVPadding \tikzumlAssocClassType \tikzumlAssocClassHPadding \textbf{\tikzumlAssocClassName} \tikzumlAssocClassHPadding \end{tabular}%
+  \nodepart{second}%
+  \begin{tabular}{l}%
+  \tikzumlAssocClassAttributes%
+  \end{tabular}%
+  \nodepart{third}%
+  \begin{tabular}{l}%
+  \tikzumlAssocClassOperations%
+  \end{tabular}%
+  };%
+  %
+  \ifthenelse{\equal{\umlassocclassTemplateParam}{}}{}{%
+    \draw (\tikzumlAssocClassNodeName.north east) node[tikzuml template style, name=\tikzumlAssocClassNodeName-template, draw=\tikzumlassocclassdraw, fill=\tikzumlassocclasstemplate, text=\tikzumlassocclasstext, font=\tikzumlfont] {\umlassocclassTemplateParam};%
+  }%
+  %
+  \pgfmathsetmacro{\tikzumlassocclassweightT}{1-\tikzumlassocclassweight}
+  \node (\tikzumlAssocClassNodeName-middle) at (barycentric cs:\tikzumlAssocClassNodeName=\tikzumlassocclassweight,\tikzumlAssocClassRelationNodeName=\tikzumlassocclassweightT) {};%
+  %
+  \ifthenelse{\equal{\tikzumlassocclassgeometry}{--}\OR\equal{\tikzumlassocclassgeometry}{-|}\OR\equal{\tikzumlassocclassgeometry}{|-}}{%
+    \edef\tikzumlassocclasspath{\tikzumlassocclassgeometry}
+  }{%
+    \ifthenelse{\equal{\tikzumlassocclassgeometry}{-|-}}{%
+      \ifthenelse{\equal{\tikzumlassocclassarm}{auto}}{%
+        \edef\tikzumlassocclasspath{-- (\tikzumlAssocClassNodeName\tikzumlassocclassSrcAnchor -| \tikzumlAssocClassNodeName-middle.center) -- (\tikzumlAssocClassNodeName-middle.center) -- (\tikzumlAssocClassNodeName-middle.center |- \tikzumlAssocClassRelationNodeName\tikzumlassocclassDestAnchor) --}%
+      }{%
+        \draw (\tikzumlAssocClassNodeName\tikzumlassocclassSrcAnchor)+(\tikzumlassocclassarm,0) node[name=\tikzumlAssocClassNodeName-tmp] {};
+        \edef\tikzumlnotepath{-- (\tikzumlAssocClassNodeName-tmp.center) |-}%
+      }%
+    }{%
+      \ifthenelse{\equal{\tikzumlassocclassgeometry}{|-|}}{%
+        \ifthenelse{\equal{\tikzumlassocclassarm}{auto}}{%
+        \edef\tikzumlassocclasspath{-- (\tikzumlAssocClassNodeName\tikzumlassocclassSrcAnchor |- \tikzumlAssocClassNodeName-middle.center) -- (\tikzumlAssocClassNodeName-middle.center) -- (\tikzumlAssocClassNodeName-middle.center -| \tikzumlAssocClassRelationNodeName\tikzumlassocclassDestAnchor) --}%
+      }{%
+        \draw (\tikzumlAssocClassNodeName\tikzumlassocclassSrcAnchor)+(0,\tikzumlassocclassarm) node[name=\tikzumlAssocClassNodeName-tmp] {};
+        \edef\tikzumlassocclasspath{-- (\thetikzumlAssocClassNodeName-tmp.center) -|}%
+      }%
+      
+      }{%
+        \errmessage{TIKZUML ERROR : Unknown geometry value !!! It should be in the following list : --, |-, -|, |-|, -|-}%
+      }%
+    }%
+  }%
+  %
+  \begin{pgfonlayer}{connections}%
+  \draw[dashed] (\tikzumlAssocClassNodeName\tikzumlassocclassSrcAnchor) \tikzumlassocclasspath (\tikzumlAssocClassRelationNodeName\tikzumlassocclassDestAnchor);%
+  \end{pgfonlayer}%
+  %
+
+
+  %
+  % add to fit
+  \ifnum\c@tikzumlPackageLevel>0%
+    \edef\tikzumlPackageFitOld{\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname}%
+    \ifthenelse{\equal{\umlassocclassTemplateParam}{}}{%
+      \expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlAssocClassNodeName)(\tikzumlAssocClassNodeName-middle)}%
+    }{%
+      \expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlAssocClassNodeName) (\tikzumlAssocClassNodeName-template)(\tikzumlAssocClassNodeName-middle)}%
+    }%
+    \stepcounter{tikzumlPackageClassNum}%
+  \fi%
+}%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                     use case diagrams                   %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\tikzstyle{tikzuml usecase style}=[ellipse, text centered]%
+\tikzstyle{tikzuml actor style}=[ellipse, inner sep=0, outer sep=0]%
+
+\newcounter{tikzumlSystemUseCaseNum}%
+\newcounter{tikzumlSystemLevel}%
+\newcounter{tikzumlUseCaseNum}%
+\newcounter{tikzumlActorNum}%
+
+% define a system
+% arg : name
+% optional : x, y coordinates of the system
+%            draw, fill, text colors
+\newenvironment{umlsystem}[2][]{%
+  \gdef\tikzumlSystemFit{}%
+  \def\tikzumlSystemName{#2}%
+  \setcounter{tikzumlSystemUseCaseNum}{0}%
+  %
+  \pgfkeys{/tikzuml/system/.cd,%
+           x/.initial=0, y/.initial=0, x/.default=0, y/.default=0,%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillsystemcolor,%
+           text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlsystem, invalid option \keyname}%
+           }}%
+  %
+  \pgfkeys{/tikzuml/system/.cd, #1}%
+  \pgfkeys{/tikzuml/system/.cd,%
+           x/.get=\xshift, y/.get=\yshift,%
+           draw/.get=\tikzumlsystemdraw, fill/.get=\tikzumlsystemfill,%
+           text/.get=\tikzumlsystemtext}%
+  %
+  \stepcounter{tikzumlSystemLevel}%
+  %
+  \begin{scope}[xshift=\xshift cm, yshift=\yshift cm]%
+}{%
+  \addtocounter{tikzumlSystemLevel}{-1}%
+  % if contains no usecase, one define a fictive node to enable the fit option
+  \ifnum\c@tikzumlSystemUseCaseNum=0%
+    \node[inner xsep=10ex, inner ysep=1em] (\tikzumlSystemName-root) at (0,0) {};%
+    \xdef\tikzumlSystemFit{(\tikzumlSystemName-root)}%
+  \fi%
+  %
+  \begin{pgfonlayer}{background}%
+  \node[inner ysep=1em, inner xsep=2ex, fit = \tikzumlSystemFit] (\tikzumlSystemName-tmp) {};%
+  \node[text=\tikzumlsystemtext, font=\tikzumlfont] (\tikzumlSystemName-caption-tmp) at (\tikzumlSystemName-tmp.north) {\tikzumlSystemName};%
+  \node[draw=\tikzumlsystemdraw, fill=\tikzumlsystemfill, text=\tikzumlsystemtext, font=\tikzumlfont, inner ysep=1em, inner xsep=2ex, fit = (\tikzumlSystemName-tmp) (\tikzumlSystemName-caption-tmp)] (\tikzumlSystemName) {};%
+  \node[text=\tikzumlsystemtext, font=\tikzumlfont] (\tikzumlSystemName-caption) at (\tikzumlSystemName-caption-tmp.north) {\tikzumlSystemName};%
+  \end{pgfonlayer}%
+  \end{scope}%
+  %
+}%
+
+% define a use case
+% arg : label of the use case
+% optional : x, y coordinates of the use case
+%            name of the node
+%            draw, fill, text colors
+\newcommand{\umlusecase}[2][]{%
+  \stepcounter{tikzumlUseCaseNum}%
+  \pgfkeys{/tikzuml/usecase/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=auto,%
+           name/.initial=usecase-\thetikzumlUseCaseNum,%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillusecasecolor,%
+           text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlusecase, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/usecase/.cd, #1}%
+  \pgfkeys{/tikzuml/usecase/.cd,%
+           x/.get=\posx, y/.get=\posy, width/.get=\tikzumlusecasetextwidth,%
+           name/.get=\usecaseName,%
+           draw/.get=\tikzumlusecasedraw, fill/.get=\tikzumlusecasefill,%
+           text/.get=\tikzumlusecasetext}%
+  %
+  \def\tikzumlUseCaseText{#2}%
+  %
+  \def\tikzumlUseCasePos{\posx,\posy}%
+  %
+  \ifthenelse{\equal{\tikzumlusecasetextwidth}{auto}}{%
+    \node[tikzuml usecase style, draw=\tikzumlusecasedraw, fill=\tikzumlusecasefill, text=\tikzumlusecasetext, font=\tikzumlfont] (\usecaseName) at (\tikzumlUseCasePos) {\tikzumlUseCaseText};%
+  }{%
+    \node[tikzuml usecase style, draw=\tikzumlusecasedraw, fill=\tikzumlusecasefill, text=\tikzumlusecasetext, font=\tikzumlfont, text width=\tikzumlusecasetextwidth] (\usecaseName) at (\tikzumlUseCasePos) {\tikzumlUseCaseText};%
+  }%
+  %
+  % add to fit
+  \ifnum\c@tikzumlSystemLevel>0%
+    \let\tikzumlSystemFitOld\tikzumlSystemFit%
+    \xdef\tikzumlSystemFit{\tikzumlSystemFitOld (\usecaseName)}%
+    \stepcounter{tikzumlSystemUseCaseNum}%
+  \fi%
+}%
+
+% define the actor symbol
+% optional : global tikzpicture styles
+\newcommand{\picturedactor}[1]{%
+  \pgfkeys{/tikzuml/picactor/.cd, scale/.initial=1, .unknown/.code={}}%
+  \pgfkeys{/tikzuml/picactor/.cd,#1}%
+  \pgfkeys{/tikzuml/picactor/.cd, scale/.get=\tikzumlpicactorscale}%
+  %
+  \begin{tikzpicture}[#1]
+  \coordinate (head) at (0,4ex);
+  \coordinate (left-hand) at (-2ex,2ex);
+  \coordinate (right-hand) at (2ex,2ex);
+  \coordinate (left-foot) at (-2ex,-2ex);
+  \coordinate (right-foot) at (2ex,-2ex);
+  \coordinate (empty) at (0,-3ex);
+  \draw (empty) (0,0) -- (head);
+  \draw (left-hand) -- (right-hand);
+  \draw (0,0) -- (left-foot) (0,0) -- (right-foot);
+  \node[fill, draw, circle, inner sep=\tikzumlpicactorscale*0.3333ex, minimum size=\tikzumlpicactorscale*2ex] at (head) {};
+  \end{tikzpicture}
+}%
+
+% define an actor
+% arg : var name
+% optional : x, y coordinates of the actor
+%            name of the node
+%            draw, text colors
+\newcommand{\umlactor}[2][]{%
+  \stepcounter{tikzumlActorNum}%
+  \pgfkeys{/tikzuml/actor/.cd,%
+           x/.initial=0, y/.initial=0, scale/.initial=1, below/.initial=0.5cm,%
+           draw/.initial=\tikzumldrawcolor, text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlactor, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/actor/.cd, #1}%
+  \pgfkeys{/tikzuml/actor/.cd,%
+           x/.get=\posx, y/.get=\posy, scale/.get=\tikzumlactorscale,%
+           below/.get=\tikzumlactorbelow,%
+           draw/.get=\tikzumlactordraw, text/.get=\tikzumlactortext}%
+  %
+  \def\tikzumlActorName{#2}%
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlActorNodeName{\tikzumlActorName}}\x%
+  %
+  \def\tikzumlActorPos{\posx,\posy}%
+  %
+  \ifthenelse{\equal{}{tikzumlEmpty}}{}{}
+  \node[tikzuml actor style, text=\tikzumlactortext, font=\tikzumlfont] (\tikzumlActorNodeName) at (\tikzumlActorPos) {\picturedactor{scale=\tikzumlactorscale, fill=white, draw=\tikzumlactordraw, thick}};%
+  \node[text=\tikzumlactortext, font=\tikzumlfont, below=\tikzumlactorscale*\tikzumlactorbelow] at (\tikzumlActorNodeName) {\tikzumlActorName};%
+  %
+}%
+
+% shortcuts for include and extend relation
+\newcommand{\umlinclude}[3][]{%
+  \pgfkeys{/tikzuml/includerelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlinclude, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlinclude, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/includerelation/.cd, #1}%
+  \umlrelation[stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+\newcommand{\umlextend}[3][]{%
+  \pgfkeys{/tikzuml/extendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlextend, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlextend, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/extendrelation/.cd, #1}%
+  \umlrelation[stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlHVinclude}[3][]{%
+  \pgfkeys{/tikzuml/includerelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlHVinclude, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlHVinclude, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/includerelation/.cd, #1}%
+  \umlrelation[geometry=-|, stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+\newcommand{\umlHVextend}[3][]{%
+  \pgfkeys{/tikzuml/extendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlHVextend, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlHVextend, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/extendrelation/.cd, #1}%
+  \umlrelation[geometry=-|, stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlVHinclude}[3][]{%
+  \pgfkeys{/tikzuml/includerelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlVHinclude, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlVHinclude, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/includerelation/.cd, #1}%
+  \umlrelation[geometry=|-, stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+\newcommand{\umlVHextend}[3][]{%
+  \pgfkeys{/tikzuml/extendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR :in umlVHextend,  forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlVHextend, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/extendrelation/.cd, #1}%
+  \umlrelation[geometry=|-, stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlHVHinclude}[3][]{%
+  \pgfkeys{/tikzuml/includerelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlHVHinclude, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlHVHinclude, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/includerelation/.cd, #1}%
+  \umlrelation[geometry=-|-, stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+\newcommand{\umlHVHextend}[3][]{%
+  \pgfkeys{/tikzuml/extendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlHVHextend, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlHVHextend, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/extendrelation/.cd, #1}%
+  \umlrelation[geometry=-|-, stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlVHVinclude}[3][]{%
+  \pgfkeys{/tikzuml/includerelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlVHVinclude, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlVHVinclude, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/includerelation/.cd, #1}%
+  \umlrelation[geometry=|-|, stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+\newcommand{\umlVHVextend}[3][]{%
+  \pgfkeys{/tikzuml/extendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlVHVextend, forbidden option stereo}%
+             }{%
+               \ifthenelse{\equal{\keyname}{geometry}}{%
+                 \errmessage{TIKZUML ERROR : in umlVHVextend, forbidden option geometry}%
+               }{}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/extendrelation/.cd, #1}%
+  \umlrelation[geometry=|-|, stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlCNinclude}[4][]{%
+  \pgfkeys{/tikzuml/includerelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlCNinclude, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/includerelation/.cd, #1}%
+  \umlCNrelation[stereo=include, style={tikzuml dependency style}, #1]{#2}{#3}{#4}%
+}%
+
+\newcommand{\umlCNextend}[4][]{%
+  \pgfkeys{/tikzuml/extendrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlCNextend, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/extendrelation/.cd, #1}%
+  \umlCNrelation[stereo=extend, style={tikzuml dependency style}, #1]{#2}{#3}{#4}%
+}%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                      state diagrams                     %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\tikzstyle{tikzuml state style}=[rectangle split, rectangle split parts=2, rounded corners, inner xsep=1.5ex]%
+\tikzstyle{tikzuml transition style}=[color=\tikzumldrawcolor, rounded corners, -angle 45]%
+
+\newcounter{tikzumlStateJoinNum}%
+\newcounter{tikzumlStateDecisionNum}%
+\newcounter{tikzumlStateInitialNum}%
+\newcounter{tikzumlStateFinalNum}%
+\newcounter{tikzumlStateEnterNum}%
+\newcounter{tikzumlStateExitNum}%
+\newcounter{tikzumlStateEndNum}%
+\newcounter{tikzumlStateHistoryNum}%
+\newcounter{tikzumlStateDeepHistoryNum}%
+\newcounter{tikzumlStateLevel}%
+\newcounter{tikzumlStateSubStateNum}%
+\newcounter{tikzumlStateText}%
+
+\newcommand{\umlstatejoin}[1][]{%
+  \pgfkeys{/tikzuml/statejoin/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=3ex,%
+           name/.initial=statejoin-\thetikzumlStateJoinNum,%
+           color/.initial=\tikzumldrawcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlstatejoin, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/statejoin/.cd, #1}%
+  \pgfkeys{/tikzuml/statejoin/.cd,%
+           x/.get=\posx, y/.get=\posy, width/.get=\tikzumlstatejoinwidth,%
+           name/.get=\tikzumlstatejoinname, color/.get=\tikzumlstatejoincolor}%
+  %
+  \def\tikzumlStateJoinPos{\posx,\posy}%
+  %
+  \node[circle, minimum size=\tikzumlstatejoinwidth, draw=\tikzumlstatejoincolor, fill=\tikzumlstatejoincolor] (\tikzumlstatejoinname) at (\tikzumlStateJoinPos) {};%
+  %
+  % add to fit
+  \ifnum\c@tikzumlStateLevel>0%
+    \edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlstatejoinname)}%
+    \stepcounter{tikzumlStateSubStateNum}%
+  \fi%
+  \stepcounter{tikzumlStateJoinNum}%
+}%
+
+\newcommand{\umlstatedecision}[1][]{%
+  \pgfkeys{/tikzuml/statedecision/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=3ex,%
+           name/.initial=statedecision-\thetikzumlStateDecisionNum,%
+           color/.initial=\tikzumldrawcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlstatedecision, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/statedecision/.cd, #1}%
+  \pgfkeys{/tikzuml/statedecision/.cd,%
+           x/.get=\posx, y/.get=\posy, width/.get=\tikzumlstatedecisionwidth,%
+           name/.get=\tikzumlstatedecisionname, color/.get=\tikzumlstatedecisioncolor}%
+  %  
+  \def\tikzumlStateDecisionPos{\posx,\posy}%
+  %
+  \node[rectangle, rotate=45, minimum size=\tikzumlstatedecisionwidth, draw=\tikzumlstatedecisioncolor] (\tikzumlstatedecisionname) at (\tikzumlStateDecisionPos) {};%
+  %
+  % add to fit
+  \ifnum\c@tikzumlStateLevel>0%
+    \edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlstatedecisionname)}%
+    \stepcounter{tikzumlStateSubStateNum}%
+  \fi%
+  \stepcounter{tikzumlStateDecisionNum}%
+}%
+
+\newcommand{\umlstateinitial}[1][]{%
+  \pgfkeys{/tikzuml/stateinitial/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=5ex,%
+           name/.initial=stateinitial-\thetikzumlStateInitialNum,%
+           color/.initial=\tikzumldrawcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlstateinitial, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/stateinitial/.cd, #1}%
+  \pgfkeys{/tikzuml/stateinitial/.cd,%
+           x/.get=\posx, y/.get=\posy, width/.get=\tikzumlstateinitialwidth,%
+           name/.get=\tikzumlstateinitialname, color/.get=\tikzumlstateinitialcolor}%
+  %  
+  \def\tikzumlStateInitialPos{\posx,\posy}%
+  %
+  \node[circle, minimum size=\tikzumlstateinitialwidth, fill=\tikzumlstateinitialcolor] (\tikzumlstateinitialname) at (\tikzumlStateInitialPos) {};%
+  %
+  % add to fit
+  \ifnum\c@tikzumlStateLevel>0%
+    \edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlstateinitialname)}%
+    \stepcounter{tikzumlStateSubStateNum}%
+  \fi%
+  \stepcounter{tikzumlStateInitialNum}%
+}%
+
+\newcommand{\umlstatefinal}[1][]{%
+  \pgfkeys{/tikzuml/statefinal/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=5.5ex,%
+           name/.initial=statefinal-\thetikzumlStateFinalNum,%
+           color/.initial=\tikzumldrawcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlstatefinal, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/statefinal/.cd, #1}%
+  \pgfkeys{/tikzuml/statefinal/.cd, x/.get=\posx, y/.get=\posy, width/.get=\tikzumlstatefinalwidth,%
+                                       name/.get=\tikzumlstatefinalname, color/.get=\tikzumlstatefinalcolor}%
+  %  
+  \def\tikzumlStateFinalPos{\posx,\posy}%
+  %
+  \node[circle, minimum size=\tikzumlstatefinalwidth, draw=\tikzumlstatefinalcolor, fill=\tikzumlstatefinalcolor, double, double distance=0.1cm] (\tikzumlstatefinalname) at (\tikzumlStateFinalPos) {};%
+  %
+  % add to fit
+  \ifnum\c@tikzumlStateLevel>0%
+    \edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlstatefinalname)}%
+    \stepcounter{tikzumlStateSubStateNum}%
+  \fi%
+  \stepcounter{tikzumlStateFinalNum}%
+}%
+
+\newcommand{\umlstateenter}[1][]{%
+  \pgfkeys{/tikzuml/stateenter/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=5ex,%
+           name/.initial=stateenter-\thetikzumlStateEnterNum,%
+           color/.initial=\tikzumldrawcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlstateenter, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/stateenter/.cd, #1}%
+  \pgfkeys{/tikzuml/stateenter/.cd,%
+           x/.get=\posx, y/.get=\posy, width/.get=\tikzumlstateenterwidth,%
+           name/.get=\tikzumlstateentername, color/.get=\tikzumlstateentercolor}%
+  %  
+  \def\tikzumlStateEnterPos{\posx,\posy}%
+  %
+  \node[circle, minimum size=\tikzumlstateenterwidth, draw=\tikzumlstateentercolor] (\tikzumlstateentername) at (\tikzumlStateEnterPos) {};%
+  %
+  % add to fit
+  \ifnum\c@tikzumlStateLevel>0%
+    \edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlstateentername)}%
+    \stepcounter{tikzumlStateSubStateNum}%
+  \fi%
+  \stepcounter{tikzumlStateEnterNum}%
+}%
+
+\newcommand{\umlstateexit}[1][]{%
+  \pgfkeys{/tikzuml/stateexit/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=5ex,%
+           name/.initial=stateexit-\thetikzumlStateExitNum,%
+           color/.initial=\tikzumldrawcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlstateexit, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/stateexit/.cd, #1}%
+  \pgfkeys{/tikzuml/stateexit/.cd,%
+           x/.get=\posx, y/.get=\posy, width/.get=\tikzumlstateexitwidth,%
+           name/.get=\tikzumlstateexitname, color/.get=\tikzumlstateexitcolor}%
+  %  
+  \def\tikzumlStateExitPos{\posx,\posy}%
+  %
+  \node[circle, minimum size=\tikzumlstateexitwidth, draw=\tikzumlstateexitcolor] (\tikzumlstateexitname) at (\tikzumlStateExitPos) {};%
+  \draw[draw=\tikzumlstateexitcolor] (\tikzumlstateexitname.north east) -- (\tikzumlstateexitname.south west) (\tikzumlstateexitname.north west) -- (\tikzumlstateexitname.south east);
+  %
+  % add to fit
+  \ifnum\c@tikzumlStateLevel>0%
+    \edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlstateexitname)}%
+    \stepcounter{tikzumlStateSubStateNum}%
+  \fi%
+  \stepcounter{tikzumlStateExitNum}%
+}%
+
+\newcommand{\umlstateend}[1][]{%
+  \pgfkeys{/tikzuml/stateend/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=5ex,%
+           name/.initial=stateend-\thetikzumlStateEndNum, color/.initial=\tikzumldrawcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlstateend, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/stateend/.cd, #1}%
+  \pgfkeys{/tikzuml/stateend/.cd, x/.get=\posx, y/.get=\posy, width/.get=\tikzumlstateendwidth,%
+                                       name/.get=\tikzumlstateendname, color/.get=\tikzumlstateendcolor}%
+  %  
+  \def\tikzumlStateEndPos{\posx,\posy}%
+  %
+  \node[circle, minimum size=\tikzumlstateendwidth] (\tikzumlstateendname) at (\tikzumlStateEndPos) {};%
+  \draw[draw=\tikzumlstateendcolor] (\tikzumlstateendname.north east) -- (\tikzumlstateendname.south west) (\tikzumlstateendname.north west) -- (\tikzumlstateendname.south east);
+  %
+  % add to fit
+  \ifnum\c@tikzumlStateLevel>0%
+    \edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlstateendname)}%
+    \stepcounter{tikzumlStateSubStateNum}%
+  \fi%
+  \stepcounter{tikzumlStateEndNum}%
+}%
+
+\newcommand{\picturedhistory}[1]{%
+  \begin{tikzpicture}[#1]
+  \draw[thick] (-0.1cm,-0.15cm) -- (-0.1cm,0.15cm)
+               (-0.1cm,0) -- (0.1cm,0)
+               (0.1cm,-0.15cm) -- (0.1cm,0.15cm);
+  \end{tikzpicture}
+}%
+
+\newcommand{\umlstatehistory}[1][]{%
+  \pgfkeys{/tikzuml/statehistory/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=5ex,%
+           name/.initial=statehistory-\thetikzumlStateHistoryNum,%
+           color/.initial=\tikzumldrawcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlstatehistory, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/statehistory/.cd, #1}%
+  \pgfkeys{/tikzuml/statehistory/.cd, x/.get=\posx, y/.get=\posy, width/.get=\tikzumlstatehistorywidth,%
+                                       name/.get=\tikzumlstatehistoryname, color/.get=\tikzumlstatehistorycolor}%
+  %
+  \def\tikzumlStateHistoryPos{\posx,\posy}%
+  %
+  \node[circle, minimum size=\tikzumlstatehistorywidth, draw=\tikzumlstatehistorycolor] (\tikzumlstatehistoryname) at (\tikzumlStateHistoryPos) {\picturedhistory{draw=\tikzumlstatehistorycolor}};%
+  %
+  % add to fit
+  \ifnum\c@tikzumlStateLevel>0%
+    \edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlstatehistoryname)}%
+    \stepcounter{tikzumlStateSubStateNum}%
+  \fi%
+  \stepcounter{tikzumlStateHistoryNum}%
+}%
+
+\newcommand{\pictureddeephistory}[1]{%
+  \begin{tikzpicture}[#1]
+  \draw[thick] (-0.1cm,-0.15cm) -- (-0.1cm,0.15cm)
+               (-0.1cm,0) -- (0.1cm,0)
+               (0.1cm,-0.15cm) -- (0.1cm,0.15cm)
+               (0.23cm,0.19cm) -- (0.23cm,0.11cm)
+               (0.20cm,0.17cm) -- (0.26cm,0.13cm)
+               (0.20cm,0.13cm) -- (0.26cm,0.17cm);
+  \end{tikzpicture}
+}%
+
+\newcommand{\umlstatedeephistory}[1][]{%
+  \pgfkeys{/tikzuml/statedeephistory/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=5ex,%
+           name/.initial=statedeephistory-\thetikzumlStateDeepHistoryNum,%
+           color/.initial=\tikzumldrawcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlstatedeephistory, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/statedeephistory/.cd, #1}%
+  \pgfkeys{/tikzuml/statedeephistory/.cd, x/.get=\posx, y/.get=\posy, width/.get=\tikzumlstatedeephistorywidth,%
+                                       name/.get=\tikzumlstatedeephistoryname, color/.get=\tikzumlstatedeephistorycolor}%
+  %  
+  \def\tikzumlStateDeepHistoryPos{\posx,\posy}%
+  %
+  \node[circle, minimum size=\tikzumlstatedeephistorywidth, draw=\tikzumlstatedeephistorycolor] (\tikzumlstatedeephistoryname) at (\tikzumlStateDeepHistoryPos) {\pictureddeephistory{draw=\tikzumlstatedeephistorycolor}};%
+  %
+  % add to fit
+  \ifnum\c@tikzumlStateLevel>0%
+    \edef\tikzumlStateFitOld{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitOld (\tikzumlstatedeephistoryname)}%
+    \stepcounter{tikzumlStateSubStateNum}%
+  \fi%
+  \stepcounter{tikzumlStateDeepHistoryNum}%
+}%
+
+% define a uml state
+% args : name of the state
+%         content of the state
+% optional args : x,y coordinates of the state
+%                 width of the state node
+\newenvironment{umlstate}[2][]{%
+  \ifnum\thetikzumlStateLevel>0%
+    \let\tikzumlState@nameold\tikzumlState@fitname%
+    \let\tikzumlState@parentold\tikzumlState@parent%
+    \edef\tikzumlState@parent{\tikzumlState@parentold @@\tikzumlState@nameold}%
+  \else%
+    \def\tikzumlState@parent{}%
+  \fi%
+  
+  \stepcounter{tikzumlStateLevel}%
+  
+  \pgfkeys{/tikzuml/state/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=8ex, type/.initial=class,%
+           name/.initial={},%
+           entry/.initial={}, do/.initial={}, exit/.initial={},%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillstatecolor,%
+           text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlstate, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/state/.cd, #1}%
+  \pgfkeys{/tikzuml/state/.cd,%
+           x/.get=\tikzumlstateX, y/.get=\tikzumlstateY, width/.get=\umlstateMinimumWidth,%
+           type/.get=\umlstateType, name/.get=\umlstateName,%
+           entry/.get=\umlstateentry, do/.get=\umlstatedo, exit/.get=\umlstateexit,%
+           draw/.get=\tikzumlstatedraw, fill/.get=\tikzumlstatefill,%
+           text/.get=\tikzumlstatetext}%
+  %
+  \ifthenelse{\equal{\umlstateName}{}}{%
+    \edef\tikzumlState@name{#2}%
+  }{%
+    \edef\tikzumlState@name{\umlstateName}%
+  }%
+  %
+  \begingroup%
+    \def\_{@}\edef\x{\endgroup%
+      \def\noexpand\tikzumlState@fitname{\tikzumlState@name}}\x%
+  %
+  \let\tikzumlState@nodeNameold\tikzumlState@nodeName%
+  \def\tikzumlState@caption{#2}%
+  % 
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlState@nodeName{\tikzumlState@name}}\x%
+  %
+  \expandafter\gdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{}%
+  %
+  \setcounter{tikzumlStateSubStateNum}{0}%
+  \setcounter{tikzumlStateText}{0}%
+  %
+  \def\tikzumlStateText{tikzumlEmpty}%
+  \begin{scope}[xshift=\tikzumlstateX cm, yshift=\tikzumlstateY cm]%
+}{%
+  %  
+  \def\tikzumlstaterootlabel{\phantom{\tikzumlState@nodeName}}%
+  %
+  \def\tikzumlstaterootinnerysep{0.5ex}%
+  \def\tikzumlstatebodyinnerysep{2ex}%
+  %
+  \ifthenelse{\equal{\umlstateentry}{}}{}{%
+    \def\tikzumlStateText{entry/\umlstateentry}%
+    \setcounter{tikzumlStateText}{1}%
+    \ifnum\c@tikzumlStateSubStateNum=0%
+      \def\tikzumlstatebodyinnerysep{0}%
+      \def\tikzumlstaterootinnerysep{0}%
+    \fi%
+  }%
+  \ifthenelse{\equal{\umlstatedo}{}}{}{%
+    \ifnum\c@tikzumlStateText=0%
+      \def\tikzumlStateText{do/\umlstatedo}%
+    \else%
+      \let\tikzumlStateTextOld\tikzumlStateText%
+      \def\tikzumlStateText{\tikzumlStateTextOld \\ do/\umlstatedo}%
+    \fi%
+    \setcounter{tikzumlStateText}{1}%
+    \ifnum\c@tikzumlStateSubStateNum=0%
+      \def\tikzumlstatebodyinnerysep{0}%
+      \def\tikzumlstaterootinnerysep{0}%
+    \fi%
+  }%
+  \ifthenelse{\equal{\umlstateexit}{}}{}{%
+    \ifnum\c@tikzumlStateText=0%
+      \def\tikzumlStateText{exit/\umlstateexit}%
+    \else%
+      \let\tikzumlStateTextOld\tikzumlStateText%
+      \def\tikzumlStateText{\tikzumlStateTextOld \\ exit/\umlstateexit}%
+    \fi%
+    \setcounter{tikzumlStateText}{1}%
+    \ifnum\c@tikzumlStateSubStateNum=0%
+      \def\tikzumlstatebodyinnerysep{0}%
+      \def\tikzumlstaterootinnerysep{0}%
+    \fi%
+  }%
+  %
+  \addtocounter{tikzumlStateLevel}{-1}%
+  \begin{pgfonlayer}{state\thetikzumlStateLevel}%
+  %
+  % if contains nothing, one define a fictive node to enable the fit option
+  \ifnum\c@tikzumlStateSubStateNum=0%
+    \node[inner ysep=\tikzumlstaterootinnerysep, minimum width=\umlstateMinimumWidth] (\tikzumlState@nodeName-root) at (0,0) {\tikzumlstaterootlabel};%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{(\tikzumlState@nodeName-root)}%
+  \fi%
+  %
+  \ifnum\c@tikzumlStateLevel>0%
+    \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent\endcsname}%
+    \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent\endcsname{\tikzumlStateFitTmp (\tikzumlState@nodeName-body) (\tikzumlState@nodeName-caption)}%
+    \stepcounter{tikzumlStateSubStateNum}%
+  \fi%
+  %
+  \node[inner xsep=2ex, inner ysep=\tikzumlstatebodyinnerysep, fit = \csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname] (\tikzumlState@nodeName-body) {};%
+  \def\tikzumlState@orig{body}%
+  \ifnum\c@tikzumlStateText=1%
+    \node[above=0] (\tikzumlState@nodeName-texttmp) at (\tikzumlState@nodeName-\tikzumlState@orig.north) {\begin{tabular}{l}\tikzumlStateText \end{tabular}};%
+    \def\tikzumlState@orig{texttmp}%
+  \fi%
+  \node[above] (\tikzumlState@nodeName-captiontmp) at (\tikzumlState@nodeName-\tikzumlState@orig.north) {\tikzumlState@caption};%
+  \node[rounded corners, draw=\tikzumlstatedraw, fill=\tikzumlstatefill, name=\tikzumlState@nodeName, fit=(\tikzumlState@nodeName-body) (\tikzumlState@nodeName-captiontmp)] {};%
+  \ifnum\c@tikzumlStateText=1%
+    \node (\tikzumlState@nodeName-text) at (\tikzumlState@nodeName-texttmp) {\begin{tabular}{l}\tikzumlStateText \end{tabular}};%
+  \fi%
+  \node (\tikzumlState@nodeName-caption) at (\tikzumlState@nodeName-captiontmp) {\tikzumlState@caption};%
+  \draw (\tikzumlState@nodeName-caption.south -| \tikzumlState@nodeName.north west) -- (\tikzumlState@nodeName-caption.south -| \tikzumlState@nodeName.north east);%
+  \end{pgfonlayer}%
+  \end{scope}%
+}%
+
+% shortcut for empty state
+\newcommand{\umlbasicstate}[2][]{\begin{umlstate}[#1]{#2} \end{umlstate}}%
+
+% command to add text in a state
+\newcommand{\umlstatetext}[1]{%
+  \def\tikzumlStateText{#1}%
+  \setcounter{tikzumlStateText}{1}%
+}%
+
+% shortcuts for state transitions macros
+\newcommand{\umltrans}[3][]{%
+  \ifthenelse{\equal{#2}{#3}}{%
+    \umlrelation[style={tikzuml transition style}, recursive mode=transition, #1]{#2}{#3}%
+  }{%
+    \umlrelation[style={tikzuml transition style}, #1]{#2}{#3}%
+  }%
+}%
+\newcommand{\umlHVtrans}[3][]{\umlHVrelation[style={tikzuml transition style}, #1]{#2}{#3}}%
+\newcommand{\umlVHtrans}[3][]{\umlVHrelation[style={tikzuml transition style}, #1]{#2}{#3}}%
+\newcommand{\umlVHVtrans}[3][]{\umlVHVrelation[style={tikzuml transition style}, #1]{#2}{#3}}%
+\newcommand{\umlHVHtrans}[3][]{\umlHVHrelation[style={tikzuml transition style}, #1]{#2}{#3}}%
+\newcommand{\umlCNtrans}[4][]{\umlCNrelation[style={tikzuml transition style}, #1]{#2}{#3}{#4}}%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                     sequence diagrams                   %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\tikzstyle{tikzuml synchron-msg style}=[color=\tikzumldrawcolor, -triangle 45]%
+\tikzstyle{tikzuml asynchron-msg style}=[color=\tikzumldrawcolor, -angle 45]%
+\tikzstyle{tikzuml return-msg style}=[color=\tikzumldrawcolor, dashed, -angle 45]%
+\tikzstyle{tikzuml call return style}=[color=\tikzumldrawcolor, dashed, -angle 45]%
+\tikzstyle{tikzuml activity style}=[inner xsep=1ex, inner ysep=1ex]%
+
+\newcounter{tikzumlObjectNum}
+\newcounter{tikzumlCallLevel}
+\newcounter{tikzumlCallNum}
+\newcounter{tikzumlFragmentLevel}
+\newcounter{tikzumlFragmentLevelNum}
+\newcounter{tikzumlFragmentNum}
+\newcounter{tikzumlFragmentPartNum}
+\newcounter{tikzumlCallStartFragmentNum}
+\newcounter{tikzumlCallEndFragmentNum}
+
+% define a sequence diagram
+% 
+\newenvironment{umlseqdiag}{%
+  \gdef\tikzumlInCreateCall{0}%
+  \setcounter{tikzumlObjectNum}{0}%
+  \setcounter{tikzumlCallLevel}{0}%
+  \setcounter{tikzumlCallNum}{0}%
+  \setcounter{tikzumlFragmentLevel}{0}%
+  \setcounter{tikzumlFragmentLevelNum}{0}%
+  \setcounter{tikzumlFragmentNum}{0}%
+  \setcounter{tikzumlFragmentPartNum}{0}%
+  \setcounter{tikzumlCallStartFragmentNum}{0}%
+  \setcounter{tikzumlCallEndFragmentNum}{0}%
+  %
+  \ifx \@umlactor \@empty
+    \newcommand{\umlactor}[2][]{%
+      \pgfkeys{/tikzuml/actorobj/.cd,%
+               .unknown/.code={%
+                 \let\keyname=\pgfkeyscurrentname%
+                 \ifthenelse{\equal{\keyname}{stereo}}{%
+                   \errmessage{TIKZUML ERROR : in umlactor, forbidden option stereo}%
+                 }{}%
+               }}%
+      %
+      \pgfkeys{/tikzuml/actorobj/.cd, ##1}%
+      \umlobject[stereo=actor, ##1]{##2}%
+    }%
+  \else%
+    \renewcommand{\umlactor}[2][]{
+      \pgfkeys{/tikzuml/actorobj/.cd,%
+               .unknown/.code={%
+                 \let\keyname=\pgfkeyscurrentname%
+                 \ifthenelse{\equal{\keyname}{stereo}}{%
+                   \errmessage{TIKZUML ERROR : in umlactor, forbidden option stereo}%
+                 }{}%
+               }}%
+      %
+      \pgfkeys{/tikzuml/actorobj/.cd, ##1}%
+      \umlobject[stereo=actor, ##1]{##2}%
+    }%
+  \fi%
+  \begin{scope}[font=\tikzumlfont]%
+}{%
+  % draw lifelines of each object
+  \begin{pgfonlayer}{lifelines}%
+  \foreach \id in \tikzumlIdList {%
+    \draw (\csname tikzumlLastChild@\id \endcsname)+(0,-2.5ex) node[inner sep=0, name=end-\id] {};%
+    \draw[dotted] (\id) -- (end-\id);%
+  }%
+  \end{pgfonlayer}%
+  \end{scope}%
+}%
+
+% define the actor symbol
+% optional : global tikzpicture styles
+\newcommand{\pictureddatabase}[1]{%
+  \pgfkeys{/tikzuml/database/.cd, scale/.initial=1, .unknown/.code={}}%
+  \pgfkeys{/tikzuml/database/.cd,#1}%
+  \pgfkeys{/tikzuml/database/.cd, scale/.get=\tikzumldatabasescale}%
+  %
+  \begin{tikzpicture}[#1]
+  \node[fill, draw, ellipse, minimum width=\tikzumldatabasescale*4ex, minimum height=\tikzumldatabasescale*2ex, inner sep=0] (bottom) at (0,-2ex) {};
+  \node[fill, draw, ellipse, minimum width=\tikzumldatabasescale*4ex, minimum height=\tikzumldatabasescale*2ex, inner sep=0] (top) at (0,4ex) {};
+  \fill (bottom.west) rectangle (top.east);
+  \begin{scope}
+  \clip (-3.5ex,-0.5ex) rectangle (3.5ex,2.5ex);
+  \node[draw, dashed, ellipse, minimum width=\tikzumldatabasescale*4ex, minimum height=\tikzumldatabasescale*2ex, inner sep=0] (bottom2) at (0,-2ex) {};
+  \end{scope}
+  \node[draw, ellipse, minimum width=\tikzumldatabasescale*4ex, minimum height=\tikzumldatabasescale*2ex, inner sep=0] (top2) at (0,4ex) {};
+  \draw (bottom.west) -- (top.west) (bottom.east) -- (top.east);
+  \end{tikzpicture}
+}%
+
+% define the actor symbol
+% optional : global tikzpicture styles
+\newcommand{\picturedentity}[1]{%
+  \pgfkeys{/tikzuml/entity/.cd, scale/.initial=1, .unknown/.code={}}%
+  \pgfkeys{/tikzuml/entity/.cd,#1}%
+  \pgfkeys{/tikzuml/entity/.cd, scale/.get=\tikzumlentityscale}%
+  %
+  \begin{tikzpicture}[#1]%
+  \node[fill, draw, circle, inner sep=0, minimum size=\tikzumlentityscale*5ex] (center) at (0,0) {};%
+  \draw (center.south) node[coordinate, name=bottom] {};%
+  \draw (bottom)+(-2ex,0) node[coordinate, name=bottom-left] {};%
+  \draw (bottom)+(2ex,0) node[coordinate, name=bottom-right] {};%
+  \draw (center) -- (bottom);%
+  \draw (bottom-left) -- (bottom-right);%
+  \end{tikzpicture}%
+}%
+
+% define the actor symbol
+% optional : global tikzpicture styles
+\newcommand{\picturedboundary}[1]{%
+  \pgfkeys{/tikzuml/boundary/.cd, scale/.initial=1, .unknown/.code={}}%
+  \pgfkeys{/tikzuml/boundary/.cd,#1}%
+  \pgfkeys{/tikzuml/boundary/.cd, scale/.get=\tikzumlboundaryscale}%
+  %
+  \begin{tikzpicture}[#1]
+  \node[fill, draw, circle, inner sep=0, minimum size=\tikzumlboundaryscale*5ex] (center) at (0,0) {};
+  \draw (center.west)+(-0.8ex,0) node[coordinate, name=left] {};
+  \draw (left)+(0,0.2ex) node[coordinate, name=left-top] {};
+  \draw (left)+(0,-0.2ex) node[coordinate, name=left-bottom] {};
+  \draw (center) -- (left);
+  \draw (left-top) -- (left-bottom);
+  \end{tikzpicture}
+}%
+
+% define the actor symbol
+% optional : global tikzpicture styles
+\newcommand{\picturedcontrol}[1]{%
+  \pgfkeys{/tikzuml/control/.cd, scale/.initial=1, .unknown/.code={}}%
+  \pgfkeys{/tikzuml/control/.cd,#1}%
+  \pgfkeys{/tikzuml/control/.cd, scale/.get=\tikzumlcontrolscale}%
+  %
+  \begin{tikzpicture}[#1, decoration={markings, mark=at position 0.25 with {\arrow{>}}}]
+  \node[fill, draw, circle, inner sep=0, minimum size=\tikzumlcontrolscale*5ex, postaction={decorate}] (center) at (0,0) {};
+  \end{tikzpicture}
+}% 
+
+% define a uml object for a sequence diagram
+% args : name of the object
+% optional : x, y coordinates of the object
+%            stereotype of the object (object, actor, database, boundary, control, entity, multiobject)
+%            class of the object
+%            draw, fill, text colors
+\newcommand{\umlobject}[2][]{
+  \stepcounter{tikzumlObjectNum}%
+  %
+  \edef\tikzumlobject@ddot{:}%
+  \pgfkeys{/tikzuml/obj/.cd,%
+           x/.initial={tikzumlEmpty}, y/.initial=0, stereo/.initial=object,%
+           class/.initial={}, scale/.initial=1,%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillobjectcolor,%
+           text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{no ddots}}{%
+               \edef\tikzumlobject@ddot{}%
+             }{%
+               \errmessage{TIKZUML ERROR : in umlobj, invalid option \keyname}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/obj/.cd, #1}%
+  \pgfkeys{/tikzuml/obj/.cd,%
+           x/.get=\tikzumlobjectX, y/.get=\tikzumlobjectY,%
+           stereo/.get=\tikzumlobjectstereo, class/.get=\tikzumlobjectclass,%
+           scale/.get=\tikzumlobjectscale,%
+           draw/.get=\tikzumlobjectdraw, fill/.get=\tikzumlobjectfill,%
+           text/.get=\tikzumlobjecttext}%
+  %
+  \ifthenelse{\equal{\tikzumlobjectX}{tikzumlEmpty}}{%
+    \pgfmathsetmacro{\tikzumlobjectX}{4*(\thetikzumlObjectNum-1)}%
+  }{}%
+  %
+  \def\tikzumlObjectName{#2}%
+  \expandafter\xdef\csname tikzumlLastChild@\tikzumlObjectName \endcsname{\tikzumlObjectName}%
+  %
+  \ifnum\thetikzumlObjectNum=1%
+    \xdef\tikzumlIdList{\tikzumlObjectName}%
+  \else%
+    \let\tikzumlIdListOld\tikzumlIdList%
+    \xdef\tikzumlIdList{\tikzumlIdListOld,\tikzumlObjectName}%
+  \fi%
+  %
+  \tikzstyle{tikzuml object box style}=[rectangle, text=\tikzumlobjecttext, font=\tikzumlfont]%
+  %
+  \ifthenelse{\equal{\tikzumlobjectstereo}{object}}{%
+    \tikzstyle{tikzuml object box style}+=[draw=\tikzumlobjectdraw, fill=\tikzumlobjectfill]%
+  }{%
+    \ifthenelse{\equal{\tikzumlobjectstereo}{multi}}{%
+      \tikzstyle{tikzuml object box style}+=[fill=\tikzumlobjectfill]%
+    }{}%
+  }%
+  %
+  \ifnum\tikzumlInCreateCall=1%
+    \draw (\tikzumlCreateCallObjectSrc -| \tikzumlobjectX,0) node[tikzuml object box style] (\tikzumlObjectName) {\tikzumlObjectName\tikzumlobject@ddot\tikzumlobjectclass};%
+  \else%
+    \node[tikzuml object box style] (\tikzumlObjectName) at (\tikzumlobjectX,\tikzumlobjectY) {\tikzumlObjectName\tikzumlobject@ddot\tikzumlobjectclass};%
+  \fi%
+  %
+  \ifthenelse{\equal{\tikzumlobjectstereo}{multi}}{%
+    \draw (\tikzumlObjectName.north east)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-tr, coordinate] {};
+    \draw (\tikzumlObjectName.north west)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-tl, coordinate] {};
+    \draw (\tikzumlObjectName.south east)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-br, coordinate] {};
+    \draw (\tikzumlObjectName-tr)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-ttr, coordinate] {};
+    \draw (\tikzumlObjectName-tl)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-ttl, coordinate] {};
+    \draw (\tikzumlObjectName-br)+(0.4ex,0.4ex) node[name=\tikzumlObjectName-tbr, coordinate] {};
+    \fill[fill=\tikzumlobjectfill] (\tikzumlObjectName-ttl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-ttl) -- (\tikzumlObjectName-ttr) -- (\tikzumlObjectName-tbr) -- (\tikzumlObjectName-tbr -| \tikzumlObjectName.east) -- (\tikzumlObjectName.north east) -- (\tikzumlObjectName-ttl |- \tikzumlObjectName.north);
+    \draw[draw=\tikzumlobjectdraw] (\tikzumlObjectName-ttl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-ttl) -- (\tikzumlObjectName-ttr) -- (\tikzumlObjectName-tbr) -- (\tikzumlObjectName-tbr -| \tikzumlObjectName.east);
+    \fill[fill=\tikzumlobjectfill] (\tikzumlObjectName-tl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-tl) -- (\tikzumlObjectName-tr) -- (\tikzumlObjectName-br) -- (\tikzumlObjectName-br -| \tikzumlObjectName.east) -- (\tikzumlObjectName.north east) -- (\tikzumlObjectName-tl |- \tikzumlObjectName.north);
+    \draw[draw=\tikzumlobjectdraw] (\tikzumlObjectName-tl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-tl) -- (\tikzumlObjectName-tr) -- (\tikzumlObjectName-br) -- (\tikzumlObjectName-br -| \tikzumlObjectName.east);
+    \draw[draw=\tikzumlobjectdraw] (\tikzumlObjectName.north west) rectangle (\tikzumlObjectName.south east);
+  }{%
+    \ifthenelse{\equal{\tikzumlobjectstereo}{object}}{}{%
+      \node[above=1ex, name=\tikzumlObjectName-picture] at (\tikzumlObjectName) {\csname pictured\tikzumlobjectstereo \endcsname{draw=\tikzumlobjectdraw, fill=\tikzumlobjectfill, scale=\tikzumlobjectscale}};
+    }%
+  }%
+}
+
+% shortcuts for objects
+\newcommand{\umlbasicobject}[2][]{%
+  \pgfkeys{/tikzuml/basicobj/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{no ddots}}{%
+               \errmessage{TIKZUML ERROR : in umlbasicobject, forbidden option no ddots}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/basicobj/.cd, #1}%
+  \umlobject[no ddots, #1]{#2}%
+}%
+
+\newcommand{\umldatabase}[2][]{%
+  \pgfkeys{/tikzuml/databaseobj/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umldatabase, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/databaseobj/.cd, #1}%
+  \umlobject[stereo=database, #1]{#2}%
+}%
+\newcommand{\umlentity}[2][]{%
+  \pgfkeys{/tikzuml/entityobj/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlentity, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/entityobj/.cd, #1}%
+  \umlobject[stereo=entity, #1]{#2}%
+}%
+\newcommand{\umlcontrol}[2][]{%
+  \pgfkeys{/tikzuml/controlobj/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlcontrol, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/controlobj/.cd, #1}%
+  \umlobject[stereo=control, #1]{#2}%
+}%
+\newcommand{\umlboundary}[2][]{%
+  \pgfkeys{/tikzuml/boundaryobj/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlboundary, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/boundaryobj/.cd, #1}%
+  \umlobject[stereo=boundary, #1]{#2}%
+}%
+\newcommand{\umlmulti}[2][]{%
+  \pgfkeys{/tikzuml/multiobj/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlmulti, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/multiobj/.cd, #1}%
+  \umlobject[stereo=multi, #1]{#2}%
+}%
+
+\newlength{\tikzumlCall@xa}%
+\newlength{\tikzumlCall@xb}%
+
+% define a uml operation call for sequence diagrams
+% args : call sender
+%        call receiver
+% optional : dt, time delay from precedent event end
+%            name of the call
+%            operation name and input args
+%            return value
+%            type of the call (synchron, asynchron)
+%            draw, fill, text colors
+%            time padding from call start and to call end
+\newenvironment{umlcall}[3][]{%
+  \stepcounter{tikzumlCallNum}%
+  \def\tikzumlCallWithReturn{tikzumlFalse}%
+  \edef\tikzumlCall@lastchildNum{\thetikzumlCallNum}% for testing presence of sub-calls
+  \gdef\tikzumlCallBottom{0}%
+  %
+  \pgfkeys{/tikzuml/call/.cd,%
+           dt/.initial={tikzumlEmpty}, name/.initial={call-\thetikzumlCallNum},%
+           op/.initial={}, return/.initial={}, type/.initial=synchron,%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillcallcolor,%
+           text/.initial=\tikzumltextcolor,%
+           padding/.initial=2,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{with return}}{%
+               \def\tikzumlCallWithReturn{tikzumlTrue}%
+             }{%
+               \errmessage{TIKZUML ERROR : in umlcall,  invalid option \keyname}%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/call/.cd, #1}%
+  \pgfkeys{/tikzuml/call/.cd,%
+           dt/.get=\tikzumlcallDT, name/.get=\tikzumlcallname, op/.get=\tikzumlcallop,%
+           return/.get=\tikzumlcallreturn, type/.get=\tikzumlcalltype,%
+           padding/.get=\tikzumlcallpadding,%
+           draw/.get=\tikzumlcalldraw, fill/.get=\tikzumlcallfill,%
+           text/.get=\tikzumlcalltext}%
+  %
+  \edef\tikzumlfillcall{\tikzumlcallfill}%
+  \edef\tikzumldrawcall{\tikzumlcalldraw}%
+  \edef\tikzumltextcall{\tikzumlcalltext}%
+  \edef\tikzumltypecall{\tikzumlcalltype}%
+  %
+  \ifthenelse{\equal{\tikzumlcallDT}{tikzumlEmpty}}{%
+    \ifnum\thetikzumlCallNum=1%
+      \def\tikzumlcallDT{2}%
+      \def\tikzumlcallSrc{2}%
+    \else%
+      \def\tikzumlcallDT{2}%
+      \def\tikzumlcallSrc{1}%
+    \fi%
+  }{
+    \def\tikzumlcallSrc{0}%
+  }%
+  %
+  \let\tikzumlCallStartNodeNameold\tikzumlCallStartNodeName%
+  \def\tikzumlCallStartNodeName{#2}%
+  \let\tikzumlCallEndNodeNameold\tikzumlCallEndNodeName%
+  \def\tikzumlCallEndNodeName{#3}%
+  \def\tikzumlcallheight{\tikzumlcallpadding}%
+  %
+  % managing time delays from previous/parent fragments 
+  \ifnum\thetikzumlCallStartFragmentNum>0%
+    \let\tikzumlcallDTold\tikzumlcallDT%
+    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlcallDTold}%
+    \edef\tikzumlcallDT{\pgfmathresult}%
+    \addtocounter{tikzumlCallStartFragmentNum}{-1}
+  \fi%
+  \ifnum\thetikzumlCallEndFragmentNum>0%
+    \let\tikzumlcallDTold\tikzumlcallDT%
+    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlcallDTold}%
+    \edef\tikzumlcallDT{\pgfmathresult}%
+    \addtocounter{tikzumlCallEndFragmentNum}{-1}
+  \fi%
+  \ifnum\thetikzumlFragmentPartNum>0%
+    \let\tikzumlcallDTold\tikzumlcallDT%
+    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlcallDTold}%
+    \edef\tikzumlcallDT{\pgfmathresult}%
+  \fi%
+  %
+  % managing parent-child structure
+  \ifnum\thetikzumlCallLevel>0%
+    \let\tikzumlCall@nameold\tikzumlCall@name%
+    \edef\tikzumlCall@name{\tikzumlcallname}%
+    \let\tikzumlCall@parentold\tikzumlCall@parent%
+    \edef\tikzumlCall@parent{\tikzumlCall@parentold @@\tikzumlCall@nameold}%
+  \else%
+    \edef\tikzumlCall@parent{}%
+    \edef\tikzumlCall@parentold{}%
+    \edef\tikzumlCall@nameold{}
+    \edef\tikzumlCall@name{\tikzumlcallname}%
+  \fi%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlCall@nodeName{\tikzumlCall@name}}\x%
+  %
+  \let\tikzumlCall@nodeNameold\tikzumlCall@nodeName%
+  %
+  \def\tikzumlcallstyle{tikzuml \tikzumlcalltype-msg style}%
+  %
+  % top node of activity period of call sender
+  \begin{pgfonlayer}{connections}%
+  \pgfmathparse{\tikzumlcallDT+\tikzumlcallSrc}%
+  \draw (\csname tikzumlLastChild@\tikzumlCallStartNodeName \endcsname)+(0,-\pgfmathresult ex) node[coordinate, name=tikzumlTmpNode] {};%
+  \node[tikzuml activity style] (st-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};%
+  %
+  % update last node drawn on sender lifeline
+  \expandafter\xdef\csname tikzumlLastChild@\tikzumlCallStartNodeName \endcsname{st-\tikzumlCall@nodeName}%
+  %
+  % top node of activity period of call receiver
+  \ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
+    \draw (st-\tikzumlCall@nodeName)+(0,-0.75*\tikzumlcallpadding ex) node[coordinate, name=tikzumlTmpNode] {};%
+    \node[tikzuml activity style] (et-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};%
+  }{%
+    \node[tikzuml activity style] (et-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- st-\tikzumlCall@nodeName) {};%
+  }%
+  %
+  % update last node drawn on receiver lifeline
+  \expandafter\xdef\csname tikzumlLastChild@\tikzumlCallEndNodeName \endcsname{et-\tikzumlCall@nodeName}%
+  \xdef\tikzumlCallBottomSrc{et-\tikzumlCall@nodeName}%
+  \end{pgfonlayer}%
+  %
+  \stepcounter{tikzumlCallLevel}%
+}{%
+  \addtocounter{tikzumlCallLevel}{-1}%
+  %
+  % bottom nodes of activity periods of call sender and receiver
+  \begin{pgfonlayer}{connections}%
+  \ifnum\tikzumlCall@lastchildNum=\thetikzumlCallNum%
+    %
+    % this test occurs a bug with latex package preview
+    \ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
+      \draw (\tikzumlCallBottomSrc)+(0,-\tikzumlcallpadding ex) node[coordinate, name=tikzumlTmpNode] {};%
+      \node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};% 
+      \draw (eb-\tikzumlCall@nodeName)+(0,-0.75*\tikzumlcallpadding ex) node[coordinate, name=tikzumlTmpNode] {};%
+      \node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};% 
+    }{%
+      \ifthenelse{\equal{\tikzumlcallreturn}{tikzumlEmpty}}{%
+        \pgfmathsetmacro{\tikzumlcallpaddingd}{0.5*\tikzumlcallpadding}%
+      }{%
+        \pgfmathsetmacro{\tikzumlcallpaddingd}{1.2*\tikzumlcallpadding}%
+      }%
+      \draw (\tikzumlCallBottomSrc)+(0,-\tikzumlcallpaddingd ex) node[coordinate, name=tikzumlTmpNode] {};%
+      \node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};%
+      \node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- eb-\tikzumlCall@nodeName) {};%
+    }%
+    \xdef\tikzumlCallBottomSrc{sb-\tikzumlCall@nodeName}%
+  \else%
+    %
+    % managing time delays from previous/parent fragments
+    \ifnum\thetikzumlCallStartFragmentNum>0%
+      \let\tikzumlcallheightold\tikzumlcallpadding
+      \pgfmathparse{\tikzumlcallheightold+0.5*\tikzumlFragment@paddingy}
+      \edef\tikzumlcallheight{\pgfmathresult}
+      \addtocounter{tikzumlCallStartFragmentNum}{-1}
+    \fi%
+    \ifnum\thetikzumlCallEndFragmentNum>0%
+      \let\tikzumlcallheightold\tikzumlcallpadding
+      \pgfmathparse{\tikzumlcallheightold+0.5*\tikzumlFragment@paddingy}
+      \edef\tikzumlcallheight{\pgfmathresult}
+      \addtocounter{tikzumlCallEndFragmentNum}{-1}
+    \fi%
+    %
+    \ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
+      \draw (\tikzumlCallBottomSrc)+(0,-\tikzumlcallheight ex) node[coordinate, name=tikzumlTmpNode] {};%
+      \node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};%
+      \draw (eb-\tikzumlCall@nodeName)+(0,-0.75*\tikzumlcallpadding ex) node[coordinate, name=tikzumlTmpNode] {};%
+      \node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- tikzumlTmpNode) {};%
+    }{%
+      \draw (\tikzumlCallBottomSrc)+(0,-\tikzumlcallheight ex) node[coordinate, name=tikzumlTmpNode] {};%
+      \node[tikzuml activity style] (eb-\tikzumlCall@nodeName) at (\tikzumlCallEndNodeName |- tikzumlTmpNode) {};%
+      \node[tikzuml activity style] (sb-\tikzumlCall@nodeName) at (\tikzumlCallStartNodeName |- eb-\tikzumlCall@nodeName) {};%
+    }%
+    %
+    \xdef\tikzumlCallBottomSrc{sb-\tikzumlCall@nodeName}%
+  \fi%
+  \end{pgfonlayer}%
+  %
+  % draw activity periods
+  \begin{pgfonlayer}{activity}%
+  \ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
+    % draw root activity period only
+    \ifnum\thetikzumlCallLevel=0%
+      \draw[draw=\tikzumldrawcall, fill=\tikzumlfillcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south east);%
+    \else%
+      % draw root activity from inner call
+      \ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeNameold}}{}{%
+        \draw[draw=\tikzumldrawcall, fill=\tikzumlfillcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south east);%
+      }%
+    \fi%
+  }{%
+    % draw root activity period
+    \ifnum\thetikzumlCallLevel=0%
+      \draw[draw=\tikzumldrawcall, fill=\tikzumlfillcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south east);%
+    \else%
+      % draw root activity from inner call
+      \ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeNameold}}{}{%
+        \draw[draw=\tikzumldrawcall, fill=\tikzumlfillcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south east);%
+      }%
+    \fi%
+    % draw receiver activity period
+    \draw[draw=\tikzumldrawcall, fill=\tikzumlfillcall] (et-\tikzumlCall@nodeName.north west) rectangle (eb-\tikzumlCall@nodeName.south east);%
+  }%
+  \end{pgfonlayer}%
+  \ifthenelse{\equal{\tikzumlfillcallcolor}{\tikzumlcallfill}}{}{%
+    \fill[\tikzumlfillcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south east);%
+    \draw[\tikzumldrawcall] (st-\tikzumlCall@nodeName.north west) rectangle (sb-\tikzumlCall@nodeName.south west) (st-\tikzumlCall@nodeName.north east) rectangle (sb-\tikzumlCall@nodeName.south east);
+  }%
+  %
+  % update last nodes drawn on sender and receiver lifelines
+  \expandafter\xdef\csname tikzumlLastChild@\tikzumlCallEndNodeName \endcsname{eb-\tikzumlCall@nodeName}%
+  \expandafter\xdef\csname tikzumlLastChild@\tikzumlCallStartNodeName \endcsname{sb-\tikzumlCall@nodeName}%
+  %
+  % draw call arrows
+  \begin{pgfonlayer}{connections}%
+  \ifthenelse{\equal{\tikzumlCallStartNodeName}{\tikzumlCallEndNodeName}}{%
+    \draw[\tikzumlcallstyle, \tikzumldrawcall] (st-\tikzumlCall@nodeName.east) -- ++(2.5*\tikzumlcallpadding ex,0) %
+                                                    -- ++(0,-0.75*\tikzumlcallpadding ex) %
+                                                    node[font=\tikzumlfont, text=\tikzumltextcall, midway, right, name=\tikzumlCall@nodeName-op] {\tikzumlcallop} %
+                                                    -- (et-\tikzumlCall@nodeName.east);%
+    %
+    % draw return arrow and update fit for parent fragment
+    \ifthenelse{\equal{\tikzumltypecall}{synchron}}{%
+      \ifthenelse{\NOT\equal{\tikzumlcallreturn}{}\OR\equal{\tikzumlCallWithReturn}{tikzumlTrue}}{%
+        \ifnum\c@tikzumlFragmentLevel>0%
+          \edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
+          \expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op) (\tikzumlCall@nodeName-return)}%
+        \fi%
+        %
+        \draw[tikzuml call return style, \tikzumldrawcall] (eb-\tikzumlCall@nodeName.east) -- ++(2.5*\tikzumlcallpadding ex,0) -- ++(0,-0.75*\tikzumlcallpadding ex) %
+                                                  node[font=\tikzumlfont, text=\tikzumltextcall, midway, right, name=\tikzumlCall@nodeName-return] {\tikzumlcallreturn} %
+                                                  -- (sb-\tikzumlCall@nodeName.east);%
+     }{%
+        \ifnum\c@tikzumlFragmentLevel>0%
+          \edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
+          \expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op)}%
+        \fi%
+}%
+    }{%
+      \ifnum\c@tikzumlFragmentLevel>0%
+        \edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
+        \expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op)}%
+      \fi%
+      %
+    }%
+  }{%
+    % draw call arrows
+    \pgfextractx{\tikzumlCall@xa}{\pgfpointanchor{\tikzumlCallStartNodeName}{center}}%
+    \pgfextractx{\tikzumlCall@xb}{\pgfpointanchor{\tikzumlCallEndNodeName}{center}}%
+    %
+    \ifthenelse{\tikzumlCall@xb>\tikzumlCall@xa}{%
+      \draw[\tikzumlcallstyle, \tikzumldrawcall] (st-\tikzumlCall@nodeName.east) -- (et-\tikzumlCall@nodeName.west) %
+                                                    node[font=\tikzumlfont, text=\tikzumltextcall, midway, above=-0.4ex, name=\tikzumlCall@nodeName-op] {\tikzumlcallop};%
+    }{%
+      \draw[\tikzumlcallstyle, \tikzumldrawcall] (st-\tikzumlCall@nodeName.west) -- (et-\tikzumlCall@nodeName.east) %
+                                                    node[font=\tikzumlfont, text=\tikzumltextcall, midway, above=-0.4ex, name=\tikzumlCall@nodeName-op] {\tikzumlcallop};%
+    }%
+    %
+    % draw return arrow and update fit for parent fragment
+    \ifthenelse{\equal{\tikzumltypecall}{synchron}}{%
+      \ifthenelse{\NOT\equal{\tikzumlcallreturn}{}\OR\equal{\tikzumlCallWithReturn}{tikzumlTrue}}{%
+        \ifnum\c@tikzumlFragmentLevel>0%
+          \edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
+          \expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op) (\tikzumlCall@nodeName-return)}%
+        \fi%
+        %
+        \ifthenelse{\tikzumlCall@xb>\tikzumlCall@xa}{%
+          \draw[tikzuml call return style, \tikzumldrawcall] (eb-\tikzumlCall@nodeName.west) -- (sb-\tikzumlCall@nodeName.east) %
+                                       node[font=\tikzumlfont, text=\tikzumltextcall, midway, above=-0.4ex, name=\tikzumlCall@nodeName-return] {\tikzumlcallreturn};%
+        }{%
+          \draw[tikzuml call return style, \tikzumldrawcall] (eb-\tikzumlCall@nodeName.east) -- (sb-\tikzumlCall@nodeName.west) %
+                                       node[font=\tikzumlfont, text=\tikzumltextcall, midway, above=-0.4ex, name=\tikzumlCall@nodeName-return] {\tikzumlcallreturn};%
+        }%
+      }{%
+        \ifnum\c@tikzumlFragmentLevel>0%
+          \edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
+          \expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op)}%
+        \fi%
+      }%
+    }{%
+      \ifnum\c@tikzumlFragmentLevel>0%
+        \edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
+        \expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCall@nodeName) (et-\tikzumlCall@nodeName) (eb-\tikzumlCall@nodeName) (sb-\tikzumlCall@nodeName) (\tikzumlCall@nodeName-op)}%
+      \fi%
+    }%
+  }%
+  \end{pgfonlayer}%
+}%
+
+% alias for function self call
+\newenvironment{umlcallself}[2][]{\begin{umlcall}[#1]{#2}{#2} }{\end{umlcall}}%
+
+% define a combined fragment
+% optional : name of fragment
+%            type of fragment (opt, alt, break, loop, par, critical, ignore, consider, assert, neg, weak, strict, ref)
+%            label of fragment (ex : condition for opt, iterator for loop, ...)
+%            inner xsep and ysep (padding of the fragment box)
+%            draw, fill, text colors
+\newenvironment{umlfragment}[1][]{%
+
+  % define a fragment separator
+  % optional : label of the fragment part (ex : else for alt)
+  \providecommand{\umlfpart}[1][]{%
+    \stepcounter{tikzumlFragmentPartNum}%
+    %
+    \node[outer sep=0, inner xsep=\tikzumlfragmentxsep ex, inner ysep=\tikzumlfragmentysep ex, fit=\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname, name=\tikzumlFragment@name-Part-tmp] {};%
+    \node[anchor=east, name=\tikzumlFragment@name-PartType-\thetikzumlFragmentPartNum] at (\tikzumlFragment@name-Part-tmp.north west |- \tikzumlCallBottomSrc) {\phantom{\tikzumlfragmenttype}};
+    \draw (\tikzumlFragment@name-PartType-\thetikzumlFragmentPartNum.north west |- \tikzumlCallBottomSrc)+(0,-0.4*\tikzumlFragment@paddingy ex) node[name=\tikzumlFragment@name-PartWest-\thetikzumlFragmentPartNum] {};
+    \draw (\tikzumlFragment@name-Part-tmp.north east |- \tikzumlCallBottomSrc)+(0,-0.4*\tikzumlFragment@paddingy ex) node[name=\tikzumlFragment@name-PartEast-\thetikzumlFragmentPartNum] {};
+    \draw[dashed] (\tikzumlFragment@name-PartWest-\thetikzumlFragmentPartNum) -- (\tikzumlFragment@name-PartEast-\thetikzumlFragmentPartNum);
+    \draw (\tikzumlFragment@name-PartType-\thetikzumlFragmentPartNum)+(0,-0.4*\tikzumlFragment@paddingy ex) node[name=tikzumlTmpNode] {\phantom{\tikzumlfragmenttype}};
+    \node[anchor=north west] at (tikzumlTmpNode.south west) {[##1]};%
+  }%
+  
+  \stepcounter{tikzumlFragmentNum}%
+  %
+  \pgfkeys{/tikzuml/fragment/.cd,%
+           name/.initial={fragment@\alph{tikzumlFragmentNum}}, type/.initial=opt,%
+           label/.initial={tikzumlEmpty},%
+           inner xsep/.initial=1, inner ysep/.initial=1,%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillfragmentcolor,%
+           text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlfragment, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/fragment/.cd, #1}%
+  \pgfkeys{/tikzuml/fragment/.cd,%
+           name/.get=\tikzumlfragmentname, type/.get=\tikzumlfragmenttype,%
+           label/.get=\tikzumlfragmentlabel,%
+           inner xsep/.get=\tikzumlfragmentxsep, inner ysep/.get=\tikzumlfragmentysep,%
+           draw/.get=\tikzumlfragmentdraw, fill/.get=\tikzumlfragmentfill,%
+           text/.get=\tikzumlfragmenttext}%
+  %
+  \ifthenelse{\equal{\tikzumlfragmentlabel}{tikzumlEmpty}}{%
+    \def\tikzumlfragmentlabel{}%
+  }{%
+    \let\tikzumlfragmentlabelold\tikzumlfragmentlabel%
+    \def\tikzumlfragmentlabel{[\tikzumlfragmentlabelold]}%
+  }%
+  
+  %
+  \ifnum\thetikzumlFragmentLevel>0%
+    \let\tikzumlFragment@parentold\tikzumlFragment@parent%
+    \let\tikzumlFragment@nameold\tikzumlFragment@name%
+    \edef\tikzumlFragment@parent{\tikzumlFragment@nameold}%
+  \else%
+    \setcounter{tikzumlFragmentPartNum}{0}%
+    \edef\tikzumlFragment@parent{}%
+    \edef\tikzumlFragment@parentold{}%
+    \edef\tikzumlFragment@nameold{}%
+  \fi%
+  %
+  \edef\tikzumlFragment@name{\tikzumlfragmentname}%
+  \expandafter\gdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{}%
+  %
+  \stepcounter{tikzumlFragmentLevel}%
+  %
+  \ifnum\thetikzumlCallLevel>0%
+    \stepcounter{tikzumlCallStartFragmentNum}%
+  \fi%
+  %
+  \pgfmathparse{6*\tikzumlfragmentysep}%
+  \xdef\tikzumlFragment@paddingy{\pgfmathresult}%
+  \if\c@tikzumlFragmentLevelNum=0%
+    \setcounter{tikzumlFragmentLevelNum}{\thetikzumlFragmentLevel}%
+  \fi%
+  %
+  % time delay adjustment for two consecutive fragments
+  \ifnum\thetikzumlCallEndFragmentNum>0%
+    \addtocounter{tikzumlCallEndFragmentNum}{-1}
+  \fi%
+}{%
+  %
+  \addtocounter{tikzumlFragmentLevel}{-1}%
+  %
+  \ifnum\thetikzumlFragmentLevel>0%
+    \edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@parent \endcsname}%
+    \expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@parent \endcsname{\tikzumlFragmentFitOld (\tikzumlFragment@name)}%
+  \fi%
+  %
+  % draw working fragment box
+  \begin{pgfonlayer}{fragment\thetikzumlFragmentLevel}%
+  \node[outer sep=0, inner xsep=\tikzumlfragmentxsep ex, inner ysep=\tikzumlfragmentysep ex, fit=\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname, name=\tikzumlFragment@name-back] {};%
+  \end{pgfonlayer}%
+  %
+  % draw type and label
+  \node[text=\tikzumlfragmenttext, font=\tikzumlfont, anchor=north east, name=\tikzumlFragment@name-type] %
+                                   at (\tikzumlFragment@name-back.north west) {\tikzumlfragmenttype};%
+  \node[text=\tikzumlfragmenttext, font=\tikzumlfont, anchor=north west, name=\tikzumlFragment@name-label] %
+                                   at (\tikzumlFragment@name-type.south west) {\tikzumlfragmentlabel};%
+  %
+  % draw final fragment box
+  \begin{pgfonlayer}{fragment\thetikzumlFragmentLevel}%
+  \node[draw=\tikzumlfragmentdraw, fill=\tikzumlfragmentfill, outer sep=0, inner sep=0, font=\tikzumlfont, fit=(\tikzumlFragment@name-back) (\tikzumlFragment@name-type) (\tikzumlFragment@name-label), name=\tikzumlFragment@name] {};%
+  \end{pgfonlayer}%
+  %
+  \draw[draw=\tikzumlfragmentdraw] (\tikzumlFragment@name.north west) rectangle (\tikzumlFragment@name.south east);%
+  \draw (\tikzumlFragment@name-type.south east)+(0,1ex) node[name=\tikzumlFragment@name-typetop, inner sep=0] {};%
+  \draw (\tikzumlFragment@name-type.south east)+(-1ex,0) node[name=\tikzumlFragment@name-typeleft, inner sep=0] {};%
+  \draw (\tikzumlFragment@name.north west) -| (\tikzumlFragment@name-typetop.center) -- (\tikzumlFragment@name-typeleft.center) -| (\tikzumlFragment@name.north west);%
+  %
+  \ifnum\thetikzumlCallLevel>0%
+    \stepcounter{tikzumlCallEndFragmentNum}%
+  \fi%
+}%
+
+% define a constructor call
+% arg : call sender
+%       name of constructed object
+% optional : x coordinate of the new object
+%            stereotype of the new object
+%            class type of the new object
+%            time delay from last event
+%            name of the call
+%            draw, fill, text colors
+\newcommand{\umlcreatecall}[3][]{%
+  \stepcounter{tikzumlCallNum}%
+  \edef\tikzumlCall@lastchildNum{\thetikzumlCallNum}% for testing presence of sub-calls
+  \gdef\tikzumlInCreateCall{1}%
+  \pgfkeys{/tikzuml/createcall/.cd,%
+           x/.initial={tikzumlEmpty}, stereo/.initial=object, class/.initial={},%
+           dt/.initial=4, name/.initial={call-\thetikzumlCallNum},%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillcallcolor,%
+           text/.initial=\tikzumltextcolor,%
+           draw obj/.initial=\tikzumldrawcolor, fill obj/.initial=\tikzumlfillobjectcolor,%
+           text obj/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlcreatecall, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/createcall/.cd, #1}%
+  \pgfkeys{/tikzuml/createcall/.cd,%
+           x/.get=\tikzumlcallX, stereo/.get=\tikzumlcallstereo,%
+           class/.get=\tikzumlcallclass,%
+           dt/.get=\tikzumlcallDT, name/.get=\tikzumlcallname,%
+           draw/.get=\tikzumlcalldraw, fill/.get=\tikzumlcallfill,%
+           text/.get=\tikzumlcalltext,%
+           draw obj/.get=\tikzumlcallobjdraw, fill obj/.get=\tikzumlcallobjfill,%
+           text obj/.get=\tikzumlcallobjtext}%
+  %
+  \def\tikzumlCreateCallSrc@name{#2}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlCreateCallSrc@nodeName{\tikzumlCreateCallSrc@name}}\x%
+  %
+  % managing time delays from previous/parent fragments 
+  \ifnum\thetikzumlCallStartFragmentNum>0%
+    \let\tikzumlcallDTold\tikzumlcallDT%
+    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlcallDTold}%
+    \edef\tikzumlcallDT{\pgfmathresult}%
+    \addtocounter{tikzumlCallStartFragmentNum}{-1}
+  \fi%
+  \ifnum\thetikzumlCallEndFragmentNum>0%
+    \let\tikzumlcallDTold\tikzumlcallDT%
+    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlcallDTold}%
+    \edef\tikzumlcallDT{\pgfmathresult}%
+    \addtocounter{tikzumlCallEndFragmentNum}{-1}
+  \fi%
+  \ifnum\thetikzumlFragmentPartNum>0%
+    \let\tikzumlcallDTold\tikzumlcallDT%
+    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlcallDTold}%
+    \edef\tikzumlcallDT{\pgfmathresult}%
+  \fi%
+  %
+  % managing parent-child structure
+  \ifnum\thetikzumlCallLevel>0%
+    \let\tikzumlCall@nameold\tikzumlCall@name%
+    \def\tikzumlCall@name{\tikzumlcallname}%
+    \let\tikzumlCall@parentold\tikzumlCall@parent%
+    \edef\tikzumlCall@parent{\tikzumlCall@parentold @@\tikzumlCall@nameold}%
+  \else%
+    \edef\tikzumlCall@parent{}%
+    \edef\tikzumlCall@parentold{}%
+    \edef\tikzumlCall@nameold{}
+    \edef\tikzumlCall@name{\tikzumlcallname}%
+  \fi%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlCreateCall@nodeName{\tikzumlCall@name}}\x%
+  %
+  \draw (\csname tikzumlLastChild@\tikzumlCreateCallSrc@nodeName \endcsname)+(0,-\tikzumlcallDT ex) node[name=st-\tikzumlCreateCall@nodeName, tikzuml activity style] {};%
+  %
+  \xdef\tikzumlCreateCallObjectSrc{st-\tikzumlCreateCall@nodeName}%
+  %
+  \umlobject[x=\tikzumlcallX, stereo=\tikzumlcallstereo, class=\tikzumlcallclass, draw=\tikzumlcallobjdraw, fill=\tikzumlcallobjfill, text=\tikzumlcallobjtext]{#3}%
+  %
+  \draw (\csname tikzumlLastChild@\tikzumlCreateCallSrc@nodeName \endcsname |- #3)+(0,-0.5*\tikzumlcallDT ex) node[name=sb-\tikzumlCreateCall@nodeName, tikzuml activity style] {};%
+  %
+  \expandafter\xdef\csname tikzumlLastChild@\tikzumlCreateCallSrc@nodeName \endcsname{sb-\tikzumlCreateCall@nodeName}%
+  \xdef\tikzumlCallBottomSrc{sb-\tikzumlCreateCall@nodeName}%
+  %
+  \begin{pgfonlayer}{connections}%
+  \draw[tikzuml synchron-msg style, \tikzumlcalldraw] (st-\tikzumlCreateCall@nodeName) -- (#3) node[midway, above, font=\tikzumlfont, text=\tikzumlcalltext, name=\tikzumlCreateCall@nodeName-op] {create};%
+  \end{pgfonlayer}%
+  %
+  \ifnum\thetikzumlCallLevel=0%
+    \begin{pgfonlayer}{activity}%
+    \draw[draw=\tikzumlcalldraw, fill=\tikzumlcallfill] (st-\tikzumlCreateCall@nodeName.north west) rectangle (sb-\tikzumlCreateCall@nodeName.south east);%
+    \end{pgfonlayer}%
+  \fi%
+  % add to fit fragment
+  \ifnum\c@tikzumlFragmentLevel>0%
+    \edef\tikzumlFragmentFitOld{\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname}%
+    \expandafter\xdef\csname tikzumlFragmentFit\tikzumlFragment@name \endcsname{\tikzumlFragmentFitOld (st-\tikzumlCreateCall@nodeName) (sb-\tikzumlCreateCall@nodeName) (\tikzumlCreateCall@nodeName-op) (#3) }%
+  \fi%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                     component diagrams                   %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\tikzstyle{tikzuml connector style}=[color=\tikzumldrawcolor, -]%
+
+\newcounter{tikzumlComponentLevel}%
+\newcounter{tikzumlComponentSubComponentNum}%
+\newcounter{tikzumlConnectorNum}%
+\setcounter{tikzumlConnectorNum}{1}%
+
+\newcommand{\picturedcomponent}[1]{%
+  \pgfkeys{/tikzuml/component/picture/.cd, scale/.initial=1, .unknown/.code={}}%
+  \pgfkeys{/tikzuml/component/picture/.cd,#1}%
+  \pgfkeys{/tikzuml/component/picture/.cd, scale/.get=\tikzumlcomponentscale}%
+  \begin{tikzpicture}[#1]%
+  \filldraw (0,0) rectangle (1ex,1.5ex);%
+  \filldraw (-0.2ex,0.4ex) rectangle (0.2ex,0.6ex);%
+  \filldraw (-0.2ex,0.9ex) rectangle (0.2ex,1.1ex);%
+  \end{tikzpicture}%
+}%
+
+% define a uml component
+% args : name of the component
+%         content of the component
+% optional args : x,y coordinates of the component
+%                 width of the component node
+\newenvironment{umlcomponent}[2][]{%
+  \ifnum\thetikzumlComponentLevel>0%
+    \let\tikzumlComponent@nameold\tikzumlComponent@fitname%
+    \let\tikzumlComponent@parentold\tikzumlComponent@parent%
+    \edef\tikzumlComponent@parent{\tikzumlComponent@parentold @@\tikzumlComponent@nameold}%
+  \else%
+    \def\tikzumlComponent@parent{}%
+  \fi%
+  %
+  \stepcounter{tikzumlComponentLevel}%
+  %
+  \pgfkeys{/tikzuml/component/.cd,%
+           x/.initial=0, y/.initial=0, width/.initial=8ex, name/.initial={},%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillcomponentcolor,%
+           text/.initial=\tikzumltextcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlcomponent, invalid option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/component/.cd, #1}%
+  \pgfkeys{/tikzuml/component/.cd,%
+           x/.get=\tikzumlcomponentX, y/.get=\tikzumlcomponentY,%
+           width/.get=\umlcomponentMinimumWidth, name/.get=\umlcomponentName,%
+           draw/.get=\tikzumlcomponentdraw, fill/.get=\tikzumlcomponentfill,%
+           text/.get=\tikzumlcomponenttext}%
+  %
+  \ifthenelse{\equal{\umlcomponentName}{}}{%
+    \edef\tikzumlComponent@name{#2}%
+  }{%
+    \edef\tikzumlComponent@name{\umlcomponentName}%
+  }%
+  %
+  \begingroup%
+    \def\_{@}\edef\x{\endgroup%
+      \def\noexpand\tikzumlComponent@fitname{\tikzumlComponent@name}}\x%
+  %
+  \let\tikzumlComponent@nodeNameold\tikzumlComponent@nodeName%
+  \def\tikzumlComponent@caption{#2}%
+  %  
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlComponent@nodeName{\tikzumlComponent@name}}\x%
+  %
+  \expandafter\gdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{}%
+  %
+  \setcounter{tikzumlComponentSubComponentNum}{0}%
+  %
+  \begin{scope}[xshift=\tikzumlcomponentX cm, yshift=\tikzumlcomponentY cm]%
+}{%
+  \addtocounter{tikzumlComponentLevel}{-1}%
+  \begin{pgfonlayer}{component\thetikzumlComponentLevel}%
+  %
+  % if contains nothing, one define a fictive node to enable the fit option
+  \ifnum\c@tikzumlComponentSubComponentNum=0%
+    \node[inner ysep=0.5ex, minimum width=\umlcomponentMinimumWidth, font=\tikzumlfont] (\tikzumlComponent@nodeName-root) at (0,0) {\phantom{\tikzumlComponent@nodeName}};%
+    \expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{(\tikzumlComponent@nodeName-root)}%
+  \fi%
+  %
+  \ifnum\c@tikzumlComponentLevel>0%
+    \def\tikzumlComponentFitTmp{\csname tikzumlComponentFit\tikzumlComponent@parent\endcsname}%
+    \expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent\endcsname{\tikzumlComponentFitTmp (\tikzumlComponent@nodeName-body) (\tikzumlComponent@nodeName-caption)}%
+    \stepcounter{tikzumlComponentSubComponentNum}%
+  \fi%
+  %
+  \node[inner sep=2ex, font=\tikzumlfont, fit = \csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname] (\tikzumlComponent@nodeName-body) {};%
+  \node[above, font=\tikzumlfont] (\tikzumlComponent@nodeName-captiontmp) at (\tikzumlComponent@nodeName-body.north) {\tikzumlComponent@caption};%
+  \node (\tikzumlComponent@nodeName-logotmp) at (\tikzumlComponent@nodeName-captiontmp.north -| \tikzumlComponent@nodeName-body.east) {\picturedcomponent{draw=\tikzumlcomponentdraw, fill=\tikzumlcomponentfill, font=\tikzumlfont} };%
+  \node[draw=\tikzumlcomponentdraw, fill=\tikzumlcomponentfill, name=\tikzumlComponent@nodeName, fit=(\tikzumlComponent@nodeName-body) (\tikzumlComponent@nodeName-captiontmp)] {};%
+  \node[font=\tikzumlfont] (\tikzumlComponent@nodeName-caption) at (\tikzumlComponent@nodeName-captiontmp) {\tikzumlComponent@caption};%
+  \draw (\tikzumlComponent@nodeName-caption.north -| \tikzumlComponent@nodeName.east) node[font=\tikzumlfont, xshift=-1ex, below=-1ex, name=\tikzumlComponent@nodeName-logo] {\picturedcomponent{draw=\tikzumlcomponentdraw, fill=\tikzumlcomponentfill, font=\tikzumlfont} };%
+  \draw (\tikzumlComponent@nodeName-caption.south -| \tikzumlComponent@nodeName.north west) -- (\tikzumlComponent@nodeName-caption.south -| \tikzumlComponent@nodeName.north east);%
+  \coordinate (\tikzumlComponent@nodeName-west-port) at (\tikzumlComponent@nodeName.west);
+  \coordinate (\tikzumlComponent@nodeName-east-port) at (\tikzumlComponent@nodeName.east);
+  \coordinate (\tikzumlComponent@nodeName-south-port) at (\tikzumlComponent@nodeName.south);
+  \coordinate (\tikzumlComponent@nodeName-north-port) at (\tikzumlComponent@nodeName.north);
+
+  \end{pgfonlayer}%
+  \end{scope}%
+  %
+  % add to fit
+  \ifnum\c@tikzumlPackageLevel>0%
+    \edef\tikzumlPackageFitOld{\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname}%
+    \expandafter\xdef\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname{\tikzumlPackageFitOld (\tikzumlComponent@nodeName)}%
+    \stepcounter{tikzumlPackageClassNum}%
+  \fi%
+}%
+
+% shortcut for empty state
+\newcommand{\umlbasiccomponent}[2][]{\begin{umlcomponent}[#1]{#2} \end{umlcomponent}}%
+
+\newcommand{\umlrequiredinterface}[2][]{%
+  \def\tikzumlInterfaceWithPort{tikzumlFalse}%
+  \pgfkeys{/tikzuml/requiredinterfacerelation/.cd,%
+           interface/.initial={}, distance/.initial=2.5cm,%
+           width/.initial=1em, padding/.initial=1cm,%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillcomponentcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{with port}}{%
+               \def\tikzumlInterfaceWithPort{tikzumlTrue}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/requiredinterfacerelation/.cd, #1}%
+  \pgfkeys{/tikzuml/requiredinterfacerelation/.cd,%
+           interface/.get=\tikzumlRequiredInterfaceLabel,%
+           distance/.get=\tikzumlRequiredInterfaceDistance,%
+           width/.get=\tikzumlRequiredInterfaceWidth,%
+           padding/.get=\tikzumlRequiredInterfacePadding,%
+           draw/.get=\tikzumlrequiredinterfacedraw,%
+           fill/.get=\tikzumlrequiredinterfacefill,}%
+  %
+  \edef\tikzumlRequiredInterface@name{#2}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlRequiredInterface@nodeName{\tikzumlRequiredInterface@name}}\x%
+  %
+  \ifthenelse{\equal{\tikzumlInterfaceWithPort}{tikzumlTrue}}{%
+    \node[inner sep=0.5*\tikzumlRequiredInterfaceWidth, rectangle, draw=\tikzumlrequiredinterfacedraw, fill=\tikzumlrequiredinterfacefill] (\tikzumlRequiredInterface@nodeName-east-port) at (\tikzumlRequiredInterface@nodeName.east) {};%
+  }{%
+    \node[inner sep=0] (\tikzumlRequiredInterface@nodeName-east-port) at (\tikzumlRequiredInterface@nodeName.east) {};%
+  }%
+  \begin{scope}%
+  \draw (\tikzumlRequiredInterface@nodeName)+(\tikzumlRequiredInterfaceDistance,0) node[inner sep=0, text width=\tikzumlRequiredInterfaceWidth, circle, name=\tikzumlRequiredInterface@nodeName-east-interface-tmp] {};%
+  \clip (\tikzumlRequiredInterface@nodeName-east-interface-tmp.north) rectangle (\tikzumlRequiredInterface@nodeName-east-interface-tmp.south -| \tikzumlRequiredInterface@nodeName-east-interface-tmp.west);%
+  \node[inner sep=0, text width=\tikzumlRequiredInterfaceWidth, circle, draw=\tikzumlrequiredinterfacedraw] (\tikzumlRequiredInterface@nodeName-east-interface) at (\tikzumlRequiredInterface@nodeName-east-interface-tmp) {};%
+  \end{scope}%
+  \node[above] at (\tikzumlRequiredInterface@nodeName-east-interface.north) {\tikzumlRequiredInterfaceLabel};%
+  %
+  \umlrelation[style={tikzuml connector style}, #1]{\tikzumlRequiredInterface@nodeName-east-port}{\tikzumlRequiredInterface@nodeName-east-interface}%
+
+  \draw (\tikzumlRequiredInterface@nodeName-east-interface)+(\tikzumlRequiredInterfacePadding,0) node[name=\tikzumlRequiredInterface@nodeName-east-padding] {};%
+
+  % add to fit
+  \ifnum\c@tikzumlComponentLevel>0%
+        \def\tikzumlComponentFitTmp{\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname}%
+        \expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{\tikzumlComponentFitTmp (\tikzumlRequiredInterface@nodeName-east-padding) (\tikzumlRequiredInterface@nodeName-east-port) }%
+  \fi%
+}%
+
+\newcommand{\umlprovidedinterface}[2][]{%
+  \def\tikzumlInterfaceWithPort{tikzumlFalse}%
+  \pgfkeys{/tikzuml/providedinterfacerelation/.cd,%
+           interface/.initial={}, distance/.initial=3cm,%
+           width/.initial=1em, padding/.initial=1cm,%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillcomponentcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{with port}}{%
+               \def\tikzumlInterfaceWithPort{tikzumlTrue}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/providedinterfacerelation/.cd, #1}%
+  \pgfkeys{/tikzuml/providedinterfacerelation/.cd,%
+           interface/.get=\tikzumlProvidedInterfaceLabel,%
+           distance/.get=\tikzumlProvidedInterfaceDistance,%
+           padding/.get=\tikzumlProvidedInterfacePadding,%
+           width/.get=\tikzumlProvidedInterfaceWidth,%
+           draw/.get=\tikzumlprovidedinterfacedraw,%
+           fill/.get=\tikzumlprovidedinterfacefill}%
+  %
+  \edef\tikzumlProvidedInterface@name{#2}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlProvidedInterface@nodeName{\tikzumlProvidedInterface@name}}\x%
+  %
+  \ifthenelse{\equal{\tikzumlInterfaceWithPort}{tikzumlTrue}}{%
+    \node[inner sep=0.5*\tikzumlProvidedInterfaceWidth, rectangle, draw=\tikzumlprovidedinterfacedraw, fill=\tikzumlprovidedinterfacefill] (\tikzumlProvidedInterface@nodeName-west-port) at (\tikzumlProvidedInterface@nodeName.west) {};%
+  }{%
+    \node[inner sep=0] (\tikzumlProvidedInterface@nodeName-west-port) at (\tikzumlProvidedInterface@nodeName.west) {};%
+  }%
+  \draw (\tikzumlProvidedInterface@nodeName)+(-\tikzumlProvidedInterfaceDistance,0) node[inner sep=0, text width=\tikzumlProvidedInterfaceWidth, circle, draw=\tikzumlprovidedinterfacedraw, fill=\tikzumlprovidedinterfacefill, name=\tikzumlProvidedInterface@nodeName-west-interface] {};%
+  \node[above] at (\tikzumlProvidedInterface@nodeName-west-interface.north)
+ {\tikzumlProvidedInterfaceLabel};%
+  %
+  \umlrelation[style={tikzuml connector style}, #1]{\tikzumlProvidedInterface@nodeName-west-port}{\tikzumlProvidedInterface@nodeName-west-interface}%
+
+  \draw (\tikzumlProvidedInterface@nodeName-west-interface)+(-\tikzumlProvidedInterfacePadding,0) node[name=\tikzumlProvidedInterface@nodeName-west-padding] {};%
+   % add to fit
+  \ifnum\thetikzumlComponentLevel>0%
+        \def\tikzumlComponentFitTmp{\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname}%
+        \expandafter\xdef\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname{\tikzumlComponentFitTmp (\tikzumlProvidedInterface@nodeName-west-padding) (\tikzumlProvidedInterface@nodeName-west-port) }%
+      \fi%
+}%
+
+\newlength{\tikzuml@AC@xa}%
+\newlength{\tikzuml@AC@ya}%
+\newlength{\tikzuml@AC@xb}%
+\newlength{\tikzuml@AC@yb}%
+\newlength{\tikzuml@AC@xi}%
+\newlength{\tikzuml@AC@yi}%
+\newlength{\tikzuml@AC@xic}%
+\newlength{\tikzuml@AC@yic}%
+\newlength{\tikzuml@AC@xio}%
+\newlength{\tikzuml@AC@yio}%
+\newlength{\tikzuml@AC@AB}%
+\newlength{\tikzuml@AC@lambda}%
+\newlength{\tikzuml@AC@xtrc}%
+\newlength{\tikzuml@AC@ytrc}%
+\newlength{\tikzuml@AC@xtlc}%
+\newlength{\tikzuml@AC@ytlc}%
+\newlength{\tikzuml@AC@xblc}%
+\newlength{\tikzuml@AC@yblc}%
+\newlength{\tikzuml@AC@xbrc}%
+\newlength{\tikzuml@AC@ybrc}%
+\newlength{\tikzuml@AC@middleArm}%
+
+\newcommand{\umlassemblyconnectorsymbol}[2]{%
+  \ifthenelse{\NOT\equal{\tikzumlAssemblyConnectorLabel}{}}{%
+  \edef\tikzuml@ACStart@name{#1}%
+  \edef\tikzuml@ACEnd@name{#2}%
+  \edef\tikzuml@AC@width{\tikzumlAssemblyConnectorWidth}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzuml@ACStart@nodeName{\tikzuml@ACStart@name}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzuml@ACEnd@nodeName{\tikzuml@ACEnd@name}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzuml@ACInterface@nodeName{\tikzumlAssemblyConnectorSymbolName}}\x%
+  %
+  \pgfextractx{\tikzuml@AC@xa}{\pgfpointanchor{\tikzuml@ACStart@nodeName}{\tikzumlAssemblyConnectorStartAnchor}}%
+  \pgfextracty{\tikzuml@AC@ya}{\pgfpointanchor{\tikzuml@ACStart@nodeName}{\tikzumlAssemblyConnectorStartAnchor}}%
+  \pgfextractx{\tikzuml@AC@xb}{\pgfpointanchor{\tikzuml@ACEnd@nodeName}{\tikzumlAssemblyConnectorEndAnchor}}%
+  \pgfextracty{\tikzuml@AC@yb}{\pgfpointanchor{\tikzuml@ACEnd@nodeName}{\tikzumlAssemblyConnectorEndAnchor}}%
+  \pgfmathsetlength{\tikzuml@AC@xi}{0.5*\tikzuml@AC@xa+0.5*\tikzuml@AC@xb}%
+  \pgfmathsetlength{\tikzuml@AC@yi}{0.5*\tikzuml@AC@ya+0.5*\tikzuml@AC@yb}%
+  \pgfmathsetlength{\tikzuml@AC@AB}{veclen(\tikzuml@AC@xa-\tikzuml@AC@xb,\tikzuml@AC@ya-\tikzuml@AC@yb)}%
+  \pgfmathsetlength{\tikzuml@AC@lambda}{0.25*\tikzuml@AC@width/\tikzuml@AC@AB}%
+  \pgfmathsetlength{\tikzuml@AC@xic}{\tikzuml@AC@xi-\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa)}%
+  \pgfmathsetlength{\tikzuml@AC@yic}{\tikzuml@AC@yi-\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya)}%
+  \pgfmathsetlength{\tikzuml@AC@xio}{\tikzuml@AC@xi+\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa)}%
+  \pgfmathsetlength{\tikzuml@AC@yio}{\tikzuml@AC@yi+\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya)}%
+  \node[inner sep=0.5*\tikzuml@AC@width] (\tikzuml@ACInterface@nodeName-interface) at (\tikzuml@AC@xi,\tikzuml@AC@yi) {};%
+  \node[inner sep=0, text width=\tikzuml@AC@width, circle, draw=\tikzumlassemblyconnectordraw, fill=\tikzumlassemblyconnectorfill] (\tikzuml@ACInterface@nodeName-io) at (\tikzuml@AC@xio,\tikzuml@AC@yio) {};%
+  \begin{scope}%
+  \pgfmathsetlength{\tikzuml@AC@xtrc}{\tikzuml@AC@xic-2*\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya)}%
+  \pgfmathsetlength{\tikzuml@AC@ytrc}{\tikzuml@AC@yic+2*\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa)}%
+  \pgfmathsetlength{\tikzuml@AC@xbrc}{\tikzuml@AC@xic+2*\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya)}%
+  \pgfmathsetlength{\tikzuml@AC@ybrc}{\tikzuml@AC@yic-2*\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa)}%
+  \pgfmathsetlength{\tikzuml@AC@xtlc}{\tikzuml@AC@xic-3*\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya+\tikzuml@AC@xb-\tikzuml@AC@xa)}%
+  \pgfmathsetlength{\tikzuml@AC@ytlc}{\tikzuml@AC@yic+3*\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa+\tikzuml@AC@ya-\tikzuml@AC@yb)}%
+  \pgfmathsetlength{\tikzuml@AC@xblc}{\tikzuml@AC@xic+3*\tikzuml@AC@lambda*(\tikzuml@AC@yb-\tikzuml@AC@ya+\tikzuml@AC@xa-\tikzuml@AC@xb)}%
+  \pgfmathsetlength{\tikzuml@AC@yblc}{\tikzuml@AC@yic-3*\tikzuml@AC@lambda*(\tikzuml@AC@xb-\tikzuml@AC@xa+\tikzuml@AC@yb-\tikzuml@AC@ya)}%
+  \coordinate (\tikzuml@ACInterface@nodeName-trc) at (\tikzuml@AC@xtrc,\tikzuml@AC@ytrc);%
+  \coordinate (\tikzuml@ACInterface@nodeName-brc) at (\tikzuml@AC@xbrc,\tikzuml@AC@ybrc);%
+  \coordinate (\tikzuml@ACInterface@nodeName-tlc) at (\tikzuml@AC@xtlc,\tikzuml@AC@ytlc);%
+  \coordinate (\tikzuml@ACInterface@nodeName-blc) at (\tikzuml@AC@xblc,\tikzuml@AC@yblc);%
+  \clip (\tikzuml@ACInterface@nodeName-trc) --  (\tikzuml@ACInterface@nodeName-tlc) -- (\tikzuml@ACInterface@nodeName-blc) -- (\tikzuml@ACInterface@nodeName-brc) -- cycle;%
+  \node[inner sep=0, text width=\tikzuml@AC@width, circle, draw=\tikzumlassemblyconnectordraw, fill=\tikzumlassemblyconnectorfill] (\tikzuml@ACInterface@nodeName-ic) at (\tikzuml@AC@xic,\tikzuml@AC@yic) {};%
+  \end{scope}%
+  \node[above, font=\tikzumlfont] at (\tikzuml@ACInterface@nodeName-interface.north)
+ {\tikzumlAssemblyConnectorLabel};%
+  }{}%
+}%
+
+\newcommand{\umlassemblyconnector}[3][]{%
+  \def\tikzumlAssemblyConnectorWithPort{tikzumlFalse}%
+  \def\tikzumlAssemblyConnectorFirstArm{tikzumlFalse}%
+  \def\tikzumlAssemblyConnectorSecondArm{tikzumlFalse}%
+  \def\tikzumlAssemblyConnectorMiddleArm{tikzumlFalse}%
+  \def\tikzumlAssemblyConnectorLastArm{tikzumlFalse}%
+  \pgfkeys{/tikzuml/assemblyconnectorrelation/.cd,%
+           geometry/.initial=--, interface/.initial={},%
+           arm1/.initial={auto}, arm2/.initial={auto},%
+           name/.initial=connector-\thetikzumlConnectorNum, width/.initial=1em,%
+           anchor1/.initial={}, anchor2/.initial={},%
+           draw/.initial=\tikzumldrawcolor,%
+           fill assembly connector/.initial=\tikzumlfillassemblyconnectorcolor,%
+           fill port/.initial=\tikzumlfillportcolor,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{with port}}{%
+               \def\tikzumlAssemblyConnectorWithPort{tikzumlTrue}%
+             }{%
+               \ifthenelse{\equal{\keyname}{first arm}}{%
+                 \def\tikzumlAssemblyConnectorFirstArm{tikzumlTrue}%
+               }{%
+                 \ifthenelse{\equal{\keyname}{second arm}}{%
+                   \def\tikzumlAssemblyConnectorSecondArm{tikzumlTrue}%
+                 }{%
+                   \ifthenelse{\equal{\keyname}{middle arm}}{%
+                     \def\tikzumlAssemblyConnectorMiddleArm{tikzumlTrue}%
+                   }{%
+                     \ifthenelse{\equal{\keyname}{last arm}}{%
+                       \def\tikzumlAssemblyConnectorLastArm{tikzumlTrue}%
+                     }{%
+                     }%
+                   }%
+                 }%
+               }%
+             }%
+           }}%
+  \pgfkeys{/tikzuml/assemblyconnectorrelation/.cd, #1}%
+  \pgfkeys{/tikzuml/assemblyconnectorrelation/.cd,%
+           geometry/.get=\tikzumlAssemblyConnectorGeometry,%
+           name/.get=\tikzumlAssemblyConnectorName,%
+           interface/.get=\tikzumlAssemblyConnectorLabel,%
+           width/.get=\tikzumlAssemblyConnectorWidth,%
+           arm1/.get=\tikzumlAssemblyConnectorStartArm,%
+           arm2/.get=\tikzumlAssemblyConnectorEndArm,%
+           anchor1/.get=\umlAssemblyConnectorStartAnchor,%
+           anchor2/.get=\umlAssemblyConnectorEndAnchor,%
+           draw/.get=\tikzumlassemblyconnectordraw,%
+           fill assembly connector/.get=\tikzumlassemblyconnectorfill,%
+           fill port/.get=\tikzumlassemblyconnectorportfill}%
+  %
+  \edef\tikzumlAssemblyConnectorStart@name{#2}%
+  \edef\tikzumlAssemblyConnectorEnd@name{#3}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlAssemblyConnectorStart@nodeName{\tikzumlAssemblyConnectorStart@name}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlAssemblyConnectorEnd@nodeName{\tikzumlAssemblyConnectorEnd@name}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlAssemblyConnectorLabel@nodeName{\tikzumlAssemblyConnectorLabel}}\x%
+  %
+  \pgfextractx{\tikzuml@AC@xa}{\pgfpointanchor{\tikzumlAssemblyConnectorStart@nodeName}{center}}%
+  \pgfextracty{\tikzuml@AC@ya}{\pgfpointanchor{\tikzumlAssemblyConnectorStart@nodeName}{center}}%
+  \pgfextractx{\tikzuml@AC@xb}{\pgfpointanchor{\tikzumlAssemblyConnectorEnd@nodeName}{center}}%
+  \pgfextracty{\tikzuml@AC@yb}{\pgfpointanchor{\tikzumlAssemblyConnectorEnd@nodeName}{center}}%
+  %
+  \ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{--}}{%
+    \ifthenelse{\tikzuml@AC@xb>\tikzuml@AC@xa}{%
+      \def\tikzumlAssemblyConnectorStartAnchor{east}%
+      \def\tikzumlAssemblyConnectorEndAnchor{west}%
+    }{%
+      \def\tikzumlAssemblyConnectorStartAnchor{west}%
+      \def\tikzumlAssemblyConnectorEndAnchor{east}%
+    }
+  }{}%
+  %
+  \ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{-|}}{%
+    \ifthenelse{\tikzuml@AC@xb>\tikzuml@AC@xa}{%
+      \def\tikzumlAssemblyConnectorStartAnchor{east}%
+    }{%
+      \def\tikzumlAssemblyConnectorStartAnchor{west}%
+    }
+    \ifthenelse{\tikzuml@AC@yb>\tikzuml@AC@ya}{%
+      \def\tikzumlAssemblyConnectorEndAnchor{south}%
+    }{%
+      \def\tikzumlAssemblyConnectorEndAnchor{north}%
+    }
+  }{}%
+  %
+  \ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{|-}}{%
+    \ifthenelse{\tikzuml@AC@xb>\tikzuml@AC@xa}{%
+      \def\tikzumlAssemblyConnectorEndAnchor{west}%
+    }{%
+      \def\tikzumlAssemblyConnectorEndAnchor{east}%
+    }
+    \ifthenelse{\tikzuml@AC@yb>\tikzuml@AC@ya}{%
+      \def\tikzumlAssemblyConnectorStartAnchor{north}%
+    }{%
+      \def\tikzumlAssemblyConnectorStartAnchor{south}%
+    }
+  }{}%
+  %
+  \ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{-|-}}{%
+    \ifthenelse{\equal{\tikzumlAssemblyConnectorStartArm}{auto}}{%
+      \ifthenelse{\equal{\tikzumlAssemblyConnectorEndArm}{auto}}{%
+	\pgfmathsetlength{\tikzuml@AC@middleArm}{0.5 * \tikzuml@AC@xa + 0.5 * \tikzuml@AC@xb}%
+      }{%
+        \pgfmathsetlength{\tikzuml@AC@middleArm}{\tikzuml@AC@xb+\tikzumlAssemblyConnectorEndArm}%
+      }%
+    }{%
+      \pgfmathsetlength{\tikzuml@AC@middleArm}{\tikzuml@AC@xa+\tikzumlAssemblyConnectorStartArm}%
+    }%
+    \pgfmathparse{\tikzuml@AC@middleArm>\tikzuml@AC@xa}
+    \pgfmathparse{\tikzuml@AC@middleArm>\tikzuml@AC@xb}
+    \ifthenelse{\lengthtest{\tikzuml@AC@middleArm>\tikzuml@AC@xa}}{%
+      \def\tikzumlAssemblyConnectorStartAnchor{east}%
+    }{%
+      \def\tikzumlAssemblyConnectorStartAnchor{west}%
+    }
+    \ifthenelse{\lengthtest{\tikzuml@AC@middleArm>\tikzuml@AC@xb}}{%
+      \def\tikzumlAssemblyConnectorEndAnchor{east}%
+    }{%
+      \def\tikzumlAssemblyConnectorEndAnchor{west}%
+    }
+  }{}%
+  %
+  \ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{|-|}}{%
+    \ifthenelse{\equal{\tikzumlAssemblyConnectorStartArm}{auto}}{%
+      \ifthenelse{\equal{\tikzumlAssemblyConnectorEndArm}{auto}}{%
+	\pgfmathsetlength{\tikzuml@AC@middleArm}{0.5 * \tikzuml@AC@ya + 0.5 * \tikzuml@AC@yb}%
+      }{%
+        \pgfmathsetlength{\tikzuml@AC@middleArm}{\tikzuml@AC@yb+\tikzumlAssemblyConnectorEndArm}%
+      }%
+    }{%
+      \pgfmathsetlength{\tikzuml@AC@middleArm}{\tikzuml@AC@ya+\tikzumlAssemblyConnectorStartArm}%
+    }%
+    \ifthenelse{\tikzuml@AC@middleArm>\tikzuml@AC@ya}{%
+      \def\tikzumlAssemblyConnectorStartAnchor{north}%
+    }{%
+      \def\tikzumlAssemblyConnectorStartAnchor{south}%
+    }
+    \ifthenelse{\tikzuml@AC@middleArm>\tikzuml@AC@yb}{%
+      \def\tikzumlAssemblyConnectorEndAnchor{north}%
+    }{%
+      \def\tikzumlAssemblyConnectorEndAnchor{south}%
+    }
+  }{}%
+  %
+  \ifthenelse{\equal{\umlAssemblyConnectorStartAnchor}{}}{%
+  }{%
+    \def\tikzumlAssemblyConnectorStartAnchor{\umlAssemblyConnectorStartAnchor}%
+  }%
+  \ifthenelse{\equal{\umlAssemblyConnectorEndAnchor}{}}{%
+  }{%
+    \def\tikzumlAssemblyConnectorEndAnchor{\umlAssemblyConnectorEndAnchor}%
+  }%
+  %
+  \node[inner sep=0] (\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp) at (\tikzumlAssemblyConnectorStart@nodeName.\tikzumlAssemblyConnectorStartAnchor) {};%
+  \node[inner sep=0] (\tikzumlAssemblyConnectorEnd@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp) at (\tikzumlAssemblyConnectorEnd@nodeName.\tikzumlAssemblyConnectorEndAnchor) {};%
+  %
+  \umlrelation[style={tikzuml connector style}, #1]{\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp}{\tikzumlAssemblyConnectorEnd@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp}%
+  %
+  \ifthenelse{\equal{\tikzumlAssemblyConnectorWithPort}{tikzumlTrue}}{%
+    \node[inner sep=0.5*\tikzumlAssemblyConnectorWidth, rectangle, draw=\tikzumlassemblyconnectordraw, fill=\tikzumlassemblyconnectorportfill] (\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port) at (\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp) {};%
+    \node[inner sep=0.5*\tikzumlAssemblyConnectorWidth, rectangle, draw=\tikzumlassemblyconnectordraw, fill=\tikzumlassemblyconnectorportfill] (\tikzumlAssemblyConnectorEnd@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port) at (\tikzumlAssemblyConnectorEnd@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp) {};%
+  }{%
+    \node[inner sep=0] (\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port) at (\tikzumlAssemblyConnectorStart@nodeName.\tikzumlAssemblyConnectorStartAnchor) {};%
+    \node[inner sep=0] (\tikzumlAssemblyConnectorEnd@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port) at (\tikzumlAssemblyConnectorEnd@nodeName.\tikzumlAssemblyConnectorEndAnchor) {};%
+  }%
+  %
+  \addtocounter{tikzumlRelationNum}{-1}%
+  \ifthenelse{\equal{\tikzumlAssemblyConnectorName}{connector-\thetikzumlConnectorNum}}{%
+    \edef\tikzumlAssemblyConnectorName{relation-\thetikzumlRelationNum}%
+    \edef\tikzumlAssemblyConnectorSymbolName{\tikzumlAssemblyConnectorLabel@nodeName}%
+  }{%
+    \edef\tikzumlAssemblyConnectorSymbolName{\tikzumlAssemblyConnectorName}%
+  }%
+  %
+  \stepcounter{tikzumlRelationNum}%
+  %
+  \ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{--}}{%
+    \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorStart@nodeName}{\tikzumlAssemblyConnectorEnd@nodeName}%
+  }{%
+    \ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{-|}}{%
+      \ifthenelse{\equal{\tikzumlAssemblyConnectorFirstArm}{tikzumlTrue}}{%
+        \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorStart@nodeName}{\tikzumlAssemblyConnectorName-2}%
+      }{%
+        \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-2}{\tikzumlAssemblyConnectorEnd@nodeName}%
+      }%
+    }{%
+      \ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{|-}}{%
+        \ifthenelse{\equal{\tikzumlAssemblyConnectorFirstArm}{tikzumlTrue}}{%
+          \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorStart@nodeName}{\tikzumlAssemblyConnectorName-2}%
+        }{%
+          \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-2}{\tikzumlAssemblyConnectorEnd@nodeName}%
+        }%
+      }{%
+        \ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{-|-}}{%
+          \ifthenelse{\equal{\tikzumlAssemblyConnectorFirstArm}{tikzumlTrue}}{%
+            \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorStart@nodeName}{\tikzumlAssemblyConnectorName-2}%
+          }{%
+            \ifthenelse{\equal{\tikzumlAssemblyConnectorLastArm}{tikzumlTrue}}{%
+              \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-4}{\tikzumlAssemblyConnectorEnd@nodeName}%
+            }{%
+              \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-2}{\tikzumlAssemblyConnectorName-4}%
+            }%
+          }%
+        }{%
+          \ifthenelse{\equal{\tikzumlAssemblyConnectorGeometry}{|-|}}{%
+            \ifthenelse{\equal{\tikzumlAssemblyConnectorFirstArm}{tikzumlTrue}}{%
+              \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorStart@nodeName}{\tikzumlAssemblyConnectorName-2}%
+            }{%
+              \ifthenelse{\equal{\tikzumlAssemblyConnectorLastArm}{tikzumlTrue}}{%
+                \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-4}{\tikzumlAssemblyConnectorEnd@nodeName}%
+              }{%
+                \umlassemblyconnectorsymbol{\tikzumlAssemblyConnectorName-2}{\tikzumlAssemblyConnectorName-4}%
+              }%
+            }%
+          }{}%
+        }%
+      }%
+    }%
+  }%
+  \stepcounter{tikzumlConnectorNum}%
+}%
+
+% shortcuts of \umlassemblyconnector
+\newcommand{\umlHVassemblyconnector}[3][]{%
+  \pgfkeys{/tikzuml/HVassemblyconnector/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlHVassemblyconnector, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/HVassemblyconnector/.cd, #1}%
+  \umlassemblyconnector[geometry=-|, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlVHassemblyconnector}[3][]{%
+  \pgfkeys{/tikzuml/VHassemblyconnector/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+        \errmessage{TIKZUML ERROR : in umlVHassemblyconnector, forbidden option geometry}%
+      }{}%
+    }%
+  }%
+  \pgfkeys{/tikzuml/VHassemblyconnector/.cd, #1}%
+  \umlassemblyconnector[geometry=|-, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlHVHassemblyconnector}[3][]{%
+  \pgfkeys{/tikzuml/HVHassemblyconnector/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlHVHassemblyconnector, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/HVHassemblyconnector/.cd, #1}%
+  \umlassemblyconnector[geometry=-|-, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlVHVassemblyconnector}[3][]{%
+  \pgfkeys{/tikzuml/VHVassemblyconnector/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}}{%
+               \errmessage{TIKZUML ERROR : in umlVHVassemblyconnector, forbidden option geometry}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/VHVassemblyconnector/.cd, #1}%
+  \umlassemblyconnector[geometry=|-|, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlport}[3][]{%
+  \pgfkeys{/tikzuml/port/.cd,%
+           draw/.initial=\tikzumldrawcolor, fill/.initial=\tikzumlfillportcolor,%
+           width/.initial=1em,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \errmessage{TIKZUML ERROR : in umlport forbidden option \keyname}%
+           }}%
+  \pgfkeys{/tikzuml/port/.cd, #1}%
+  \pgfkeys{/tikzuml/port/.cd,%
+           width/.get=\tikzumlPortWidth,%
+           draw/.get=\tikzumlportdraw, fill/.get=\tikzumlportfill}%
+  \edef\tikzumlPort@name{#2}%
+  \edef\tikzumlPort@anchor{#3}%
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlPort@nodeName{\tikzumlPort@name}}\x%
+  %
+  \node[inner sep=0.5*\tikzumlPortWidth, rectangle, draw=\tikzumlportdraw, fill=\tikzumlportfill] (\tikzumlPort@nodeName-\tikzumlPort@anchor-port) at (\tikzumlPort@nodeName.\tikzumlPort@anchor) {};
+}
+
+\newcommand{\umldelegateconnector}[3][]{%
+  \def\tikzumlDelegateConnectorWithStartPort{tikzumlFalse}%
+  \def\tikzumlDelegateConnectorWithEndPort{tikzumlFalse}%
+  \pgfkeys{/tikzuml/delegateconnector/.cd,
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umldelegateconnector, forbidden option stereo}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/delegateconnector/.cd, #1}%
+  \umlrelation[style={tikzuml connector style}, stereo=delegate, #1]{#2}{#3}%
+}%
+
+
+% shortcuts of \umldelegateconnector
+\newcommand{\umlHVdelegateconnector}[3][]{%
+  \pgfkeys{/tikzuml/HVdelegateconnector/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}\OR\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlHVdelegateconnector, forbidden option \keyname}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/HVdelegateconnector/.cd, #1}%
+  \umldelegateconnector[geometry=-|, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlVHdelegateconnector}[3][]{%
+  \pgfkeys{/tikzuml/VHdelegateconnector/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}\OR\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlVHdelegateconnector, forbidden option \keyname}%
+             }{}%
+            }}%
+  \pgfkeys{/tikzuml/VHdelegateconnector/.cd, #1}%
+  \umldelegateconnector[geometry=|-, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlHVHdelegateconnector}[3][]{%
+  \pgfkeys{/tikzuml/HVHdelegateconnector/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}\OR\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlHVHdelegateconnector, forbidden option \keyname}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/HVHdelegateconnector/.cd, #1}%
+  \umldelegateconnector[geometry=-|-, #1]{#2}{#3}%
+}%
+
+\newcommand{\umlVHVdelegateconnector}[3][]{%
+  \pgfkeys{/tikzuml/VHVdelegateconnector/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \ifthenelse{\equal{\keyname}{geometry}\OR\equal{\keyname}{stereo}}{%
+               \errmessage{TIKZUML ERROR : in umlVHVdelegateconnector, forbidden option \keyname}%
+             }{}%
+           }}%
+  \pgfkeys{/tikzuml/VHVdelegateconnector/.cd, #1}%
+  \umldelegateconnector[geometry=|-|, #1]{#2}{#3}%
+}%
+%%% End of tikz-uml.sty
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ No newline at end of file
diff --git a/report/sections/appendix/appendix_add_material.tex b/report/sections/appendix/appendix_add_material.tex
index 4f12ee8..30e36cb 100644
--- a/report/sections/appendix/appendix_add_material.tex
+++ b/report/sections/appendix/appendix_add_material.tex
@@ -1,141 +1,141 @@
 
 \chapter{Additional Material}
 
 \section{Initial Protocol}
 
 \begin{figure}[h]
 \centering
 \input{sections/diagrams/protocol_diagram_old.tex}
 \caption{Sequence diagram of initial protocol between MU and SPU to compute suceptibility tests}
 \label{fig:protocol-mu-spu-old}
 \end{figure}
 
 \section{NIST Recommended Curves} \label{sec:nist-rec-curves}
 NIST named elliptic curves can be found in \reftab{tab:nist-curves}.
 %Available NIST named elliptic curves can be found in \reftab{tab:nist-curves-primary}, \reftab{tab:nist-curves-binary} and \reftab{tab:nist-curves-koblitz}.
 
 \newcommand{\tabnistprimary}{
 \begin{tabular}{l|l}
 Curve & Size [bit] \\
 \hline
 P-224	& 224\\
 P-256	& 256\\
 P-384	& 384\\
 P-521	& 521\\
 \end{tabular}
 }
 
 \newcommand{\tabnistbinary}{
 \begin{tabular}{l|l}
 Curve & Size [bit] \\
 \hline
 B-163	& 163\\
 B-233	& 233\\
 B-283	& 283\\
 B-409	& 409\\
 B-571	& 571\\
 \end{tabular}
 }
 
 \newcommand{\tabnistkoblitz}{
 \begin{tabular}{l|l}
 Curve & Size [bit] \\
 \hline
 K-163	& 163\\
 K-233	& 233\\
 K-283	& 283\\
 K-409	& 409\\
 K-571	& 571\\
 \end{tabular}
 }
 
-\begin{table}
+\begin{table}[H]
 	\centering
 	\subfloat[][]{\tabnistprimary}
 	~
 	\subfloat[][]{\tabnistbinary}
 	~
 	\subfloat[][]{\tabnistkoblitz}
 	
 	\caption{NIST recommended curves}
 	\label{tab:nist-curves}
 \end{table}
 
 
 
 %\begin{figure}
 %	\begin{subfigure}[b]{0.4\textwidth}{\tabnistprimary}
 %	\begin{subfigure}[b]{0.4\textwidth}{\tabnistbinary}
 %%	~
 %%	\begin{subfigure}[b]{0.2\textwidth}{\tabnistkoblitz}
 %\end{figure}
 
 %\begin{figure}
 %	\centering
 %	\tabnistprimary
 %	\begin{subfigure}[b]{0.3\textwidth}
 %
 %\caption{NIST aliases for SEC curves over primary fields}
 %\label{tab:nist-curves-primary}
 %	\end{subfigure}
 %	
 %	~
 %	
 %	\begin{subfigure}[b]{0.3\textwidth}
 %	\tabnistbinary
 %\caption{NIST aliases for SEC curves over binary fields}
 %\label{tab:nist-curves-binary}
 %	\end{subfigure}
 %	
 %	~
 %	
 %	\begin{subfigure}[b]{0.3\textwidth}
 %	\tabnistkoblitz
 %\caption{NIST aliases for SEC curves, Koblitz}
 %\label{tab:nist-curves-koblitz}
 %	\end{subfigure}
 %	
 %	\caption{NIST recommended curves} %\label{fig:nist-curves}
 %\end{figure}
 %
 %
 %\begin{table}
 %\begin{tabular}{l|l}
 %Curve & Size [bit] \\
 %\hline
 %P-224	& 224\\
 %P-256	& 256\\
 %P-384	& 384\\
 %P-521	& 521\\
 %\end{tabular}
 %\caption{NIST aliases for SEC curves over primary fields}
 %\label{tab:nist-curves-primary}
 %\end{table}
 %
 %\begin{table}
 %\begin{tabular}{l|l}
 %Curve & Size [bit] \\
 %\hline
 %B-163	& 163\\
 %B-233	& 233\\
 %B-283	& 283\\
 %B-409	& 409\\
 %B-571	& 571\\
 %\end{tabular}
 %\caption{NIST aliases for SEC curves over binary fields}
 %\label{tab:nist-curves-binary}
 %\end{table}
 %
 %\begin{table}
 %\begin{tabular}{l|l}
 %Curve & Size [bit] \\
 %\hline
 %K-163	& 163\\
 %K-233	& 233\\
 %K-283	& 283\\
 %K-409	& 409\\
 %K-571	& 571\\
 %\end{tabular}
 %\caption{NIST aliases for SEC curves, Koblitz}
 %\label{tab:nist-curves-koblitz}
 %\end{table}
\ No newline at end of file
diff --git a/report/sections/appendix/appendix_specs.tex b/report/sections/appendix/appendix_specs.tex
index 9d52b86..c215416 100644
--- a/report/sections/appendix/appendix_specs.tex
+++ b/report/sections/appendix/appendix_specs.tex
@@ -1,55 +1,125 @@
 \chapter{Technical Specifications}
 
 \section{Messages Format} \label{sec:spec-messages-format}
 We present here the Document Type Definition specifying the XML document format of the requests and replies exchanged between the client and the \lstinline{Request Manager} and \lstinline{Decrypt} service.
 
 
 \subsection{GetMaterial Request Format}
 DTD for GetMaterial Request can be found in \reffig{fig:spec-dtd-rqt-material}.
 \begin{figure}
 \lstinputlisting{external_dependencies/DTDs/request_material.dtd}
 \caption{GetMaterial Request message DTD for Request Manager web service.}
 \label{fig:spec-dtd-rqt-material}
 \end{figure}
 
 
 \subsection{GetMaterial Reply Format}
 DTD for GetMaterial Reply can be found in \reffig{fig:spec-dtd-awr-material}.
 \begin{figure}
 \lstinputlisting{external_dependencies/DTDs/answer_material.dtd}
 \caption{GetMaterial Reply message DTD for Request Manager web service.}
 \label{fig:spec-dtd-awr-material}
 \end{figure}
 
 
 \subsection{Decrypt Request Format}
 DTD for Decrypt Request can be found in \reffig{fig:spec-dtd-rqt-decrypt}.
 \begin{figure}
 \lstinputlisting{external_dependencies/DTDs/request_decrypt.dtd}
 \caption{Decrypt Request message DTD for Decrypt web service.}
 \label{fig:spec-dtd-rqt-decrypt}
 \end{figure}
 
 
 \subsection{Decrypt Reply Format}
 DTD for Decrypt Reply can be found in \reffig{fig:spec-dtd-awr-decrypt}.
 \begin{figure}
 \lstinputlisting{external_dependencies/DTDs/answer_decrypt.dtd}
 \caption{Decrypt Reply message DTD for Decrypt web service.}
 \label{fig:spec-dtd-awr-decrypt}
 \end{figure}
 
 
 \section{Full Architecture Diagram of SHCS}
-\missingfigure{Full diagram grouping 2 previous ones}
+\reffig{fig:ws-full} describes the full system architecture of the client (desktop or mobile application) and a 
+\begin{figure}
+\centering
+\includegraphics[width=\textwidth]{sections/diagrams/web_service_full.pdf}
+\caption{Full system architecture for online phase for SHCS and client.}
+\label{fig:ws-full}
+\end{figure}
+
 
 \section{Application Libraries Used}
 \todo[inline]{Add dependencies}
 
 \section{Database Tables}
+\todo[inline]{Add links between tables}
 
 \subsection{Client Local Tables}
-\todo[inline]{Add database tables descriptions}
+\begin{tikzpicture}
+\begin{umlpackage}[x=0,y=0]{client-database}
+\umlclass[type=table]{cf\_t}{
+	\stereotype{PK} ID\_t : int \\
+	\stereotype{PK} ID\_cf : int
+}{}
+
+\umlclass[type=table, x=4]{m\_t}{
+	ID\_t : int \\
+	ID\_m : int
+}{}
+
+\umlclass[type=table, x=8]{cryptokeys}{
+	ID\_p : int \\
+	value : blob \\
+	isPublic : bit(1)
+}{}
+
+\umlclass[type=table, x=12]{markers}{
+	\umlattrib{ID\_m}{varchar}{NN} \\
+	\stereotype{NN} ID\_m : varchar \\
+	chr : varchar \\
+	position : int \\
+	risk\_allele : varchar \\
+	ref\_allele : varchar \\
+	maf : double
+}{}
+\end{umlpackage}
+\end{tikzpicture}
+
 
 \subsection{Server Tables}
-\todo[inline]{Add database tables descriptions}
+\begin{tikzpicture}
+\begin{umlpackage}[x=0,y=0]{server-database}
+\umlclass[type=table, x=0]{cryptokeys}{
+	ID\_p : int \\
+	value : blob \\
+	isPublic : bit(1)
+}{}
+
+\umlclass[type=table, x=4]{m\_p}{
+	\umlattrib{ID\_p}{int} \\
+	\umlattrib{ID\_m}{varchar} \\
+	\umlattrib{enc\_genotype\_1}{blob} \\
+	\umlattrib{enc\_genotype\_2}{blob}
+}{}
+
+\umlclass[type=table, x=8]{cf\_p}{
+	\umlattrib{ID\_p}{int} \\
+	\umlattrib{ID\_cf}{varchar} \\
+	\umlattrib{enc\_cf\_1}{blob} \\
+	\umlattrib{enc\_cf\_2}{blob}
+}{}
+
+\umlclass[type=table, x=12]{hla\_p}{
+	\umlattrib{ID\_p}{int} \\
+	\umlattrib{enc\_hla\_A\_1}{blob} \\
+	\umlattrib{enc\_hla\_A\_2}{blob} \\
+	\umlattrib{enc\_hla\_B\_1}{blob} \\
+	\umlattrib{enc\_hla\_B\_2}{blob} \\
+	\umlattrib{enc\_hla\_C\_1}{blob} \\
+	\umlattrib{enc\_hla\_C\_2}{blob}
+}{}
+\end{umlpackage}
+\end{tikzpicture}
+
diff --git a/report/sections/crypto_background.tex b/report/sections/crypto_background.tex
index 63b43ec..be55437 100644
--- a/report/sections/crypto_background.tex
+++ b/report/sections/crypto_background.tex
@@ -1,174 +1,171 @@
 % Ortho checked pre JL
 \chapter{Cryptographic Background} \label{crypto-background}
 
 In the first section of this chapter, we want to build an Elliptic Curve Cryptosystem based on ElGamal. We follow the procedure described in \citep{DBLP:journals/corr/abs-0903-3900} to build an additive homomorphic scheme.
 In the second section, we extend this cryptosystem with Shamir Secret Sharing in order to split the secret between two parties, e.g. MU and SPU.
 In the third section, we discuss various design decisions.
 
 
 \section{Traditional Ellitpic Curve ElGamal Cryptosystem (ECCEG)}
 
 %----------------------------------------------------------------------------------------
 %	Setup
 %----------------------------------------------------------------------------------------
 
 \subsection{Setup} \label{ecceg-setup}
 
-Let $E$ be an elliptic curve over finite filed $\mathbb{GF}(p)$, the order of the curve $E$ be $n = \#E$ the cardinality of $E$, $G$ the generator point of curve $E$.
-
-Also, let $x \in \mathbb{GF}(p)$ be the secret key and $Y = xG$ be the public key.
+Let $E$ be an elliptic curve over finite filed $\mathbb{GF}(p)$, the order of the curve $E$ be $n = \#E$ the cardinality of $E$, $G$ the generator point of curve $E$. Also, let $x \in \mathbb{GF}(p)$ be the secret key and $Y = xG$ be the public key.\par
 
 In order to define an additively homomorphic scheme \citep{DBLP:journals/corr/abs-0903-3900}, we define the function
 \begin{align*}
 	map \colon	\mathbb{GF}(p) &  \longrightarrow  E \\
 			 	m & \longmapsto mG
 \end{align*}
 such that the $map(\cdot)$ function is additively homomorphic, i.e.
 $$map(m_1 + m_2)  = map(m_1) + map(m_2).$$
 Similarly, we define the reverse mapping function $rmap(\cdot)$ that extract $m$ from a given point $mG$, i.e. $$rmap(map(m)) = m.$$
 
-By definition, this mapping is additively homomorphic. However it has the inconvenient to be hard to revert. Extracting $m$ from $mG$ is known as the Elliptic Curve Discrete Logarithm Problem \todo{Add ref for that, no Internet} and is known to be hard to solve. As this $map(\cdot)$ is a trapdoor function, we store compute and store beforehand a lookup table to reverse the mapping. This design decision is further discussed in \todo[inline]{Add ref to section}.
+By definition, this mapping is additively homomorphic. However it has the inconvenient to be hard to revert. Extracting $m$ from $mG$ is known as the Elliptic Curve Discrete Logarithm Problem and is known to be hard to solve \citep{Koblitz1987}. As this $map(\cdot)$ is a trapdoor function, we compute and store beforehand a lookup table to reverse the mapping. This is further discussed in \refsection{ecceg-mapping-decision}.
 
 
 %----------------------------------------------------------------------------------------
 %	Encryption
 %----------------------------------------------------------------------------------------
 
 \subsection{Encryption}
 The encryption procedure for ECCEG scheme is described in Algorithm~\ref{alg-ecceg-enc}.
 
-\begin{algorithm}
+\begin{algorithm}[H]
 \caption{EC ElGamal Encryption}
 \label{alg-ecceg-enc}
 \begin{algorithmic}
 \REQUIRE public key $Y$, plaintext $m$
 \ENSURE ciphertext $(R,S)$
 \STATE choose random $k\in [1,n-1]$
 \STATE $M := map(m)$
 \STATE $R := kG$
 \STATE $S := M + kY$
 \RETURN $(R,S)$
 \end{algorithmic}
 \end{algorithm}
 
 %----------------------------------------------------------------------------------------
 %	Decryption
 %----------------------------------------------------------------------------------------
 
 \subsection{Decryption}
-The decryption procedure for ECCEG scheme is described in Algorithm~\ref{alg-ecceg-dec}.
+The decryption procedure for ECCEG scheme is described in Algorithm~\ref{alg-ecceg-dec}. The proof of the decryption can be found in \refappendix{proof-ecceg-dec}.
 
-\begin{algorithm}
+\begin{algorithm}[H]
 \caption{EC-ElGamal Decryption}
 \label{alg-ecceg-dec}
 \begin{algorithmic}
 \REQUIRE secret key $x$, ciphertext $(R,S)$
 \ENSURE plaintext $m$
 \STATE $M := -xR + S$
 \STATE $m := rmap(M)$
 \RETURN $m$
 \end{algorithmic}
 \end{algorithm}
 
-The proof of the decryption can be found in \refappendix{proof-ecceg-dec}.
 
 %----------------------------------------------------------------------------------------
 %	Homomorphic Properties
 %----------------------------------------------------------------------------------------
 \subsection{Homomorphic Properties}
 ElGamal on Elliptic Curve with our mapping function has by design the interesting property to be additively homomorphic and homomorphic for multiplication by a scalar. Proofs for both homomorphic properties can be found in \refappendix{proof-homo-add} and \refappendix{proof-homo-scale}.
 
 
 %----------------------------------------------------------------------------------------
 \section{Elliptic Curve ElGamal Threshold Cryptosystem (ECCEG-TC)}
 In order to share the security of the genomic material between the MU and the SPU, we introduce the notion of Threshold Cryptosystem on top of EC-ElGamal cryptosystem. With a $(t,n)$-Threshold Cryptosystem, a ciphertext can only be decrypted if at least $t$ parties among $n$ participating collaborate to decrypt the ciphertext. If less than $t$ parties collaborate to decrypt the ciphertext, they obtain no useful information on the plaintext.
 
 Here we use a degenerated version of a $(t,n)$-Threshold Cryptosystem where $2$ parties among $2$ collaborate to decrypt the ciphertext, i.e. $(t,n) = (2,2)$.
 
 In order to build a Threshold Cryptosystem on top of ECCEG, we follow \citep{Ruan2012} which applies Shamir Secret Sharing with Lagrange Interpolation to Elliptic Curve ElGamal. Precisions on Lagrange Interpolation and Shamir Secret Sharing can be found in \refappendix{ecceg-tc-basis}.
 
 
 %----------------------------------------------------------------------------------------
 \subsection{ECCEG-TC Key Generation}
 
-Assume from now that there are only two parties share the parts of the secret key. The public key $PK$ is generated and distributed to all parties. The party distributing the keys generates partial keys $SK_1$, $SK_2$ and distributes one to every party participating. The ECCEG-TC Key Generation procedure is described in \refalgo{alg-ecceg-tc-key}.
+Assume from now that only the SPU and MU share parts of the secret key. The public key $PK$ is generated and distributed to all parties. The Key Manager distributing the key shares generates partial keys $SK_1$, $SK_2$ and distributes one to every party participating. The ECCEG-TC Key Generation procedure is described in \refalgo{alg-ecceg-tc-key}.
 
-\begin{algorithm}
+\begin{algorithm}[H]
 \caption{ECCEG-TC Key Generation}
 \label{alg-ecceg-tc-key}
 \begin{algorithmic}
-\REQUIRE secret key $a$, generator $g$ on $E_p$
+\REQUIRE secret key $a$, generator $g$ on elliptic curve $E$
 \ENSURE public key $PK = (E, g, y)$, secret keys $SK_i, \; \forall i = 1,2$
 \STATE $y := ag$
 \STATE select randomly $a_1 \in \mathbb{Z}_q$
 \STATE $a_0 := a$
 \STATE $SK_i := f(i) \mod q = a_0 + a_1 i \mod q, \; i=1,2$
 \end{algorithmic}
 \end{algorithm}
 
 \subsection{ECCEG-TC Encryption}
 The encryption for ECCEG-TC is the same as with ECCEG based on the same public key. \refalgo{alg-ecceg-tc-enc} describes the encryption procedure of a message.
 
-\begin{algorithm}
+\begin{algorithm}[H]
 \caption{ECCEG-TC Encryption}
 \label{alg-ecceg-tc-enc}
 \begin{algorithmic}
 \REQUIRE public key $y$, plaintext $m$
 \ENSURE ciphertext $(R,S)$
 \STATE choose random $k\in \mathbb{Z}_q$
 \STATE $M := map(m)$
 \STATE $R := kg$
 \STATE $S := M + ky$
 \RETURN $(R,S)$
 \end{algorithmic}
 \end{algorithm}
 
 \subsection{ECCEG-TC Decryption}
 
 The partial decryption is slightly different than the traditional ECCEG decryption procedure. Every party decrypts the ciphertext using its secret key share $SK_i$ following the procedure described in \refalgo{alg-ecceg-tc-pdec} and outputs a fragment $(i, R, S, T_i)$. Then a party collects all the 2 fragments. It assembles both of the fragments using the procedure described in \refalgo{alg-ecceg-tc-fdec} and obtains the cleartext message. Details on how to compute the $b_i$ factor in \refalgo{alg-ecceg-tc-fdec} can be found in \refappendix{shamir-secret}.
 
-\begin{algorithm}
+\begin{algorithm}[H]
 \caption{ECCEG-TC Partial Decryption}
 \label{alg-ecceg-tc-pdec}
 \begin{algorithmic}
 \REQUIRE partial secret key $SK_i$, ciphertext $(R,S)$
 \ENSURE decryption fragment $(i, R, S, T_i)$
 \STATE $T_i := R \cdot SK_i$
 \RETURN $(i, R, S, T_i)$
 \end{algorithmic}
 \end{algorithm}
 
-\begin{algorithm}
+\begin{algorithm}[H]
 \caption{ECCEG-TC full decryption}
 \label{alg-ecceg-tc-fdec}
 \begin{algorithmic}
 \REQUIRE decryption fragments $(i, R, S, T_i), \; \forall i=1,2$
 \ENSURE plaintext $m$
 \STATE $b_1 = 2 \mod q, b_2 = -1 \mod q$
 \STATE $F := \sum_{j=1}^{2} b_j T_j = ky$
 \STATE $M := S - v = M + ky - F$
 \STATE $m := rmap(M)$
 \RETURN $m$
 \end{algorithmic}
 \end{algorithm}
 
 %----------------------------------------------------------------------------------------
 %	Design Decisions
 %----------------------------------------------------------------------------------------
 \section{Design Decisions}
 
 \subsection{Bijection between Message Space and Elliptic Curve} \label{ecceg-mapping-decision}
 
 As the mapping described in \refsection{ecceg-setup} is hard to reverse, an effort was made to investigate other homomorphic mappings.
 
 The common use of ElGamal on Elliptic Curve does not require a deterministic mapping between message space and elliptic curve. Common encryption schemes such as Elliptic Curve Integrated Encryption Scheme (ECIES) or Hashed ElGamal \citep{chevallier2006encoding} do not process messages on elliptic curve space. As such schemes loose the homomorphic property we need, we investigate deterministic homomorphic mappings from message space onto elliptic curve.
 
 There exist probabilistic mappings \citep{Koblitz1987} \citep[chap. 2.4]{fouque2013injective} of message space onto elliptic curve, but none of them map the full message space onto the Elliptic Curve. Some more complex probabilistic mappings \citep{king2009mapping} appear to map a larger range of the message space.
 
 Finally according to \citep[chap. 4]{fouque2013injective}, it is not possible to find a full mapping between message space and Elliptic Curve.
 
 As no mapping found are deterministic and map the full message space onto the curve, we decided to use the mapping described in \refsection{ecceg-setup} and create a lookup table storing the ciphertext and plaintext for the whole message space. As our application using this cryptosystem uses only a small message space \todo[inline]{add ref to section speaking about message size}, it is reasonable to generate, store and query a lookup table for the whole message space.
 \todo[inline]{Add discussion of lookup table sizes and runtime}
 
 
 
diff --git a/report/sections/deployment.tex b/report/sections/deployment.tex
index 02df108..19bf05e 100644
--- a/report/sections/deployment.tex
+++ b/report/sections/deployment.tex
@@ -1,214 +1,216 @@
 \chapter{Deployment into Production Environment}
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%
 % State of the Project
 \section{State of the Project}
 
 
 \subsection{Swiss HIV Cohort Study}
-The Swiss HIV Cohort Study (SHCS) is an ongoing research project dealing with HIV infected adults. It regroups 7 outpatient clinics and ten laboratories involving almost all researchers implicated in patient-oriented HIV research in Switzerland. SHCS main objective is to perform and facilitate a wide range of timely research projects of high quality through their national network of collaborators and throughout interdisciplinary collaboration with any interested partner. SHCS aims to collect in a systematic way patient-related data and provide the infrastructure for it in order to facilitate research and improve the high standard of care of HIV infected patients in Switzerland\citep{shcs-intro,shcs-obj}.
+The Swiss HIV Cohort Study (SHCS) is an ongoing research project dealing with HIV infected adults. It regroups 7 outpatient clinics and 10 laboratories involving almost all researchers implicated in patient-oriented HIV research in Switzerland. SHCS main objective is to perform and facilitate a wide range of timely research projects of high quality through their national network of collaborators and throughout interdisciplinary collaboration with any interested partner. SHCS aims to collect in a systematic way patient-related data and provide the infrastructure for it in order to facilitate research and improve the high standard of care of HIV infected patients in Switzerland\citep{shcs-intro,shcs-obj}.
 
 
 \subsection{State of the Protocol}
-In a first step, the genomic and non-genomic data are stored in SHCS data centers in plaintext only. The susceptibility tests are performed on plaintext. Hence the current configuration does not provide any privacy to SHCS patients.\par
+In a first step, the genomic and non-genomic data of each patient in the study are stored in SHCS data centers anonymized but in plaintext. The susceptibility tests are performed on plaintext values and reported on pdf reports to the clinician. Hence the current configuration does not provide any privacy to SHCS patients since as shown by several research contributions \citep{lin04}, standard anonymization techniques for genomic data are not sufficient to guarantee individuals' privacy.\par
+
 Our goal is to deploy our improved scheme at the SHCS to provide efficient susceptibility tests and protect the privacy of the patients and MUs.
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%
 % Constraints
 \section{Constraints}
-Medical and specially genomic data privacy is a highly important topic for medical data storage providers. As SHCS stores the genomic and non-genomic data on its servers, there are many security mechanisms put in place to restrict the access to the data. In consequence, getting granted a direct access to the databases storing the data or accessing our own application running within SHCS infrastructure was not possible in the time frame of this project. The mitigations to the constraints presented bellow result from discussions with SHCS data center administrators.
+Medical and specially genomic data privacy is a highly important topic for medical data storage providers. As SHCS stores the genomic and non-genomic data on its servers, there are many security mechanisms put in place to restrict the access to the data. In consequence, getting granted a direct access to the databases storing the data or accessing our own application running within SHCS infrastructure was not possible in the time frame of this project. After discussions with SHCS data center administrators, we decided that the client application would access SHCS infrastructure using web services. Web services are easily deployable and their message format is precisely defined using Web Services Description Language (WSDL) files. Furthermore, they are platform, programming language and library independent which is of a great advantage as heterogeneous devices will access their services. The detailed mitigations to the constraints presented bellow result from discussions with SHCS data center administrators.
 
 \subsection{Storage Infrastructure}
 Getting a direct access to the database at SHCS data centers was not something achievable in the short time frame of this project.\par
 
 An available workaround is to deploy a web service which would query the databases directly. The web service is within SHCS firewall. As getting a web service deployed could be easily granted, we decided to choose this approach. SHCS setup is described in \reffig{fig:ws-request-manager}.
 
 \begin{figure}
 \centering
 \includegraphics[width=\textwidth]{sections/diagrams/web_service_request_manager.pdf}
 \caption{Request Manager Web Service behind SHCS firewall with back-end databases access.}
 \label{fig:ws-request-manager}
 \end{figure}
 
 % Computing Backend Instrastructure
 \subsection{Computing Backend Infrastructure} \label{sec:constraint-backend-infra}
-In our protocol, the SPU needs to decrypt partially some encrypted data and send it back to the MU. In the SHCS configuration, this was not something which could be trivially be achieved as a service running on their back-ends within the data center could not establish communications outside of the firewall.\par
+In our protocol, the SPU needs to decrypt partially some encrypted data and send it back to the MU. In the SHCS configuration, this was not something which could be trivially achieved as a service running on their back-ends within the data center could not establish communications outside of the firewall.\par
 
 One solution proposed was that the web service and the server communicate using databases as incoming and outgoing message queues. SHCS setup is described in \reffig{fig:ws-decrypt}. On a new request, the web service inserts it to \lstinline{Request} database. The server periodically fetches the results from \lstinline{Request} database. As every request is characterized by a \lstinline{patientId}, the server retrieves the corresponding secret key share form \lstinline{Cryptographic keys} database. It then decrypts partially the ciphertexts and inserts the serialized results to \lstinline{Reply} database. The web service also periodically fetches the results from \lstinline{Reply} database and forwards the reply to the client.
 
 Due to SHCS policy and system constraints, it appears not to be possible to run the server more often than every 2 minutes. In consequence, the expected delay for a request to be processed is 1 minute. This hard constraint influence the design of our protocol, and is particularly discussed in \refsection{sec:mod-all-tests}.
 
 \begin{figure}
 \centering
 \includegraphics[width=\textwidth]{sections/diagrams/web_service_decrypt.pdf}
 \caption{Decrypt Web Service behind SHCS firewall with Request and Reply database queues, Server App running on back-end system and Cryptographic Key Share database.}
 \label{fig:ws-decrypt}
 \end{figure}
 
 % Client infrastructure
 \subsection{Client Infrastructure} \label{sec:constraint-client-infra}
 The client infrastructure is also subject to strict policies. In our initial setup, the client was running a MySQL database locally in order to store cryptographic keys as well as SNP weights per tests. MySQL is not installed by default on SHCS clients and installing a new software is again subject to strict policies. A mitigation found was to use the already available Microsoft Access database instead of MySQL database. As we use only very simple database declarations, the syntax of Microsoft Access does not change from MySQL.
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%
 % Design
 \section{Design}
 
 % Protocol modifications
 \subsection{Protocol Modifications} \label{sec:prot-modif}
-In order to limit the complexity of the system, little modifications were put in place in order to reduce the calls the web services at SHCS.\par
+In order to limit the complexity of the system, little modifications were put in place in order to reduce the calls to the web services at SHCS.\par
 
 We can distinguish two types of operations. First we need to be able to retrieve the genomic and non-genomic material from the databases at SPU. Second we need to decrypt the result of a test and the values of the HLAs. We define two services \verb#Request Manager# and \verb#Decrypt# services. The \verb#Request Manager# service retrieves from the databases the SNPs, CFs and HLAs given the SNP markers and CF identifiers. The \verb#Decrypt# service decrypts partially a list of encrypted tests results as well as the values of the HLAs.\par
 
-Also, we wanted to address the possibility to protect the Intellectual Property of the SNP weights during the susceptibility test computation. Computing the encrypted test result at MU instead of SPU allows us to hide the SNP weights from the SPU.\par
+Furthermore, we wanted to address the possibility to protect the Intellectual Property of the SNP weights during the susceptibility test computation. Computing the encrypted test result at MU instead of SPU allows us to hide the SNP weights from the SPU.\par
 
 \begin{figure}
 \centering
 \input{sections/diagrams/protocol_diagram.tex}
 \caption{Sequence diagram of modified protocol between MU and SPU to compute susceptibility tests}
 \label{protocol-mu-spu-new}
 \end{figure}
 
 \begin{enumerate}
 	\item \lstinline{getMaterial( materialRequest )}: ask for the material required for a susceptibility test. \lstinline{material Request} is composed of a \lstinline{List(SNP_marker)} and of a \lstinline{List(CF_id)}.
 
 	\item \verb#return materialReply#: return the material required for a suceptibility test. \verb#materialReply# is composed of a \verb#List(SNP)#, a \verb#List(CF)# and a \verb#List(HLA)#.
 
 	\item \lstinline{decrypt( decryptRequest )}: ask for decryption of encrypted test results. \lstinline{decryptRequest} is composed of a \lstinline{List(EncryptedTestResult)} and a \lstinline{List(HLA)}.
 	
 	\item \lstinline{return decryptReply}: return the partially decrypted results and HLAs. \lstinline{decryptReply} is composed of a \lstinline{List(PartialDecryptedTestResult)} and a \lstinline{List(PartialDecryptedHLA)}.
 \end{enumerate}
 
 The old protocol is referenced in \reffig{fig:protocol-mu-spu-old}. Some key modifications to the protocol are described and discussed in \refsection{sec:prot-mod-discussion}.
 
 % Protocol Modification Discussion
 \subsection{Protocol Modifications Discussions} \label{sec:prot-mod-discussion}
 
 %--
 \subsubsection{Pack the HLAs with SNPs and CFs} \label{sec:mod-pack-hla-snp-cf}
 Due to the separation of services of database queries and decryption, the HLAs are automatically packaged with the answer of the \lstinline{GetMaterial} call to \lstinline{Request Manager} service.\par
 
-This modification increases a bit the communication overhead to \lstinline{Decrypt} Service as the HLAs will have to be sent along the encrypted test results. However this slightly overhead simplifies a lot the deployment of the solution as it avoids the need of a third service which would query the database for HLAs and partially decrypt them.
+This modification increases a bit the communication overhead to \lstinline{Decrypt} Service as the HLAs will have to be sent along the encrypted test results. However this slight overhead simplifies a lot the deployment of the solution as it avoids the need of a third service which would query the database for HLAs and partially decrypt them.
 
 %--
 \subsubsection{Query all SNPs for all Potential Tests} \label{sec:mod-all-tests}
 There are some particular cases where you need to run more complex tests if the first results are not conclusive (e.g. EFV PHARMACOKINETICS\_CYP2B6 or HIV Progression Test). The previous version of the protocol was running the first test and depending on the decrypted test results, running the subsequent tests. Due to the delay of the \lstinline{Decrypt} Service, this protocol is not longer satisfactory. The proposed solution is to get the required material for all potential tests at once. This implies again a communication overhead between the client and all services, but avoid stacking multiple decryption delays which would impact the end-user.
 
 %--
 \subsubsection{Tradeoff between Communication Overhead and Delay}
 As described in \refsection{sec:mod-pack-hla-snp-cf} and \refsection{sec:mod-all-tests}, our modifications involve communication overhead. We present here our motivations to prefer a communication overhead for the sake of lower delay.\par
 
 As described in \refsection{sec:constraint-backend-infra}, every test has an expected delay of 1 minute and 2 minutes in worst cases. Running nested tests (e.g. EFV PHARMACOKINETICS\_CYP2B6 or HIV Progression Test) sequentially would involve stacking multiple 2 minutes delays, which would deteriorate the end-user experience of the application.\par
 
 For the current 19 available tests, two of them, EFV PHARMACOKINETICS\_CYP2B6 and HIV Progression Test, may require nested test calls up to 2 subsequent calls. In worst case, a test needs up to 21 SNPs (for Coronary Artery Disease, CAD) and up to 6 CFs (for CAD). Taking a conservative approach, the communication overhead resulting from the 27 encoded ciphertext is roughly $27 \cdot 270 \byte = 7290 \byte$ (taking the weight of one encoded ciphertext under a strong elliptic curve to the sense of \refsection{sec:perf-analysis}). In consequence for the 3 additional tests, we have an overhead of $3 \cdot 7290 \byte = 21870 \byte$, which is really modest in comparison of having at least a 5 minute delay to decrypt the results of the test by \lstinline{Decrypt} web service.
 
 
 % Web Service Limitations
 \subsection{Web Service Limitations}
 In order to facilitate the deployment of the web service at SHCS, we decided to simplify the service as much as possible. Also, as we will need a local web service running to test the code and to have the possibility to continue running our application locally, we needed to choose a technology which is standard, easily deployable, and requires little development.\par
 
 In opposition to common trend to use RESTful web services (allowing representational state transfer), we decide to use stateless web services as it simplifies the deployment of solution at SHCS and does not bring any benefit.\par
 
 In a first phase, Document Type Definitions (DTD) have been designed for requests and replies for both services. This allows us to agree with SHCS IT administrators on the messages format for both web services. The full description of these specifications can be found in \refappendix{sec:spec-messages-format}. In a second phase, a WSDL (Web Service Description Language) description will have to be written (or generated) for proper compatibility between the web services running at SHCS and EPFL.
 
 
 \subsection{Client Databases Migration to Microsoft Access}
 Clients use a local database to store basic patient demographic information as well as cryptographic key shares but also information on test weights.\par
 
 In our previous application, clients were using local MySQL databases. However as discussed in \refsection{sec:constraint-client-infra}, MySQL cannot be deployed in a reasonable time. We decide to migrate to Microsoft Access databases as it is already deployed on clients.\par
 
 The implementation of the solution using Microsoft Access is described in \refsection{sec:impl-migr-access}.
 
 
 \subsection{SPU Database Migration to Oracle}
 The initial server application was using MySQL databases to store genomic, non-genomic and cryptographic keys. SHCS databases uses Oracle as database vendor. Implementation details are described in \refsection{sec:impl-migr-oracle}.
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%
 % Implementation
 \section{Implementation}
 
 The initial code was separated over three independant projects:
 
 \begin{enumerate}
 \item \lstinline{PPPClient}: client application run by the MU,
 \item \lstinline{PPPServer}: server application run by the SPU,
 \item \lstinline{PPPCertifiedInstitution}: certified institution run by the CI.
 \end{enumerate}
 
 % Preparation work
 \subsection{Preparation Work}
 
 Preparatory work was needed in order to replace various module of the current solution. A first issue was that the cryptographic, database, message and other classes were duplicated over the \lstinline{PPPClient}, \lstinline{PPPServer} and \lstinline{PPPCertifiedInstitution} applications.\par
 
 A fourth project \lstinline{PPPCommons} was created in order to group all similar classes within one project containing all helper, network communication, database communication, cryptographic libraries and message classes.\par
 
 Grouping all these common classes within one project required generalizing some classes, and extending these within the specific end-user projects. An example is the database communication module which was in large parts duplicated over all 3 projects with only little local modifications to accommodate specialized database queries. Modularizing this component will allow a faster transition to Oracle databases for the server application as well as for the Microsoft Access transition for the client application.\par
 
 Grouping the cryptographic classes was a not a trivial thing to achieve. The initial Paillier cryptographic classes had a weak API because it did not offer a level of abstraction high enough to ensure that the library call would be executed correctly, i.e. returning \lstinline{BigInteger} arrays instead of packaging ciphertexts, keys, and related objects within distinct classes. Parameters to Paillier scheme were also disseminated throughout the user interface and logic source codes. The cryptographic scheme was re-written in a way that it would provide a set of operations (encrypt, decrypt, partially decrypt, add and scale) data without actually handling \lstinline{BigInteger} objects.\par
 
 Another effort was made to modularize better the execution of the tests as large portion of code was again duplicated within the same class.
 
 A clearer separation was made between
 \begin{itemize}
 \item Database communications: \lstinline{database.*} package,
 \item Genomic logic for test computation and analysis: \lstinline{framework.*} package,
 \item Input and output classes for PDF reader/writer and network communication: \lstinline{io.*} package,
 \item User interface: \lstinline{ui.*} package,
 \item Helper functions such as property file parser: \lstinline{utils.*} package.
 \end{itemize}
 
 Doing that preparation work helped both the author of this work to understand better the logic of the program as well as putting solid foundations to further extensions of the project while facilitating drastically the modifications and improvements described here-above. On that solid basis, the modifications to the protocol described in \refsection{sec:prot-modif} and discussed in \refsection{sec:prot-mod-discussion} were fairly straight-forward to put in place.
 
 
 % Replacement of Paillier by ECCEG Module
 \subsection{Replacement of Paillier by ECCEG Module}
-\todo[inline]{To be done}
-Provide better abstraction with higher level interface to handle encrypted results.
+In order to replace the Paillier by the ECCEG module, various adaptations were to be made. The initial Paillier module was most of the time returning lists of \lstinline{java.math.BigInteger} objects. It did not provide any interface to abstract the notion of ciphertext, partially decrypted ciphertext or cryptographic key share. Also adding or scaling ciphertext had to be made by accessing \lstinline{java.math.BigInteger} objects. Lots of the bugs and security flaws may happen with an inadequate usage of cryptographic libraries. An effort was made to write a high level interface hiding the underlying algorithms and computations while keeping the module easy to use for the user.\par
+
+On the deployment aspect, all the tables storing encrypted data or the secret key shares were to be modified. They were originally storing \lstinline{java.math.BigInteger} objects inside \lstinline{varchar} objects in the databases. In order to reduce the storage space, we decide to store directly the bytes of the keys and ciphertexts inside \lstinline{blob} (Binary Large Objects) objects.
 
 % Migration to Microsoft Access
 \subsection{Migration to Microsoft Access} \label{sec:impl-migr-access}
-\todo[inline]{To be done}
-Intro on what do client databases store.
-Library limitation with Java to use MS Access as not deployable on any platform. Use UCanAccess library to handle simple transactions with MS Access databases.
+Microsoft Access does not provide native BLOB objects as in MySQL. In order to store the cryptographic keys at the client, we need to serialize them to characters using base64 encoding. We will then store them in regular \lstinline{varchar} objects.\par
+
+Up to Java 7, the usual way to communication with MS Access databases was to use the JDBC-ODBC (Java Database Connectivity - Open Database Connectivity) bridge technology. However as this will be removed in Java 8 \citep{jdbc-odbc-remove} as that bridge was platform dependent. A mitigation to that is to use a third party JDBC driver as with the UCanAccess library implementing simple transactions on and basic functionalities for MS Access databases \citep{lib-ucanaccess}.
 
 % Migration to Oracle
 \subsection{Migration to Oracle} \label{sec:impl-migr-oracle}
 In order to migrate the server application to use Oracle databases, little modification is needed.
 \todo[inline]{Add references and continue}
 
 % Development of a Web Service
 \subsection{Development of a Web Services}
 Developing a web services in Java opens the realm of Java Enterprise Edition (EE). We quickly decided to develop our local web services with GlassFish Server which is delivered with Java EE and provides efficient and reliable tools to quickly develop web services \citep{glassfish-doc}. We decided to choose GlassFish Server because it comes along with Java EE and is integrated in all development tools. It is also well documented and supported as it is officially sponsored by Oracle. This appeared to be a more resilient solution than other packages such as Apache Web Services projects \citep{apache-ws}.
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%
 % Limitations
 \section{Limitations}
 We present here limitations of and issues with the current scheme and suggest improvements that could be done in a future work.
 
 % Marker obfuscation
 \subsection{Marker Obfuscation} \label{sec:depl-marker-obf}
 The current application leaks SNP markers and CF identifiers to the SPU. A mitigation is to encrypt the identifiers using a symmetric deterministic encryption. The symmetric key will again be distributed along with MU secret key share by the Key Manager to the MU. However this falls out of the scope of this project and will be provided in an extension of the current work.
 
 % Timing attacks
 \subsection{Timing Attacks}
 Assume we perform marker obfuscation as described in \refsection{sec:depl-marker-obf}, the real markers are not leaked, but the number of SNPs requested leaks information on which test is performed. Similarly, some practician A could need to run only one test when practician B would run many more tests. An eavesdropper could infer whether the patient visits practician A or B by observing the size of the request.\par
 
 A mitigation to this issue could be to use dummy requests or pad the number of SNPs requested by dummy SNPs. Also the padding of the SNPs should be deterministic. If a practician runs the same test again, with some different dummy SNPs, attacker could easily infer which are the relevant markers to the test. The same idea holds for tests using clinical factors.
 
 % Message level security
 \subsection{Message Level Security}
 It is not clear yet what the options for securing the communication between the web services and the clients are. Typical technologies allowing secure communications to web services use Security Assertion Markup Language (SAML), Kerberos or X.509 security token formats. It is usually preferable to rely on standard and tested protocols instead of reinventing the wheel and start doing home-made cryptography. This usually reduces the attack surface of the system.\par
 
 Another possibility would be to use a typical end-to-end protocol such as SSL for the communication with the web service. This seems to be feasable, but a detailed analysis of Android API has to be conducted to see whether it would be totally compatible.\par
 
 Further discussions with SHCS need to be conducted in order to see which technical solutions are possible to deploy on their system.
 
 % Key management
 \subsection{Key Management}
 In this work, we did not consider the key distribution and management by the Key Master. We artificially assumed that the initial communication used to transfer the key shares was reliable and secure, e.g. by a previously distributed key. To summarize, the client needs to receive a secret key share for material decryption and a symmetric key for identifiers. The server on the other hand needs one key share for material decryption.\par
 
 Another important aspect of key management is the revocation of the keys as well as the enforcement of access controls that would not jeopardize the efficiency of reliability tests.
\ No newline at end of file
diff --git a/report/sections/diagrams/web_service_full.pdf b/report/sections/diagrams/web_service_full.pdf
new file mode 100644
index 0000000..3441840
Binary files /dev/null and b/report/sections/diagrams/web_service_full.pdf differ
diff --git a/report/sections/diagrams/web_service_full.vsdx b/report/sections/diagrams/web_service_full.vsdx
new file mode 100644
index 0000000..dd2cfa4
Binary files /dev/null and b/report/sections/diagrams/web_service_full.vsdx differ
diff --git a/report/sections/ecceg_impl.tex b/report/sections/ecceg_impl.tex
index 501e0f0..7e63506 100644
--- a/report/sections/ecceg_impl.tex
+++ b/report/sections/ecceg_impl.tex
@@ -1,24 +1,27 @@
 \chapter{Implementation of EC-ElGamal Library}
 
 
 \section{Limitations of Current EC-ElGamal Schemes}
-After long research, no cryptographic scheme using Elliptic Curve ElGamal provided homomorphic operations, as none performs an actual mapping of message onto the elliptic curve and back. This motivates our need to implement a new modules providing Elliptic Curve ElGamal with homomorphic operations.
+After long research, no existing cryptographic library provides a scheme for ElGamal on Elliptic Curve with homomorphic operations, as none performs an actual mapping of message onto the elliptic curve and back. This motivates our need to implement a new modules providing Elliptic Curve ElGamal with homomorphic operations.
 
-\section{Cryptographic Library}
-The encryption scheme described in \refchap{crypto-background} could not be found in any kind of cryptographic library. Hence we needed to build our own module. In order to do that, we want to rely on cryptographic primitives provided by a cryptographic library.
+\section{Cryptographic Library Selection}
+The encryption scheme described in \refchap{crypto-background} could not be found in any kind of cryptographic library. Hence we needed to build our own module. In order to do that, we want to rely on cryptographic primitives provided by a standard cryptographic library.\par
 
-\subsection{Operations Required}
-In order to select which cryptographic library would be used, an analysis of its requirements was made.
+The desired library should have the following features. It should
+\begin{itemize}
+	\item Provide a low level API for handling elliptic curve points,
+	\item Have a wide catalog of elliptic curves, including NIST recommended curves,
+	\item Be an open source project, as this project is academic and we want to have full control over the algorithms used,
+	\item Have a good support in case we run into any kind of bug. 
+\end{itemize}
 
-The library had to provide a low level API for handling elliptic curve points. Another strong requirement was that we could select whihc elliptic curve and which encoding for points was used. We also wanted the library to be open source as this project is academic and want to have full control over the algorithms used. Finally the library had to have a good support in case we ran into any kind of bug.
 
-\subsection{Library Selection}
-The first library inspected was the default Java Cryptography Extension (JCE) \citep{jca-ref-guide} delivered with all Java Runtime Environments (JRE). Sadly it did not provide an API to handle EC points.
-The second library inspected was the Java BouncyCastle library \citep{bc-ref}. It offers good EC point handling capabilities. It is also open source and is well supported. As BouncyCastle also allows to fine-tune the usage of asymmetric and symmetric encryption schemes, it was chosen as our cryptographic primitive library and our Java Security Provider (providing the implementations of the encryption schemes available in Java Cryptography Architecture).
+The first library inspected was the default Java Cryptography Extension (JCE) \citep{jca-ref-guide} delivered with all Java Runtime Environments (JRE). Its main limitation is that it does not provide an API to handle elliptic curve (EC) points.
+The second library inspected was the Java BouncyCastle library \citep{bc-ref}. This second one offers good EC point handling capabilities. It is also open source and is well supported. There are weekly improvements, and it offers a broad range of support interfaces through Github \citep{git-bc-activity} and JIRA \citep{bc-jira} issue trackers. As BouncyCastle also allows to fine-tune the usage of asymmetric and symmetric encryption schemes, we finally chose it as our cryptographic primitive library and our Java Security Provider (providing the implementations of the encryption schemes available in Java Cryptography Architecture).
 
 
 \section{Design Decisions}
 \subsection{Mapping from EC Space onto Message Space}
 As described in \refsection{ecceg-mapping-decision}, we generate and store a lookup table mapping every element of the curve to the message space. The Java implementation uses the \verb#java.util.HashMap<K,V># class to map \verb#org.bouncycastle.math.ec.ECPoint# to \verb#java.math.BigInteger#. We iterated over the whole message space which is of limited size. For every message $m$, we computed $mG$ and stored the $(mG, m)$ entry into the \verb#HashMap<ECPoint, BigInteger>#.
 
 After having evaluated the strengths and weaknesses of elliptic curves in \refsection{sec:perf-analysis}, the elliptic curve chosen for the application is unlikely to vary. Hence it is reasonable to generate the lookup table only once and distribute it as part of the application package.
diff --git a/report/sections/intro.tex b/report/sections/intro.tex
index 9687a9d..29bacc7 100644
--- a/report/sections/intro.tex
+++ b/report/sections/intro.tex
@@ -1,49 +1,51 @@
 \chapter{Introduction}
 
 \section{Context}
 
 \subsection{Description of the Problem}
 
-The recent evolution of genome sequencing technologies allows the development of a wide range of applications in a variety of domains, including healthcare, biomedical research, direct-to-consumer (DTC) services and forensics. However it remains difficult to anticipate the impact of genomic data in the medical domain. Genome privacy is a hot topic specially in the sense that genomic data leakage could lead to genomic discrimination e.g., insurance or employment refusal \citep{EPFL-REPORT-186866}.\par
+The recent evolution of genome sequencing technologies allows the development of a wide range of applications in a variety of domains, including healthcare, biomedical research, direct-to-consumer services and forensics. However it remains difficult to anticipate the impact of genomic data in the medical domain. Genome privacy is a hot topic specially in the sense that genomic data leakage could lead to genomic discrimination e.g., insurance or employment refusal \citep{EPFL-REPORT-186866}.\par
 
 Recent advances have been made to address that privacy concern. We base this work on a system designed to address this issue \citep{EPFL-CONF-188284}. Most medical tests and personalized medicine methods using genomic data involve a patient (P) and a medical unit (MU). The medical unit is typically represented by a practician in a medical center, a pharmacist, a pharmaceutical company or a medical council. We consider here the existence of a malicious user within the MU or that the MU can potentially be attacked by a hacker to disclose patient information.
 
 MU usually has limited resources to secure their IT infrastructure. Hence we want to rely on an external storage and processing unit (SPU) who has the competence to store and protect these data in a more efficient and reliable way. Similarly to the MU, we consider the case that there may exist some curious party at the SPU who may disclose genomic data.
 
-In this work, we consider two models for attackers:
+In this work, we assume no collusion between the SPU and MU. We consider two models for attackers:
 \begin{enumerate}
-
-	\item	A curious party at the SPU:
-	
-	\item 	A malicious entity at the MU:
-	
+	\item	A curious party at the SPU who tries to infer the genomic sequence from the stored data.
+	\item 	A malicious entity at the MU (hacker or disgruntled employee) who tries to obtain genomic data of a patient for which he is not authorized.
 \end{enumerate}
 
 In this work, we want to allow a medical unit to run a susceptibility test efficiently, e.g. level of acceptance of a drug or how a patient will react to a medical treatment, while providing genomic privacy to the patient, i.e. protecting him from potential attackers at both MU and SPU.
 
+\subsection{Genomic Background and Susceptibility Tests}
+In order to compute susceptibility tests of diseases, we look at the variations of the sequenced genome. There are approximately 4 millions of such variations that are named Single-Nucleotide Polymorphism (SNP). Also we analyze the Human Leukocyte Antigens (HLA) which build an important disease defense. Mutations in HLA may be linked to autoimmune disease. Finally we collect clinical factors (CF) e.g., age of the patient, whether the patient is smoking or not, whether the patient is subject to hypertension.\par
+
+To be able to perform susceptibility tests on patients, we store the variation of the SNPs, the values of the HLAs if mutating and the values of the clinical factors. Then the result of a susceptibility test is a weighted average over some precise SNPs and CFs. 
+\todo[inline]{Check with Jean Louis if the simplifications are acceptable or if they are wrong or not precise enough}
+
 
-\subsection{Scheme}
-We describe the initial scheme in \reffig{fig:scheme-initial} proposed by \citep{}. 
+\subsection{Framework}
+The system model (\reffig{fig:scheme-initial}) proposed by \citep{lca1-report} includes (i) a patient (P) enrolled in a pharmacogenetics study; (ii) a certified institution (CI) who genotypes the genome of the patient; (iii) a key manager (MK) that distributes the cryptographic keys and encrypts the genomic and non-genomic data; (iv) a storage and processing unit (SPU), also known as data center, that stores the encrypted data; and (v) a medical center also known as medical unit (MU) that is the end-user of the data. This framework, based on additively homomorphic encryption and threshold cryptography, preserves the privacy of the patients' genomic and non-genomic data. The algorithm consists of two phases: an offline and an online phase.\par
 
-\todo[inline]{Explain scheme step by step}
+The offline phase consists of the key distribution and distribution of the data. (0) P provides the genomic (DNA) and non-genomic (CF) material to the CI. (1) Then the CI transmits the material to the MK. The MK generates new cryptographic keys for the patient. It consists of a private key, two secret key shares and a public key. The public key is made public to everyone and is used to encrypt the data. The secret key is distributed to P to be able to use his data without limitation. On secret key share is distributed to the MU and one to the SPU. Using threshold encryption, the MU and SPU need to collaborate to decrypt encrypted data. Then (2) the MK encrypts P's genomic and non-genomic material and stores it at the SPU.\par
+
+In the online phase, the MU and SPU collaborate to compute the privacy-preserving susceptibility test. The MU requests to the SPU the material required for that test. It consists of a list of SNP markers, and a list of CF identifiers. The SPU sends the corresponding encrypted SNPs and CFs as well as all the HLAs. The MU computes the susceptibility test with the encrypted SNPs and CFs and with the corresponding non-encrypted weights. Then, the MU transmits to the SPU the encrypted result of the susceptibility test along with the encrypted HLAs. (4) Finally the SPU decrypts partially the encrypted results and HLAs with its secret key share and transmits the partial ciphertexts to the MU. The MU can finish the decryption of the result and HLAs with its secret key share and display the results on a report to the clinician.
 
 \begin{figure}
 \centering
 \includegraphics[width=0.7\textwidth]{figures/framework.eps}
-\caption{Scheme allowing efficient susceptibility tests while protecting patient genomic privacy\citep{}}
+\caption{Scheme allowing efficient susceptibility tests while protecting patient genomic privacy\citep{lca1-report}}
 \label{fig:scheme-initial}
 \end{figure}
 
 \subsection{Limitations}
-\todo[inline]{To be done}
-Current cryptographic solution works, but is slow and has very large storage requirements.
-
-Does not provide Intellectual Property to MU who would develop a new product, e.g. pharmaceutical company, as the SPU computes the result of the test.
+The current cryptographic solutions using Paillier cryptosystem has proven to be secure \citep{EPFL-CONF-188284}. However the storage requirements for the full set of genetic variation is large and the runtime of a susceptibility can take up to many seconds. Also, the previous framework did not protect Intellectual Property (IP) to the medical units (e.g. pharmaceutical companies) as it revealed to the SPU the contribution of some precise SNPs in a susceptibility tests.
 
 
 \section{Contribution}
 My contribution to this project goes along two directions.\par
 
-The current cryptographic solution does not allow efficient susceptibility tests while ensuring patient privacy. In this work, I address this issue by considering a new cryptographic solution based on ElGamal on Ellipitic Curves combined to Shamir Secret Sharing. I analyzed that new solution and compared it with Paillier cryptosystem.\par
+The current cryptographic solution does not allow efficient susceptibility tests while ensuring patient privacy. In this work, I address this issue by considering a new cryptographic solution based on ElGamal on Ellipitic Curves combined to Shamir Secret Sharing. I analyzed that new solution and compared it with Paillier cryptosystem. I also address the issue of preserving the IP of the MU with respect to the tests by computing the susceptibility tests at the MU while preserving the patient's privacy.\par
 
 In a second phase, I considered the deployment of the application in a production environment. I gathered the technical requirements and limitations of the targeted systems. I address in this work the design decisions following the technical constraints as well as preparation of the application for a deployment into production. I also built a know-how on the considered technologies which would lay a basis to further improvements of the project and suggest improvements to the later system.
diff --git a/report/sections/performance_analysis.tex b/report/sections/performance_analysis.tex
index 8fa3500..89a94de 100644
--- a/report/sections/performance_analysis.tex
+++ b/report/sections/performance_analysis.tex
@@ -1,109 +1,110 @@
 \chapter{Performance Analysis of EC-ElGamal Solution}
 
+Our first goal is to select the most efficient elliptic curve, for our ECCEG scheme, allowing a MU to perform susceptibility tests on patients in a short time without violating their genome privacy. Then, we want to compare the efficiency of the Paillier with the ElGamal solution in term of genome storage and susceptibility test runtime. Finally, we analyze the monetary stakes of both solutions.
 
 
-In a first step, we want to select the most efficient elliptic curve which would allow the ElGamal solution to provide efficient susceptibility tests while ensuring patient privacy. In a second step, we want to compare the efficiency of the Paillier with the ElGamal solution in term of genome storage and susceptibility test runtime. In a third step, we analyze the monetary stakes of both solutions.
-
 \section{Choice Space}
 We decide to choose an optimal elliptic curve for our application based on the size of the field of the elliptic curve and on the type of curve used.
 
 \subsection{Cryptographic Strength}
-The current solution uses Paillier Encryption Scheme with keys of 4048 bits. We want to provide with the new solution a security at least as good as with Paillier. Paillier is in the class of Integer Factorization Cryptography (IFC) as well as RSA. We compare the strength of using \reftab{tab:comp-key-strength}. We can see that for a key of 4048 bits for IFC, we need a field size of at least 384 bits long. In conclusion, in order to have a security at least as good as Paillier with 4048 bit key, we need to have a field size of more than 384 bit length.
+The current solution uses Paillier Encryption Scheme with a security parameter of 4048 bits. We want to provide with the new solution a security at least as good as with Paillier. Paillier is in the class of Integer Factorization Cryptography (IFC) as well as RSA. We compare the strength of using \reftab{tab:comp-key-strength}. We observe that for a key of 4048 bits for IFC, we need a field size above 384 bits.
 
 \begin{table}
 \centering
 \begin{tabular}{c|c|c|c|c}
 \shortstack{Bits of\\security} & \shortstack{Symmetric key\\algorithms} & \shortstack{FFC\\(e.g., DSA, D-H)} & \shortstack{IFC\\(e.g., RSA)} & \shortstack{ECC\\(e.g., ECDSA)} \\
 \hline
 80 & 2TDEA & L = 1024, N = 160 & k = 1024 & f = 160 - 223 \\
 112 & 3TDEA & L = 2048, N = 224 & k = 2048 & f = 224 - 255 \\
 128 & AES-128 & L = 3072, N = 256 & k = 3072 & f = 256 - 383 \\
 192 & AES-192 & L = 7680, N = 384 & k = 7680 & f = 384 - 511 \\
 256 & AES-256 & L = 15360, N = 512 & k = 15360 & f = 512+ \\
 \end{tabular}
 \caption{Comparative Key Strength \citep[Table 2, page 64]{NIST-800-57} between Symmetric key algorithms, Finite Field Cryptography (FFC), Integer Factorization Cryptography (IFC) and Elliptic-Curve Cryptography (ECC).}
 \label{tab:comp-key-strength}
 \end{table}
 
 \subsection{Type of Curves}
 Elliptic curves can be defined over primary or binary fields. Furthremore, there exist a special case of elliptic curves over binary fields known as Koblitz curves which have faster point multiplications. As suggested by \citep[section 3.4]{hankerson2004guide}\citep{Ugus_performanceof,MA_Ugus}, various elliptic curves can have different performance in term of additions, point multiplications and storage.
 
 
 \section{Performance Analysis} \label{sec:perf-analysis}
-We perform this analysis on all the elliptic curves suggested by NIST\citep{fips-dss} provided by the BouncyCastle library. The full list of NIST available curves on BouncyCastle can be found in \refappendix{sec:nist-rec-curves}.
+We perform this analysis on all the elliptic curves suggested by NIST\citep{fips-dss} provided by the BouncyCastle library. The full list of NIST available curves on BouncyCastle can be found in \refappendix{sec:nist-rec-curves}.\par
+
+We compare empirically the performance of each of the different elliptic curve. We measure the size of an encoded pair of elliptic curve points to obtain the memory requirements of a ciphertext for a given elliptic curve. Then we measure the runtime of multiple susceptibility tests to obtain the mean duration of a test. Standard susceptibility tests are performed over 1 to 50 SNPs. We compute artificial susceptibility test over 20 SNPs. We generate random SNP values and random weights, and perform a weighted average on the generated material. As the runtime of one test is rather short, we perform 100 different tests and report the mean runtime.
 
-In order to compare the performance of each of these different elliptic curves, we compare them empirically. In order to obtain the memory requirements of a single ciphertext, we measure the size of encoded pair of elliptic curve points representing the ciphertext. In a susceptibility test, we perform a weighted average of SNPs typically over 20 of them. In this analysis, we perform a weighted average over 20 random elliptic curve points. As the runtime of one average is fairly short, we perform 100 different weighted averages and report the mean runtime.
 
 \subsection{Memory Tradeoff}
 We can see on \reffig{graph:perf-storage} that the storage requirement increases linearly with the size of field. We can also see that the storage is independent on the type of elliptic curve.
 
 \begin{figure}
 \begin{center}
 \input{plots/perf_storage.tex}
 \end{center}
 \caption{Storage requirement to store full genome for different elliptic curves.}
 \label{graph:perf-storage}
 \end{figure}
 
 
 \subsection{Runtime Tradeoff}
 On \reffig{graph:perf-runtime}, we can see that elliptic curves over primary field or Koblitz curves have much smaller runtime than normal curves over binary fields. Also for a larger field size the Koblitz curve has the same runtime as the primary one.
 
 \begin{figure}
 \begin{center}
 \input{plots/perf_runtime.tex}
 \end{center}
 \caption{Runtime to compute a weighted average for 20 SNPs for different elliptic curves.}
 \label{graph:perf-runtime}
 \end{figure}
 
 
 \section{Selected Curve}	\label{sec:select-curve}
 In the analysis above, we have seen that we need to choose an elliptic curve with field of length at least 384 bits. We chose the NIST curve P-384 as it minimizes the storage and does not have any drawback in term of runtime. Also it provides security as good as the current Paillier solution.
 
 
 \section{Comparison of Paillier with ElGamal on EC}
 We compare in this section Paillier using a key of length 4048 bit and ElGamal on Elliptic Curve using the P-384 curve as motivated in \refsection{sec:select-curve}.
 
+
 \subsection{Performance Comparison}
 We compare both solutions in term of storage requirements and runtime for a weighed average over 20 values. We base our analysis on a fully sequenced genome which is composed of 5 millions SNPs. A SNP in plaintext can be represented by only 2 bits. We can see on \reftab{tab:perf-comp-sum} that the ElGamal solution is 15 times faster than the Paillier solution. In term of storage requirement, ElGamal on EC is almost 7 times cheaper than than the Paillier solution. We can see that ElGamal on EC cryptosystem can provide much more efficient susceptibility tests while providing security equivalent to current Paillier cryptosystem configuration.
 
 \todo[inline]{Add information about machine}
 
 \begin{table}
 \centering
 \begin{tabular}{l|l|l|c}
 Solution & Storage for full genome [MB] & Runtime for weighted avg [ms] \\
 \hline
 Paillier & 5000 & 346.0\\
 ElGamal on EC & 740 & 22.2\\
 \end{tabular}
 \caption{Performance comparison of Pailler against ElGamal on EC. Tests are performed on a computer running Windows \textregistered 7 with Intel \textregistered Core\texttrademark i5 Processors of 2.4GHz.}
 \label{tab:perf-comp-sum}
 \end{table}
 
 \subsection{Monetary Cost Analysis}
 We want to compare the monetary cost of the Paillier with the ElGamal on elliptic curve solutions. As for the pricing of the storage, we selected two different providers: Amazon S3 as worldwide storage provider and Swisscom Dynamic Computing Services (DCS) as local storage provider. The Swisscom DCS guarantees that all the data will be stored in data centers in Switzerland \citep{swisscom-dcs-sales}, when Amazon S3 does not provide any of such guarantees. We want to emphasize the difference between traditional storage of non-sensitive data which could be cost efficiently done with Amazon S3 services and the need of storing sensitive medical data inland only, due to legal or regulatory requirements in Switzerland. Pricing of both alternatives are shown in \reftab{tab:storage-pricing}.\par
 
 \begin{table}
 \centering
 \begin{tabular}{l|l|l|c}
 Provider location & Storage provider & Service name & Cost per GB per month \\
 \hline
 Worldwide & Amazon Web Services & Amazon S3 & USD 0.030 \citep{amazon-s3-pricing} \\
 Switzerland & Swisscom DCS & Dynamic Storage & CHF 0.14 \citep{swisscom-dcs-sales} \\
 \end{tabular}
 \caption{Pricing for storage with duplication for Amazon Web Services and Swisscom Dynamic Computing Services (DCS).}
 \label{tab:storage-pricing}
 \end{table}
 
 On \reffig{fig:comp-mon} we can see that using the ElGamal on EC at the level of Switzerland and using a Swiss storage provide, it would cost only XXX when Paillier would have cost about 5 times more.
 
 \begin{figure}
 \begin{center}
 %\input{plots/perf_mon.tex}
 \end{center}
 \caption{Monetary comparison of Paillier with ElGamal on EC.}
 \label{fig:comp-mon}
 \end{figure}
 
diff --git a/report/youssef-genomic.tex b/report/youssef-genomic.tex
index 11eb92f..839c547 100644
--- a/report/youssef-genomic.tex
+++ b/report/youssef-genomic.tex
@@ -1,129 +1,144 @@
 %\documentclass[11pt]{./layouts/report}
 \documentclass[11pt,twoside,a4paper]{report}
 \setcounter{secnumdepth}{3}
 
 % include graphics
 \usepackage[pdftex]{graphicx}
 \usepackage{float}
 
 \usepackage{amssymb}
 \usepackage{dsfont}
 \usepackage[top=1.5cm, bottom=1.5cm, left=2cm, right=2cm]{geometry}
 \usepackage{mathtools}
 
 \usepackage{caption}
 %\usepackage{subcaption}
 \usepackage{subfig}
 
 \usepackage{epstopdf}
 \usepackage{eurosym}
 
 % use math packages
 \usepackage{amsmath,amsfonts,amsthm} % Math packages
 \usepackage{algorithm}
 \usepackage{algorithmic}
 \newcommand{\byte}[0]{
 \text{[B]}
 }
 
 % TODOs package
 \usepackage{todonotes}
 \usepackage{lipsum}
 \setlipsumdefault{1}
 
 % After matter packages
 \usepackage{appendix}
 \usepackage{natbib}
 
 %\setlength{\parindent}{0in}
 
 % Drawing diagrams
 \usepackage{tikz}
 \usepackage{pgf-umlsd}
 
+% Drawing UML
+\usepackage[T1]{fontenc}
+\usepackage{external_sty/tikz-uml}
+\newcommand{\stereotype}[1]{
+\guillemotleft#1\guillemotright
+}
+
+\newcommand{\umlattrib}[2]{
+#1 : #2
+}
+
+\newcommand{\umlattribstereo}[3]{
+\stereotype{#3} \umlattrib{#1}{#2}
+}
+
 % Reference
 \usepackage{hyperref}
 \newcommand{\refappendix}[1]{
 Appendix ~\ref{#1} \nameref{#1}
 }
 \newcommand{\refsection}[1]{
 Section ~\ref{#1} \nameref{#1}
 }
 \newcommand{\refchap}[1]{
 Chapter ~\ref{#1} \nameref{#1}
 }
 \newcommand{\refalgo}[1]{
 Algorithm ~\ref{#1}
 }
 \newcommand{\reffig}[1]{
 Figure ~\ref{#1}
 }
 \newcommand{\reftab}[1]{
 Table ~\ref{#1}
 }
 
 % source code environment
 \usepackage{listings}
 \lstset{basicstyle=\ttfamily,breaklines=true}
 
 \begin{document}
 
 %%%%%%%%%%%%%%%%%%%%
 % Front Matter
 %%%%%%%%%%%%%%%%%%%%
 
 % Title Page
 \input{./title/youssef-genomic_title.tex}
 
 % Table of Contents
 \setcounter{tocdepth}{3}
 \tableofcontents
 \clearpage
 
 % Tables of Illustrations
 \begingroup
 \let\cleardoublepage\relax
 \let\clearpage\relax
-% List of Tables
-\listoftables
 % List of Figures
 \listoffigures
+% List of Tables
+\listoftables
 % List of Algorithms
 \listofalgorithms
 \endgroup
 
 %%%%%%%%%%%%%%%%%%%%
 % Main Matter
 %%%%%%%%%%%%%%%%%%%%
 
 % Introduction
 \input{sections/intro.tex}
 
 % Genomic Background
 %\input{sections/genomic_background.tex}
 
 % Cryptographic Background
 \input{sections/crypto_background.tex}
 
 % Implementation of ECCEG
 \input{sections/ecceg_impl.tex}
 
 % Performance and Monatory Analysis of ECCEG Solution
 \input{sections/performance_analysis.tex}
 
 % Deployment into Production Environment
 \input{sections/deployment.tex}
 
 % Conclusion and Next Steps
 \input{sections/conclusion.tex}
 
 %%%%%%%%%%%%%%%%%%%%
 % Back Matter
 %%%%%%%%%%%%%%%%%%%%
 
 \input{sections/appendix.tex}
 
 \bibliography{biblio/research}{}
 \bibliographystyle{plain}
 
 \end{document}
\ No newline at end of file