diff --git a/figures/Dashboard (hardcoded).PNG b/figures/Dashboard (hardcoded).PNG
new file mode 100644
index 0000000000000000000000000000000000000000..2475c5d7653d872fd1aeb03e45d3b7d336457c78
Binary files /dev/null and b/figures/Dashboard (hardcoded).PNG differ
diff --git a/figures/DeviceMagicUserInterface1.PNG b/figures/DeviceMagicUserInterface1.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..2deb2a37360ea4dae28dd133b0b9deece9f77d02
Binary files /dev/null and b/figures/DeviceMagicUserInterface1.PNG differ
diff --git a/figures/DeviceMagicUserInterface2.PNG b/figures/DeviceMagicUserInterface2.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..2be62718c240963ca20e52e15ef8633c6bf34c73
Binary files /dev/null and b/figures/DeviceMagicUserInterface2.PNG differ
diff --git a/figures/Firebase.PNG b/figures/Firebase.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..8a24f40b7ae89c7c76c58eb95be2fd89ebab7d59
Binary files /dev/null and b/figures/Firebase.PNG differ
diff --git a/figures/FormstackUserInterface1.PNG b/figures/FormstackUserInterface1.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..73d4de46ee2f9d5280fd390c4e1dc758b65e3ee1
Binary files /dev/null and b/figures/FormstackUserInterface1.PNG differ
diff --git a/figures/FormstackUserInterface2.PNG b/figures/FormstackUserInterface2.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..657664e6f3e39dd792e86437c694a5b5ea93c148
Binary files /dev/null and b/figures/FormstackUserInterface2.PNG differ
diff --git a/report/00_Introduction.tex b/report/00_Introduction.tex
deleted file mode 100644
index 02d1e84274e80ba67281cb5dd5ff5f5e7c44b5c1..0000000000000000000000000000000000000000
--- a/report/00_Introduction.tex
+++ /dev/null
@@ -1,5 +0,0 @@
-%% ----------------------------------------------------------------
-%% Introduction.tex
-%% ---------------------------------------------------------------- 
-\chapter{Introduction} \label{Chapter:Introduction}
-Example Introduction
\ No newline at end of file
diff --git a/report/0_Abstract.tex b/report/0_Abstract.tex
index fbf39cc600be76d26df98001767b7ba660c294e4..b959efc0a99c098fd218f2834380e51a5812535c 100644
--- a/report/0_Abstract.tex
+++ b/report/0_Abstract.tex
@@ -1 +1,7 @@
-This is the abstract
\ No newline at end of file
+\section*{Abstract}
+
+There are hundreds of cyber security compliance standards, and many businesses require their partner companies and/or members of their supply chain to comply with numerous standards. Keeping track of each company's compliance to a particular standard is a lengthy and potentially expensive process since it can be very difficult to maintain without the use of an external service or consultant. Most SMEs will be unable to afford this - due to the required time and level of experience, it may not be something a system administrator can do on top of their other responsibilities, and a consultant could be too expensive.
+
+An engine that automatically generates cyber security compliance forms could provide a low cost, time efficient solution for businesses that need a flexible and customisable way of tracing their partner's compliance (or their own compliance) with multiple standards.
+
+The goal of this project is to create a web application system that will generate and store compliance forms for the end user. The forms will be generated by a user, and accessible to specified partners chosen by the user. This will include the ability to update the forms at a later date. The scope of this project includes cyber security compliance - while this project may be relevant to other forms of compliance, the focus will be on compliance within the cyber security field only, with the potential for future work to explore alternative forms of compliance.
\ No newline at end of file
diff --git a/report/10_FutureWork.tex b/report/10_FutureWork.tex
deleted file mode 100644
index c818d957abe558c9394c20365f512964394a50f3..0000000000000000000000000000000000000000
--- a/report/10_FutureWork.tex
+++ /dev/null
@@ -1,5 +0,0 @@
-%% ----------------------------------------------------------------
-%% FutureWork.tex
-%% ---------------------------------------------------------------- 
-\chapter{Future Work} \label{Chapter: Future Work}
-It works.
diff --git a/report/11_Bibliography.tex b/report/11_Bibliography.tex
deleted file mode 100644
index 225e0ac524d69aab0710fd65734dd590e50af1d0..0000000000000000000000000000000000000000
--- a/report/11_Bibliography.tex
+++ /dev/null
@@ -1,5 +0,0 @@
-%% ----------------------------------------------------------------
-%% Bibliography.tex
-%% ---------------------------------------------------------------- 
-\chapter{Bibliography} \label{Chapter: Bibliography}
-It works.
diff --git a/report/1_Chapter1.tex b/report/1_Chapter1.tex
deleted file mode 100644
index f9072e69e843708bd2ae42202c33ee0799a63950..0000000000000000000000000000000000000000
--- a/report/1_Chapter1.tex
+++ /dev/null
@@ -1,5 +0,0 @@
-%% ----------------------------------------------------------------
-%% Chapter1.tex
-%% ---------------------------------------------------------------- 
-\chapter{Project Goals} \label{Chapter:one}
-Example Chapter
\ No newline at end of file
diff --git a/report/1_Introduction.tex b/report/1_Introduction.tex
new file mode 100644
index 0000000000000000000000000000000000000000..d6db29b245b8e6a7dcceb766f7d6fd8d1c3b98ae
--- /dev/null
+++ b/report/1_Introduction.tex
@@ -0,0 +1,32 @@
+%% ----------------------------------------------------------------
+%% 1_Introduction.tex
+%% ---------------------------------------------------------------- 
+\chapter{INTRODUCTION}
+
+\section{Overview}
+    Many businesses require their partners to comply with numerous and varied cyber security compliances, of which there are literally hundreds. Cyber supply chain risk management (CSCRM) differs from cyber security, by gaining a higher degree of governance over the company in question, and over its extended enterprise partners, such as all its suppliers and customers. Whereas cyber security only considers security of a technical nature, CSCRM attempts to encompass both managerial and human factors in preventing risks from disrupting IT systems\textquoteright\ operations. \cite{CSCRM}
+
+    The following chapter will give an overview of the project\textquoteright s goals and objectives. The subsequent chapters will go on to talk about compliance in cyber security, cyber crime, supply chains and the impacts of security breaches on businesses, use cases, requirements, risks and functionality for the proposed application, followed by the proposed design of the implementation for the application.
+
+\section{Problem}
+    Keeping track of each company\textquoteright s compliance to a specific standard is a lengthy and potentially expensive task since it can be very difficult to maintain without the use of an external service or consultant. Due to the time and experience level required, it is unlikely to be a task a system administrator would be able to perform in addition to their other responsibilities, and a specialist will, in all likelihood, be too expensive for most SMEs.
+
+    An automatically generated cyber security compliance form engine, could provide a low cost, time efficient solution for businesses that need a flexible, customisable way of tracking their partner\textquoteright s compliance - or their own compliance - with multiple standards.
+
+\section{Aim}
+    Ultimately, the goal of the project is to enable organisations to maintain and improve their cyber security by adhering to various compliance standards, such as the guidelines set out by the UK government's Cyber Essentials scheme. The scheme aims to protect organisations from a range of attacks that could be carried out by relatively unskilled individuals - the most common cyber threat to businesses. \cite{CyberEssentials}
+
+    \subsection{Research}
+        A thorough review of relevant literature will be required to fully understand the problem and the existing solutions, if any exist. If they do, an assessment of possible improvements that could be made to those solutions should also be executed. A chapter detailing the analysis of the requirements for the project will be required to determine and gauge the feasibility and enable the planning and design of the application itself. This should include an assessment of likely risks to the project.
+
+    \subsection{Development and Testing}
+        The implementation of the web application, in a manner which allows for easy maintenance, extensions and other improvements at a later date, is essential. To ensure the functionality of all parts of the application, a testing system should also be implemented - set up as continuous integration with regression testing. This software validation should be automated for consistency and to save time. 
+    
+    \subsection{Analysis}
+        An analysis of the results of the testing and of the implementation should be carried out after it is finalised, to establish adherence to the designs and assure the quality of the code. 
+
+    \subsection{Evaluation}
+        An evaluation of the whole project including its management should be performed. Finally, a summary of possible future work that could be carried out should be developed, to improve upon this project and/or extend it.
+
+\section{Functionality}
+    The goal of the application is to have a system that will generate and store compliance forms for the end-user. The forms will be automatically generated via an interface on the application by a user, and accessible by \textquoteleft partners\textquoteright. Partners will be other users that can be added by the primary user, much like friends or followers on a social media application. Users will be able to update the forms\textquoteright\ parameters, and partners will be able to update their answers to the forms, later on. This project is a cloud-based application, and it will deal with cyber security compliance only - no other forms of compliance will be within the scope of this project.
\ No newline at end of file
diff --git a/report/2_BackgroundAndLiteratureReview.tex b/report/2_BackgroundAndLiteratureReview.tex
new file mode 100644
index 0000000000000000000000000000000000000000..50cfee221de4b1f172055889e34479e1ee9840c6
--- /dev/null
+++ b/report/2_BackgroundAndLiteratureReview.tex
@@ -0,0 +1,74 @@
+%% ----------------------------------------------------------------
+%% 2_BackgroundAndLiteratureReview.tex
+%% ---------------------------------------------------------------- 
+\chapter{BACKGROUND AND LITERATURE REVIEW}
+
+\section{Crime}
+    There has been a significant increase in cyber-criminal activity in recent years. \cite{GDPR} The methods used by criminals are currently changing as businesses begin to be targeted more frequently than individuals. \cite{GDPR} Cyber crime is growing at a rapid rate, making it increasingly troublesome for regulations and legislation to keep pace, resulting in outdated laws that are often unfit for purpose. \cite{GDPR}
+
+\section{Supply Chains}
+    Supply chain management is a process essential for connecting major business actions and behaviours both internally and between organisations into a capable and effective business model. \cite{CSCRM} It encompasses all logistics management endeavours, not to mention manufacturing operations, and it drives the coordination of activities across multiple business areas including; marketing, sales, product design, finance, and IT. \cite{CSCRM}
+
+    \subsection{Supply Chain Security}
+        Supply chain security concentrates on the threats linked to an organisation\textquoteright s suppliers of goods and services, many of which potentially have considerable access to assets belonging to the company or to its customer data. \cite{CombattingCyberRisks}
+
+\section{Compliance}
+    Compliance is a crucial, costly, and complex issue for any company to deal with. \cite{ComplianceGovernance} It relates to the conformance to a set of laws, regulations, policies, or best practices known as standards. \cite{ComplianceGovernance} 1Organisations can be required to take steps to put policies and controls in place that ensure conformity with the regulations outlined in their given compliance standard(s), the purpose of which is to safeguard the organisation against security threats.
+
+    \subsection{Compliance in Cyber Security}
+        Cyber security is the aggregate of technologies, processes, and practices, which were designed to shield computer networks, software, and data from loss, theft, or manipulation. \cite{CSCRM} Cyber security standards have existed for a long time, affecting the necessary policies and practices of individuals and organisations over the last several decades. \cite{StanfordConsortium} Various regulations and legislation often struggle to keep up with the latest cyber threats due to the rapid evolution of the field. \cite{GDPR} As a result of the expanding pool of available tools, there is an ever-increasing number of people able to access the world of cyber crime. This makes it all the more crucial that conforming to the latest standards becomes an imperative for every company, regardless of the size of the enterprise. The hope for this project is that it will help to enable organisations to achieve compliance with any given standard in a cost effective manner.
+
+    \subsection{Cyber Essentials}
+        The UK Government worked with a number of other institutions to develop Cyber Essentials, a set of basic standards to help organisations defend themselves from common security threats online. \cite{CyberEssentials} The scheme is designed to prevent unskilled individuals from being able to find basic vulnerabilities in an organisation by providing advice, and two different levels of certification; \textquotedblleft Cyber Essentials\textquotedblright\ and \textquotedblleft Cyber Essentials Plus\textquotedblright. The former is a self-assessment designed to be light-weight and easy to follow, while in the latter, a certification body carries out the verification of the organisation\textquoteright s cyber security, instead of it being done by the company in question.
+
+\section{Impacts}
+    Cyber attacks are financially devastating and disrupting to people and businesses. Successful attacks have the potential to expose personal information, leaving the victims of these security breaches vulnerable to fraud. \cite{CyberCrime} Victims are also left vulnerable to further attacks, using the information previously gathered by attackers.
+        
+    \subsection{The Effect on Business and Loss of Confidence}
+        According to a survey by Ping Identity (a company that sells a number of cloud and software identity security solutions), 75\% of people stop engaging with a brand online following a data breach, as well as 59\% saying they were not willing to sign up to use an online service or application that had recently experienced a data breach. \cite{ITGovernance} In spite of this, a staggering 56\% said they were unwilling to pay any amount of money for additional security to protect their personal information. \cite{ITGovernance}
+
+    \subsection{Legal consequences}
+        GDPR requires proper management of all the personal information held by an organisation. \cite{BusinessInfo} If this information is compromised, and that organisation has neglected to deploy basic security measures, it is possible they will face fines and regulatory sanctions. \cite{BusinessInfo}
+
+
+\section{Case Study: Pouring Pounds Ltd}
+    Two cashback sites owned by Pouring Pounds Ltd were found to have leaked two terabytes worth of personally identifiable information and account data. This was made possible because of an unprotected database, which could be accessed through an exposed port on the company's server. The leak occurred in October 2019 and has affected approximately 3.5 million individuals. \cite{z6mag}
+
+
+\section{Previous and Similar Work}
+    Below is an overview and evaluation of two other products found during background research for the project.
+
+    \subsection{Formstack}
+        Formstack boasts a drag and drop interface to allow quick and easy customisation of a form you create, with various components for different data types and layouts and you can see your changes in real time. The product is aimed at developers and non-technical people, offering a time-saving way to build forms for a wide variety of different functions, including collecting payments, gathering customer data and automating day-to-day tasks. \cite{Formstack}
+
+        At the time of writing, the product has multiple pricing tiers, starting from \$19 USD per month with 'Bronze' and ending up at a \$249 USD per month for 'Platinum', which includes \textquotedblleft Advanced data collection features \& priority support\textquotedblright. \cite{Formstack} There is also an 'Enterprise' edition, however pricing for that seems to be on a case-by-case basis.
+
+        \begin{figure}[H]
+            \center
+            \includegraphics[height=90mm, width=145mm]{../figures/FormstackUserInterface1}
+            \caption{Formstack User Interface 1}
+        \end{figure}
+
+        \begin{figure}[H]
+            \center
+            \includegraphics[height=90mm, width=145mm]{../figures/FormstackUserInterface2}
+            \caption{Formstack User Interface 2}
+        \end{figure}
+    
+    \subsection{Device Magic}
+        With a broad focus that includes; job reports, inspections, audits, work orders and invoices, Device Magic is a data collection application that allows users to create and complete mobile forms. \cite{DeviceMagic} One of the key selling points is the ability to use all the features of the app when offline. It possesses an easy-to-use drag and drop user interface similar to that of Formstack and also allows users to preview forms in mobile format when creating them on a desktop. \cite{DeviceMagic} It also features the capability to capture rich data (such as images), and to automate workflows, for example, allowing a form submission to trigger another form to be sent. \cite{DeviceMagic}
+
+        \begin{figure}[H]
+            \center
+            \includegraphics[height=100mm, width=145mm]{../figures/DeviceMagicUserInterface1}
+            \caption{Device Magic User Interface 1}
+        \end{figure}
+
+        \begin{figure}[H]
+            \center
+            \includegraphics[height=100mm, width=145mm]{../figures/DeviceMagicUserInterface2}
+            \caption{Device Magic User Interface 2}
+        \end{figure}
+    
+    \subsection{Evaluation and Comparison of Existing Products}
+        The range of customisations available in Formstack and Device Magic make them a generic solution in comparison to the specialised nature of proposed in this project. CompForge will have a more streamlined interface and method for form creation. Compliance forms have a more straightforward and predictable structure, a fact which was taken advantage of during the design phase (see Chapter 4: Design).
\ No newline at end of file
diff --git a/report/2_Chapter2.tex b/report/2_Chapter2.tex
deleted file mode 100644
index 22287de287251244f4c4fae48607a1a581665080..0000000000000000000000000000000000000000
--- a/report/2_Chapter2.tex
+++ /dev/null
@@ -1,4 +0,0 @@
-%% ----------------------------------------------------------------
-%% Chapter2.tex
-%% ---------------------------------------------------------------- 
-\chapter{Background and Literature Review} \label{Chapter:two}
diff --git a/report/3_Chapter3.tex b/report/3_Chapter3.tex
deleted file mode 100644
index 10e263930f165d2556a2f49b9b642de780f2f9d2..0000000000000000000000000000000000000000
--- a/report/3_Chapter3.tex
+++ /dev/null
@@ -1,4 +0,0 @@
-%% ----------------------------------------------------------------
-%% Chapter3.tex
-%% ---------------------------------------------------------------- 
-\chapter{Designs} \label{Chapter:three}
\ No newline at end of file
diff --git a/report/3_RequirementsAndAnalysis.tex b/report/3_RequirementsAndAnalysis.tex
new file mode 100644
index 0000000000000000000000000000000000000000..46a27ef0a644165e8a45c3e65f3048059ac0b7d4
--- /dev/null
+++ b/report/3_RequirementsAndAnalysis.tex
@@ -0,0 +1,421 @@
+%% ----------------------------------------------------------------
+%% 3_RequirementsAndAnalysis.tex
+%% ----------------------------------------------------------------
+\chapter{REQUIREMENTS AND ANALYSIS}
+
+This chapter will analyse the requirements of the proposed application and inform the design decisions that have been made.
+
+\section{Use Cases}
+    Use cases describe the various interactions between external actors and a given system as part of the Unified Modelling Language (UML). They are used in this chapter to define the interactions between users and the proposed application.\\\\
+
+    \begin{figure}[H]
+        \center
+        \begin{tikzpicture}
+            % components
+            \umlactor[x=0, y=0, scale=2]{user}
+            \umlusecase[x=-3, y=3, scale=1.25, name=register]{Register}
+            \umlusecase[x=-5, y=1.5, scale=1.25, name=signIn]{Sign In}
+            \umlusecase[x=-6, y=0, scale=1.25, name=signOut]{Sign Out}
+            \umlusecase[x=-5, y=-1.5, scale=1.25, name=createForm]{Create Form}
+            \umlusecase[x=-3, y=-3, scale=1.25, name=viewForms]{View Forms}
+            \umlusecase[x=3, y=3, scale=1.25, name=shareForm]{Share Form}
+            \umlusecase[x=5, y=1.5, scale=1.25, name=editForm]{Edit Form}
+            \umlusecase[x=6, y=0, scale=1.25, name=deleteForm]{Delete Form}
+            \umlusecase[x=5, y=-1.5, scale=1.25, name=submitForm]{Submit Form}
+            \umlusecase[x=3, y=-3, scale=1.25, name=addPartner]{Add Partner}
+            % connections
+            \umlinherit{user}{register}
+            \umlinherit{user}{signIn}
+            \umlinherit{user}{addPartner}
+            \umlinherit{user}{createForm}
+            \umlinherit{user}{shareForm}
+            \umlinherit{user}{viewForms}
+            \umlinherit{user}{submitForm}
+            \umlinherit{user}{signOut}
+        \end{tikzpicture}
+        \caption{Use Case Diagram 1}
+    \end{figure}
+
+    \begin{figure}[H]
+        \center
+        \begin{tikzpicture}
+            % components
+            \umlusecase[x=0, y=0, scale=1.5, fill=Red!20, name=dashboard]{Dashboard}
+            \umlusecase[x=-3, y=3, scale=1.25, width=2.5cm, name=displayForms]{Display forms}
+            \umlusecase[x=-6, y=1, scale=1.25, width=2.5cm, name=createForm]{Create form button}
+            \umlusecase[x=-6, y=-1, scale=1.25, width=2.5cm, name=viewForm]{View form button}
+            \umlusecase[x=-3, y=-3, scale=1.25, width=2.5cm, name=shareForm]{Share form button}
+            \umlusecase[x=3, y=3, scale=1.25, width=2.5cm, name=editForm]{Edit form button}
+            \umlusecase[x=6, y=1, scale=1.25, width=2.5cm, name=deleteForm]{Delete form button}
+            \umlusecase[x=6, y=-1, scale=1.25, width=2.5cm, name=addPartner]{Add partner button}
+            \umlusecase[x=3, y=-3, scale=1.25, width=2.5cm, name=signOut]{Sign out button}
+            % connections
+            \umlinclude{dashboard}{displayForms}
+            \umlinclude{dashboard}{createForm}
+            \umlinclude{dashboard}{viewForm}
+            \umlinclude{dashboard}{shareForm}
+            \umlinclude{dashboard}{editForm}
+            \umlinclude{dashboard}{deleteForm}
+            \umlinclude{dashboard}{addPartner}
+            \umlinclude{dashboard}{signOut}
+        \end{tikzpicture}
+        \caption{Use Case Diagram 2}
+    \end{figure}
+
+    \clearpage
+
+    \subsection{Use Case Description}
+
+        The following table explains the major use cases for the application:\\
+
+        \begin{table}[h]
+            \centering
+            \begin{tabular}{|c|c|}
+                \hline
+                Use Case & Description\\
+                \hline
+                \hline
+                Display forms & \makecell{A list of forms created by and shared with the user\\will be displayed, with the form's name, owner and\\date it was created.}\\
+                \hline
+                Create form button & \makecell{Takes the user to a page where they can enter the\\questions and possible responses for a new form.}\\
+                \hline
+                View form button & \makecell{Allows the user to view the questions and possible\\responses for a given form.}\\
+                \hline
+                Share form button & \makecell{Allows the user to share forms they have created\\with partners.}\\
+                \hline
+                Edit form button & \makecell{Allows the user to change the questions and/or\\responses of a form.}\\
+                \hline
+                Delete form button & \makecell{Allows the user to permanently delete forms (only\\forms that they have created).}\\
+                \hline
+                Add partner button & \makecell{Allows the user to search for other users' accounts\\and add them as partners.}\\
+                \hline
+                Sign out button & Allows the user to sign out from the application.\\
+                \hline
+            \end{tabular}
+            \caption{Use Case Descriptions}
+        \end{table}
+
+
+\section{Functional Requirements}
+    A functional requirement defines the intended behaviour of a component or part of a system. In the table below, the major functional requirements have been described:\\
+
+    \begin{table}[H]
+        \centering
+        \begin{tabular}{|c|c|}
+            \hline
+            Requirement & Description\\
+            \hline
+            \hline
+            Register & \makecell{New users will create an account before being allowed to use\\the application.}\\
+            \hline
+            Sign in & \makecell{Users will need to log in before they are able to\\access their account, create, share, and complete forms.}\\
+            \hline
+            Sign out & Users will be able to sign out of the application.\\
+            \hline
+            Create a form & \makecell{Users will be able to create a new form, which will be saved to\\their account.}\\
+            \hline
+            View a form & \makecell{Users will be able to view created forms, including questions\\and possible responses.}\\
+            \hline
+            Share a form & \makecell{Users will be able to share a form that they have created with\\a partner.}\\
+            \hline
+            Edit a form & \makecell{Users will be able to edit created forms, including questions\\and possible responses.}\\
+            \hline
+            Delete a form & \makecell{Users will be able to delete a form that they have created.}\\
+            \hline
+            Submit a form & \makecell{Users will be able to complete and submit responses for each form\\back to the form's author.}\\
+            \hline
+            Add a partner & \makecell{Users will be able to view and edit their account information,\\including; name, email, company and password (not viewable).}\\
+            \hline
+        \end{tabular}
+        \caption{Functional Requirements}
+    \end{table}
+
+    \subsection{Functional Requirements Analysis}
+        An importance level has been assigned to each of the functional requirements, in order to effectively plan the work to be done in order to create the minimum viable product. An additional table shows how the importance levels have been determined.\\
+
+        \begin{table}[H]
+            \centering
+            \begin{tabular}{|c||c|c|c|c|c|}
+                \hline
+                Complexity/Time & Low & Medium & High\\
+                \hline
+                \hline
+                Short & \cellcolor{Green}0.0625 & \cellcolor{Green}0.125 & \cellcolor{Yellow}0.25\\
+                \hline
+                Medium & \cellcolor{Green}0.125 & \cellcolor{Yellow}0.25 & \cellcolor{Yellow}0.5\\
+                \hline
+                Long & \cellcolor{Yellow}0.25 & \cellcolor{Yellow}0.5 & \cellcolor{Red}0.75\\
+                \hline
+            \end{tabular}
+            \caption{Importance Levels}
+        \end{table}
+
+        \begin{table}[H]
+            \centering
+            \begin{tabular}{|c|c|c|c|}
+                \hline
+                Requirement & Complexity & Time & Importance Level\\
+                \hline
+                \hline
+                Register & Low & Short & \cellcolor{Green}0.0625\\
+                \hline
+                Sign in & Low & Short & \cellcolor{Green}0.0625\\
+                \hline
+                Sign out & Low & Short & \cellcolor{Green}0.0625\\
+                \hline
+                Create a form & Medium & Long & \cellcolor{Yellow}0.5\\
+                \hline
+                View a form & Medium & Medium & \cellcolor{Yellow}0.25\\
+                \hline
+                Share a form & High & Long & \cellcolor{Red}0.75\\
+                \hline
+                Edit a form & High & Medium & \cellcolor{Yellow}0.5\\
+                \hline
+                Delete a form & Low & Medium & \cellcolor{Green}0.125\\
+                \hline
+                Submit a form & High & Medium & \cellcolor{Yellow}0.5\\
+                \hline
+                Add a partner & High & Long & \cellcolor{Red}0.75\\
+                \hline
+            \end{tabular}
+            \caption{Functional Requirements Analysis}
+        \end{table}
+
+
+\section{Non-Functional Requirements}
+    Non-functional requirements are high-level requirements, that need to be considered during the development decisions for the entire application.\\
+
+    \begin{table}[H]
+        \centering
+        \begin{tabular}{|c|c|}
+            \hline
+            Requirement & Description\\
+            \hline
+            \hline
+            Internet connection & \makecell{The application will be hosted online, therefore users will require\\a connection to the internet in order to access the application.}\\
+            \hline
+            Confidentiality & \makecell{The application will need to keep the personal information of\\ its users safe from third parties and malicious individuals.}\\
+            \hline
+            Integrity & \makecell{The application must present accurate information in an\\ easy-to-understand format.}\\
+            \hline
+            Availability & \makecell{The application must always be accessible. Loss of\\ Availability could lead to users leaving the application for\\ more reliable competitors.}\\
+            \hline
+        \end{tabular}
+        \caption{Non-Functional Requirements}
+    \end{table}
+
+
+\section{Risk Analysis}
+    The following risk analysis has been produced, based on the requirements above and potential risks to the application. A rating system, similar to that of the importance levels for the functional requirements, has been devised for the risk level.\\
+
+    \begin{table}[H]
+        \centering
+        \begin{tabular}{|c||c|c|c|c|c|}
+            \hline
+            Consequence/Likelihood & Negligible & Minor & Moderate & Major & Catastrophic\\
+            \hline
+            \hline
+            Impossible & \cellcolor{Green}0 & \cellcolor{Green}0 & \cellcolor{Green}0 & \cellcolor{Green}0 & \cellcolor{Green}0\\
+            \hline
+            Low & \cellcolor{Green}0 & \cellcolor{Green}0.0625 & \cellcolor{Green}0.125 & \cellcolor{Green}0.1875 & \cellcolor{Yellow}0.25\\
+            \hline
+            Medium & \cellcolor{Green}0 & \cellcolor{Green}0.125 & \cellcolor{Yellow}0.25 & \cellcolor{Yellow}0.375 & \cellcolor{Yellow}0.5\\
+            \hline
+            High & \cellcolor{Green}0 & \cellcolor{Green}0.1875 & \cellcolor{Yellow}0.375 & \cellcolor{Red}0.5625 & \cellcolor{Red}0.75\\
+            \hline
+            Certain & \cellcolor{Green}0 & \cellcolor{Yellow}0.25 & \cellcolor{Yellow}0.5 & \cellcolor{Red}0.75 & \cellcolor{Red}1\\
+            \hline
+        \end{tabular}
+        \caption{Risk Levels}
+    \end{table}
+
+    \hfill\break
+
+    \begin{table}[H]
+        \centering
+        \begin{tabular}{|c|c|c|c|c|c|}
+            \hline
+            Risk & Likelihood & Consequence & \makecell{Risk\\Rating} & Mitigation\\
+            \hline
+            \hline
+            \makecell{Network\\loss} & High & Minor & \cellcolor{Green}0.1875 & Frequent update of database.\\
+            \hline
+            \makecell{Data\\loss} & Low & Catastrophic & \cellcolor{Yellow}0.25 & Redundant database.\\
+            \hline
+            \makecell{Security\\breach} & Medium & Catastrophic & \cellcolor{Yellow}0.5 & \makecell{Follow good practice for secure\\development of cloud applications.}\\
+            \hline
+            \makecell{Function\\error} & High & Major & \cellcolor{Red}0.5625 & \makecell{Implementation of test\\framework to ensure application\\is fully functional.}\\
+            \hline
+            \makecell{Interface\\error} & High & Major & \cellcolor{Red}0.5625 & \makecell{Implementation of test\\framework to ensure application\\is fully functional.}\\
+            \hline
+        \end{tabular}
+        \caption{Risk Analysis}
+    \end{table}
+
+
+\section{Functionality}
+    Below is a series of diagrams which describe the flow of some of the primary pieces of functionality in the application. They show the logic behind various aspects of the application, as well as some of the infrastructure that will be in place.
+
+    \pagebreak
+
+    \subsection{Activity Diagrams}
+
+        % Define block styles
+        \tikzstyle{entry} = [ellipse, draw, fill=Red!20,
+                            text centered,
+                            minimum height=4em,
+                            minimum width=4em,
+                            node distance=10em]
+
+        \tikzstyle{block} = [rectangle, draw, fill=blue!20,
+                            text centered, text width=7em,
+                            minimum height=3em,
+                            node distance=12em, rounded corners]
+
+        \tikzstyle{decision} = [diamond, draw, fill=Green!20,
+                                text badly centered, text width=7em,
+                                minimum height=3em,
+                                node distance=10em, inner sep=0pt]
+
+        \tikzstyle{database} = [cylinder, draw, fill=Yellow!20,
+                                text centered, text width=7em,
+                                minimum height=3em,
+                                node distance=12em, shape border rotate=90, aspect=0.5]
+
+        \tikzstyle{line} = [draw, -latex']
+
+        \begin{figure}[H]
+            \center
+            \begin{tikzpicture}[every node/.style={scale=0.85}]
+                % components
+                \node [entry] (start) {};
+                \node [decision, below of=start] (signedIn) {User already signed in?};
+                \node [block, left of=signedIn] (displayDashboard) {Display Dashboard};
+                \node [block, below of=signedIn] (displayRegistrationOrSignIn) {Display registration/sign in interface};
+                \node [decision, right of=displayRegistrationOrSignIn] (hasAccount) {User has an account?};
+                \node [block, right of=hasAccount] (userRegisters) {User registers};
+                \node [database, above of=userRegisters] (newAccount) {New account information stored in database};
+                \node [block, below of=hasAccount] (userLogin) {User logs in};
+                \node [decision, below of=userLogin] (credentialsValid) {Account credentials valid?};
+                \node [block, right of=credentialsValid] (displayDashboard2) {Display Dashboard};
+                \node [block, left of=credentialsValid] (errorMessage) {Display error message};
+                % connections
+                \path [line] (start) -- (signedIn);
+                \path [line] (signedIn) -- node {Yes} (displayDashboard);
+                \path [line] (signedIn) -- node {No} (displayRegistrationOrSignIn);
+                \path [line] (displayRegistrationOrSignIn) -- (hasAccount);
+                \path [line] (hasAccount) -- node {No} (userRegisters);
+                \path [line] (userRegisters) -- (newAccount);
+                \path [line] (newAccount) -| (hasAccount);
+                \path [line] (hasAccount) -- node {Yes} (userLogin);
+                \path [line] (userLogin) -- (credentialsValid);
+                \path [line] (credentialsValid) -- node {Yes} (displayDashboard2);
+                \path [line] (credentialsValid) -- node {No} (errorMessage);
+                \path [line] (errorMessage) |- (userLogin);
+            \end{tikzpicture}
+            \caption{Activity Diagram: Authentication}
+        \end{figure}
+
+        \clearpage
+
+        \begin{figure}[t]
+            \center
+            \begin{tikzpicture}[every node/.style={scale=0.85}]
+                % components
+                \node [entry] (start) {};
+                \node [block, right of=start] (displayDashboard) {Display Dashboard};
+                \node [block, right of=displayDashboard] (clickCreate) {User clicks \textquotedblleft Create new form\textquotedblright\ button};
+                \node [block, below of=clickCreate] (enterFormDetails) {user enters form questions and possible responses};
+                \node [block, left of=enterFormDetails] (clickSubmit) {User clicks \textquotedblleft Submit\textquotedblright\ button};
+                \node [database, left of=clickSubmit] (dataStored) {Form data stored in database};
+                \node [block, below of=dataStored] (displayDashboard2) {Display Dashboard with new form};
+                % connections
+                \path [line] (start) -- (displayDashboard);
+                \path [line] (displayDashboard) -- (clickCreate);
+                \path [line] (clickCreate) -- (enterFormDetails);
+                \path [line] (enterFormDetails) -- (clickSubmit);
+                \path [line] (clickSubmit) -- (dataStored);
+                \path [line] (dataStored) -- (displayDashboard2);
+            \end{tikzpicture}
+            \caption{Activity Diagram: Form Creation}
+        \end{figure}
+        
+        \begin{figure}[b]
+            \center
+            \begin{tikzpicture}[every node/.style={scale=0.85}]
+                % components
+                \node [entry] (start) {};
+                \node [block, right of=start] (displayDashboard) {Display Dashboard};
+                \node [block, right of=displayDashboard] (clickShare) {User clicks \textquotedblleft Share form\textquotedblright\ button};
+                \node [block, below of=clickCreate] (selectPartners) {User selects one or more of their partner from a list};
+                \node [block, left of=enterFormDetails] (clickSubmit) {User clicks \textquotedblleft Submit\textquotedblright\ button};
+                \node [database, left of=clickSubmit] (dataUpdated) {Database updated, forms appear in partners' dashboards};
+                \node [block, below of=dataUpdated] (displayDashboard2) {Display Dashboard};
+                % connections
+                \path [line] (start) -- (displayDashboard);
+                \path [line] (displayDashboard) -- (clickShare);
+                \path [line] (clickShare) -- (selectPartners);
+                \path [line] (selectPartners) -- (clickSubmit);
+                \path [line] (clickSubmit) -- (dataUpdated);
+                \path [line] (dataUpdated) -- (displayDashboard2);
+            \end{tikzpicture}
+            \caption{Activity Diagram: Form Sharing}
+        \end{figure}
+
+        \clearpage
+
+        \begin{figure}[t]
+            \center
+            \begin{tikzpicture}[every node/.style={scale=0.85}]
+                % components
+                \node [entry] (start) {};
+                \node [block, right of=start] (displayDashboard) {Display Dashboard};
+                \node [block, right of=displayDashboard] (clickAdd) {User clicks \textquotedblleft Add partner\textquotedblright\ button};
+                \node [block, below of=clickAdd, node distance=10em] (searchPartner) {User enters partner's email};
+                \node [block, left of=searchPartner] (clickSubmit) {User clicks \textquotedblleft Submit\textquotedblright\ button};
+                \node [decision, below of=clickSubmit] (isValid) {Does the user exist?};
+                \node [block, left of=isValid] (invitationSent) {Invitation sent to partner accounts};
+                \node [database, below of=invitationSent] (databaseUpdated) {Database entry updated with additional partners};
+                \node [block, right of=databaseUpdated] (displayDashboard2) {Display Dashboard};
+                \node [block, right of=isValid] (errorMessage) {Display error message};
+                % connections
+                \path [line] (start) -- (displayDashboard);
+                \path [line] (displayDashboard) -- (clickAdd);
+                \path [line] (clickAdd) -- (searchPartner);
+                \path [line] (searchPartner) -- (clickSubmit);
+                \path [line] (clickSubmit) -- (isValid);
+                \path [line] (isValid) -- node {Yes} (invitationSent);
+                \path [line] (invitationSent) -- (databaseUpdated);
+                \path [line] (databaseUpdated) -- (displayDashboard2);
+                \path [line] (isValid) -- node {No} (errorMessage);
+                \path [line] (errorMessage) -- (searchPartner);
+            \end{tikzpicture}
+            \caption{Activity Diagram: Add Partner}
+        \end{figure}
+
+    \subsection{Architecture Diagram}
+
+        \hfill\break
+
+        \tikzstyle{component} = [rectangle, draw, fill=blue!20,
+                            text centered, text width=7em,
+                            minimum height=3em,
+                            node distance=12em, rounded corners]
+
+        \begin{figure}[b]
+            \center
+            \begin{tikzpicture}[to/.style={->,>=stealth',shorten >=1pt,semithick,font=\sffamily\footnotesize}, every node/.style={scale=0.85}]
+                % components
+                \node [component] (user) {User};
+                \node [component, below of=user] (react) {React Frontend};
+                \node [component, left of=react] (firebaseAuth) {Firebase Authentication};
+                \node [component, right of=react] (firestore) {Firestore};
+                % connections
+                \path [line] (user) -- node[near start, right] {1) Action} (react);
+                \draw[to] (react)  to[bend right=50] node[midway, above] {2) Request} node[midway, below] {auth token} (firebaseAuth);
+                \draw[to] (firebaseAuth) to[bend right=50] node[midway, above] {3) Send} node[midway, below] {auth token} (react);
+                \draw[to] (react) to[bend right=50] node[midway, above] {4) Update} node[midway, below] {database} (firestore);
+                \draw[to] (firestore) to[bend right=50] node[midway, above] {5) Populate with} node[midway, below] {new data} (react);
+            \end{tikzpicture}
+            \caption{Architecture}
+        \end{figure}
diff --git a/report/4_Chapter4.tex b/report/4_Chapter4.tex
deleted file mode 100644
index 790d962d846b9ec070a385aa501e8ec0ec2b4bc6..0000000000000000000000000000000000000000
--- a/report/4_Chapter4.tex
+++ /dev/null
@@ -1,4 +0,0 @@
-%% ----------------------------------------------------------------
-%% Chapter4.tex
-%% ---------------------------------------------------------------- 
-\chapter{Implementation} \label{Chapter:four}
\ No newline at end of file
diff --git a/report/4_Design.tex b/report/4_Design.tex
new file mode 100644
index 0000000000000000000000000000000000000000..696f3a84577c8cf964e2d804a949e85fb45cb22d
--- /dev/null
+++ b/report/4_Design.tex
@@ -0,0 +1,72 @@
+%% ----------------------------------------------------------------
+%% 4_Design.tex
+%% ---------------------------------------------------------------- 
+\chapter{DESIGN}
+
+The design of the web application will be based on the requirements established in the previous chapter, coupled with standards for user friendly interfaces and the user experience.
+
+\section{Conducting User Research}
+    In order to design a good user interface, one needs to take into account who the user is and what kind of interface will suit them.
+
+    In an SME, any one person could be in charge of compliance, from an employee in IT to someone in an administration role or even the CEO. In light of the fact that the application must allow for both technical and non-technical users, the design must be as accessible as possible. In order to ensure accessibility, the application will be designed with non-technical users in mind, and to that end will also be tested and evaluated by them.
+
+    \subsection{Competitor Research}
+        Existing products have been evaluated in chapter 2. As previously stated, the design of these products is unnecessarily bloated for the purpose of producing cyber security compliance forms. Such products are designed to generate many other form types, whereas this product capitalises on the simple structure of compliance to streamline the design of the tool needed to build them.
+
+    \subsection{User Personas}
+        Creating personas allows the production of dependable, authentic representations of the target user group, in order to perform stakeholder analysis. \cite{Personas}
+
+        \begin{itemize}
+            \item
+                Alan is a 35-year-old head of IT at a small company. He is very capable when it comes to maintaining the company's network and cyber security, but does not know anything about the level of security at other organisations in his company's supply chain. He knows that those organisations could be compromised and used as an attack vector to infiltrate the company network and steal valuable data or do other serious harm.
+
+            \item
+                Emily is a 22-year-old computer science graduate, tasked with producing some cyber security best practices for her company to follow, in order for it to fend off the basic attacks that could be carried out by an unskilled individual. She knows about cyber security best practices from some of her modules at university but is not sure where to start with producing compliance forms for her company to follow.
+
+            \item
+                Bob is a 57-year-old systems administrator at a medium sized company that has just undergone a merger with another firm. He is tasked with combining the cyber security compliance standards that both old companies were using into a single standard for the new company to follow.
+        \end{itemize}
+
+
+\section{User Flows and Wireframes}
+    This section will illustrate the flow of the application from beginning to end, similar to the flow charts in chapter 3, but with wireframes representing the UI and how each page will transition to another.
+
+    \subsection{Wireframes} % 2D outline of single page
+        TODO: Sign in / Sign up wireframe
+
+
+
+        TODO: Dashboard wireframe
+
+        TODO: Create a Form wireframe
+
+        TODO: Add a Partner wireframe
+
+    \subsection{Flow Charts} % Map journey
+        TODO: Minified versions of the wireframes with arrows showing flow of the application...
+
+
+\section{Material-UI}
+    Material-UI is a popular React UI framework for faster and easier web development. It has a massive suite of components that help with building a fully customisable UI, it is incredibly well documented, and it receives regular monthly updates from its developers. For these reasons, Material-UI has been used for many of the components in the project in order to increase development speed.
+
+
+\section{Minimum Viable Product}
+    The Minimum Viable Product (MVP) is the encapsulation of the core features that allow an application to function. While not fully functional, it will have the necessary functionality to allow the application to work at its most basic level, and it provides a solid starting point for a project to work towards.
+
+    In the case of CompForge, the core features have been listed below:
+
+    \begin{itemize}
+        \item Register
+        \item Sign in
+        \item Sign out
+        \item Create Form
+        \item View Form
+        \item Share Form
+        \item Delete Form
+        \item Submit Form
+    \end{itemize}
+
+    \begin{itemize}
+        \item Edit Form
+        \item Add Partner
+    \end{itemize}
\ No newline at end of file
diff --git a/report/5_Chapter5.tex b/report/5_Chapter5.tex
deleted file mode 100644
index ef3283223d218ad7cdf65e6f2ef9f710dd4f0f49..0000000000000000000000000000000000000000
--- a/report/5_Chapter5.tex
+++ /dev/null
@@ -1,4 +0,0 @@
-%% ----------------------------------------------------------------
-%% Chapter5.tex
-%% ---------------------------------------------------------------- 
-\chapter{Testing and Software Validation} \label{Chapter:five}
\ No newline at end of file
diff --git a/report/5_Implementation.tex b/report/5_Implementation.tex
new file mode 100644
index 0000000000000000000000000000000000000000..eb96220586e197fd768e33d5da4aaebe401a4338
--- /dev/null
+++ b/report/5_Implementation.tex
@@ -0,0 +1,121 @@
+%% ----------------------------------------------------------------
+%% 5_Implementation.tex
+%% ---------------------------------------------------------------- 
+\chapter{IMPLEMENTATION}
+
+\section{Project Development Objective}
+    The objective of this project was to produce a web application that would allow an organisation to create, store and share and submit completed compliance forms, in order to reduce the cost of tracking and maintaining compliance to any cyber security standard.
+    
+    \subsection{Functionality}
+        The application, called CompForge, allows a user to create custom compliance forms, which are stored on a serverless database, hosted on Google Firebase. These forms can be shared with partners - other users that are added in a similar fashion to friends or followers on social media. When a form is shared with a partner, that partner can complete and return it to the original user, with their given responses to each question.
+
+
+\section{Technologies}
+    The implementation of a variety of different features was required to complete the application and this required the employment of a number of different technologies. Requirements included a fast and flexible frontend framework to reduce loading times and adapt quickly to changes from the backend, a real-time database to send those changes to the frontend, and good out-of-the-box security.
+
+    \begin{table}[H]
+        \centering
+        \begin{tabular}{|c|c|c|}
+            \hline
+            Tool/Library & Purpose & Justification\\
+            \hline
+            \hline
+            \multicolumn{3}{|c|}{Application}\\
+            \hline
+            \hline
+            \makecell{React} & \makecell{Front end development} & \makecell{Reusable components,\\development speed,\\ reduced loading times}\\
+            \hline
+            \makecell{React Router} & \makecell{Navigation between\\virtual pages} & \makecell{Reduced loading times}\\
+            \hline
+            \makecell{Material-UI} & \makecell{Flexible pre-built\\components} & \makecell{Development speed}\\
+            \hline
+            \makecell{create-react-app} & \makecell{Quick start\\for React apps} & \makecell{Development speed}\\
+            \hline
+            \makecell{Firebase} & \makecell{Backend as a Service} & \makecell{Development speed,\\no need to\\setup and maintain\\own server}\\
+            \hline
+            \makecell{Firebase Authentication} & \makecell{Authentication as a Service} & \makecell{Development speed,\\security}\\
+            \hline
+            \makecell{Firestore} & \makecell{Serverless real-time\\NoSQL database} & \makecell{Development speed,\\real-time updates}\\
+            \hline
+            \makecell{Firebase CLI} & \makecell{Utility for\\administering\\Firebase projects} & \makecell{Configuration of\\React-Firebase connection}\\
+            \hline
+            \hline
+            \multicolumn{3}{|c|}{Report}\\
+            \hline
+            \hline
+            \makecell{Latex} & \makecell{Document preparation system} & \makecell{Produces refined and\\polished PDF reports}\\
+            \hline
+            \makecell{TikZ} & \makecell{Latex library for\\drawing and\\diagram creation} & \makecell{Creation of clean wireframes\\and UML diagrams}\\
+            \hline
+            \hline
+            \multicolumn{3}{|c|}{Miscellaneous}\\
+            \hline
+            \hline
+            \makecell{GitLab} & \makecell{Version control system} & \makecell{Project planning and\\code management}\\
+            \hline
+            \makecell{Batch \& WSL} & \makecell{Scripting \& providing\\Linux commands\\on Windows} & \makecell{Latex build and\\clean up script\\(see appendix)}\\
+            \hline
+        \end{tabular}
+        \caption{Technologies and Justifications for Use}
+    \end{table}
+
+    \subsection{React}
+        React is a JavaScript library specialising in the development of user interfaces, developed and maintained by Facebook. \cite{React} React was chosen as the medium for the frontend due to it's manipulation of the virtual DOM, which reduces loading times; reusable components to increase development speed, and built-in defence against Cross Site Scripting attacks. Given that the core of the application involves user inputting data to forms, the latter is especially important.
+
+        \subsubsection{Redux/Thunk}
+            Redux was utilised to manage the state of the application, including the user's data, and whether they are authenticated. Redux imposes certain restrictions when it comes to state management, increasing a developer's control over how and when the state can be updated.
+
+            To change the application's state, you need to dispatch an action (a JavaScript object). The action and the application's current state are passed into a JavaScript function, called a reducer. A reducer takes these two parameters and returns the new state of the application. Usually the state of an application will be quite large, so instead of managing the entire state with a single reducer, multiple reducers are written to manage different parts of the state.
+
+            Thunk allows asynchronous logic to interact with the state. It was used in CompForge to do ...
+
+        \subsubsection{Code Structure}
+            The structure of the React frontend is heavily influenced by create-react-app - a tool used in this project to get a head start on the setup and configuration of the frontend application. Since there is no recommended way to structure React projects, my opinion on the best way to do this for the remainder source code was to group by page, thereby simplifying the process of finding and editing related components.
+
+        \subsubsection{Single Page Application and Routing}
+            Another reason for using the create-react-app tool is that it initialises the application as a single-page application (SPA), which further reduces the loading time for users. As an SPA, the entire frontend is loaded when the user enters the application, and it is not necessary to load anything further, even when navigating the app. From there all the routing between the different pages is done by React Router, a library of React components that are used to navigate between pages in an SPA. However, everything in React is a component, including the \textquoteleft pages\textquoteright, and so the beauty of React Router is that it allows redirection between components, and as such, will only need to re-render the relevant component(s) that are being loaded to the screen, as opposed to the entire page.
+
+        \subsubsection{Node.js}
+            Node is a free cross platform open source server environment that runs JavaScript. It was used in this project as a local testing environment as it allows the React project to run on a local development server. Node also manages a range of modules that the project was dependent on, including Material-UI, and the Firebase CLI.
+    
+    \subsection{Google Firebase}
+        Firebase is Google's mobile application development platform. \cite{Firebase} It is used by many large applications such as Lyft, Venmo and Trivago for its multitude of services including hosting, authentication, database, storage, and functions.
+
+        \subsubsection{Firestore}
+            The benefit of using Firebase's database (called Firestore) is that data sent to the database is immediately forwarded on to relevant interested instances of the application, so changes made by one user can update another user in close to real time. In addition, you can add multiple apps to the service and they will all share the same database, making maintaining the application across multiple platforms, like Web, iOS and Android far easier, however, this project is only a web application.
+        
+        \subsubsection{Serverless Architecture}
+            Serverless architecture is the model Firebase uses as its platform. It is not, in fact, serverless as the name suggests. It simply means that the need for server software and hardware management by the developer is erased, because the infrastructure is provided by a host, like Firebase. This allows for improved scalability for hosted applications.
+
+\section{Progression}
+    This section describes the progression of the implementation during each sprint. The original plan for these sprints is laid out in chapter 8. Much of the implementation took longer than expected due to the fact it was the first time many of the technologies were being used, resulting in a steep learning curve for myself.
+
+    \subsection{Sprint 1}
+        The implementation started with the installation and running of create-react-app to kickstart frontend development. From there Material-UI components were used and tweaked alongside custom code to construct the \textquotedblleft Dashboard\textquotedblright\, and \textquotedblleft Create a Form\textquotedblright\ pages. Below is a screenshot of an early iteration of the dashboard.
+
+        \begin{figure}[H]
+            \center
+            \includegraphics[height=100mm, width=145mm]{../figures/Dashboard (hardcoded)}
+            \caption{Dashboard}
+        \end{figure}
+
+    \subsection{Sprint 2}
+        A \textquoteleft Compforge\textquoteright\ project was created on Firebase. Some configuration in the React code ws needed to connect to the project's Firestore. In addition, a lot of work was done to implement the Redux/Thunk reducers and actions needed to store and manipulate the state of the application.
+
+        \begin{figure}[H]
+            \center
+            \includegraphics[height=100mm, width=145mm]{../figures/Firebase}
+            \caption{Firestore}
+        \end{figure}
+
+    \subsection{Sprint 3}
+        With the basics finished, the next step was to set up authentication and user accounts, implemented using Firebase Authentication. For simplicity, I only configured sign ups by email, though it is possible to set up authentication via many other methods in Firebase namely; phone number, Google, Facebook, Twitter, GitHub, Yahoo, Microsoft and Apple accounts. Once accounts and authentication were completed, the frontend needed a \textquoteleft Sign up\textquoteright\ and \textquoteleft Sign in\textquoteright\ page. Using a Material-UI template, some configuration of the React code, as well as adjustments to the routing, the ability to sign up, sign in and sign out was added to the web app.
+
+    \subsection{Sprint 4}
+        After user accounts had been set up, the had been to implement the partner system. However, due to time constraints (discussed further in Chapter 7: Evaluation) this requirement was removed. Instead work focused on finishing the MVP; saving forms from the form creation page to Firestore, and the ability to share forms direct to users via their email addresses.
+
+    \subsection{Sprint 5}
+        The final requirements were for a user to create submissions for forms that are shared with them, and to view forms and submissions. After creating a frontend page for completing and submitting a form, and adding it to the routing, the submissions were stored in Firestore in their own collection.
+
+    \subsection{Sprint 6}
+        Refinements to the UI were made to improve the user experience, including changes to the columns shown on the form table on the dashboard. Some compiler warnings were also cleared and links between the \textquotedblleft sign in\textquotedblright\ and \textquotedblleft sign up\textquotedblright\ pages were created.
\ No newline at end of file
diff --git a/report/6_Chapter6.tex b/report/6_Chapter6.tex
deleted file mode 100644
index 63bcdcb7285f6b9319b015544c8d0b598ba81b0c..0000000000000000000000000000000000000000
--- a/report/6_Chapter6.tex
+++ /dev/null
@@ -1,4 +0,0 @@
-%% ----------------------------------------------------------------
-%% Chapter6.tex
-%% ---------------------------------------------------------------- 
-\chapter{Results and Analysis} \label{Chapter:six}
\ No newline at end of file
diff --git a/report/6_TestingAndSoftwareValidation.tex b/report/6_TestingAndSoftwareValidation.tex
new file mode 100644
index 0000000000000000000000000000000000000000..18b675af359ff335184501277614f68e59e0f961
--- /dev/null
+++ b/report/6_TestingAndSoftwareValidation.tex
@@ -0,0 +1,77 @@
+%% ----------------------------------------------------------------
+%% 6_TestingAndSoftwareValidation.tex
+%% ---------------------------------------------------------------- 
+\chapter{TESTING AND SOFTWARE VALIDATION}
+
+    Verification and validation are essential parts of any software project. Consequently, multiple different methods for testing the application have been employed to confirm that the application is fully functional and robust, from manual and automated to user and requirements testing.
+
+\section{Verification}
+    Verification tests have been carried to make sure that all functionality has been implemented in the project to meet the requirements of the target users. 
+
+    \subsection{Requirements testing}
+
+        \begin{table}[H]
+            \centering
+            \begin{tabular}{|c|c|c|c|}
+                \hline
+                Requirement & Expectation & Outcome & Result\\
+                \hline
+                \hline
+                \makecell{Register} & \makecell{Use email address to\\create an account} & \makecell{Users are able to use their\\email address to create a\\persistent account} & \cellcolor{green}\checkmark\\
+                \hline
+                \makecell{Sign in} & \makecell{Use email address and\\password created at sign\\up to sign in} & \makecell{Users are able to login} & \cellcolor{green}\checkmark\\
+                \hline
+                \makecell{Sign out} & \makecell{Sign out of account\\so that account is\\no longer accessible\\without signing back in} & \makecell{On clicking the sign out\\button the user is no\\longer able to access\\their account without\\logging back in} & \cellcolor{green}\checkmark\\
+                \hline
+                \makecell{Create Form} & \makecell{Create a custom\\compliance form which is\\stored in association\\with the user's account} & \makecell{Ability to create a compliance\\form which is stored and\\associated with the user's\\account} & \cellcolor{green}\checkmark\\
+                \hline
+                \makecell{View Form} & \makecell{View created forms} & \makecell{Users can view their own\\forms and those of other\\users that have been shared\\with them.} & \cellcolor{green}\checkmark\\
+                \hline
+                \makecell{Share Form} & \makecell{Share a form created\\by the user with\\another user} & \makecell{Sharing a form with\\another user allows that\\ user to view, fill out and\\return a form submission} & \cellcolor{green}\checkmark\\
+                \hline
+                \makecell{Edit Form} & \makecell{Edit the questions and\\responses of created forms.} & \makecell{Requirement dropped due\\to time constraints as it\\was not a part of the MVP.} & \cellcolor{red}\texttimes\\
+                \hline
+                \makecell{Delete Form} & \makecell{Delete a form created\\by the user} & \makecell{Deleting a form that\\was originally created by\\that user. Unable to\\delete forms created\\by other users} & \cellcolor{green}\checkmark\\
+                \hline
+                \makecell{Form Submission} & \makecell{To return a user's responses\\to a form to its author} & \makecell{Users can select responses\\for each form's questions\\and submit their responses\\to the form's author} & \cellcolor{green}\checkmark\\
+                \hline
+                \makecell{Add Partner} & \makecell{To search and add another\\user as a partner} & \makecell{Requirement dropped due\\to time constraints as it\\was not a part of the MVP.} & \cellcolor{red}\texttimes\\
+                \hline
+            \end{tabular}
+            \caption{Requirements testing}
+        \end{table}
+
+\section{Validation}
+    To ensure that CompForge met the functional requirements specified in chapter 2, and to establish the absence of bugs, the application was evaluated using an automated test suite.
+
+    \subsection{Manual Testing}
+        The most straightforward way to test the application was to simply use it. Listed below are the steps taken to manually test CompForge.
+
+        \begin{itemize}
+            \item Accounts 1, 2 \& 3 created.
+            \item Account 1 creates and shares Forms 1 \& 2 with the other accounts.
+            \item Account 1 \& 2 view Form 1.
+            \item Account 1 deletes Form 1.
+            \item Accounts 1 \& 2 verify Form 1 is no longer visible.
+            \item Account 2 creates a submission for Form 2.
+            \item Account 1 views the submission from Account 2 for Form 2.
+            \item Account 3 verifies that it can view Form 2, but not the submission for Form 2, and that it does not have the ability to delete Form 2.
+            \item Account 3 creates a submission for Form 2.
+            \item Account 1 verifies that there are 2 separate, viewable submissions of Form 2, for Accounts 2 \& 3.
+        \end{itemize}
+
+    \subsection{Robot Framework}
+        The testing and validation of the application was done using Robot Framework. Robot Framework is a generic, open source, automation framework for acceptance testing \cite{Robot}, developed with Python. The framework has many libraries that extend its functionality, and one such library is Selenium, which was used extensively to automatically drive the application's user interface.
+
+        \subsubsection{Integration}
+            TODO:
+            How robot was integrated into the project
+
+        \subsubsection{Testing Writing}
+            TODO:
+            The process of planning and implementing tests
+            Test cases etc
+
+        \subsubsection{Results}
+            TODO:
+            Insert the beautiful HTML results page (and discuss?)
\ No newline at end of file
diff --git a/report/7_Chapter7.tex b/report/7_Chapter7.tex
deleted file mode 100644
index b6b5726ddb52682db8fbf3aa73ef2c3c6b11584d..0000000000000000000000000000000000000000
--- a/report/7_Chapter7.tex
+++ /dev/null
@@ -1,4 +0,0 @@
-%% ----------------------------------------------------------------
-%% Chapter7.tex
-%% ---------------------------------------------------------------- 
-\chapter{Evaluation} \label{Chapter:seven}
\ No newline at end of file
diff --git a/report/7_Evaluation.tex b/report/7_Evaluation.tex
new file mode 100644
index 0000000000000000000000000000000000000000..6bf2b37da3071484988e1b74286f2b725f2d7e16
--- /dev/null
+++ b/report/7_Evaluation.tex
@@ -0,0 +1,129 @@
+%% ----------------------------------------------------------------
+%% 7_Evaluation.tex
+%% ---------------------------------------------------------------- 
+\chapter{EVALUATION}
+
+This chapter will evaluate the project by critical evaluation and will discuss the results of the requirements testing, taking into consideration issues that were faced during implementation.
+
+\section{Critical Evaluation}
+    While React was a good choice from a development and maintenance point of view, it would probably have been more prudent to use a language/library/framework with which I was already more familiar. Whilst a great deal was learned from the implementation of this project, it was significantly delayed - in part due to the time required to learn how to properly use the React library, including React Router and Redux/Thunk.
+
+    With regard to the outcome of the project versus the initial functional requirements, the project is functional because all of the components identified as the MVP have been implemented, however with the obvious downfall that some features, namely adding partners and editing forms, were not implemented which was disappointing, albeit unavoidable, given the delays.
+
+
+\section{Project Management}
+    Some of the first parts of the project actually progressed ahead of schedule, such as the creation of the initial Gantt chart. Until the deadline for the progress report in December, the project was progressing on schedule. Understandably, the implementation, testing and final report write up were severely impacted by the university closure from the 23rd March onwards, due to the spread of COVID-19. This, coupled with delays during the implementation caused by an underestimation of the learning curve of the technologies that were used, resulted in much of the remainder of the project being completed behind schedule.
+
+    \subsection{Gantt Chart}
+
+        The initial Gantt chart is represented by the cells in blue, with the aforementioned delays to the project represented in orange. Major components are represented in a darker shade of each colour, with each subcomponent represented by respective lighter shades. For readability, it has been split over two pages.
+
+        \begin{sidewaystable}[h]
+            \centering
+            \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|}
+                \hline
+                Component & Subcomponent & October & November & December & January & February & March & April & May\\
+                \hline
+                \hline
+                Project Brief & & \cellcolor{RoyalBlue} & & & & & & & \\
+                \hline
+                & Background Research & \cellcolor{Cyan} & & & & & & & \\
+                \hline
+                & Write up & \cellcolor{Cyan} & & & & & & & \\
+                \hline
+                \hline
+                \makecell{Time Management\\Planning} & & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & & & & & \\
+                \hline
+                & Gantt Chart & \cellcolor{Cyan} & \cellcolor{Cyan} & \cellcolor{Cyan} & & & & & \\
+                \hline
+                \hline
+                Research & & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & & & & & \\
+                \hline
+                & \makecell{Further\\background research} & \cellcolor{Cyan} & \cellcolor{Cyan} & & & & & & \\
+                \hline
+                & Literature review & & \cellcolor{Cyan} & \cellcolor{Cyan} & & & & & \\
+                \hline
+                \hline
+                Design & & & \cellcolor{RoyalBlue} & & & & & & \\
+                \hline
+                & Planning diagrams & & \cellcolor{Cyan} & & & & & & \\
+                \hline
+                \hline
+                Progress Report & & & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & & & & & \\
+                \hline
+                & Write up & & \cellcolor{Cyan} & \cellcolor{Cyan} & & & & & \\
+                \hline
+                \hline
+                Implementation & & & & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & \cellcolor{BurntOrange} & & \\
+                \hline
+                & Sign up & & & \cellcolor{Cyan} & \cellcolor{Apricot} & & & & \\
+                \hline
+                & Sign in & & & \cellcolor{Cyan} & \cellcolor{Apricot} & & & & \\
+                \hline
+                & Sign out & & & \cellcolor{Cyan} & \cellcolor{Apricot} & & & & \\
+                \hline
+                & Create form & & & & \cellcolor{Cyan} & \cellcolor{Apricot} & & & \\
+                \hline
+                & Delete form & & & & \cellcolor{Cyan} & \cellcolor{Apricot} & & & \\
+                \hline
+                & View form & & & & \cellcolor{Cyan} & \cellcolor{Apricot} & & & \\
+                \hline
+                & Share form & & & & & \cellcolor{Cyan} & \cellcolor{Apricot} & & \\
+                \hline
+                & Submit form & & & & & \cellcolor{Cyan} & \cellcolor{Apricot} & & \\
+                \hline
+                & View submissions & & & & & \cellcolor{Cyan} & \cellcolor{Apricot} & & \\
+                \hline
+            \end{tabular}
+            \caption{Gantt Chart}
+        \end{sidewaystable}
+
+        \pagebreak
+
+        \begin{sidewaystable}[h]
+            \centering
+            \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|}
+                \hline
+                Component & Subcomponent & October & November & December & January & February & March & April & May\\
+                \hline
+                \hline
+                \makecell{Testing and\\Validation} & & & & & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & \cellcolor{BurntOrange} & \cellcolor{BurntOrange} & \\
+                \hline
+                & Robot Framework setup & & & & \cellcolor{Cyan} & \cellcolor{Apricot} & \cellcolor{Apricot} & \cellcolor{Apricot} & \\
+                \hline
+                & Test Implementation & & & & \cellcolor{Cyan} & \cellcolor{Cyan} & \cellcolor{Apricot} & \cellcolor{Apricot} & \\
+                \hline
+                Final Report & & & & & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & \cellcolor{RoyalBlue} & \cellcolor{BurntOrange}\\
+                \hline
+                & Introduction & & & \cellcolor{Cyan} & & & & & \\
+                \hline
+                & \makecell{Background and\\Literature Review} & & & \cellcolor{Cyan} & & & & & \\
+                \hline
+                & Designs & & & \cellcolor{Cyan} & & & & & \\
+                \hline
+                & Implementation & & & & & \cellcolor{Cyan} & \cellcolor{Cyan} & \cellcolor{Apricot} & \\
+                \hline
+                & Testing and software validation & & & & & & \cellcolor{Cyan} & \cellcolor{Cyan} & \cellcolor{Apricot} \\
+                \hline
+                & Results and Analysis & & & & & & \cellcolor{Cyan} & \cellcolor{Cyan} & \cellcolor{Apricot} \\
+                \hline
+                & Evaluation & & & & & & \cellcolor{Cyan} & \cellcolor{Cyan} & \cellcolor{Apricot}\\
+                \hline
+                & Project management & & & & & & \cellcolor{Cyan} & \cellcolor{Cyan} & \cellcolor{Apricot}\\
+                \hline
+                & Conclusions & & & & & & \cellcolor{Cyan} & \cellcolor{Cyan} & \cellcolor{Apricot}\\
+                \hline
+                & Future work & & & & & & & \cellcolor{Cyan} & \cellcolor{Apricot}\\
+                \hline
+                & Bibliography & & & & & & & \cellcolor{Cyan} & \cellcolor{Apricot}\\
+                \hline
+                & Appendices & & & & & & & \cellcolor{Cyan} & \cellcolor{Apricot}\\
+                \hline
+                \hline
+                \makecell{\st{Project Viva}\\(cancelled)} & - & - & - & - & - & - & - & \cellcolor{RoyalBlue} - & - \\
+                \hline
+                - & \st{Viva} & - & - & - & - & - & - & \cellcolor{Cyan} - & - \\
+                \hline
+            \end{tabular}
+            \caption{Gantt Chart cont.}
+        \end{sidewaystable}
\ No newline at end of file
diff --git a/report/8_Chapter8.tex b/report/8_Chapter8.tex
deleted file mode 100644
index 35aca70d71e0c6bb64e3f8a5a89a16d22f02281d..0000000000000000000000000000000000000000
--- a/report/8_Chapter8.tex
+++ /dev/null
@@ -1,6 +0,0 @@
-%% ----------------------------------------------------------------
-%% Chapter8.tex
-%% ---------------------------------------------------------------- 
-\chapter{Project Management} \label{Chapter:eight}
-It works.
-
diff --git a/report/8_Conclusions.tex b/report/8_Conclusions.tex
new file mode 100644
index 0000000000000000000000000000000000000000..3c2a1d1b9330e401fa25a6b57de12f77fa29917f
--- /dev/null
+++ b/report/8_Conclusions.tex
@@ -0,0 +1,27 @@
+%% ----------------------------------------------------------------
+%% 9_Conclusions.tex
+%% ---------------------------------------------------------------- 
+\chapter{CONCLUSION} \label{Chapter: Conclusions}
+
+This project aimed to enable SMEs to create and customise their own compliance forms in order to stay up to date with the latest cyber security standards, as well as ensure that their partner organisations and other organisations in their supply chain are keeping to those same standards. CompForge has lowered the time and cost required to perform these tasks, with a user-friendly UI and real time updates from the application's Firestore database.
+
+\section{Improvements}
+    After evaluating the application and comparing it to competitors, a number of improvements that could be made have come to mind.
+    
+    The ability to edit forms that have already been created, would be a useful tool in case a mistake is found, or an update is required. This is to be expected in the continuously growing field of cyber security, as doubtless many of the standards that are active today will change with time as technology continues to move forward along with the threats.
+
+    On the same vein, it would be useful to add the ability to share a form with new partners after it has been created. Organisations change and grow, and it could be necessary to share a form with additional organisations.
+
+    To save time, another useful feature would be the ability to add partners in a similar way to adding a friend on a social media platform. There would be no need to look up email addresses every time you needed to share a new form with an existing partner.
+
+    Finally, the number of forms you can create and share is technically infinite, so a search bar and sorting filter would both be useful additions to the application.
+
+
+\section{Future Work}
+    Further to the above improvements, there are some more major improvements that could be made with future work.
+
+    Specifically, a feature that allows a user to export form templates and specific submissions from partners to a particular format. Users may wish to print another user's submission to their form or share a form template with another user.
+
+    Conversely, the ability to import existing form templates would allow users to share popular standards such as; ISO/IEC 27001, Cloud Controls Matrix, the Cyber Essentials Scheme, or its progeny, IASME.
+
+    Finally, the use of email notifications to notify users when a form has been shared with them, or when a partner has made a submission would be convenient, as it is unlikely a user will have the application open at all times.
\ No newline at end of file
diff --git a/report/12_Appendices.tex b/report/99_Appendix.tex
similarity index 93%
rename from report/12_Appendices.tex
rename to report/99_Appendix.tex
index fd15e2a218eb670a68bf40b9bf3ed2c4e9ba316d..e15b536711d92e32b987d57246f1e9e021aaa308 100644
--- a/report/12_Appendices.tex
+++ b/report/99_Appendix.tex
@@ -1,5 +1,5 @@
 %% ----------------------------------------------------------------
-%% Appendices.tex
+%% Appendix.tex
 %% ---------------------------------------------------------------- 
 \chapter{Appendix A: Photos} \label{appendix1}
 This is an appendix
diff --git a/report/9_Conclusions.tex b/report/9_Conclusions.tex
deleted file mode 100644
index 56041283e65b57d3b3465effa085a4c464a401fc..0000000000000000000000000000000000000000
--- a/report/9_Conclusions.tex
+++ /dev/null
@@ -1,5 +0,0 @@
-%% ----------------------------------------------------------------
-%% Conclusions.tex
-%% ---------------------------------------------------------------- 
-\chapter{Conclusions} \label{Chapter: Conclusions}
-It works.
diff --git a/report/master.bbl b/report/master.bbl
new file mode 100644
index 0000000000000000000000000000000000000000..5c4e8f6eacc8e9fca9702e49635ad136efbc2f1d
--- /dev/null
+++ b/report/master.bbl
@@ -0,0 +1,121 @@
+% Generated by IEEEtran.bst, version: 1.12 (2007/01/11)
+\begin{thebibliography}{10}
+\providecommand{\url}[1]{#1}
+\csname url@samestyle\endcsname
+\providecommand{\newblock}{\relax}
+\providecommand{\bibinfo}[2]{#2}
+\providecommand{\BIBentrySTDinterwordspacing}{\spaceskip=0pt\relax}
+\providecommand{\BIBentryALTinterwordstretchfactor}{4}
+\providecommand{\BIBentryALTinterwordspacing}{\spaceskip=\fontdimen2\font plus
+\BIBentryALTinterwordstretchfactor\fontdimen3\font minus
+  \fontdimen4\font\relax}
+\providecommand{\BIBforeignlanguage}[2]{{%
+\expandafter\ifx\csname l@#1\endcsname\relax
+\typeout{** WARNING: IEEEtran.bst: No hyphenation pattern has been}%
+\typeout{** loaded for the language `#1'. Using the pattern for}%
+\typeout{** the default language instead.}%
+\else
+\language=\csname l@#1\endcsname
+\fi
+#2}}
+\providecommand{\BIBdecl}{\relax}
+\BIBdecl
+
+\bibitem{CSCRM}
+\BIBentryALTinterwordspacing
+S.~Boyson, ``Cyber supply chain risk management: Revolutionizing the strategic
+  control of critical it systems.'' [Online]. Available:
+  \url{https://www.sciencedirect.com/science/article/pii/S0166497214000194}
+\BIBentrySTDinterwordspacing
+
+\bibitem{CyberEssentials}
+\BIBentryALTinterwordspacing
+GOV.UK, ``Cyber essentials scheme: Overview,'' 2014. [Online]. Available:
+  \url{https://www.gov.uk/government/publications/cyber-essentials-scheme-overview}
+\BIBentrySTDinterwordspacing
+
+\bibitem{GDPR}
+\BIBentryALTinterwordspacing
+J.~Zerlang, ``Gdpr: a milestone in convergence for cyber-security and
+  compliance,'' 2017. [Online]. Available:
+  \url{https://www.sciencedirect.com/science/article/pii/S1353485817300600}
+\BIBentrySTDinterwordspacing
+
+\bibitem{CombattingCyberRisks}
+\BIBentryALTinterwordspacing
+D.~Shackleford, 2015. [Online]. Available:
+  \url{https://www.raytheon.com/sites/default/files/capabilities/rtnwcm/groups/cyber/documents/content/rtn_273005.pdf}
+\BIBentrySTDinterwordspacing
+
+\bibitem{ComplianceGovernance}
+\BIBentryALTinterwordspacing
+S.~et~al., ``Aiding compliance governance in service-based business
+  processes,'' in \emph{Handbook of Research on Service-Oriented Systems and
+  Non-Functional Properties: Future Directions}, 2012, pp. 524--548. [Online].
+  Available:
+  \url{https://www.igi-global.com/chapter/handbook-research-service-oriented-systems/60900}
+\BIBentrySTDinterwordspacing
+
+\bibitem{StanfordConsortium}
+\BIBentryALTinterwordspacing
+e.~a. Elliott, ``Consrotium for research on information security and policy,''
+  1998-2001. [Online]. Available:
+  \url{https://fsi.stanford.edu/research/consortium_for_research_on_information_security_and_policy}
+\BIBentrySTDinterwordspacing
+
+\bibitem{CyberCrime}
+\BIBentryALTinterwordspacing
+N.~C. Agency, ``Cyber crime.'' [Online]. Available:
+  \url{https://www.nationalcrimeagency.gov.uk/what-we-do/crime-threats/cyber-crime}
+\BIBentrySTDinterwordspacing
+
+\bibitem{ITGovernance}
+\BIBentryALTinterwordspacing
+I.~Governance, ``Customers lose confidence - data breaches aren't just about
+  fines,'' 2018. [Online]. Available:
+  \url{https://www.itgovernance.co.uk/blog/customers-lose-confidence-data-breaches-arent-just-about-fines}
+\BIBentrySTDinterwordspacing
+
+\bibitem{BusinessInfo}
+\BIBentryALTinterwordspacing
+p.~b. I. N.~I. nibusinessinfo.co.uk, ``Cyber security for business.'' [Online].
+  Available:
+  \url{https://www.nibusinessinfo.co.uk/content/impact-cyber-attack-your-business}
+\BIBentrySTDinterwordspacing
+
+\bibitem{z6mag}
+\BIBentryALTinterwordspacing
+z6mag, ``Two cashback sites leaked data of 3.5 million users.'' [Online].
+  Available:
+  \url{https://z6mag.com/2019/10/16/two-cashback-sites-leaked-data-of-3-5-million-users/}
+\BIBentrySTDinterwordspacing
+
+\bibitem{Formstack}
+\BIBentryALTinterwordspacing
+Formstack. [Online]. Available: \url{https://formstack.com/}
+\BIBentrySTDinterwordspacing
+
+\bibitem{DeviceMagic}
+\BIBentryALTinterwordspacing
+D.~Magic. [Online]. Available: \url{https://devicemagic.com/}
+\BIBentrySTDinterwordspacing
+
+\bibitem{Personas}
+Usability.gov.
+
+\bibitem{React}
+\BIBentryALTinterwordspacing
+Facebook. [Online]. Available: \url{https://reactjs.org/}
+\BIBentrySTDinterwordspacing
+
+\bibitem{Firebase}
+\BIBentryALTinterwordspacing
+Google. [Online]. Available: \url{https://firebase.google.com/}
+\BIBentrySTDinterwordspacing
+
+\bibitem{Robot}
+\BIBentryALTinterwordspacing
+R.~F. Foundation. [Online]. Available: \url{https://www.robotframework.org/}
+\BIBentrySTDinterwordspacing
+
+\end{thebibliography}
diff --git a/report/master.bib b/report/master.bib
index d3e12566f45fe6e3ddc383b1597e73f864ad2fb0..9e865b6e5d2c587d865ec391d60e5e214253d09a 100644
--- a/report/master.bib
+++ b/report/master.bib
@@ -6,3 +6,101 @@
   title =        {PDFLaTeX Instructions},
   url =          {http://www.ecs.soton.ac.uk/~srg/softwaretools/document/}
 }
+
+@article{CSCRM,
+  author =      {Boyson, Sandor},
+  title =       {Cyber supply chain risk management: Revolutionizing the strategic control of critical IT systems},
+  url =         {https://www.sciencedirect.com/science/article/pii/S0166497214000194}
+}
+
+@incollection{ComplianceGovernance,
+  author =      {Silveira et al.},
+  title =       {Aiding Compliance Governance in Service-Based Business Processes},
+  year =        {2012},
+  pages =       {524-548},
+  booktitle =   {Handbook of Research on Service-Oriented Systems and Non-Functional Properties: Future Directions},
+  url =         {https://www.igi-global.com/chapter/handbook-research-service-oriented-systems/60900}
+}
+
+@document{CombattingCyberRisks,
+  author =      {Shackleford, Dave},
+  publisher =   {SANS Whitepaper},
+  year =        {2015},
+  url =         {https://www.raytheon.com/sites/default/files/capabilities/rtnwcm/groups/cyber/documents/content/rtn_273005.pdf}
+}
+
+@misc{CyberCrime,
+  author =      {National Crime Agency},
+  title =       {Cyber Crime},
+  url =         {https://www.nationalcrimeagency.gov.uk/what-we-do/crime-threats/cyber-crime}
+}
+
+@misc{CyberEssentials,
+  author =      {GOV.UK},
+  title =       {Cyber Essentials Scheme: Overview},
+  year =        {2014},
+  url =         {https://www.gov.uk/government/publications/cyber-essentials-scheme-overview}
+}
+
+@misc{StanfordConsortium,
+  author =      {Elliott, et al.},
+  title =       {Consrotium for Research on Information Security and Policy},
+  year =        {1998-2001},
+  url =         {https://fsi.stanford.edu/research/consortium_for_research_on_information_security_and_policy}
+}
+
+@article{GDPR,
+  author =      {Zerlang, Jesper},
+  title =       {GDPR: a milestone in convergence for cyber-security and compliance},
+  issue =       {6},
+  year =        {2017},
+  url =         {https://www.sciencedirect.com/science/article/pii/S1353485817300600}
+}
+
+@misc{ITGovernance,
+  author =      {IT Governance},
+  title =       {Customers lose confidence - data breaches aren't just about fines},
+  year =        {2018},
+  url =         {https://www.itgovernance.co.uk/blog/customers-lose-confidence-data-breaches-arent-just-about-fines}
+}
+
+@misc{BusinessInfo,
+  author =      {nibusinessinfo.co.uk, provided by Invest Northern Ireland},
+  title =       {Cyber security for business},
+  url =         {https://www.nibusinessinfo.co.uk/content/impact-cyber-attack-your-business}
+}
+
+@misc{Robot,
+  author =      {Robot Framework Foundation},
+  url =         {https://www.robotframework.org/}
+}
+
+@misc{z6mag,
+  author =      {z6mag},
+  title =       {Two cashback sites leaked data of 3.5 million users},
+  url =         {https://z6mag.com/2019/10/16/two-cashback-sites-leaked-data-of-3-5-million-users/}
+}
+
+@misc{React,
+  author =      {Facebook},
+  url =         {https://reactjs.org/}
+}
+
+@misc{Firebase,
+  author =      {Google},
+  url =         {https://firebase.google.com/}
+}
+
+@misc{Formstack,
+  author =      {Formstack},
+  url =         {https://formstack.com/}
+}
+
+@misc{DeviceMagic,
+  author =      {Device Magic},
+  url =         {https://devicemagic.com/}
+}
+
+@misc{Personas,
+  author =      {Usability.gov},
+  url =         {https://usability.gov/how-to-and-tools/methods/personas.html}
\ No newline at end of file
diff --git a/report/master.dvi b/report/master.dvi
index 57d182e979b68d252516c5ef8ed3629186a24b62..5b51653874bf1a4d1e971a8e818b0757e89bdd2e 100644
Binary files a/report/master.dvi and b/report/master.dvi differ
diff --git a/report/master.pdf b/report/master.pdf
index 6b655d07a0a749f44e1756b2a90fcc158b2aa9e6..bc87660d94b5231827bcd49f86d78395f620a77b 100644
Binary files a/report/master.pdf and b/report/master.pdf differ
diff --git a/report/master.tex b/report/master.tex
index 3e86eb2e7d01ef8c3798f0d84233b53d4b257011..29f5c4b00f4d40a3562ff281a375444af71032db 100644
--- a/report/master.tex
+++ b/report/master.tex
@@ -8,33 +8,31 @@
 %% ----------------------------------------------------------------
 \begin{document}
 \frontmatter
-\title      {Electronics and Computer Science\\Faculty of Engineering and Physical Sciences\\University of Southampton}
+\title      {Automatically Generated Cyber Security Compliance Engine}
 \authors	{
 {James D'Alton}
 }
 \addresses  {\groupname\\\deptname\\\univname}
-\date       {October 21st, 2019}
-\subject    {Automatically Generated Cyber Security Compliance Engine}
+\date       {19 May 2020}
+\subject    {}
 \keywords   {}
-\supervisor {Dr. Nawfal Fadhel}
-\examiner   {Dr Person B}
-\degree     {Bachelor of Science}
-\reporttype {individual project report}
+\supervisor {Dr Nawfal Fadhel}
+\examiner   {Dr Jie Zhang}
+\degree     {BSc Computer Science}
+\reporttype {project report} % Change here if you're doing a 3YP report
 \maketitle
 
-\begin{abstract}
 \include{0_Abstract}
-\end{abstract}
 
 \tableofcontents
 \listoffigures
 \listoftables
-\lstlistoflistings
+%\lstlistoflistings
 
 %% ----------------------------------------------------------------
 % Optional extra pages
 %\listofsymbols{ll}{$w$ & The weight vector}
-\acknowledgements{Here are some acknowledgements}
+%\acknowledgements{Here are some acknowledgements} TODO
 %\dedicatory{To \dots}
 %% ----------------------------------------------------------------
 
@@ -43,18 +41,14 @@
 
 \mainmatter
 
-\include{00_Introduction}
-\include{1_Chapter1}
-\include{2_Chapter2}
-\include{3_Chapter3}
-\include{4_Chapter4}
-\include{5_Chapter5}
-\include{6_Chapter6}
-\include{7_Chapter7}
-\include{8_Chapter8}
-\include{9_Conclusions}
-\include{10_FutureWork}
-\include{11_Bibliography}
+\include{1_Introduction}
+\include{2_BackgroundAndLiteratureReview}
+\include{3_RequirementsAndAnalysis}
+\include{4_Design}
+\include{5_Implementation}
+\include{6_TestingAndSoftwareValidation}
+\include{7_Evaluation}
+\include{8_Conclusions}
 
 % \backmatter means that we've gone from 1,2,3,4,5 chapter numbering 
 % to unnumbered bibliography/appendices. 
@@ -62,7 +56,7 @@
 
 \bibliographystyle{src/IEEEtran}
 \bibliography{master}
-\appendix
-\include{12_Appendices}
+% \appendix
+% \include{99_Appendix}
 
 \end{document}
diff --git a/report/report.bat b/report/report.bat
new file mode 100644
index 0000000000000000000000000000000000000000..6b93d1ed72fe3e0f33b636b5b26c2948f7f2497b
--- /dev/null
+++ b/report/report.bat
@@ -0,0 +1,10 @@
+@ECHO OFF
+taskkill /IM MicrosoftEdge.exe /F
+pdflatex master.tex
+bibtex master
+pdflatex master.tex
+pdflatex master.tex
+
+latexmk -c
+
+start master.pdf
diff --git a/report/report.sh b/report/report.sh
new file mode 100644
index 0000000000000000000000000000000000000000..31c3d32bbc112576272ae96d96b986c374fa7f53
--- /dev/null
+++ b/report/report.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+cmd.exe /c report.bat
diff --git a/report/src/ecsgdp.cls b/report/src/ecsgdp.cls
index 90e6f3675ee699fb9ba03af581bb2dc2ccc1f038..d39bff2cb6b522d577fd74c48ae5ec151cfff818 100644
--- a/report/src/ecsgdp.cls
+++ b/report/src/ecsgdp.cls
@@ -32,6 +32,7 @@
 \newcommand\bhrule{\typeout{------------------------------------------------------------------------------}}
 \newcommand\btypeout[1]{\bhrule\typeout{\space #1}\bhrule}
 \usepackage{setspace}
+\usepackage{titlesec}
 \onehalfspacing
 \setlength{\parindent}{0pt}
 \setlength{\parskip}{2.0ex plus0.5ex minus0.2ex}
@@ -55,8 +56,10 @@
 \lhead[\rm\thepage]{\fancyplain{}{\sl{\rightmark}}}
 \rhead[\fancyplain{}{\sl{\leftmark}}]{\rm\thepage}
 \chead{}\lfoot{}\rfoot{}\cfoot{}
+\titleformat{\chapter}[display]
+  {\normalfont\bfseries}{}{0pt}{\Large}
 \pagestyle{fancy}
-\renewcommand{\chaptermark}[1]{\btypeout{\thechapter\space #1}\markboth{\@chapapp\ \thechapter\ #1}{\@chapapp\ \thechapter\ #1}}
+\renewcommand{\chaptermark}[1]{\markboth{#1}{}}
 \renewcommand{\sectionmark}[1]{}
 \renewcommand{\subsectionmark}[1]{}
 \def\cleardoublepage{\clearpage\if@twoside \ifodd\c@page\else
@@ -98,8 +101,14 @@
 \usepackage{epstopdf}
 \usepackage[scriptsize]{subfigure}
 \usepackage{booktabs}
-\usepackage{rotating}
 \usepackage{listings}
+\usepackage{float}
+\usepackage{makecell}
+\usepackage[dvipsnames, table]{xcolor}
+\usepackage{tikz}
+\usepackage{tikz-uml}
+\usepackage[figuresright]{rotating}
+\usepackage{soul}
 \lstset{captionpos=b,
         frame=tb,
         basicstyle=\scriptsize\ttfamily,
@@ -183,7 +192,7 @@
       {\large\textbf{\UNIVNAME}\par}
       {\large \facname \par}
       \vfill
-      {\large An \reporttype{} submitted for}
+      {\large A \reporttype{} submitted for}
       {\large the award of \par \degreename \par}
       \vfill
       {\normalsize Supervisor: \supname \par}
diff --git a/report/tikz-uml.sty b/report/tikz-uml.sty
new file mode 100644
index 0000000000000000000000000000000000000000..eacab58d6dd4ad1bf636858aa6da3ece1bd021ce
--- /dev/null
+++ b/report/tikz-uml.sty
@@ -0,0 +1,5376 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% 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 march 2016 to compile with pgf 3.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,%
+                       x/.initial=0, y/.initial=0,%
+                       package type/.initial=tikzumlEmpty, fill package/.initial=blue!20,%
+                       class width/.initial=10ex, simple interface width/.initial=4ex, class type/.initial=class, fill class/.initial=yellow!20, fill template/.initial=yellow!2,%
+                       narynode width/.initial=6ex,%
+                       relation geometry/.initial=--, relation angle1/.initial=-30, relation angle2/.initial=30, relation loopsize/.initial=3em, relation weight/.initial=0.5, relation pos1/.initial=0.2, relation pos2/.initial=0.8, relation pos stereo/.initial=0.5,%
+                       note width/.initial=3cm, fill note/.initial=green!20,%
+                       fill system/.initial=white,%
+                       fill usecase/.initial=blue!20,%
+                       actor below/.initial=0.5cm,%
+                       state join width/.initial=3ex,%
+                       state decision width/.initial=3ex,%
+                       state initial width/.initial=5ex,%
+                       state final width/.initial=5.5ex,%
+                       state enter width/.initial=5ex,%
+                       state exit width/.initial=5ex,%
+                       state end width/.initial=5ex,%
+                       state history width/.initial=5ex,%
+                       state deep history width/.initial=5ex,%
+                       state width/.initial=8ex, fill state/.initial=yellow!20,%
+                       object stereo/.initial=object, fill object/.initial=yellow!20,%
+                       call dt/.initial=tikzumlEmpty, call padding/.initial=2, call type/.initial=synchron, fill call/.initial=white,%
+                       fragment type/.initial=opt, fragment inner xsep/.initial=1, fragment inner ysep/.initial=1, fill fragment/.initial= none,%
+                       create call dt/.initial=4,%
+                       component width/.initial=8ex, fill component/.initial= yellow!20,%
+                       required interface distance/.initial=2.5cm, required interface width/.initial=1em, required interface padding/.initial=1cm,%
+                       provided interface distance/.initial=3cm, provided interface width/.initial=1em, provided interface padding/.initial=1cm,%
+                       port width/.initial=1ex, fill port/.initial= yellow!20,%
+                       fill assembly connector/.initial= white,%
+                       .unknown/.code={%
+                         \let\keyname=\pgfkeyscurrentname%
+                         \let\keyvalue=\pgfkeyscurrentvalue%
+                         \errmessage{TIKZUML ERROR : in tikzuml global, invalid option \keyname}%
+                       }%
+}%
+%
+\pgfkeys{/tikzuml/.cd, text/.get=\tikzumlDefaultTextColor, draw/.get=\tikzumlDefaultDrawColor, font/.get=\tikzumlDefaultFont,%
+                       x/.get=\tikzumlDefaultX, y/.get=\tikzumlDefaultY,%
+                       package type/.get=\tikzumlPackageDefaultType, fill package/.get=\tikzumlPackageDefaultFillColor,%
+                       class width/.get=\tikzumlClassDefaultWidth, simple interface width/.get=\tikzumlSimpleInterfaceDefaultWidth, class type/.get=\tikzumlClassDefaultType, fill class/.get=\tikzumlClassDefaultFillColor, fill template/.get=\tikzumlClassTemplateFillColorDefaultFillColor,%
+                       narynode width/.get=\tikzumlNaryNodeDefaultWidth,%
+                       relation geometry/.get=\tikzumlRelationDefaultGeometry, relation angle1/.get=\tikzumlRelationDefaultAngleO, relation angle2/.get=\tikzumlRelationDefaultAngleT, relation loopsize/.get=\tikzumlRelationDefaultLoopSize, relation weight/.get=\tikzumlRelationDefaultWeight, relation pos1/.get=\tikzumlRelationDefaultPosO, relation pos2/.get=\tikzumlRelationDefaultPosT, relation pos stereo/.get=\tikzumlRelationDefaultPosStereo,%
+                       note width/.get=\tikzumlNoteDefaultWidth, fill note/.get=\tikzumlNoteDefaultFillColor,%
+                       fill system/.get=\tikzumlSystemDefaultFillColor,%
+                       fill usecase/.get=\tikzumlUseCaseDefaultFillColor,%
+                       actor below/.get=\tikzumlActorDefaultBelow,%
+                       state join width/.get=\tikzumlStateJoinDefaultWidth,%
+                       state decision width/.get=\tikzumlStateDecisionDefaultWidth,%
+                       state initial width/.get=\tikzumlStateInitialDefaultWidth,%
+                       state final width/.get=\tikzumlStateFinalDefaultWidth,%
+                       state enter width/.get=\tikzumlStateEnterDefaultWidth,%
+                       state exit width/.get=\tikzumlStateExitDefaultWidth,%
+                       state end width/.get=\tikzumlStateEndDefaultWidth,%
+                       state history width/.get=\tikzumlStateHistoryDefaultWidth,%
+                       state deep history width/.get=\tikzumlStateDeepHistoryDefaultWidth,%
+                       state width/.get=\tikzumlStateDefaultWidth, fill state/.get=\tikzumlStateDefaultFillColor,%
+                       object stereo/.get=\tikzumlObjectDefaultStereo, fill object/.get=\tikzumlObjectDefaultFillColor,%
+                       call dt/.get=\tikzumlCallDefaultDT, call padding/.get=\tikzumlCallDefaultPadding, call type/.get=\tikzumlCallDefaultType, fill call/.get=\tikzumlCallDefaultFillColor,%
+                       fragment type/.get=\tikzumlFragmentDefaultType, fragment inner xsep/.get=\tikzumlFragmentDefaultXSep, fragment inner ysep/.get=\tikzumlFragmentDefaultYSep, fill fragment/.get=\tikzumlFragmentDefaultFillColor,%
+                       create call dt/.get=\tikzumlCreateCallDefaultDT,%
+                       component width/.get=\tikzumlComponentDefaultWidth, fill component/.get=\tikzumlComponentDefaultFillColor,%
+                       required interface distance/.get=\tikzumlRequiredInterfaceDefaultDistance, required interface width/.get=\tikzumlRequiredInterfaceDefaultWidth, required interface padding/.get=\tikzumlRequiredInterfaceDefaultPadding,%
+                       provided interface distance/.get=\tikzumlProvidedInterfaceDefaultDistance, provided interface width/.get=\tikzumlProvidedInterfaceDefaultWidth, provided interface padding/.get=\tikzumlProvidedInterfaceDefaultPadding,%
+                       port width/.get=\tikzumlPortDefaultWidth, fill port/.get=\tikzumlPortDefaultFillColor,%
+                       fill assembly connector/.get=\tikzumlAssemblyConnectorDefaultFillColor%
+}%
+%
+% utility : change default colors
+\newcommand{\tikzumlset}[1]{%
+  \pgfkeys{/tikzuml/.cd,#1}%
+  \pgfkeys{/tikzuml/.cd, text/.get=\tikzumlDefaultTextColor, draw/.get=\tikzumlDefaultDrawColor, font/.get=\tikzumlDefaultFont,%
+                         x/.get=\tikzumlDefaultX, y/.get=\tikzumlDefaultY,%
+                         package type/.get=\tikzumlPackageDefaultType, fill package/.get=\tikzumlPackageDefaultFillColor,%
+                         class width/.get=\tikzumlClassDefaultWidth, simple interface width/.get=\tikzumlSimpleInterfaceDefaultWidth, class type/.get=\tikzumlClassDefaultType, fill class/.get=\tikzumlClassDefaultFillColor, fill template/.get=\tikzumlClassTemplateFillColorDefaultFillColor,%
+                         narynode width/.get=\tikzumlNaryNodeWidth,%
+                         relation geometry/.get=\tikzumlRelationDefaultGeometry, relation angle1/.get=\tikzumlRelationDefaultAngleO, relation angle2/.get=\tikzumlRelationDefaultAngleT, relation loopsize/.get=\tikzumlRelationDefaultLoopSize, relation weight/.get=\tikzumlRelationDefaultWeight, relation pos1/.get=\tikzumlRelationDefaultPosO, relation pos2/.get=\tikzumlRelationDefaultPosT, relation pos stereo/.get=\tikzumlRelationDefaultPosStereo,%
+                         note width/.get=\tikzumlNoteDefaultWidth, fill note/.get=\tikzumlNoteDefaultFillColor,%
+                         fill system/.get=\tikzumlSystemDefaultFillColor,%
+                         fill usecase/.get=\tikzumlUseCaseDefaultFillColor,%
+                         actor below/.get=\tikzumlActorDefaultBelow,%
+                         state join width/.get=\tikzumlStateJoinDefaultWidth,%
+                         state decision width/.get=\tikzumlStateDecisionDefaultWidth,%
+                         state initial width/.get=\tikzumlStateInitialDefaultWidth,%
+                         state final width/.get=\tikzumlStateFinalDefaultWidth,%
+                         state enter width/.get=\tikzumlStateEnterDefaultWidth,%
+                         state exit width/.get=\tikzumlStateExitDefaultWidth,%
+                         state end width/.get=\tikzumlStateEndDefaultWidth,%
+                         state history width/.get=\tikzumlStateHistoryDefaultWidth,%
+                         state deep history width/.get=\tikzumlStateDeepHistoryDefaultWidth,%
+                         state width/.get=\tikzumlStateDefaultWidth, fill state/.get=\tikzumlStateDefaultFillColor,%
+                         object stereo/.get=\tikzumlObjectDefaultStereo, fill object/.get=\tikzumlObjectDefaultFillColor,%
+                         call dt/.get=\tikzumlCallDefaultDT, call padding/.get=\tikzumlCallDefaultPadding, call type/.get=\tikzumlCallDefaultType, fill call/.get=\tikzumlCallDefaultFillColor,%
+                         fragment type/.get=\tikzumlFragmentDefaultType, fragment inner xsep/.get=\tikzumlFragmentDefaultXSep, fragment inner ysep/.get=\tikzumlFragmentDefaultYSep, fill fragment/.get=\tikzumlFragmentDefaultFillColor,%
+                         create call dt/.get=\tikzumlCreateCallDT,%
+                         component width/.get=\tikzumlComponentDefaultWidth, fill component/.get=\tikzumlComponentDefaultFillColor,%
+                         required interface distance/.get=\tikzumlRequiredInterfaceDefaultDistance, required interface width/.get=\tikzumlRequiredInterfaceDefaultWidth, required interface padding/.get=\tikzumlRequiredInterfaceDefaultPadding,%
+                         provided interface distance/.get=\tikzumlProvidedInterfaceDefaultDistance, provided interface width/.get=\tikzumlProvidedInterfaceDefaultWidth, provided interface padding/.get=\tikzumlProvidedInterfaceDefaultPadding,%
+                         port width/.get=\tikzumlPortDefaultWidth, fill port/.get=\tikzumlPortDefaultFillColor,%
+                         fill assembly connector/.get=\tikzumlAssemblyConnectorDefaultFillColor%
+  }%
+}%
+%
+% 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%
+}%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                       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 simpleinterface style}=[circle, minimum height=1em, node distance=1em]%
+\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=\tikzumlDefaultDrawColor, -]%
+\tikzstyle{tikzuml bidirectional association style}=[color=\tikzumlDefaultDrawColor, angle45-angle45]%
+\tikzstyle{tikzuml unidirectional association style}=[color=\tikzumlDefaultDrawColor, -angle 45]%
+\tikzstyle{tikzuml aggregation style}=[color=\tikzumlDefaultDrawColor, open diamond-]%
+\tikzstyle{tikzuml unidirectional aggregation style}=[color=\tikzumlDefaultDrawColor, open diamond-angle 45]%
+\tikzstyle{tikzuml composition style}=[color=\tikzumlDefaultDrawColor, diamond-]%
+\tikzstyle{tikzuml unidirectional composition style}=[color=\tikzumlDefaultDrawColor, diamond-angle 45]%
+\tikzstyle{tikzuml nesting style}=[color=\tikzumlDefaultDrawColor]%
+\tikzstyle{tikzuml dependency style}=[color=\tikzumlDefaultDrawColor, -angle 45, dashed]%
+\tikzstyle{tikzuml import style}=[color=\tikzumlDefaultDrawColor, -angle 45, dashed]%
+\tikzstyle{tikzuml inherit style}=[color=\tikzumlDefaultDrawColor, -open triangle 45]%
+\tikzstyle{tikzuml implements style}=[color=\tikzumlDefaultDrawColor, -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\iftikzumlpackageSimpleStyle%
+\newif\iftikzumlclassSimpleStyle%
+\newif\iftikzumlclassCircleShape%
+\newif\iftikzumlpackageWithoutCoords%
+\newif\iftikzumlclassWithoutCoords%
+\newif\iftikzumlassocclassWithoutCoords%
+\newif\iftikzumlnoteWithoutCoords%
+%
+% define a uml package
+% arg : package name
+% optional : x, y: coordinates of the package
+%            type: stereotype of the package
+%            name: name of the package node
+%            draw, fill, text: colors
+%            style: to manage every default TikZ option
+%            no coords: to tell that the package position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newenvironment{umlpackage}[2][]{%
+  \pgfkeys{/tikzuml/package/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, style/.style={},%
+                                 name/.initial=tikzumlEmpty, type/.initial=\tikzumlPackageDefaultType, draw/.initial=\tikzumlDefaultDrawColor,% 
+                                 fill/.initial=\tikzumlPackageDefaultFillColor, text/.initial=\tikzumlDefaultTextColor,%
+                                 no coords/.is if=tikzumlpackageWithoutCoords,%
+                                 no coords=false,%
+                                 .unknown/.code={%
+                                   \let\keyname=\pgfkeyscurrentname%
+                                   \let\keyvalue=\pgfkeyscurrentvalue%
+                                   \ifthenelse{\equal{\keyname}{above}\OR%
+                                               \equal{\keyname}{left}\OR%
+                                               \equal{\keyname}{below}\OR%
+                                               \equal{\keyname}{right}\OR%
+                                               \equal{\keyname}{above left}\OR%
+                                               \equal{\keyname}{above right}\OR%
+                                               \equal{\keyname}{below left}\OR%
+                                               \equal{\keyname}{below right}}{%
+                                     \IfSubStr{\keyvalue}{ of }{%
+                                       \pgfkeys{/tikzuml/package/.cd, no coords}%
+                                     }{}%
+                                   }{}%
+                                   \ifx\keyvalue\pgfkeysnovalue%
+                                     \pgfkeys{/tikzuml/package/.cd, style/.append style/.expand once={\keyname}}%
+                                   \else%
+                                     \pgfkeys{/tikzuml/package/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                   \fi%
+                                   %\errmessage{TIKZUML ERROR : in umlpackage, invalid option \keyname}%
+                                 }%
+  }%
+  \pgfkeys{/tikzuml/package/.cd, #1}%
+  \pgfkeys{/tikzuml/package/.cd, x/.get=\tikzumlPackageXShift, y/.get=\tikzumlPackageYShift, name/.get=\tikzumlPackageName, type/.get=\tikzumlPackageTypeTmp,%
+                                 draw/.get=\tikzumlPackageDrawColor, fill/.get=\tikzumlPackageFillColor,%
+                                 text/.get=\tikzumlPackageTextColor%
+  }%
+  %
+
+  %
+  \ifthenelse{\equal{\tikzumlPackageTypeTmp}{tikzumlEmpty}}{%
+    \def\tikzumlPackageType{}%
+  }{%
+    \expandafter\def\expandafter\tikzumlPackageType\expandafter{$\ll$\tikzumlPackageTypeTmp$\gg$ \\}%
+  }%
+  %
+  \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=\tikzumlPackageXShift cm, yshift=\tikzumlPackageYShift cm]%
+}{%
+  \addtocounter{tikzumlPackageLevel}{-1}%
+  \begin{pgfonlayer}{package\thetikzumlPackageLevel}%
+  %
+  % if contains no class, and not simple, one define a fictive node to enable the fit option
+  \ifnum\c@tikzumlPackageClassNum=0%
+    \ifnum\c@tikzumlPackageSubPackageNum=0%
+      \iftikzumlpackageWithoutCoords%
+        \node[inner sep=1.5ex, /tikzuml/package/style] (\tikzumlPackage@nodeName-root) {\phantom{\tikzumlPackage@nodeName}};%
+      \else%
+        \node[inner sep=1.5ex, /tikzuml/package/style] (\tikzumlPackage@nodeName-root) at (0,0) {\phantom{\tikzumlPackage@nodeName}};%
+      \fi%
+      \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=\tikzumlPackageDrawColor, fill=\tikzumlPackageFillColor, text=\tikzumlPackageTextColor, font=\tikzumlDefaultFont, inner sep=1.5ex, /tikzuml/package/style, fit = \csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname] (\tikzumlPackage@nodeName) {};%
+  \node[draw=\tikzumlPackageDrawColor, fill=\tikzumlPackageFillColor, text=\tikzumlPackageTextColor, font=\tikzumlDefaultFont, minimum height=1.5em, outer ysep=-0.3, anchor=south west] (\tikzumlPackage@nodeName-caption) at (\tikzumlPackage@nodeName.north west) {\begin{tabular}{c} \tikzumlPackageType \textbf{\tikzumlPackage@name}\end{tabular}};%
+  \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: type of class (class, interface, typedef, enum)
+%            tags: tagged values of class
+%            template: template parameters
+%            simple: if used, class is empty and drawn with a rectangle
+%            circle: if used with simple, class is empty and drawn with a circle
+%            draw, fill, fill template, and text: colors
+%            style: to manage every default TikZ option
+%            no coords: to tell that the class position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlclass}[4][]{%
+  \pgfkeys{/tikzuml/class/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlClassDefaultWidth, type/.initial=\tikzumlClassDefaultType,%
+                               tags/.initial={}, style/.style={},%
+                               template/.initial={}, name/.initial=tikzumlEmpty,%
+                               draw/.initial=\tikzumlDefaultDrawColor,%
+                               fill template/.initial=\tikzumlClassTemplateFillColorDefaultFillColor,%
+                               fill/.initial=\tikzumlClassDefaultFillColor,%
+                               text/.initial=\tikzumlDefaultTextColor,%
+                               simple/.is if=tikzumlclassSimpleStyle, circle/.is if=tikzumlclassCircleShape, no coords/.is if=tikzumlclassWithoutCoords,%
+                               simple=false, circle=false, no coords=false,%
+                               .unknown/.code={%
+                                 \let\keyname=\pgfkeyscurrentname%
+                                 \let\keyvalue=\pgfkeyscurrentvalue%
+                                 \ifthenelse{\equal{\keyname}{above}\OR%
+                                             \equal{\keyname}{left}\OR%
+                                             \equal{\keyname}{below}\OR%
+                                             \equal{\keyname}{right}\OR%
+                                             \equal{\keyname}{above left}\OR%
+                                             \equal{\keyname}{above right}\OR%
+                                             \equal{\keyname}{below left}\OR%
+                                             \equal{\keyname}{below right}}{%
+                                   \IfSubStr{\keyvalue}{ of }{%
+                                     \pgfkeys{/tikzuml/class/.cd, no coords}%
+                                   }{}%
+                                 }{}%
+                                 \ifx\keyvalue\pgfkeysnovalue%
+                                   \pgfkeys{/tikzuml/class/.cd, style/.append style/.expand once={\keyname}}%
+                                 \else%
+                                   \pgfkeys{/tikzuml/class/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                 \fi%
+                                 %\errmessage{TIKZUML ERROR : in umlclass, invalid option \keyname}%
+                               }%
+  }%
+  \pgfkeys{/tikzuml/class/.cd,#1}%
+  %
+  \iftikzumlclassSimpleStyle%
+    \iftikzumlclassCircleShape%
+      \pgfkeys{/tikzuml/class/.cd, width/.initial=\tikzumlSimpleInterfaceDefaultWidth}%
+    \fi%
+  \fi%
+  %
+  \pgfkeys{/tikzuml/class/.cd, x/.get=\tikzumlClassX, y/.get=\tikzumlClassY, width/.get=\tikzumlClassMinimumWidth,% 
+                               type/.get=\tikzumlClassTypeTmp, tags/.get=\tikzumlClassTagsTmp, template/.get=\tikzumlClassTemplateFillColorParam,%
+                               name/.get=\tikzumlClassName,%
+                               draw/.get=\tikzumlClassDrawColor, fill/.get=\tikzumlClassFillColor,%
+                               text/.get=\tikzumlClassTextColor, fill template/.get=\tikzumlClassTemplateFillColor%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlClassTypeTmp}{class}\OR\equal{\tikzumlClassTypeTmp}{abstract}}{%
+    \def\tikzumlClassType{}%
+  }{%
+    \expandafter\def\expandafter\tikzumlClassType\expandafter{$\ll$\tikzumlClassTypeTmp$\gg$ \\}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlClassTagsTmp}{}}{%
+    \def\tikzumlClassTags{}%
+  }{%
+    \def\tikzumlClassTags{\\ \{\tikzumlClassTagsTmp\}}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{%
+    \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{\tikzumlClassName}{tikzumlEmpty}}{}{%
+    \def\tikzumlClassNodeName{\tikzumlClassName}%
+  }%
+  %
+  \StrSubstitute{\tikzumlClassNodeName}{:}{@COLON@}[\tikzumlClassNodeName]%
+  \StrSubstitute{\tikzumlClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlClassNodeName]%
+  %
+  \ifthenelse{\equal{\tikzumlClassTypeTmp}{abstract}}{%
+    \let\tikzumlClassNameOld\tikzumlClassName%
+    \def\tikzumlClassName{{\it \tikzumlClassNameOld}}%
+  }{}%
+  %
+  \def\tikzumlClassPos{\tikzumlClassX,\tikzumlClassY}%
+  \def\tikzumlClassAttributes{#3}%
+  \def\tikzumlClassOperations{#4}%
+  %
+  \iftikzumlclassSimpleStyle%
+    \iftikzumlclassWithoutCoords%
+      \iftikzumlclassCircleShape%
+        \node[tikzuml simpleinterface style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) {};%
+        \node[anchor=south] (\tikzumlClassNodeName-label) at (\tikzumlClassNodeName.north) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
+        };%
+      \else%
+        \node[tikzuml simpleclass style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
+        };%
+      \fi%
+    \else%
+      \iftikzumlclassCircleShape%
+        \node[tikzuml simpleinterface style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) at (\tikzumlClassPos) {};
+        \node[anchor=south] (\tikzumlClassNodeName-label) at (\tikzumlClassNodeName.north){\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
+        };%
+      \else%
+        \node[tikzuml simpleclass style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) at (\tikzumlClassPos) {\begin{tabular}{c}\tikzumlClassVPadding \tikzumlClassType \tikzumlClassHPadding \textbf{\tikzumlClassName} \tikzumlClassHPadding \tikzumlClassTags \end{tabular}%
+        };%
+      \fi%
+    \fi%
+  \else%
+    \iftikzumlclassWithoutCoords%
+      \node[tikzuml class style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\tikzumlClassNodeName) {\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}%
+      };%
+    \else%
+      \node[tikzuml class style, draw=\tikzumlClassDrawColor, fill=\tikzumlClassFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlClassMinimumWidth, /tikzuml/class/style] (\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%
+  \fi%
+  %
+  \ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{}{%
+    \draw (\tikzumlClassNodeName.north east) node[tikzuml template style, name=\tikzumlClassNodeName-template, draw=\tikzumlClassDrawColor, fill=\tikzumlClassTemplateFillColor, text=\tikzumlClassTextColor, font=\tikzumlDefaultFont] {\tikzumlClassTemplateFillColorParam};%
+  }%
+  %
+  % add to fit
+  \ifnum\c@tikzumlPackageLevel>0%
+    \edef\tikzumlPackageFitOld{\csname tikzumlPackageFit\tikzumlPackage@parent @@\tikzumlPackage@fitname\endcsname}%
+    \ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{%
+      \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%
+    \def\tikzumlComponentFitTmp{\csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname}%
+    \ifthenelse{\equal{\tikzumlClassTemplateFillColorParam}{}}{%
+      \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][]{%
+  \pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
+                                          \let\keyname=\pgfkeyscurrentname%
+                                          \let\keyvalue=\pgfkeyscurrentvalue%
+                                          \ifthenelse{\equal{\keyname}{type}}{%
+                                            \errmessage{TIKZUML ERROR : in umlabstract, forbidden option type}%
+                                          }{}%
+                                        }%
+  }%
+  \pgfkeys{/tikzuml/class/.cd, #1}%
+  \umlclass[type=abstract,#1]{#2}{#3}{#4}%
+}%
+\newcommand{\umlinterface}[4][]{%
+  \pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
+                                          \let\keyname=\pgfkeyscurrentname%
+                                          \let\keyvalue=\pgfkeyscurrentvalue%
+                                          \ifthenelse{\equal{\keyname}{type}}{%
+                                            \errmessage{TIKZUML ERROR : in umlinterface, forbidden option type}%
+                                          }{}%
+                                        }%
+  }%
+  \pgfkeys{/tikzuml/class/.cd, #1}%
+  \umlclass[type=interface,#1]{#2}{#3}{#4}%
+}%
+\newcommand{\umltypedef}[4][]{%
+  \pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
+                                          \let\keyname=\pgfkeyscurrentname%
+                                          \let\keyvalue=\pgfkeyscurrentvalue%
+                                          \ifthenelse{\equal{\keyname}{type}}{%
+                                            \errmessage{TIKZUML ERROR : in umltypedef, forbidden option type}%
+                                          }{}%
+                                        }%
+  }%
+  \pgfkeys{/tikzuml/class/.cd, #1}%
+  \umlclass[type=typedef,#1]{#2}{#3}{#4}%
+}%
+\newcommand{\umlenum}[4][]{%
+  \pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
+                                          \let\keyname=\pgfkeyscurrentname%
+                                          \let\keyvalue=\pgfkeyscurrentvalue%
+                                          \ifthenelse{\equal{\keyname}{type}}{%
+                                            \errmessage{TIKZUML ERROR : in umlenum, forbidden option type}%
+                                          }{}%
+                                        }%
+  }%
+  \pgfkeys{/tikzuml/class/.cd, #1}%
+  \umlclass[type=enum,#1]{#2}{#3}{#4}
+}%
+%
+% shortcut to define an empty class
+\newcommand{\umlemptyclass}[2][]{\umlclass[#1]{#2}{}{}}%
+\newcommand{\umlsimpleclass}[2][]{%
+  \pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
+                                          \let\keyname=\pgfkeyscurrentname%
+                                          \let\keyvalue=\pgfkeyscurrentvalue%
+                                          \ifthenelse{\equal{\keyname}{simple}}{%
+                                            \errmessage{TIKZUML ERROR : in umlsimpleclass, forbidden option simple}%
+                                          }{}%
+                                        }%
+  }%
+  \pgfkeys{/tikzuml/class/.cd, #1}%
+  \umlemptyclass[simple, #1]{#2}%
+}%
+%
+\newcommand{\umlsimpleinterface}[2][]{%
+  \pgfkeys{/tikzuml/class/.cd, .unknown/.code={%
+                                 \let\keyname=\pgfkeyscurrentname%
+                                 \let\keyvalue=\pgfkeyscurrentvalue%
+                                 \ifthenelse{\equal{\keyname}{simple}}{%
+                                   \errmessage{TIKZUML ERROR : in umlsimpleinterface, forbidden option simple}%
+                                 }{%
+                                   \ifthenelse{\equal{\keyname}{circle}}{%
+                                     \errmessage{TIKZUML ERROR : in umlsimpleinterface, forbidden option circle}%
+                                   }{}%
+                                 }%
+                               }%
+  }%
+  \pgfkeys{/tikzuml/class/.cd, #1}%
+  \umlsimpleclass[circle, #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=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlNaryNodeDefaultWidth, name/.initial=tikzumlEmpty,%
+                                  draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlClassDefaultFillColor,%
+                                  text/.initial=\tikzumlDefaultTextColor, style/.style={},%
+                                  .unknown/.code={%
+                                    \let\keyname=\pgfkeyscurrentname%
+                                    \let\keyvalue=\pgfkeyscurrentvalue%
+                                    \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}%
+                                                  }{%
+                                                    \ifx\keyvalue\pgfkeysnovalue%
+                                                      \pgfkeys{/tikzuml/narynode/.cd, style/.append style/.expand once={\keyname}}%
+                                                    \else%
+                                                      \pgfkeys{/tikzuml/narynode/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                                    \fi%
+                                                    %\errmessage{TIKZUML ERROR : in umlNarynode, invalid option \keyname}%
+                                                  }%
+                                                }%
+                                              }%
+                                            }%
+                                          }%
+                                        }%
+                                      }%
+                                    }%
+                                  }%
+  }%
+  \pgfkeys{/tikzuml/narynode/.cd,#1}%
+  \pgfkeys{/tikzuml/narynode/.cd, x/.get=\tikzumlNaryNodeX, y/.get=\tikzumlNaryNodeY, width/.get=\tikzumlNaryNodeMinimumWidth,%
+                                  name/.get=\tikzumlNaryNodeName,%
+                                  draw/.get=\tikzumlNaryNodeDrawColor, fill/.get=\tikzumlNaryNodeFillColor,%
+                                  text/.get=\tikzumlNaryNodeTextColor%
+  }%
+  %
+  \def\tikzumlNaryName{#2}%
+  %
+  \ifthenelse{\equal{\tikzumlNaryNodeName}{tikzumlEmpty}}{%
+    \edef\tikzumlNaryNodeName{\tikzumlNaryName}%
+  }{%
+    \edef\tikzumlNaryNodeName{\tikzumlNaryNodeName}%
+  }%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlNaryNode@nodeName{\tikzumlNaryNodeName}}\x%
+  %
+  \StrSubstitute{\tikzumlNaryNode@nodeName}{:}{@COLON@}[\tikzumlNaryNode@nodeName]%
+  \StrSubstitute{\tikzumlNaryNode@nodeName}{\_}{@UNDERSCORE@}[\tikzumlNaryNode@nodeName]%
+  %
+  \def\tikzumlNarynodePos{\tikzumlNaryNodeX,\tikzumlNaryNodeY}%
+  %
+  \node[tikzuml narynode style, draw=\tikzumlNaryNodeDrawColor, fill=\tikzumlNaryNodeFillColor, text=\tikzumlNaryNodeTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlNaryNodeMinimumWidth, minimum height=\tikzumlNaryNodeMinimumWidth, /tikzuml/narynode/style] (\tikzumlNaryNode@nodeName) at (\tikzumlNarynodePos) {};%
+  \draw (\tikzumlNaryNode@nodeName\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 (\tikzumlNaryNode@nodeName)}%
+    \stepcounter{tikzumlPackageClassNum}%
+  \fi%
+}%
+%
+\newdimen\tikzumlNestingSymbolSize%
+%
+% main command to define a relation between two classes
+% args : src class
+%        dest class
+% optional : geometry: geometry of the line
+%            weight: barycentric weight of the middle part when geometry is a 3-line
+%            arm1, arm2: lengths of first or last part when geometry id a 3-line
+%            arg1, arg2, arg: name of the src/dest/dest side class type attribute defined by the relation
+%            mult1, mult2, mult: multiplicity of the src/dest/dest side class type attribute defined by the relation
+%            pos1, pos2, pos: position of the src/dest/dest side class type attribute defined by the relation
+%            align1, align2, align: text justification of the src/dest/dest side class type attribute defined by the relation
+%            anchor1, anchor2: src/dest anchors on linked classes
+%            angle1, angle2, loopsize: start angle, end angle and size of the relation (only if recursive)
+%            stereo: stereotype of the relation
+%            pos stereo: position of the stereotype on the relation
+%            style: style of the relation (association, aggregation, composition, inherit, ...)
+%            name: rootname used for naming nodes of the relation
+%            recursive mode: type of recursive arrow (transition for state diagrams, or default)
+%            recursive direction start/end: when transition relation, start/end directions of the relation arrow
+\newcommand{\umlrelation}[3][]{%
+  \pgfkeys{/tikzuml/relation/.cd, geometry/.initial=\tikzumlRelationDefaultGeometry, weight/.initial=\tikzumlRelationDefaultWeight,%
+                                  arm1/.initial=auto, arm2/.initial=auto,%
+                                  arg1/.initial={}, arg2/.initial={}, arg/.initial={},%
+                                  mult1/.initial={}, mult2/.initial={}, mult/.initial={},%
+                                  pos1/.initial=\tikzumlRelationDefaultPosO, pos2/.initial=\tikzumlRelationDefaultPosT, pos/.initial=tikzumlEmpty,%
+                                  align1/.initial={}, align2/.initial={}, align/.initial={},%
+                                  anchor1/.initial=tikzumlEmpty, anchor2/.initial=tikzumlEmpty,%
+                                  angle1/.initial=\tikzumlRelationDefaultAngleO, angle2/.initial=\tikzumlRelationDefaultAngleT, loopsize/.initial=\tikzumlRelationDefaultLoopSize,%
+                                  stereo/.initial={}, pos stereo/.initial=\tikzumlRelationDefaultPosStereo,%
+                                  style/.initial=->, style2/.style={}, name/.initial=relation-\thetikzumlRelationNum,%
+                                  recursive mode/.initial=default, recursive direction start/.initial=right,%
+                                  recursive direction end/.initial=bottom,%
+                                  .unknown/.code={%
+                                    \let\keyname=\pgfkeyscurrentname%
+                                    \let\keyvalue=\pgfkeyscurrentvalue%
+                                    \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}}{}{%
+                                               \ifx\keyvalue\pgfkeysnovalue%
+                                                 \pgfkeys{/tikzuml/relation/.cd, style2/.append style/.expand once={\keyname}}%
+                                               \else%
+                                                 \pgfkeys{/tikzuml/relation/.cd, style2/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                               \fi%
+                                               %\errmessage{TIKZUML ERROR : in umlrelation, invalid option \keyname}%
+                                    }%
+                                  }%
+  }%
+  \pgfkeys{/tikzuml/relation/.cd,#1}%
+  \pgfkeys{/tikzuml/relation/.cd, geometry/.get=\tikzumlRelationGeometry, weight/.get=\tikzumlRelationWeight,%
+                                  arm1/.get=\tikzumlRelationArmO, arm2/.get=\tikzumlRelationArmT,%
+                                  arg1/.get=\tikzumlRelationAttrName, arg2/.get=\tikzumlRelationAttrNameTO, arg/.get=\tikzumlRelationAttrNameTT,%
+                                  mult1/.get=\tikzumlRelationMultiplicity, mult2/.get=\tikzumlRelationMultiplicityTO, mult/.get=\tikzumlRelationMultiplicityTT,%
+                                  pos1/.get=\tikzumlRelationPosition, pos2/.get=\tikzumlRelationPositionTO, pos/.get=\tikzumlRelationPositionTT,%
+                                  align1/.get=\tikzumlRelationAlign, align2/.get=\tikzumlRelationAlignTO, align/.get=\tikzumlRelationAlignTT,%
+                                  anchor1/.get=\tikzumlRelationSrcAnchor, anchor2/.get=\tikzumlRelationDestAnchor,%
+                                  angle1/.get=\tikzumlRelationStartAngle, angle2/.get=\tikzumlRelationEndAngle, loopsize/.get=\tikzumlRelationLoopSize,%
+                                  stereo/.get=\tikzumlRelationStereoType, pos stereo/.get=\tikzumlRelationPositionStereotype,%
+                                  style/.get=\tikzumlRelationStyle, name/.get=\tikzumlRelationName,%
+                                  recursive mode/.get=\tikzumlRelationRecursiveMode,%
+                                  recursive direction start/.get=\tikzumlRelationRecursiveDirectionStart,%
+                                  recursive direction end/.get=\tikzumlRelationRecursiveDirectionEnd%
+  }%
+  %
+  \def\tikzumlSrcClassName{#2}%
+  %
+  % managing \_ in class names for node names
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlSrcClassNodeName{\tikzumlSrcClassName}}\x%
+  %
+  \StrSubstitute{\tikzumlSrcClassNodeName}{:}{@COLON@}[\tikzumlSrcClassNodeName]%
+  \StrSubstitute{\tikzumlSrcClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlSrcClassNodeName]%
+  %
+  \def\tikzumlDestClassName{#3}%
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlDestClassNodeName{\tikzumlDestClassName}}\x%
+  %
+  \StrSubstitute{\tikzumlDestClassNodeName}{:}{@COLON@}[\tikzumlDestClassNodeName]%
+  \StrSubstitute{\tikzumlDestClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlDestClassNodeName]%
+  %
+  % managing alias keys
+  \def\tikzumlRelationAttrNameT{\tikzumlRelationAttrNameTO\tikzumlRelationAttrNameTT}%
+  \def\tikzumlRelationMultiplicityT{\tikzumlRelationMultiplicityTO\tikzumlRelationMultiplicityTT}%
+  \def\tikzumlRelationAlignT{\tikzumlRelationAlignTO\tikzumlRelationAlignTT}%
+  \def\posAttrName{}%
+  \def\posMultiplicity{}%
+  \def\posAttrNameT{}%
+  \def\posMultiplicityT{}%
+  %
+  \ifthenelse{\equal{\tikzumlRelationPositionTT}{tikzumlEmpty}}{%
+    \def\tikzumlRelationPositionT{\tikzumlRelationPositionTO}%
+  }{%
+    \def\tikzumlRelationPositionT{\tikzumlRelationPositionTT}%
+  }%
+  %
+  \def\attrAlign{}%
+  \def\multAlign{}%
+  \def\attrAlignT{}%
+  \def\multAlignT{}%
+  %
+  \ifthenelse{\equal{\tikzumlRelationAlign}{left}}{%
+    \def\attrAlign{above right}%
+    \def\multAlign{below right}%
+  }{%
+    \ifthenelse{\equal{\tikzumlRelationAlign}{right}}{%
+      \def\attrAlign{above left}%
+      \def\multAlign{below left}%
+    }{}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlRelationAlignT}{left}}{%
+    \def\attrAlignT{above right}%
+    \def\multAlignT{below right}%
+  }{%
+    \ifthenelse{\equal{\tikzumlRelationAlignT}{right}}{%
+      \def\attrAlignT{above left}%
+      \def\multAlignT{below left}%
+    }{}%
+  }%
+  %
+  % def stereotype
+  \ifthenelse{\equal{\tikzumlRelationStereoType}{}}{%
+    \def\stereotype{}%
+  }{%
+    \def\stereotype{$\ll$\tikzumlRelationStereoType$\gg$}%
+  }%
+  
+  % def anchors macros
+  \ifthenelse{\equal{\tikzumlRelationSrcAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlRelationSrcAnchor{}%
+  }{%
+    \let\tikzumlRelationSrcAnchorold\tikzumlRelationSrcAnchor%
+    \def\tikzumlRelationSrcAnchor{.\tikzumlRelationSrcAnchorold}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlRelationDestAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlRelationDestAnchor{}%
+  }{%
+    \let\tikzumlRelationDestAnchorold\tikzumlRelationDestAnchor%
+    \def\tikzumlRelationDestAnchor{.\tikzumlRelationDestAnchorold}%
+  }%
+  %
+  \setcounter{pos}{100*\real{\tikzumlRelationPosition}}%
+  \setcounter{posT}{100*\real{\tikzumlRelationPositionT}}%
+  \setcounter{posStereo}{100*\real{\tikzumlRelationPositionStereotype}}%
+  %
+  \pgfmathsetmacro{\tikzumlRelationWeightT}{1.0-\tikzumlRelationWeight}%
+  %
+  %\newcounter{tikzumlControlNodesNum}%
+  %\setcounter{tikzumlControlNodesNum}{0}%
+  %
+  \node[inner sep=0] (\tikzumlRelationName-middle) at (barycentric cs:\tikzumlSrcClassNodeName=\tikzumlRelationWeightT,\tikzumlDestClassNodeName=\tikzumlRelationWeight) {};%
+  %
+  % straight line
+  \ifthenelse{\equal{\tikzumlRelationGeometry}{--}}%
+  {%
+    \ifthenelse{\equal{\tikzumlSrcClassNodeName}{\tikzumlDestClassNodeName}}{%
+      \def\arcNum{1}%
+      \def\arcNumT{1}%
+      %
+      \ifthenelse{\equal{\tikzumlRelationRecursiveMode}{default}}{%
+        \xdef\tikzumlLastArc{node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                             node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
+                             node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                             node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
+                             node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+        \xdef\tikzumlPath{(\tikzumlSrcClassNodeName) edge[in=\tikzumlRelationEndAngle, out=\tikzumlRelationStartAngle, distance=\tikzumlRelationLoopSize] \tikzumlLastArc%
+                                                          node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center] {} (\tikzumlDestClassNodeName) }%
+      }{%
+        \ifthenelse{\equal{\tikzumlRelationRecursiveMode}{transition}}{%
+          \xdef\tikzumlFirstArc{node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center] {}}%
+          \xdef\tikzumlMidOneArc{node[midway, inner sep=0, name=\tikzumlRelationName-3, anchor=center] {}}%
+          %
+          \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{\tikzumlRelationRecursiveDirectionEnd}}{%
+            \def\numArcs{3}%
+            \xdef\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-5, anchor=center] {}}%
+            %
+            \begin{pgfonlayer}{connections}%
+            \draw (\tikzumlSrcClassNodeName) edge[in=\tikzumlRelationEndAngle, out=\tikzumlRelationStartAngle, distance=\tikzumlRelationLoopSize, draw=none] %
+                                                  node[midway, inner sep=0, name=\tikzumlRelationName-tmp, anchor=center] {} (\tikzumlDestClassNodeName);%
+            \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}\OR\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
+              \node[inner sep=0, name=\tikzumlRelationName-2] at (\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle -| \tikzumlRelationName-tmp) {};%
+              \node[inner sep=0, name=\tikzumlRelationName-4] at (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle -| \tikzumlRelationName-tmp) {};%
+            }{%
+              \node[inner sep=0, name=\tikzumlRelationName-2] at (\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle |- \tikzumlRelationName-tmp) {};%
+              \node[inner sep=0, name=\tikzumlRelationName-4] at (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle |- \tikzumlRelationName-tmp) {};%
+            }%
+            \end{pgfonlayer}%
+          }{%
+            \def\numArcs{4}%
+            \xdef\tikzumlMidTwoArc{node[midway, inner sep=0, name=\tikzumlRelationName-5, anchor=center] {}}%
+            \xdef\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-7, anchor=center] {}}%
+            %
+            \begin{pgfonlayer}{connections}%
+            \draw (\tikzumlSrcClassNodeName) edge[in=\tikzumlRelationEndAngle, out=\tikzumlRelationStartAngle, distance=\tikzumlRelationLoopSize, draw=none] %
+                                                  node[midway, name=\tikzumlRelationName-4, anchor=center] {} (\tikzumlDestClassNodeName);%
+            \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}\OR\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
+              \node[inner sep=0, name=\tikzumlRelationName-2] at (\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle -| \tikzumlRelationName-4) {};%
+              \node[inner sep=0, name=\tikzumlRelationName-6] at (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle |- \tikzumlRelationName-4) {};%
+            }{%
+              \node[inner sep=0, name=\tikzumlRelationName-2] at (\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle |- \tikzumlRelationName-4) {};%
+              \node[inner sep=0, name=\tikzumlRelationName-6] at (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle -| \tikzumlRelationName-4) {};%
+            }%
+            \end{pgfonlayer}%
+          }%
+          %
+          \ifnum\numArcs=4%
+            \ifnum\theposStereo>300%
+              \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-300)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype}}%
+            \else%
+              \ifnum\theposStereo<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype}}%
+              \else%
+                \ifnum\theposStereo>200%
+                  \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-200)/100}%
+                  \xdef\tikzumlMidTwoArc{\tikzumlMidTwoArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype}}%
+                \else%
+                  \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
+                  \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype}}%
+                \fi%
+              \fi%
+            \fi%
+            %
+            \ifthenelse{\thepos=300\OR\thepos=100}{%
+              \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
+                  \def\posAttrName{above right}%
+                  \def\posMultiplicity{below left}%
+                }{%
+                  \def\posAttrName{above left}%
+                  \def\posMultiplicity{below right}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
+                    \def\posAttrName{above left}%
+                    \def\posMultiplicity{below right}%
+                  }{%
+                    \def\posAttrName{above right}%
+                    \def\posMultiplicity{below left}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
+                    \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }%
+                  }{%
+                    \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifthenelse{\thepos=200}{%
+              \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
+                  \def\posAttrName{above left}%
+                  \def\posMultiplicity{below right}%
+                }{%
+                  \def\posAttrName{above right}%
+                  \def\posMultiplicity{below left}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
+                    \def\posAttrName{above right}%
+                    \def\posMultiplicity{below left}%
+                  }{%
+                    \def\posAttrName{above left}%
+                    \def\posMultiplicity{below right}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
+                    \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }%
+                  }{%
+                    \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifnum\thepos>300%
+              \pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-300)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                   node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
+                                   }%
+            \else%
+              \ifnum\thepos<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                     node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
+                                     }%
+              \else%
+                \ifnum\thepos>200%
+                  \pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-200)/100}%
+                  \xdef\tikzumlMidTwoArc{\tikzumlMidTwoArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                         node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
+                                        }%
+                \else%
+                  \pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-100)/100}%
+                  \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                         node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
+                                        }%
+                \fi%
+              \fi%
+            \fi%
+            %
+            \ifthenelse{\theposT=300\OR\theposT=100}{%
+              \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
+                  \def\posAttrNameT{above right}%
+                  \def\posMultiplicityT{below left}%
+                }{%
+                  \def\posAttrNameT{above left}%
+                  \def\posMultiplicityT{below right}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
+                    \def\posAttrNameT{above left}%
+                    \def\posMultiplicityT{below right}%
+                  }{%
+                    \def\posAttrNameT{above right}%
+                    \def\posMultiplicityT{below left}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
+                    \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }%
+                  }{%
+                    \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            \ifthenelse{\theposT=200}{%
+              \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
+                  \def\posAttrNameT{above left}%
+                  \def\posMultiplicity{below right}%
+                }{%
+                  \def\posAttrNameT{above right}%
+                  \def\posMultiplicityT{below left}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{bottom}}{%
+                    \def\posAttrNameT{above right}%
+                    \def\posMultiplicityT{below left}%
+                  }{%
+                    \def\posAttrNameT{above left}%
+                    \def\posMultiplicityT{below right}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
+                    \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }%
+                  }{%
+                    \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionEnd}{left}}{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifnum\theposT>300%
+              \pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-300)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                   node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
+                                   }%
+            \else%
+              \ifnum\theposT<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                     node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
+                                     }%
+              \else%
+                \ifnum\theposT>200%
+                  \pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-200)/100}%
+                  \xdef\tikzumlMidTwoArc{\tikzumlMidTwoArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                         node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
+                                        }%
+                \else%
+                  \pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-100)/100}%
+                  \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                         node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
+                                        }%
+                \fi%
+              \fi%
+            \fi%
+          \else%
+            \ifnum\theposStereo>200%
+              \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-200)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+            \else%
+              \ifnum\theposStereo<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+              \else%
+                \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
+                \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+              \fi%
+            \fi%
+            %
+            \ifthenelse{\thepos=100}{%
+              \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
+                \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                  \def\posAttrName{above right}%
+                  \def\posMultiplicity{below left}%
+                }{%
+                  \def\posAttrName{above left}%
+                  \def\posMultiplicity{below right}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
+                  \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                    \def\posAttrName{above left}%
+                    \def\posMultiplicity{below right}%
+                  }{%
+                    \def\posAttrName{above right}%
+                    \def\posMultiplicity{below left}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
+                    \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }%
+                  }{%
+                    \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifthenelse{\thepos=200}{%
+              \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
+                \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                  \def\posAttrName{above left}%
+                  \def\posMultiplicity{below right}%
+                }{%
+                  \def\posAttrName{above right}%
+                  \def\posMultiplicity{below left}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
+                  \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                    \def\posAttrName{above right}%
+                    \def\posMultiplicity{below left}%
+                  }{%
+                    \def\posAttrName{above left}%
+                    \def\posMultiplicity{below right}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
+                    \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }%
+                  }{%
+                    \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                      \def\posAttrName{above right}%
+                      \def\posMultiplicity{below left}%
+                    }{%
+                      \def\posAttrName{above left}%
+                      \def\posMultiplicity{below right}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifnum\thepos>200%
+              \pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-200)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                   node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
+                                   }%
+            \else%
+              \ifnum\thepos<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                     node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
+                                     }%
+              \else%
+                \pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-100)/100}%
+                \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                       node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
+                                      }%
+              \fi%
+            \fi%
+            %
+            \ifthenelse{\theposT=100}{%
+              \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
+                \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                  \def\posAttrNameT{above right}%
+                  \def\posMultiplicityT{below left}%
+                }{%
+                  \def\posAttrNameT{above left}%
+                  \def\posMultiplicityT{below right}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
+                  \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                    \def\posAttrNameT{above left}%
+                    \def\posMultiplicityT{below right}%
+                  }{%
+                    \def\posAttrNameT{above right}%
+                    \def\posMultiplicityT{below left}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
+                    \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }%
+                  }{%
+                    \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifthenelse{\theposT=200}{%
+              \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{right}}{%
+                \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                  \def\posAttrNameT{above left}%
+                  \def\posMultiplicityT{below right}%
+                }{%
+                  \def\posAttrNameT{above right}%
+                  \def\posMultiplicityT{below left}%
+                }%
+              }{%
+                \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{left}}{%
+                  \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                    \def\posAttrNameT{above right}%
+                    \def\posMultiplicityT{below left}%
+                  }{%
+                    \def\posAttrNameT{above left}%
+                    \def\posMultiplicityT{below right}%
+                  }%
+                }{%
+                  \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{top}}{%
+                    \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }%
+                  }{%
+                    \ifthenelse{\tikzumlRelationEndAngle<\tikzumlRelationStartAngle}{%
+                      \def\posAttrNameT{above right}%
+                      \def\posMultiplicityT{below left}%
+                    }{%
+                      \def\posAttrNameT{above left}%
+                      \def\posMultiplicityT{below right}%
+                    }%
+                  }%
+                }%
+              }%
+            }{}%
+            %
+            \ifnum\theposT>200%
+              \pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-200)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                   node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
+                                   }%
+            \else%
+              \ifnum\theposT<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                     node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
+                                     }%
+              \else%
+                \pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-100)/100}%
+                \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                       node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
+                                      }%
+              \fi%
+            \fi%
+          \fi%
+          %
+          \ifthenelse{\equal{\tikzumlRelationRecursiveDirectionStart}{\tikzumlRelationRecursiveDirectionEnd}}{%
+            \xdef\tikzumlPath{(\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle) -- \tikzumlFirstArc (\tikzumlRelationName-2.center) -- \tikzumlMidOneArc (\tikzumlRelationName-4.center) -- \tikzumlLastArc (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle) }%
+            \ifnum\thetikzumlStateLevel>0%
+              \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+              \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) (\tikzumlRelationName-4) (\tikzumlRelationName-5)}%
+            \fi%
+          }{%
+            \xdef\tikzumlPath{(\tikzumlSrcClassNodeName.\tikzumlRelationStartAngle) -- \tikzumlFirstArc (\tikzumlRelationName-2.center) -- \tikzumlMidOneArc (\tikzumlRelationName-4.center) -- \tikzumlMidTwoArc (\tikzumlRelationName-6.center) -- \tikzumlLastArc (\tikzumlDestClassNodeName.\tikzumlRelationEndAngle) }%
+            \ifnum\thetikzumlStateLevel>0%
+              \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+              \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) (\tikzumlRelationName-4) (\tikzumlRelationName-5) (\tikzumlRelationName-6) (\tikzumlRelationName-7)}%
+            \fi%
+          }%
+        }{}%
+      }%
+    }{%
+      \def\arcNum{1}%
+      \def\arcNumT{1}%
+      %
+      \node[inner sep=0] (\tikzumlRelationName-1) at (\tikzumlRelationName-middle) {};%
+      \xdef\tikzumlLastArc{node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                           node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity}%
+                           node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                           node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT}%
+                           node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+      \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor) }%
+      \ifnum\thetikzumlStateLevel>0%
+        \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+        \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) }%
+      \fi%
+    }%
+  }{%
+    % first vertical then horizontal line
+    \ifthenelse{\equal{\tikzumlRelationGeometry}{|-}}%
+    {%
+      %\setcounter{tikzumlControlNodesNum}{1}%
+      %
+      \def\tikzumlFirstArc{node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center] {} }%
+      \def\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-3, anchor=center]{} }%
+      %
+      \begin{pgfonlayer}{connections}%
+      \node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor |- \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
+      \end{pgfonlayer}%
+      %
+      \ifnum\theposStereo>100%
+        \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
+        \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+      \else%
+        \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+      \fi%
+      %
+      \ifnum\thepos>100%
+        \pgfmathsetmacro{\tikzumlRelationPosition}{(\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=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                               node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
+      \fi%
+      \ifnum\arcNum=2%
+        \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                             node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
+      \fi%
+      %
+      \ifnum\theposT>100%
+        \pgfmathsetmacro{\tikzumlRelationPositionT}{(\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=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                               node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
+      \fi%
+      \ifnum\arcNumT=2%
+        \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                             node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
+      \fi%
+      %
+      \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) -- \tikzumlFirstArc (\tikzumlRelationName-2.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor) }%
+      \ifnum\thetikzumlStateLevel>0%
+        \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+        \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) }%
+      \fi%
+    }{%
+      % first horizontal then vertical line
+      \ifthenelse{\equal{\tikzumlRelationGeometry}{-|}}%
+      {%
+        %\setcounter{tikzumlControlNodesNum}{1}%
+        %
+        \def\tikzumlFirstArc{node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center]{} }%
+        \def\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-3, anchor=center] {} }%
+        %
+        \begin{pgfonlayer}{connections}%
+        \node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor -| \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
+        \end{pgfonlayer}%
+        %
+        \ifnum\theposStereo>100%
+          \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
+          \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+        \else%
+          \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+        \fi%
+        %
+        \ifnum\thepos>100%
+          \pgfmathsetmacro{\tikzumlRelationPosition}{(\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=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                                 node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
+        \fi%
+        \ifnum\arcNum=2%
+          \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                               node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
+        \fi%
+        %
+        \ifnum\theposT>100%
+          \pgfmathsetmacro{\tikzumlRelationPositionT}{(\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=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                                 node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
+        \fi%
+        \ifnum\arcNumT=2%
+          \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                               node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
+        \fi%
+        %
+        \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) -- \tikzumlFirstArc (\tikzumlRelationName-2.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor) }%
+        \ifnum\thetikzumlStateLevel>0%
+          \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+          \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) }%
+        \fi%
+      }{%
+        % first vertical, then horizontal, finally vertical line
+        \ifthenelse{\equal{\tikzumlRelationGeometry}{|-|}}%
+        {%
+          %\setcounter{tikzumlControlNodesNum}{2}%
+          %
+          \def\tikzumlFirstArc{node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center] {} }%
+          \def\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-5, anchor=center] {} }%
+          \def\tikzumlMidOneArc{ }%
+          %
+          \begin{pgfonlayer}{connections}%
+          %
+          \ifthenelse{\equal{\tikzumlRelationArmO}{auto}}{%
+            \ifthenelse{\equal{\tikzumlRelationArmT}{auto}}{%
+              \node[inner sep=0] (\tikzumlRelationName-3) at (\tikzumlRelationName-middle) {};%
+              \node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor |- \tikzumlRelationName-3) {};%
+              \node[inner sep=0] (\tikzumlRelationName-4) at (\tikzumlRelationName-3 -| \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
+            }{%
+              \draw (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor)+(0,\tikzumlRelationArmT) node[inner sep=0, name=\tikzumlRelationName-4] {};%
+              \node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlRelationName-4 -| \tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) {};%
+              \node[inner sep=0] (\tikzumlRelationName-3) at (barycentric cs:\tikzumlRelationName-2=0.5,\tikzumlRelationName-4=0.5) {};%
+            }%
+          }{%
+            \draw (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor)+(0,\tikzumlRelationArmO) node[inner sep=0, name=\tikzumlRelationName-2] {};%
+            \node[inner sep=0] (\tikzumlRelationName-4) at (\tikzumlRelationName-2 -| \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
+            \node[inner sep=0] (\tikzumlRelationName-3) at (barycentric cs:\tikzumlRelationName-2=0.5,\tikzumlRelationName-4=0.5) {};%
+          }%
+          \end{pgfonlayer}%
+          %
+          \ifnum\theposStereo>200%
+            \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-200)/100}%
+            \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+          \else%
+            \ifnum\theposStereo<100%
+              \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+            \else%
+              \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
+              \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+            \fi%
+          \fi%
+          %
+          \ifthenelse{\thepos=200\OR\thepos=100}{%
+            \def\posAttrName{above left}%
+            \def\posMultiplicity{below right}%
+          }{}%
+          %
+          \ifthenelse{\thepos>200}{%
+            \pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-200)/100}%
+            \def\arcNum{3}%
+          }{%
+            \ifthenelse{\thepos<100}{%
+              \def\arcNum{1}%
+            }{%
+              \pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-100)/100}%
+              \def\arcNum{2}%
+            }%
+          }%
+          %
+          \ifnum\arcNum=1%
+            \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                                   node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
+          \fi%
+          \ifnum\arcNum=2%
+            \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                                     node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
+          \fi%
+          \ifnum\arcNum=3%
+            \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                                 node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
+          \fi%
+          %
+          \ifthenelse{\theposT=200\OR\theposT=100}{%
+            \def\posAttrNameT{above left}%
+            \def\posMultiplicityT{below right}%
+          }{}%
+          %
+          \ifthenelse{\theposT>200}{%
+            \pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-200)/100}%
+            \def\arcNumT{3}%
+          }{%
+            \ifthenelse{\theposT<100}{%
+              \def\arcNumT{1}%
+            }{%
+              \pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-100)/100}%
+              \def\arcNumT{2}%
+            }%
+          }%
+          %
+          \ifnum\arcNumT=1%
+            \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                                   node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
+          \fi%
+          \ifnum\arcNumT=2%
+            \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                                     node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
+          \fi%
+          \ifnum\arcNumT=3%
+            \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                                 node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
+          \fi%
+          %
+          \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) -- \tikzumlFirstArc (\tikzumlRelationName-2.base) -- \tikzumlMidOneArc (\tikzumlRelationName-4.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor) }%
+          \ifnum\thetikzumlStateLevel>0%
+            \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+            \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) (\tikzumlRelationName-4) (\tikzumlRelationName-5) }%
+          \fi%
+        }{%
+          % first horizontal, then vertical, finally horizontal line
+          \ifthenelse{\equal{\tikzumlRelationGeometry}{-|-}}%
+          {%
+            %\setcounter{tikzumlControlNodesNum}{2}%
+            %
+            \def\tikzumlFirstArc{node[midway, inner sep=0, name=\tikzumlRelationName-1, anchor=center] {} }%
+            \def\tikzumlLastArc{node[midway, inner sep=0, name=\tikzumlRelationName-5, anchor=center] {} }%
+            \def\tikzumlMidOneArc{}%
+            %
+            \begin{pgfonlayer}{connections}%
+            %
+            \ifthenelse{\equal{\tikzumlRelationArmO}{auto}}{%
+              \ifthenelse{\equal{\tikzumlRelationArmT}{auto}}{%
+                \node[inner sep=0] (\tikzumlRelationName-3) at (\tikzumlRelationName-middle) {};%
+                \node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor -| \tikzumlRelationName-3) {};%
+                \node[inner sep=0] (\tikzumlRelationName-4) at (\tikzumlRelationName-3 |- \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
+              }{%
+                \draw (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor)+(\tikzumlRelationArmT,0) node[inner sep=0, name=\tikzumlRelationName-4] {};%
+                \node[inner sep=0] (\tikzumlRelationName-2) at (\tikzumlRelationName-4 |- \tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) {};%
+                \node[inner sep=0] (\tikzumlRelationName-3) at (barycentric cs:\tikzumlRelationName-2=0.5,\tikzumlRelationName-4=0.5) {};%
+              }%
+            }{%
+              \draw (\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor)+(\tikzumlRelationArmO,0) node[inner sep=0, name=\tikzumlRelationName-2] {};%
+              \node[inner sep=0] (\tikzumlRelationName-4) at (\tikzumlRelationName-2 |- \tikzumlDestClassNodeName\tikzumlRelationDestAnchor) {};%
+              \node[inner sep=0] (\tikzumlRelationName-3) at (barycentric cs:\tikzumlRelationName-2=0.5,\tikzumlRelationName-4=0.5) {};%
+            }%
+            \end{pgfonlayer}%
+            %
+            \ifnum\theposStereo>200%
+              \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-200)/100}%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+            \else%
+              \ifnum\theposStereo<100%
+                \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+              \else%
+                \pgfmathsetmacro{\tikzumlRelationPositionStereotype}{(\theposStereo-100)/100}%
+                \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionStereotype, anchor=center] {\stereotype} }%
+              \fi%
+            \fi%
+            %
+            \ifthenelse{\thepos=200\OR\thepos=100}{%
+              \def\posAttrName{above left}%
+              \def\posMultiplicity{below right}%
+            }{}%
+            %
+            \ifthenelse{\thepos>200}{%
+              \pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-200)/100}%
+              \def\arcNum{3}%
+            }{%
+              \ifthenelse{\thepos<100}{%
+                \def\arcNum{1}%
+              }{%
+                \pgfmathsetmacro{\tikzumlRelationPosition}{(\thepos-100)/100}%
+                \def\arcNum{2}%
+              }%
+            }%
+            %
+            \ifnum\arcNum=1%
+              \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                                     node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
+            \fi%
+            \ifnum\arcNum=2%
+              \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                                       node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
+            \fi%
+            \ifnum\arcNum=3%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPosition, \posAttrName, \attrAlign] {\tikzumlRelationAttrName}%
+                                                   node[pos=\tikzumlRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlRelationMultiplicity} }%
+            \fi%
+            %
+            \ifthenelse{\theposT=200\OR\theposT=100}{%
+              \def\posAttrNameT{above left}%
+              \def\posMultiplicityT{below right}%
+            }{}%
+            %
+            \ifthenelse{\theposT>200}{%
+              \pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-200)/100}%
+              \def\arcNumT{3}%
+            }{%
+              \ifthenelse{\theposT<100}{%
+                \def\arcNumT{1}%
+              }{%
+                \pgfmathsetmacro{\tikzumlRelationPositionT}{(\theposT-100)/100}%
+                \def\arcNumT{2}%
+              }%
+            }%
+            %
+            \ifnum\arcNumT=1%
+              \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                                     node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
+            \fi%
+            \ifnum\arcNumT=2%
+              \xdef\tikzumlMidOneArc{\tikzumlMidOneArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                                       node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
+            \fi%
+            \ifnum\arcNumT=3%
+              \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlRelationAttrNameT}%
+                                                   node[pos=\tikzumlRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlRelationMultiplicityT} }%
+            \fi%
+            %
+            \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlRelationSrcAnchor) -- \tikzumlFirstArc (\tikzumlRelationName-2.base) -- \tikzumlMidOneArc (\tikzumlRelationName-4.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlRelationDestAnchor) }%
+            \ifnum\thetikzumlStateLevel>0%
+              \def\tikzumlStateFitTmp{\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname}%
+              \expandafter\xdef\csname tikzumlStateFit\tikzumlState@parent @@\tikzumlState@fitname\endcsname{\tikzumlStateFitTmp (\tikzumlRelationName-1) (\tikzumlRelationName-2) (\tikzumlRelationName-3) (\tikzumlRelationName-4) (\tikzumlRelationName-5) }%
+            \fi%
+          }{%
+            \errmessage{TIKZUML ERROR : Unknown geometry value !!! It should be in the following list : --, |-, -|, |-|, -|-}%
+          }%
+        }%
+      }%
+    }%
+  }%
+  %
+  \begin{pgfonlayer}{connections}%
+  \ifthenelse{\equal{\tikzumlRelationStyle}{tikzuml nesting style}}{%
+    \pgfarrowsdeclare{nested}{nested}{...}
+    {
+      \tikzumlNestingSymbolSize=0.2pt%
+      \advance\tikzumlNestingSymbolSize by .5\pgflinewidth%
+      \pgfsetdash{}{0pt} %  do not dash
+      \pgfsetroundjoin   %  fix join
+      \pgfsetroundcap    %  fix cap
+      \pgfpathmoveto{\pgfpoint{-16*\tikzumlNestingSymbolSize}{0pt}}%
+      \pgfpatharc{180}{90}{8*\tikzumlNestingSymbolSize}%
+      \pgfpatharc{90}{0}{8*\tikzumlNestingSymbolSize}%
+      \pgfpatharc{0}{-90}{8*\tikzumlNestingSymbolSize}%
+      \pgfpatharc{-90}{-180}{8*\tikzumlNestingSymbolSize}%
+      \pgfpathmoveto{\pgfpoint{-8*\tikzumlNestingSymbolSize}{8*\tikzumlNestingSymbolSize}}%
+      \pgfpathlineto{\pgfpoint{-8*\tikzumlNestingSymbolSize}{-8*\tikzumlNestingSymbolSize}}%
+      \pgfusepathqstroke%
+    }%
+    \draw[auto, nested-, font=\tikzumlDefaultFont, \tikzumlRelationStyle, /tikzuml/relation/style2] \tikzumlPath ;%
+  }{
+    \draw[auto, font=\tikzumlDefaultFont, \tikzumlRelationStyle, /tikzuml/relation/style2] \tikzumlPath ;%
+  }
+  \end{pgfonlayer}%
+  %
+  \stepcounter{tikzumlRelationNum}%
+}%
+%
+% shortcuts of \umlrelation
+\newcommand{\umlHVrelation}[3][]{%
+  \pgfkeys{/tikzuml/HVrelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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{\umlnest}[3][]{\umlrelation[style={tikzuml nesting 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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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{\umlHVnest}[3][]{\umlHVrelation[style={tikzuml nesting 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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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{\umlVHnest}[3][]{\umlVHrelation[style={tikzuml nesting 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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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{\umlHVHnest}[3][]{\umlHVHrelation[style={tikzuml nesting 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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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{\umlVHVnest}[3][]{\umlVHVrelation[style={tikzuml nesting 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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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 : arg1, arg2, arg: name of the src/dest/dest side class type attribute defined by the relation
+%            mult1, mult2, mult: multiplicity of the src/dest/dest side class type attribute defined by the relation
+%            pos1, pos2, pos: position of the src/dest/dest side class type attribute defined by the relation
+%            align1, align2, align: text justification of the src/dest/dest side class type attribute defined by the relation
+%            anchor1, anchor2: src/dest anchors on linked classes
+%            stereo: stereotype of the relation
+%            pos stereo: position of the stereotype on the relation
+%            style: style of the relation (association, aggregation, composition, inherit, ...)
+%            name: rootname used for naming nodes of the relation
+\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%
+                                    \let\keyvalue=\pgfkeyscurrentvalue%
+                                    \errmessage{TIKZUML ERROR : in umlCNrelation, invalid option \keyname}%
+                                  }%
+  }%
+  \pgfkeys{/tikzuml/relation/.cd,#1}%
+  \pgfkeys{/tikzuml/relation/.cd, arg1/.get=\tikzumlCNRelationAttrName, arg2/.get=\tikzumlCNRelationAttrNameTO, arg/.get=\tikzumlCNRelationAttrNameTT,%
+                                  mult1/.get=\tikzumlCNRelationMultiplicity, mult2/.get=\tikzumlCNRelationMultiplicityTO, mult/.get=\tikzumlCNRelationMultiplicityTT,%
+                                  pos1/.get=\tikzumlCNRelationPosition, pos2/.get=\tikzumlCNRelationPositionTO, pos/.get=\tikzumlCNRelationPositionTT,%
+                                  align1/.get=\tikzumlCNRelationAlign, align2/.get=\tikzumlCNRelationAlignTO, align/.get=\tikzumlCNRelationAlignTT,%
+                                  anchor1/.get=\tikzumlCNRelationSrcAnchor, anchor2/.get=\tikzumlCNRelationDestAnchor,%
+                                  stereo/.get=\tikzumlCNRelationStereoType, pos stereo/.get=\tikzumlCNRelationPositionStereotype,%
+                                  style/.get=\tikzumlCNRelationStyle, name/.get=\tikzumlCNRelationName%
+  }%
+  %
+  % managing \_ in class names for node names
+  \def\tikzumlSrcClassName{#2}%
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlSrcClassNodeName{\tikzumlSrcClassName}}\x%
+  %
+  \StrSubstitute{\tikzumlSrcClassNodeName}{:}{@COLON@}[\tikzumlSrcClassNodeName]%
+  \StrSubstitute{\tikzumlSrcClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlSrcClassNodeName]%
+  %
+  \def\tikzumlDestClassName{#4}%
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlDestClassNodeName{\tikzumlDestClassName}}\x%
+  %
+  \StrSubstitute{\tikzumlDestClassNodeName}{:}{@COLON@}[\tikzumlDestClassNodeName]%
+  \StrSubstitute{\tikzumlDestClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlDestClassNodeName]%
+  %
+  % managing alias keys
+  \def\tikzumlCNRelationAttrNameT{\tikzumlCNRelationAttrNameTO\tikzumlCNRelationAttrNameTT}%
+  \def\tikzumlCNRelationMultiplicityT{\tikzumlCNRelationMultiplicityTO\tikzumlCNRelationMultiplicityTT}%
+  \def\tikzumlCNRelationAlignT{\tikzumlCNRelationAlignTO\tikzumlCNRelationAlignTT}%
+  \def\orientationT{\orientationTO\orientationTT}%
+  %
+  \ifthenelse{\equal{\tikzumlCNRelationPositionTT}{tikzumlEmpty}}{%
+    \def\tikzumlCNRelationPositionT{\tikzumlCNRelationPositionTO}%
+  }{%
+    \def\tikzumlCNRelationPositionT{\tikzumlCNRelationPositionTT}%
+  }%
+  %
+  \def\attrAlign{}%
+  \def\multAlign{}%
+  \def\attrAlignT{}%
+  \def\multAlignT{}%
+  %
+  \ifthenelse{\equal{\tikzumlCNRelationAlign}{left}}{%
+    \def\attrAlign{above right}%
+    \def\multAlign{below right}%
+  }{%
+    \ifthenelse{\equal{\tikzumlCNRelationAlign}{right}}{%
+      \def\attrAlign{above left}%
+      \def\multAlign{below left}%
+    }{}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlCNRelationAlignT}{left}}{%
+    \def\attrAlignT{above right}%
+    \def\multAlignT{below right}%
+  }{%
+    \ifthenelse{\equal{\tikzumlCNRelationAlignT}{right}}{%
+      \def\attrAlignT{above left}%
+      \def\multAlignT{below left}%
+    }{}%
+  }%
+  %
+  % def stereotype
+  \ifthenelse{\equal{\tikzumlCNRelationStereoType}{}}{%
+    \def\stereotype{}%
+  }{%
+    \def\stereotype{$\ll$\tikzumlCNRelationStereoType$\gg$}%
+  }%
+  %
+  % def anchors macros
+  \ifthenelse{\equal{\tikzumlCNRelationSrcAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlCNRelationSrcAnchor{}%
+  }{%
+    \let\tikzumlCNRelationSrcAnchorold\tikzumlCNRelationSrcAnchor%
+    \def\tikzumlCNRelationSrcAnchor{.\tikzumlCNRelationSrcAnchorold}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlCNRelationDestAnchor}{tikzumlEmpty}}{%
+    \def\tikzumlCNRelationDestAnchor{}%
+  }{%
+    \let\tikzumlCNRelationDestAnchorold\tikzumlCNRelationDestAnchor%
+    \def\tikzumlCNRelationDestAnchor{.\tikzumlCNRelationDestAnchorold}%
+  }%
+  %
+  \setcounter{pos}{100*\real{\tikzumlCNRelationPosition}}%
+  \setcounter{posT}{100*\real{\tikzumlCNRelationPositionT}}%
+  \setcounter{posStereo}{100*\real{\tikzumlCNRelationPositionStereotype}}%
+  %
+  % straight line
+  %\setcounter{tikzumlControlNodesNum}{1}%
+  %
+  \def\tikzumlFirstArc{node[midway, name=\tikzumlCNRelationName-1, anchor=center] {} }%
+  \def\tikzumlLastArc{node[midway, name=\tikzumlCNRelationName-3, anchor=center]{} }%
+  \def\posAttrName{}%
+  \def\posMultiplicity{}%
+  \def\posAttrNameT{}%
+  \def\posMultiplicityT{}%
+  %
+  \begin{pgfonlayer}{connections}%
+  \node (\tikzumlCNRelationName-2) at (#3) {};%
+  \end{pgfonlayer}%
+  %
+  \ifnum\theposStereo>100%
+    \pgfmathsetmacro{\tikzumlCNRelationPositionStereotype}{(\theposStereo-100)/100}%
+    \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlCNRelationPositionStereotype, anchor=center] {\stereotype} }%
+  \else%
+    \xdef\tikzumlFirstArc{\tikzumlFirstArc node[pos=\tikzumlCNRelationPositionStereotype, anchor=center] {\stereotype} }%
+  \fi%
+  %
+  \ifnum\thepos>100%
+    \pgfmathsetmacro{\tikzumlCNRelationPosition}{(\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=\tikzumlCNRelationPosition, \posAttrName, \attrAlign] {\tikzumlCNRelationAttrName}%
+                                           node[pos=\tikzumlCNRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlCNRelationMultiplicity} }%
+  \fi%
+  \ifnum\arcNum=2%
+    \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlCNRelationPosition, \posAttrName, \attrAlign] {\tikzumlCNRelationAttrName}%
+                                         node[pos=\tikzumlCNRelationPosition, swap, \posMultiplicity, \multAlign] {\tikzumlCNRelationMultiplicity} }%
+  \fi%
+  %
+  \ifnum\theposT>100%
+    \pgfmathsetmacro{\tikzumlCNRelationPositionT}{(\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=\tikzumlCNRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlCNRelationAttrNameT}%
+                                           node[pos=\tikzumlCNRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlCNRelationMultiplicityT} }%
+  \fi%
+  \ifnum\arcNumT=2%
+    \xdef\tikzumlLastArc{\tikzumlLastArc node[pos=\tikzumlCNRelationPositionT, \posAttrNameT, \attrAlignT] {\tikzumlCNRelationAttrNameT}%
+                                         node[pos=\tikzumlCNRelationPositionT, swap, \posMultiplicityT, \multAlignT] {\tikzumlCNRelationMultiplicityT} }%
+  \fi%
+  %
+  \xdef\tikzumlPath{(\tikzumlSrcClassNodeName\tikzumlCNRelationSrcAnchor) -- \tikzumlFirstArc (\tikzumlCNRelationName-2.base) -- \tikzumlLastArc (\tikzumlDestClassNodeName\tikzumlCNRelationDestAnchor) }%
+  
+  \begin{pgfonlayer}{connections}%
+  \ifthenelse{\equal{\tikzumlCNRelationStyle}{tikzuml nesting style}}{%
+    \pgfarrowsdeclare{nested}{nested}{...}
+    {
+      \tikzumlNestingSymbolSize=0.2pt%
+      \advance\tikzumlNestingSymbolSize by .5\pgflinewidth%
+      \pgfsetdash{}{0pt} %  do not dash
+      \pgfsetroundjoin   %  fix join
+      \pgfsetroundcap    %  fix cap
+      \pgfpathmoveto{\pgfpoint{-16*\tikzumlNestingSymbolSize}{0pt}}%
+      \pgfpatharc{180}{90}{8*\tikzumlNestingSymbolSize}%
+      \pgfpatharc{90}{0}{8*\tikzumlNestingSymbolSize}%
+      \pgfpatharc{0}{-90}{8*\tikzumlNestingSymbolSize}%
+      \pgfpatharc{-90}{-180}{8*\tikzumlNestingSymbolSize}%
+      \pgfpathmoveto{\pgfpoint{-8*\tikzumlNestingSymbolSize}{8*\tikzumlNestingSymbolSize}}%
+      \pgfpathlineto{\pgfpoint{-8*\tikzumlNestingSymbolSize}{-8*\tikzumlNestingSymbolSize}}%
+      \pgfusepathqstroke%
+    }%
+    \draw[auto, \tikzumlCNRelationStyle, nested-, font=\tikzumlDefaultFont] \tikzumlPath ;%
+  }{
+    \draw[auto, \tikzumlCNRelationStyle, font=\tikzumlDefaultFont] \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{\umlCNnest}[4][]{\umlCNrelation[style={tikzuml nesting 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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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: width of the note
+%            geometry: geometry of the relation between the note and what it is about
+%            weight: barycentric weight for a 3-line relation
+%            arm: length of the first arm
+%            anchor1, anchor2: anchors of the relation
+%            draw, fill, text: colors
+%            style: to manage every default TikZ option
+%            no coords: to tell that the note position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlnote}[3][]{%
+  \pgfkeys{/tikzuml/note/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlNoteDefaultWidth,%
+                              geometry/.initial=\tikzumlRelationDefaultGeometry,%
+                              weight/.initial=\tikzumlRelationDefaultWeight, arm/.initial=auto, style/.style={},%
+                              anchor1/.initial=tikzumlEmpty, anchor2/.initial=tikzumlEmpty,%
+                              draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlNoteDefaultFillColor,%
+                              text/.initial=\tikzumlDefaultTextColor,%
+                              no coords/.is if=tikzumlnoteWithoutCoords,%
+                              no coords=false,%
+                              .unknown/.code={%
+                                \let\keyname=\pgfkeyscurrentname%
+                                \let\keyvalue=\pgfkeyscurrentvalue%
+                                \ifthenelse{\equal{\keyname}{above}\OR%
+                                            \equal{\keyname}{left}\OR%
+                                            \equal{\keyname}{below}\OR%
+                                            \equal{\keyname}{right}\OR%
+                                            \equal{\keyname}{above left}\OR%
+                                            \equal{\keyname}{above right}\OR%
+                                            \equal{\keyname}{below left}\OR%
+                                            \equal{\keyname}{below right}}{%
+                                  \IfSubStr{\keyvalue}{ of }{%
+                                    \pgfkeys{/tikzuml/note/.cd, no coords}%
+                                  }{}%
+                                }{}%
+                                \ifx\keyvalue\pgfkeysnovalue%
+                                  \pgfkeys{/tikzuml/note/.cd, style/.append style/.expand once={\keyname}}%
+                                \else%
+                                  \pgfkeys{/tikzuml/note/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                \fi%
+                                %\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=\tikzumlNoteTextWidth,%
+                              geometry/.get=\tikzumlNoteGeometry,%
+                              weight/.get=\tikzumlNoteWeight, arm/.get=\tikzumlNoteArm,%
+                              anchor1/.get=\tikzumlNoteSrcAnchor, anchor2/.get=\tikzumlNoteDestAnchor,%
+                              draw/.get=\tikzumlNoteDrawColor, fill/.get=\tikzumlNoteFillColor,%
+                              text/.get=\tikzumlNoteTextColor%
+  }%
+  %
+  \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}%
+  }%
+  %
+  \iftikzumlnoteWithoutCoords%
+    \node[text=\tikzumlNoteTextColor, text width=\tikzumlNoteTextWidth, font=\tikzumlDefaultFont, outer sep=0, inner xsep=1ex, inner ysep=3ex, /tikzuml/note/style] (note-\thetikzumlNoteNum-coord) {#3};%
+  \else%
+    \node[text=\tikzumlNoteTextColor, text width=\tikzumlNoteTextWidth, font=\tikzumlDefaultFont, outer sep=0, inner xsep=1ex, inner ysep=3ex, /tikzuml/note/style] (note-\thetikzumlNoteNum-coord) at (\tikzumlNoteX, \tikzumlNoteY) {#3};%
+  \fi%
+  \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=\tikzumlNoteDrawColor, fill=\tikzumlNoteFillColor] (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=\tikzumlNoteTextColor, text width=\tikzumlNoteTextWidth, outer sep=0, inner xsep=1ex, inner ysep=3ex, font=\tikzumlDefaultFont] (note-\thetikzumlNoteNum) at (note-\thetikzumlNoteNum-coord) {#3};%
+  \draw[draw=\tikzumlNoteDrawColor] (note-\thetikzumlNoteNum-right-top) -| (note-\thetikzumlNoteNum-top-right);%
+  %
+  \pgfmathsetmacro{\tikzumlNoteWeightT}{1.0-\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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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: width of the class node
+%            type: type of of class (class, interface, typedef, enum)
+%            template: template parameters
+%            name: name of the class node
+%            geometry: geometry of the line
+%            weight: barycentric weight of the middle part when geometry is a 3-line
+%            arm: length of first part when geometry id a 3-line
+%            anchor1, anchor2: src/dest anchors on linked classes
+%            style: style of the association class (association, aggregation, composition, inherit, ...)
+%            draw, fill, fill template, text: colors
+%            style: to manage every default TikZ option
+%            no coords: to tell that the class position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlassocclass}[5][]{%
+  \pgfkeys{/tikzuml/assocclass/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX,
+                                    width/.initial=\tikzumlClassDefaultWidth, type/.initial=\tikzumlClassDefaultType, style/.style={},%
+                                    template/.initial={}, name/.initial=tikzumlEmpty, geometry/.initial=\tikzumlRelationDefaultGeometry,%
+                                    weight/.initial=\tikzumlRelationDefaultWeight, arm/.initial=auto,%
+                                    anchor1/.initial=tikzumlEmpty, anchor2/.initial=tikzumlEmpty,%
+                                    draw/.initial=\tikzumlDefaultDrawColor,%
+                                    fill template/.initial=\tikzumlClassTemplateFillColorDefaultFillColor,%
+                                    fill/.initial=\tikzumlClassDefaultFillColor,%
+                                    text/.initial=\tikzumlDefaultTextColor,%
+                                    no coords/.is if=tikzumlassocclassWithoutCoords,%
+                                    no coords=false,%
+                                    .unknown/.code={%
+                                      \let\keyname=\pgfkeyscurrentname%
+                                      \let\keyvalue=\pgfkeyscurrentvalue%
+                                      \ifthenelse{\equal{\keyname}{above}\OR%
+                                                  \equal{\keyname}{left}\OR%
+                                                  \equal{\keyname}{below}\OR%
+                                                  \equal{\keyname}{right}\OR%
+                                                  \equal{\keyname}{above left}\OR%
+                                                  \equal{\keyname}{above right}\OR%
+                                                  \equal{\keyname}{below left}\OR%
+                                                  \equal{\keyname}{below right}}{%
+                                        \IfSubStr{\keyvalue}{ of }{%
+                                          \pgfkeys{/tikzuml/assocclass/.cd, no coords}%
+                                        }{}%
+                                      }{}%
+                                      \ifx\keyvalue\pgfkeysnovalue%
+                                        \pgfkeys{/tikzuml/assocclass/.cd, style/.append style/.expand once={\keyname}}%
+                                      \else%
+                                        \pgfkeys{/tikzuml/assocclass/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                      \fi%
+                                      %\errmessage{TIKZUML ERROR : in umlassocclass, invalid option \keyname}%
+                                    }%
+  }%
+  %
+  \pgfkeys{/tikzuml/assocclass/.cd,#1}%
+  \pgfkeys{/tikzuml/assocclass/.cd, x/.get=\tikzumlAssocClassX, y/.get=\tikzumlAssocClassY,%
+                                    width/.get=\tikzumlAssocClassMinimumWidth, type/.get=\tikzumlAssocClassTypeTmp,%
+                                    template/.get=\tikzumlAssocClassTemplateParam,%
+                                    name/.get=\tikzumlAssocClassName, geometry/.get=\tikzumlAssocClassGeometry,%
+                                    weight/.get=\tikzumlAssocClassWeight, arm/.get=\tikzumlAssocClassArm,%
+                                    anchor1/.get=\tikzumlAssocClassSrcAnchor,%
+                                    anchor2/.get=\tikzumlAssocClassDestAnchor,%
+                                    draw/.get=\tikzumlAssocClassDrawColor, fill/.get=\tikzumlAssocClassFillColor,%
+                                    text/.get=\tikzumlAssocClassTextColor, fill template/.get=\tikzumlAssocClassTemplateFillColor%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlAssocClassTypeTmp}{class}\OR\equal{\tikzumlAssocClassTypeTmp}{abstract}}{%
+    \def\tikzumlAssocClassType{}%
+  }{%
+    \def\tikzumlAssocClassType{$\ll$\tikzumlAssocClassTypeTmp$\gg$ \\}%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlAssocClassTemplateParam}{}}{%
+    \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{\tikzumlAssocClassName}{tikzumlEmpty}}{}{%
+    \def\tikzumlAssocClassNodeName{\tikzumlAssocClassName}%
+  }%
+  %
+  \StrSubstitute{\tikzumlAssocClassNodeName}{:}{@COLON@}[\tikzumlAssocClassNodeName]%
+  \StrSubstitute{\tikzumlAssocClassNodeName}{\_}{@UNDERSCORE@}[\tikzumlAssocClassNodeName]%
+  %
+  \ifthenelse{\equal{\tikzumlAssocClassTypeTmp}{abstract}}{%
+    \let\tikzumlAssocClassNameOld\tikzumlAssocClassName%
+    \def\tikzumlAssocClassName{{\it \tikzumlAssocClassNameOld}}%
+  }{}%
+  %
+  \def\tikzumlAssocClassPos{\tikzumlAssocClassX,\tikzumlAssocClassY}%
+  \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}%
+  }%
+  %
+  \iftikzumlassocclassWithoutCoords%
+    \node[tikzuml class style, draw=\tikzumlAssocClassDrawColor, fill=\tikzumlAssocClassFillColor, text=\tikzumlAssocClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlAssocClassMinimumWidth, /tikzuml/assocclass/style] (\tikzumlAssocClassNodeName) {\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}%
+    };%
+  \else%
+    \node[tikzuml class style, draw=\tikzumlAssocClassDrawColor, fill=\tikzumlAssocClassFillColor, text=\tikzumlAssocClassTextColor, font=\tikzumlDefaultFont, minimum width=\tikzumlAssocClassMinimumWidth, /tikzuml/assocclass/style] (\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}%
+    };%
+  \fi%
+  %
+  \ifthenelse{\equal{\tikzumlAssocClassTemplateParam}{}}{}{%
+    \draw (\tikzumlAssocClassNodeName.north east) node[tikzuml template style, name=\tikzumlAssocClassNodeName-template, draw=\tikzumlAssocClassDrawColor, fill=\tikzumlAssocClassTemplateFillColor, text=\tikzumlAssocClassTextColor, font=\tikzumlDefaultFont] {\tikzumlAssocClassTemplateParam};%
+  }%
+  %
+  \pgfmathsetmacro{\tikzumlAssocClassWeightT}{1.0-\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{\tikzumlAssocClassTemplateParam}{}}{%
+      \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}%
+%
+\newif\iftikzumlusecaseWithoutCoords%
+\newif\iftikzumlactorWithoutCoords%
+%
+% 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=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX,%
+                                draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlSystemDefaultFillColor,%
+                                text/.initial=\tikzumlDefaultTextColor,%
+                                .unknown/.code={%
+                                  \let\keyname=\pgfkeyscurrentname%
+                                  \let\keyvalue=\pgfkeyscurrentvalue%
+                                  \errmessage{TIKZUML ERROR : in umlsystem, invalid option \keyname}%
+                                }%
+  }%
+  %
+  \pgfkeys{/tikzuml/system/.cd, #1}%
+  \pgfkeys{/tikzuml/system/.cd, x/.get=\tikzumlSystemXShift, y/.get=\tikzumlSystemYShift,%
+                                draw/.get=\tikzumlSystemDrawColor, fill/.get=\tikzumlSystemFillColor,%
+                                text/.get=\tikzumlSystemTextColor}%
+  %
+  \stepcounter{tikzumlSystemLevel}%
+  %
+  \begin{scope}[xshift=\tikzumlSystemXShift cm, yshift=\tikzumlSystemYShift 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=\tikzumlSystemTextColor, font=\tikzumlDefaultFont] (\tikzumlSystemName-caption-tmp) at (\tikzumlSystemName-tmp.north) {\tikzumlSystemName};%
+  \node[draw=\tikzumlSystemDrawColor, fill=\tikzumlSystemFillColor, text=\tikzumlSystemTextColor, font=\tikzumlDefaultFont, inner ysep=1em, inner xsep=2ex, fit = (\tikzumlSystemName-tmp) (\tikzumlSystemName-caption-tmp)] (\tikzumlSystemName) {};%
+  \node[text=\tikzumlSystemTextColor, font=\tikzumlDefaultFont] (\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: name of the node
+%            width: node width
+%            draw, fill, text: colors
+%            style: to manage every default TikZ option
+%            no coords: to tell that the use case position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlusecase}[2][]{%
+  \stepcounter{tikzumlUseCaseNum}%
+  \pgfkeys{/tikzuml/usecase/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=auto,%
+                                 name/.initial=usecase-\thetikzumlUseCaseNum,%
+                                 draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlUseCaseDefaultFillColor,%
+                                 text/.initial=\tikzumlDefaultTextColor, style/.style={},%
+                                 no coords/.is if=tikzumlusecaseWithoutCoords,%
+                                 no coords=false,%
+                                 .unknown/.code={%
+                                   \let\keyname=\pgfkeyscurrentname%
+                                   \let\keyvalue=\pgfkeyscurrentvalue%
+                                   \ifthenelse{\equal{\keyname}{above}\OR%
+                                               \equal{\keyname}{left}\OR%
+                                               \equal{\keyname}{below}\OR%
+                                               \equal{\keyname}{right}\OR%
+                                               \equal{\keyname}{above left}\OR%
+                                               \equal{\keyname}{above right}\OR%
+                                               \equal{\keyname}{below left}\OR%
+                                               \equal{\keyname}{below right}}{%
+                                     \IfSubStr{\keyvalue}{ of }{%
+                                       \pgfkeys{/tikzuml/usecase/.cd, no coords}%
+                                     }{}%
+                                   }{}%
+                                   \ifx\keyvalue\pgfkeysnovalue%
+                                     \pgfkeys{/tikzuml/usecase/.cd, style/.append style/.expand once={\keyname}}%
+                                   \else%
+                                     \pgfkeys{/tikzuml/usecase/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                   \fi%
+                                   %\errmessage{TIKZUML ERROR : in umlusecase, invalid option \keyname}%
+                                 }%
+  }%
+  \pgfkeys{/tikzuml/usecase/.cd, #1}%
+  \pgfkeys{/tikzuml/usecase/.cd, x/.get=\tikzumlUseCaseX, y/.get=\tikzumlUseCaseY, width/.get=\tikzumlUseCaseTextWidth,%
+                                 name/.get=\tikzumlUseCaseName,%
+                                 draw/.get=\tikzumlUseCaseDrawColor, fill/.get=\tikzumlUseCaseFillColor,%
+                                 text/.get=\tikzumlUseCaseTextColor%
+  }%
+  %
+  \def\tikzumlUseCaseText{#2}%
+  %
+  \def\tikzumlUseCasePos{\tikzumlUseCaseX,\tikzumlUseCaseY}%
+  %
+  \ifthenelse{\equal{\tikzumlUseCaseTextWidth}{auto}}{%
+    \iftikzumlusecaseWithoutCoords%
+      \node[tikzuml usecase style, draw=\tikzumlUseCaseDrawColor, fill=\tikzumlUseCaseFillColor, text=\tikzumlUseCaseTextColor, font=\tikzumlDefaultFont, /tikzuml/usecase/style] (\tikzumlUseCaseName) {\tikzumlUseCaseText};%
+    \else%
+      \node[tikzuml usecase style, draw=\tikzumlUseCaseDrawColor, fill=\tikzumlUseCaseFillColor, text=\tikzumlUseCaseTextColor, font=\tikzumlDefaultFont, /tikzuml/usecase/style] (\tikzumlUseCaseName) at (\tikzumlUseCasePos) {\tikzumlUseCaseText};%
+    \fi%
+  }{%
+    \iftikzumlusecaseWithoutCoords%
+      \node[tikzuml usecase style, draw=\tikzumlUseCaseDrawColor, fill=\tikzumlUseCaseFillColor, text=\tikzumlUseCaseTextColor, font=\tikzumlDefaultFont, text width=\tikzumlUseCaseTextWidth, /tikzuml/usecase/style] (\tikzumlUseCaseName) {\tikzumlUseCaseText};%
+    \else%
+      \node[tikzuml usecase style, draw=\tikzumlUseCaseDrawColor, fill=\tikzumlUseCaseFillColor, text=\tikzumlUseCaseTextColor, font=\tikzumlDefaultFont, text width=\tikzumlUseCaseTextWidth, /tikzuml/usecase/style] (\tikzumlUseCaseName) at (\tikzumlUseCasePos) {\tikzumlUseCaseText};%
+    \fi%
+  }%
+  %
+  % add to fit
+  \ifnum\c@tikzumlSystemLevel>0%
+    \let\tikzumlSystemFitOld\tikzumlSystemFit%
+    \xdef\tikzumlSystemFit{\tikzumlSystemFitOld (\tikzumlUseCaseName)}%
+    \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=\tikzumlPicturedActorScale}%
+  %
+  \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=\tikzumlPicturedActorScale*0.3333ex, minimum size=\tikzumlPicturedActorScale*2ex, anchor=base] at (head) {};%
+  \end{tikzpicture}%
+}%
+%
+% define an actor
+% arg : var name
+% optional : x, y: coordinates of the actor
+%            scale: scale factor of the actor symbol
+%            below: distance between the actor symbol and its name below
+%            draw, text: colors
+%            style: to manage every default TikZ option
+%            no coords: to tell that the actor position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlactor}[2][]{%
+  \stepcounter{tikzumlActorNum}%
+  \pgfkeys{/tikzuml/actor/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, scale/.initial=1, below/.initial=\tikzumlActorDefaultBelow,%
+                               draw/.initial=\tikzumlDefaultDrawColor, text/.initial=\tikzumlDefaultTextColor,%
+                               style/.style={},%
+                               no coords/.is if=tikzumlactorWithoutCoords,%
+                               no coords=false,%
+                               .unknown/.code={%
+                                 \let\keyname=\pgfkeyscurrentname%
+                                 \let\keyvalue=\pgfkeyscurrentvalue%
+                                 \ifthenelse{\equal{\keyname}{above}\OR%
+                                             \equal{\keyname}{left}\OR%
+                                             \equal{\keyname}{below}\OR%
+                                             \equal{\keyname}{right}\OR%
+                                             \equal{\keyname}{above left}\OR%
+                                             \equal{\keyname}{above right}\OR%
+                                             \equal{\keyname}{below left}\OR%
+                                             \equal{\keyname}{below right}}{%
+                                   \IfSubStr{\keyvalue}{ of }{%
+                                     \pgfkeys{/tikzuml/actor/.cd, no coords}%
+                                   }{}%
+                                 }{}%
+                                 \ifx\keyvalue\pgfkeysnovalue%
+                                   \pgfkeys{/tikzuml/actor/.cd, style/.append style/.expand once={\keyname}}%
+                                 \else%
+                                   \pgfkeys{/tikzuml/actor/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                 \fi%
+                                 %\errmessage{TIKZUML ERROR : in umlactor, invalid option \keyname}%
+                               }%
+  }%
+  \pgfkeys{/tikzuml/actor/.cd, #1}%
+  \pgfkeys{/tikzuml/actor/.cd,%
+           x/.get=\tikzumlActorX, y/.get=\tikzumlActorY, scale/.get=\tikzumlActorScale,%
+           below/.get=\tikzumlActorBelow,%
+           draw/.get=\tikzumlActorDrawColor, text/.get=\tikzumlActorTextColor}%
+  %
+  \def\tikzumlActorName{#2}%
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlActorNodeName{\tikzumlActorName}}\x%
+  %
+  \def\tikzumlActorPos{\tikzumlActorX,\tikzumlActorY}%
+  %
+  \iftikzumlactorWithoutCoords%
+    \node[tikzuml actor style, text=\tikzumlActorTextColor, font=\tikzumlDefaultFont, /tikzuml/actor/style] (\tikzumlActorNodeName) {\picturedactor{scale=\tikzumlActorScale, fill=white, draw=\tikzumlActorDrawColor, thick}};%
+  \else%
+    \node[tikzuml actor style, text=\tikzumlActorTextColor, font=\tikzumlDefaultFont, /tikzuml/actor/style] (\tikzumlActorNodeName) at (\tikzumlActorPos) {\picturedactor{scale=\tikzumlActorScale, fill=white, draw=\tikzumlActorDrawColor, thick}};%
+  \fi%
+  \node[text=\tikzumlActorTextColor, font=\tikzumlDefaultFont, below=\tikzumlActorScale*\tikzumlActorBelow] at (\tikzumlActorNodeName) {\tikzumlActorName};%
+  %
+}%
+
+% shortcuts for include and extend relation
+\newcommand{\umlinclude}[3][]{%
+  \pgfkeys{/tikzuml/includerelation/.cd,%
+           .unknown/.code={%
+             \let\keyname=\pgfkeyscurrentname%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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=\tikzumlDefaultDrawColor, 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}%
+%
+\newif\iftikzumlstatejoinWithoutCoords%
+\newif\iftikzumlstatedecisionWithoutCoords%
+\newif\iftikzumlstateinitialWithoutCoords%
+\newif\iftikzumlstatefinalWithoutCoords%
+\newif\iftikzumlstateenterWithoutCoords%
+\newif\iftikzumlstateexitWithoutCoords%
+\newif\iftikzumlstateendWithoutCoords%
+\newif\iftikzumlstatehistoryWithoutCoords%
+\newif\iftikzumlstatedeephistoryWithoutCoords%
+\newif\iftikzumlstateWithoutCoords%
+%
+% define a uml join state
+% args : name of the state
+% optional : x,y: coordinates of the state
+%            width: width of the state node
+%            name: name of the state node
+%            color: color of the join symbol
+%            style: to manage every default TikZ option
+%            no coords: to tell that the state position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlstatejoin}[1][]{%
+  \pgfkeys{/tikzuml/statejoin/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateJoinDefaultWidth,%
+                                   name/.initial=statejoin-\thetikzumlStateJoinNum,%
+                                   color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
+                                   no coords/.is if=tikzumlstatejoinWithoutCoords,%
+                                   no coords=false,%
+                                   .unknown/.code={%
+                                     \let\keyname=\pgfkeyscurrentname%
+                                     \let\keyvalue=\pgfkeyscurrentvalue%
+                                     \ifthenelse{\equal{\keyname}{above}\OR%
+                                                 \equal{\keyname}{left}\OR%
+                                                 \equal{\keyname}{below}\OR%
+                                                 \equal{\keyname}{right}\OR%
+                                                 \equal{\keyname}{above left}\OR%
+                                                 \equal{\keyname}{above right}\OR%
+                                                 \equal{\keyname}{below left}\OR%
+                                                 \equal{\keyname}{below right}}{%
+                                       \IfSubStr{\keyvalue}{ of }{%
+                                         \pgfkeys{/tikzuml/statejoin/.cd, no coords}%
+                                       }{}%
+                                     }{}%
+                                     \ifx\keyvalue\pgfkeysnovalue%
+                                       \pgfkeys{/tikzuml/statejoin/.cd, style/.append style/.expand once={\keyname}}%
+                                     \else%
+                                       \pgfkeys{/tikzuml/statejoin/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                     \fi%
+                                     %\errmessage{TIKZUML ERROR : in umlstatejoin, invalid option \keyname}%
+                                   }%
+  }%
+  \pgfkeys{/tikzuml/statejoin/.cd, #1}%
+  \pgfkeys{/tikzuml/statejoin/.cd, x/.get=\tikzumlStateJoinX, y/.get=\tikzumlStateJoinY, width/.get=\tikzumlStateJoinMinimumWidth,%
+                                   name/.get=\tikzumlStateJoinName, color/.get=\tikzumlStateJoinColor%
+  }%
+  %
+  \def\tikzumlStateJoinPos{\tikzumlStateJoinX,\tikzumlStateJoinY}%
+  %
+  \iftikzumlstatejoinWithoutCoords%
+    \node[circle, minimum size=\tikzumlStateJoinMinimumWidth, draw=\tikzumlStateJoinColor, fill=\tikzumlStateJoinColor, /tikzuml/statejoin/style] (\tikzumlStateJoinName) {};%
+  \else%
+    \node[circle, minimum size=\tikzumlStateJoinMinimumWidth, draw=\tikzumlStateJoinColor, fill=\tikzumlStateJoinColor, /tikzuml/statejoin/style] (\tikzumlStateJoinName) at (\tikzumlStateJoinPos) {};%
+  \fi%
+  %
+  % 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}%
+}%
+%
+% define a uml decision state
+% args : name of the state
+% optional : x,y: coordinates of the state
+%            width: width of the state node
+%            name: name of the state node
+%            color: color of the join symbol
+%            style: to manage every default TikZ option
+%            no coords: to tell that the state position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlstatedecision}[1][]{%
+  \pgfkeys{/tikzuml/statedecision/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateDecisionDefaultWidth,%
+                                       name/.initial=statedecision-\thetikzumlStateDecisionNum,%
+                                       color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
+                                       no coords/.is if=tikzumlstatedecisionWithoutCoords,%
+                                       no coords=false,%
+                                       .unknown/.code={%
+                                         \let\keyname=\pgfkeyscurrentname%
+                                         \let\keyvalue=\pgfkeyscurrentvalue%
+                                         \ifthenelse{\equal{\keyname}{above}\OR%
+                                                     \equal{\keyname}{left}\OR%
+                                                     \equal{\keyname}{below}\OR%
+                                                     \equal{\keyname}{right}\OR%
+                                                     \equal{\keyname}{above left}\OR%
+                                                     \equal{\keyname}{above right}\OR%
+                                                     \equal{\keyname}{below left}\OR%
+                                                     \equal{\keyname}{below right}}{%
+                                           \IfSubStr{\keyvalue}{ of }{%
+                                             \pgfkeys{/tikzuml/statedecision/.cd, no coords}%
+                                           }{}%
+                                         }{}%
+                                         \ifx\keyvalue\pgfkeysnovalue%
+                                           \pgfkeys{/tikzuml/statedecision/.cd, style/.append style/.expand once={\keyname}}%
+                                         \else%
+                                           \pgfkeys{/tikzuml/statedecision/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                         \fi%
+                                         %\errmessage{TIKZUML ERROR : in umlstatedecision, invalid option \keyname}%
+                                       }%
+  }%
+  \pgfkeys{/tikzuml/statedecision/.cd, #1}%
+  \pgfkeys{/tikzuml/statedecision/.cd, x/.get=\tikzumlStateDecisionX, y/.get=\tikzumlStateDecisionY, width/.get=\tikzumlStateDecisionMinimumWidth,%
+                                       name/.get=\tikzumlStateDecisionName, color/.get=\tikzumlStateDecisionColor%
+  }%
+  %  
+  \def\tikzumlStateDecisionPos{\tikzumlStateDecisionX,\tikzumlStateDecisionY}%
+  %
+  \iftikzumlstatedecisionWithoutCoords%
+    \node[rectangle, rotate=45, minimum size=\tikzumlStateDecisionMinimumWidth, draw=\tikzumlStateDecisionColor, /tikzuml/statedecision/style] (\tikzumlStateDecisionName) {};%
+  \else%
+    \node[rectangle, rotate=45, minimum size=\tikzumlStateDecisionMinimumWidth, draw=\tikzumlStateDecisionColor, /tikzuml/statedecision/style] (\tikzumlStateDecisionName) at (\tikzumlStateDecisionPos) {};%
+  \fi%
+  %
+  % 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}%
+}%
+%
+% define a uml initial state
+% args : name of the state
+% optional : x,y: coordinates of the state
+%            width: width of the state node
+%            name: name of the state node
+%            entry, do, exit: entry/do/exit action of the state
+%            color: color of the join symbol
+%            style: to manage every default TikZ option
+%            no coords: to tell that the state position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlstateinitial}[1][]{%
+  \pgfkeys{/tikzuml/stateinitial/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateInitialDefaultWidth,%
+                                      name/.initial=stateinitial-\thetikzumlStateInitialNum,%
+                                      color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
+                                      no coords/.is if=tikzumlstateinitialWithoutCoords,%
+                                      no coords=false,%
+                                      .unknown/.code={%
+                                        \let\keyname=\pgfkeyscurrentname%
+                                        \let\keyvalue=\pgfkeyscurrentvalue%
+                                        \ifthenelse{\equal{\keyname}{above}\OR%
+                                                    \equal{\keyname}{left}\OR%
+                                                    \equal{\keyname}{below}\OR%
+                                                    \equal{\keyname}{right}\OR%
+                                                    \equal{\keyname}{above left}\OR%
+                                                    \equal{\keyname}{above right}\OR%
+                                                    \equal{\keyname}{below left}\OR%
+                                                    \equal{\keyname}{below right}}{%
+                                          \IfSubStr{\keyvalue}{ of }{%
+                                            \pgfkeys{/tikzuml/stateinitial/.cd, no coords}%
+                                          }{}%
+                                        }{}%
+                                        \ifx\keyvalue\pgfkeysnovalue%
+                                          \pgfkeys{/tikzuml/stateinitial/.cd, style/.append style/.expand once={\keyname}}%
+                                        \else%
+                                          \pgfkeys{/tikzuml/stateinitial/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                        \fi%
+                                        %\errmessage{TIKZUML ERROR : in umlstateinitial, invalid option \keyname}%
+                                      }%
+  }%
+  \pgfkeys{/tikzuml/stateinitial/.cd, #1}%
+  \pgfkeys{/tikzuml/stateinitial/.cd, x/.get=\tikzumlStateInitialX, y/.get=\tikzumlStateInitialY, width/.get=\tikzumlStateInitialMinimumWidth,%
+                                      name/.get=\tikzumlStateInitialName, color/.get=\tikzumlStateInitialColor%
+  }%
+  %  
+  \def\tikzumlStateInitialPos{\tikzumlStateInitialX,\tikzumlStateInitialY}%
+  %
+  \iftikzumlstateinitialWithoutCoords%
+    \node[circle, minimum size=\tikzumlStateInitialMinimumWidth, fill=\tikzumlStateInitialColor, /tikzuml/stateinitial/style] (\tikzumlStateInitialName) {};%
+  \else%
+    \node[circle, minimum size=\tikzumlStateInitialMinimumWidth, fill=\tikzumlStateInitialColor, /tikzuml/stateinitial/style] (\tikzumlStateInitialName) at (\tikzumlStateInitialPos) {};%
+  \fi%
+  %
+  % 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}%
+}%
+%
+% define a uml final state
+% args : name of the state
+% optional : x,y: coordinates of the state
+%            width: width of the state node
+%            name: name of the state node
+%            color: color of the join symbol
+%            style: to manage every default TikZ option
+%            no coords: to tell that the state position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlstatefinal}[1][]{%
+  \pgfkeys{/tikzuml/statefinal/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateFinalDefaultWidth,%
+                                    name/.initial=statefinal-\thetikzumlStateFinalNum,%
+                                    color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
+                                    no coords/.is if=tikzumlstatefinalWithoutCoords,%
+                                    no coords=false,%
+                                    .unknown/.code={%
+                                      \let\keyname=\pgfkeyscurrentname%
+                                      \let\keyvalue=\pgfkeyscurrentvalue%
+                                      \ifthenelse{\equal{\keyname}{above}\OR%
+                                                  \equal{\keyname}{left}\OR%
+                                                  \equal{\keyname}{below}\OR%
+                                                  \equal{\keyname}{right}\OR%
+                                                  \equal{\keyname}{above left}\OR%
+                                                  \equal{\keyname}{above right}\OR%
+                                                  \equal{\keyname}{below left}\OR%
+                                                  \equal{\keyname}{below right}}{%
+                                        \IfSubStr{\keyvalue}{ of }{%
+                                          \pgfkeys{/tikzuml/statefinal/.cd, no coords}%
+                                        }{}%
+                                      }{}%
+                                      \ifx\keyvalue\pgfkeysnovalue%
+                                        \pgfkeys{/tikzuml/statefinal/.cd, style/.append style/.expand once={\keyname}}%
+                                      \else%
+                                        \pgfkeys{/tikzuml/statefinal/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                      \fi%
+                                      %\errmessage{TIKZUML ERROR : in umlstatefinal, invalid option \keyname}%
+                                    }%
+  }%
+  \pgfkeys{/tikzuml/statefinal/.cd, #1}%
+  \pgfkeys{/tikzuml/statefinal/.cd, x/.get=\tikzumlStateFinalX, y/.get=\tikzumlStateFinalY, width/.get=\tikzumlStateFinalMinimumWidth,%
+                                       name/.get=\tikzumlStateFinalName, color/.get=\tikzumlStateFinalColor%
+  }%
+  %  
+  \def\tikzumlStateFinalPos{\tikzumlStateFinalX,\tikzumlStateFinalY}%
+  %
+  \iftikzumlstatefinalWithoutCoords%
+    \node[circle, minimum size=\tikzumlStateFinalMinimumWidth, draw=\tikzumlStateFinalColor, fill=\tikzumlStateFinalColor, double, double distance=0.1cm, /tikzuml/statefinal/style] (\tikzumlStateFinalName) {};%
+  \else%
+    \node[circle, minimum size=\tikzumlStateFinalMinimumWidth, draw=\tikzumlStateFinalColor, fill=\tikzumlStateFinalColor, double, double distance=0.1cm, /tikzuml/statefinal/style] (\tikzumlStateFinalName) at (\tikzumlStateFinalPos) {};%
+  \fi%
+  %
+  % 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}%
+}%
+%
+% define a uml enter state
+% args : name of the state
+% optional : x,y: coordinates of the state
+%            width: width of the state node
+%            name: name of the state node
+%            color: color of the join symbol
+%            style: to manage every default TikZ option
+%            no coords: to tell that the state position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlstateenter}[1][]{%
+  \pgfkeys{/tikzuml/stateenter/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateEnterDefaultWidth,%
+                                    name/.initial=stateenter-\thetikzumlStateEnterNum,%
+                                    color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
+                                    no coords/.is if=tikzumlstateenterWithoutCoords,%
+                                    no coords=false,%
+                                    .unknown/.code={%
+                                      \let\keyname=\pgfkeyscurrentname%
+                                      \let\keyvalue=\pgfkeyscurrentvalue%
+                                      \ifthenelse{\equal{\keyname}{above}\OR%
+                                                  \equal{\keyname}{left}\OR%
+                                                  \equal{\keyname}{below}\OR%
+                                                  \equal{\keyname}{right}\OR%
+                                                  \equal{\keyname}{above left}\OR%
+                                                  \equal{\keyname}{above right}\OR%
+                                                  \equal{\keyname}{below left}\OR%
+                                                  \equal{\keyname}{below right}}{%
+                                        \IfSubStr{\keyvalue}{ of }{%
+                                          \pgfkeys{/tikzuml/stateenter/.cd, no coords}%
+                                        }{}%
+                                      }{}%
+                                      \ifx\keyvalue\pgfkeysnovalue%
+                                        \pgfkeys{/tikzuml/stateenter/.cd, style/.append style/.expand once={\keyname}}%
+                                      \else%
+                                        \pgfkeys{/tikzuml/stateenter/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                      \fi%
+                                      %\errmessage{TIKZUML ERROR : in umlstateenter, invalid option \keyname}%
+                                    }%
+  }%
+  \pgfkeys{/tikzuml/stateenter/.cd, #1}%
+  \pgfkeys{/tikzuml/stateenter/.cd, x/.get=\tikzumlStateEnterX, y/.get=\tikzumlStateEnterY, width/.get=\tikzumlStateEnterMinimumWidth,%
+                                    name/.get=\tikzumlStateEnterName, color/.get=\tikzumlStateEnterColor%
+  }%
+  %  
+  \def\tikzumlStateEnterPos{\tikzumlStateEnterX,\tikzumlStateEnterY}%
+  %
+  \iftikzumlstateenterWithoutCoords%
+    \node[circle, minimum size=\tikzumlStateEnterMinimumWidth, draw=\tikzumlStateEnterColor, /tikzuml/stateenter/style] (\tikzumlStateEnterName) {};%
+  \else%
+    \node[circle, minimum size=\tikzumlStateEnterMinimumWidth, draw=\tikzumlStateEnterColor, /tikzuml/stateenter/style] (\tikzumlStateEnterName) at (\tikzumlStateEnterPos) {};%
+  \fi%
+  %
+  % 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}%
+}%
+%
+% define a uml exit state
+% args : name of the state
+% optional : x,y: coordinates of the state
+%            width: width of the state node
+%            name: name of the state node
+%            color: color of the join symbol
+%            style: to manage every default TikZ option
+%            no coords: to tell that the state position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlstateexit}[1][]{%
+  \pgfkeys{/tikzuml/stateexit/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateExitDefaultWidth,%
+                                   name/.initial=stateexit-\thetikzumlStateExitNum,%
+                                   color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
+                                   no coords/.is if=tikzumlstateexitWithoutCoords,%
+                                   no coords=false,%
+                                   .unknown/.code={%
+                                     \let\keyname=\pgfkeyscurrentname%
+                                     \let\keyvalue=\pgfkeyscurrentvalue%
+                                     \ifthenelse{\equal{\keyname}{above}\OR%
+                                                 \equal{\keyname}{left}\OR%
+                                                 \equal{\keyname}{below}\OR%
+                                                 \equal{\keyname}{right}\OR%
+                                                 \equal{\keyname}{above left}\OR%
+                                                 \equal{\keyname}{above right}\OR%
+                                                 \equal{\keyname}{below left}\OR%
+                                                 \equal{\keyname}{below right}}{%
+                                       \IfSubStr{\keyvalue}{ of }{%
+                                         \pgfkeys{/tikzuml/stateexit/.cd, no coords}%
+                                       }{}%
+                                     }{}%
+                                     \ifx\keyvalue\pgfkeysnovalue%
+                                       \pgfkeys{/tikzuml/stateexit/.cd, style/.append style/.expand once={\keyname}}%
+                                     \else%
+                                       \pgfkeys{/tikzuml/stateexit/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                     \fi%
+                                     %\errmessage{TIKZUML ERROR : in umlstateexit, invalid option \keyname}%
+                                   }%
+  }%
+  \pgfkeys{/tikzuml/stateexit/.cd, #1}%
+  \pgfkeys{/tikzuml/stateexit/.cd, x/.get=\tikzumlStateExitX, y/.get=\tikzumlStateExitY, width/.get=\tikzumlStateExitMinimumWidth,%
+                                   name/.get=\tikzumlStateExitName, color/.get=\tikzumlStateExitColor%
+  }%
+  %  
+  \def\tikzumlStateExitPos{\tikzumlStateExitX,\tikzumlStateExitY}%
+  %
+  \iftikzumlstateexitWithoutCoords%
+    \node[circle, minimum size=\tikzumlStateExitMinimumWidth, draw=\tikzumlStateExitColor, /tikzuml/stateexit/style] (\tikzumlStateExitName) {};%
+  \else%
+    \node[circle, minimum size=\tikzumlStateExitMinimumWidth, draw=\tikzumlStateExitColor, /tikzuml/stateexit/style] (\tikzumlStateExitName) at (\tikzumlStateExitPos) {};%
+  \fi%
+  \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}%
+}%
+%
+% define a uml end state
+% args : name of the state
+% optional : x,y: coordinates of the state
+%            width: width of the state node
+%            name: name of the state node
+%            color: color of the join symbol
+%            style: to manage every default TikZ option
+%            no coords: to tell that the state position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlstateend}[1][]{%
+  \pgfkeys{/tikzuml/stateend/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateEndDefaultWidth,%
+                                  name/.initial=stateend-\thetikzumlStateEndNum,%
+                                  color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
+                                  no coords/.is if=tikzumlstateendWithoutCoords,%
+                                  no coords=false,%
+                                  .unknown/.code={%
+                                    \let\keyname=\pgfkeyscurrentname%
+                                    \let\keyvalue=\pgfkeyscurrentvalue%
+                                    \ifthenelse{\equal{\keyname}{above}\OR%
+                                                \equal{\keyname}{left}\OR%
+                                                \equal{\keyname}{below}\OR%
+                                                \equal{\keyname}{right}\OR%
+                                                \equal{\keyname}{above left}\OR%
+                                                \equal{\keyname}{above right}\OR%
+                                                \equal{\keyname}{below left}\OR%
+                                                \equal{\keyname}{below right}}{%
+                                      \IfSubStr{\keyvalue}{ of }{%
+                                        \pgfkeys{/tikzuml/stateend/.cd, no coords}%
+                                      }{}%
+                                    }{}%
+                                    \ifx\keyvalue\pgfkeysnovalue%
+                                      \pgfkeys{/tikzuml/stateend/.cd, style/.append style/.expand once={\keyname}}%
+                                    \else%
+                                      \pgfkeys{/tikzuml/stateend/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                    \fi%
+                                    %\errmessage{TIKZUML ERROR : in umlstateend, invalid option \keyname}%
+                                  }%
+  }%
+  \pgfkeys{/tikzuml/stateend/.cd, #1}%
+  \pgfkeys{/tikzuml/stateend/.cd, x/.get=\tikzumlStateEndX, y/.get=\tikzumlStateEndY, width/.get=\tikzumlStateEndMinimumWidth,%
+                                  name/.get=\tikzumlStateEndName, color/.get=\tikzumlStateEndColor%
+  }%
+  %  
+  \def\tikzumlStateEndPos{\tikzumlStateEndX,\tikzumlStateEndY}%
+  %
+  \iftikzumlstateendWithoutCoords%
+    \node[circle, minimum size=\tikzumlStateEndMinimumWidth, /tikzuml/stateend/style] (\tikzumlStateEndName) {};%
+  \else%
+    \node[circle, minimum size=\tikzumlStateEndMinimumWidth, /tikzuml/stateend/style] (\tikzumlStateEndName) at (\tikzumlStateEndPos) {};%
+  \fi%
+  \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}%
+}%
+%
+% define a uml history state
+% args : name of the state
+% optional : x,y: coordinates of the state
+%            width: width of the state node
+%            name: name of the state node
+%            color: color of the join symbol
+%            style: to manage every default TikZ option
+%            no coords: to tell that the state position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlstatehistory}[1][]{%
+  \pgfkeys{/tikzuml/statehistory/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateHistoryDefaultWidth,%
+                                      name/.initial=statehistory-\thetikzumlStateHistoryNum,%
+                                      color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
+                                      no coords/.is if=tikzumlstatehistoryWithoutCoords,%
+                                      no coords=false,%
+                                      .unknown/.code={%
+                                        \let\keyname=\pgfkeyscurrentname%
+                                        \let\keyvalue=\pgfkeyscurrentvalue%
+                                        \ifthenelse{\equal{\keyname}{above}\OR%
+                                                    \equal{\keyname}{left}\OR%
+                                                    \equal{\keyname}{below}\OR%
+                                                    \equal{\keyname}{right}\OR%
+                                                    \equal{\keyname}{above left}\OR%
+                                                    \equal{\keyname}{above right}\OR%
+                                                    \equal{\keyname}{below left}\OR%
+                                                    \equal{\keyname}{below right}}{%
+                                          \IfSubStr{\keyvalue}{ of }{%
+                                            \pgfkeys{/tikzuml/statehistory/.cd, no coords}%
+                                          }{}%
+                                        }{}%
+                                        \ifx\keyvalue\pgfkeysnovalue%
+                                          \pgfkeys{/tikzuml/statehistory/.cd, style/.append style/.expand once={\keyname}}%
+                                        \else%
+                                          \pgfkeys{/tikzuml/statehistory/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                        \fi%
+                                        %\errmessage{TIKZUML ERROR : in umlstatehistory, invalid option \keyname}%
+                                      }%
+  }%
+  \pgfkeys{/tikzuml/statehistory/.cd, #1}%
+  \pgfkeys{/tikzuml/statehistory/.cd, x/.get=\tikzumlStateHistoryX, y/.get=\tikzumlStateHistoryY, width/.get=\tikzumlStateHistoryMinimumWidth,%
+                                      name/.get=\tikzumlStateHistoryName, color/.get=\tikzumlStateHistoryColor%
+  }%
+  %
+  \def\tikzumlStateHistoryPos{\tikzumlStateHistoryX,\tikzumlStateHistoryY}%
+  %
+  \iftikzumlstatehistoryWithoutCoords%
+    \node[circle, minimum size=\tikzumlStateHistoryMinimumWidth, draw=\tikzumlStateHistoryColor, /tikzuml/statehistory/style] (\tikzumlStateHistoryName) {\picturedhistory{draw=\tikzumlStateHistoryColor}};%
+  \else%
+    \node[circle, minimum size=\tikzumlStateHistoryMinimumWidth, draw=\tikzumlStateHistoryColor, /tikzuml/statehistory/style] (\tikzumlStateHistoryName) at (\tikzumlStateHistoryPos) {\picturedhistory{draw=\tikzumlStateHistoryColor}};%
+  \fi%
+  %
+  % 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}%
+}%
+%
+% define a uml deep-history state
+% args : name of the state
+% optional : x,y: coordinates of the state
+%            width: width of the state node
+%            name: name of the state node
+%            color: color of the join symbol
+%            style: to manage every default TikZ option
+%            no coords: to tell that the state position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\newcommand{\umlstatedeephistory}[1][]{%
+  \pgfkeys{/tikzuml/statedeephistory/.cd, x/.initial=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateDeepHistoryDefaultWidth,%
+                                          name/.initial=statedeephistory-\thetikzumlStateDeepHistoryNum,%
+                                          color/.initial=\tikzumlDefaultDrawColor, style/.style={},%
+                                          no coords/.is if=tikzumlstatedeephistoryWithoutCoords,%
+                                          no coords=false,%
+                                          .unknown/.code={%
+                                            \let\keyname=\pgfkeyscurrentname%
+                                            \let\keyvalue=\pgfkeyscurrentvalue%
+                                            \ifthenelse{\equal{\keyname}{above}\OR%
+                                                        \equal{\keyname}{left}\OR%
+                                                        \equal{\keyname}{below}\OR%
+                                                        \equal{\keyname}{right}\OR%
+                                                        \equal{\keyname}{above left}\OR%
+                                                        \equal{\keyname}{above right}\OR%
+                                                        \equal{\keyname}{below left}\OR%
+                                                        \equal{\keyname}{below right}}{%
+                                              \IfSubStr{\keyvalue}{ of }{%
+                                                \pgfkeys{/tikzuml/statedeephistory/.cd, no coords}%
+                                              }{}%
+                                            }{}%
+                                            \ifx\keyvalue\pgfkeysnovalue%
+                                              \pgfkeys{/tikzuml/statedeephistory/.cd, style/.append style/.expand once={\keyname}}%
+                                            \else%
+                                              \pgfkeys{/tikzuml/statedeephistory/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                            \fi%
+                                            %\errmessage{TIKZUML ERROR : in umlstatedeephistory, invalid option \keyname}%
+                                          }%
+  }%
+  \pgfkeys{/tikzuml/statedeephistory/.cd, #1}%
+  \pgfkeys{/tikzuml/statedeephistory/.cd, x/.get=\tikzumlStateDeepHistoryX, y/.get=\tikzumlStateDeepHistoryY, width/.get=\tikzumlStateDeepHistoryMinimumWidth,%
+                                          name/.get=\tikzumlStateDeepHistoryName, color/.get=\tikzumlStateDeepHistoryColor%
+  }%
+  %  
+  \def\tikzumlStateDeepHistoryPos{\tikzumlStateDeepHistoryX,\tikzumlStateDeepHistoryY}%
+  %
+  \iftikzumlstatedeephistoryWithoutCoords%
+    \node[circle, minimum size=\tikzumlStateDeepHistoryMinimumWidth, draw=\tikzumlStateDeepHistoryColor, /tikzuml/statedeephistory/style] (\tikzumlStateDeepHistoryName) {\pictureddeephistory{draw=\tikzumlStateDeepHistoryColor}};%
+  \else%
+    \node[circle, minimum size=\tikzumlStateDeepHistoryMinimumWidth, draw=\tikzumlStateDeepHistoryColor, /tikzuml/statedeephistory/style] (\tikzumlStateDeepHistoryName) at (\tikzumlStateDeepHistoryPos) {\pictureddeephistory{draw=\tikzumlStateDeepHistoryColor}};%
+  \fi%
+  %
+  % 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 : x,y: coordinates of the state
+%            width: width of the state node
+%            name: name of the state node
+%            entry, do, exit: entry/do/exit action of the state
+%            draw, fill, text: colors
+%            style: to manage every default TikZ option
+%            no coords: to tell that the state position is defined relatively
+%                       to another node (automatically used with TikZ options above, below, left, right, below left, ...)
+\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=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlStateDefaultWidth,%
+                               name/.initial={},%
+                               entry/.initial={}, do/.initial={}, exit/.initial={},%
+                               draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlStateDefaultFillColor,%
+                               text/.initial=\tikzumlDefaultTextColor, style/.style={},%
+                               no coords/.is if=tikzumlstateWithoutCoords,%
+                               no coords=false,%
+                               .unknown/.code={%
+                                 \let\keyname=\pgfkeyscurrentname%
+                                 \let\keyvalue=\pgfkeyscurrentvalue%
+                                 \ifthenelse{\equal{\keyname}{above}\OR%
+                                             \equal{\keyname}{left}\OR%
+                                             \equal{\keyname}{below}\OR%
+                                             \equal{\keyname}{right}\OR%
+                                             \equal{\keyname}{above left}\OR%
+                                             \equal{\keyname}{above right}\OR%
+                                             \equal{\keyname}{below left}\OR%
+                                             \equal{\keyname}{below right}}{%
+                                   \IfSubStr{\keyvalue}{ of }{%
+                                     \pgfkeys{/tikzuml/state/.cd, no coords}%
+                                   }{}%
+                                 }{}%
+                                 \ifx\keyvalue\pgfkeysnovalue%
+                                   \pgfkeys{/tikzuml/state/.cd, style/.append style/.expand once={\keyname}}%
+                                 \else%
+                                   \pgfkeys{/tikzuml/state/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                 \fi%
+                    %             \errmessage{TIKZUML ERROR : in umlstate, invalid option \keyname}%
+                               }%
+  }%
+  \pgfkeys{/tikzuml/state/.cd, #1}%
+  \pgfkeys{/tikzuml/state/.cd, x/.get=\tikzumlStateXShift, y/.get=\tikzumlStateYShift, width/.get=\tikzumlStateMinimumWidth, name/.get=\tikzumlStateName,%
+                               entry/.get=\tikzumlStateEntry, do/.get=\tikzumlStateDo, exit/.get=\tikzumlStateExit,%
+                               draw/.get=\tikzumlStateDrawColor, fill/.get=\tikzumlStateFillColor,%
+                               text/.get=\tikzumlStateTextColor%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlStateName}{}}{%
+    \edef\tikzumlState@name{#2}%
+  }{%
+    \edef\tikzumlState@name{\tikzumlStateName}%
+  }%
+  %
+  \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=\tikzumlStateXShift cm, yshift=\tikzumlStateYShift cm]%
+}{%
+  %  
+  \def\tikzumlstaterootlabel{\phantom{\tikzumlState@nodeName}}%
+  %
+  \def\tikzumlstaterootinnerysep{0.5ex}%
+  \def\tikzumlstatebodyinnerysep{2ex}%
+  %
+  \ifthenelse{\equal{\tikzumlStateEntry}{}}{}{%
+    \ifnum\c@tikzumlStateText=0%
+      \def\tikzumlStateText{entry/\tikzumlStateEntry}%
+    \else%
+      \let\tikzumlStateTextOld\tikzumlStateText%
+      \ifthenelse{\equal{\tikzumlStateText}{tikzumlEmpty}}{%
+        \def\tikzumlStateText{entry/\tikzumlStateEntry}%
+      }{%
+        \expandafter\def\expandafter\tikzumlStateText\expandafter{\tikzumlStateTextOld \\ entry/\tikzumlStateEntry}%
+      }%
+    \fi%
+    \setcounter{tikzumlStateText}{1}%
+    \ifnum\c@tikzumlStateSubStateNum=0%
+      \def\tikzumlstatebodyinnerysep{0}%
+      \def\tikzumlstaterootinnerysep{0}%
+    \fi%
+  }%
+  \ifthenelse{\equal{\tikzumlStateDo}{}}{}{%
+    \ifnum\c@tikzumlStateText=0%
+      \def\tikzumlStateText{do/\tikzumlStateDo}%
+    \else%
+      \let\tikzumlStateTextOld\tikzumlStateText%
+      \ifthenelse{\equal{\tikzumlStateText}{tikzumlEmpty}}{%
+        \def\tikzumlStateText{do/\tikzumlStateDo}%
+      }{%
+        \expandafter\def\expandafter\tikzumlStateText\expandafter{\tikzumlStateTextOld \\ do/\tikzumlStateDo}%
+      }%
+    \fi%
+    \setcounter{tikzumlStateText}{1}%
+    \ifnum\c@tikzumlStateSubStateNum=0%
+      \def\tikzumlstatebodyinnerysep{0}%
+      \def\tikzumlstaterootinnerysep{0}%
+    \fi%
+  }%
+  \ifthenelse{\equal{\tikzumlStateExit}{}}{}{%
+    \ifnum\c@tikzumlStateText=0%
+      \def\tikzumlStateText{exit/\tikzumlStateExit}%
+    \else%
+      \let\tikzumlStateTextOld\tikzumlStateText%
+      \ifthenelse{\equal{\tikzumlStateText}{tikzumlEmpty}}{%
+        \def\tikzumlStateText{exit/\tikzumlStateExit}%
+      }{%
+        \expandafter\def\expandafter\tikzumlStateText\expandafter{\tikzumlStateTextOld \\ exit/\tikzumlStateExit}%
+      }%
+    \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%
+    \iftikzumlstateWithoutCoords%
+      \node[inner ysep=\tikzumlstaterootinnerysep, minimum width=\tikzumlStateMinimumWidth, /tikzuml/state/style] (\tikzumlState@nodeName-root) {\tikzumlstaterootlabel};%
+    \else%
+      \node[inner ysep=\tikzumlstaterootinnerysep, minimum width=\tikzumlStateMinimumWidth, /tikzuml/state/style] (\tikzumlState@nodeName-root) at (0,0) {\tikzumlstaterootlabel};%
+    \fi%
+    \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, /tikzuml/state/style ] (\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};%
+  \ifnum\c@tikzumlStateText=1%
+    \node[rounded corners, draw=\tikzumlStateDrawColor, fill=\tikzumlStateFillColor, name=\tikzumlState@nodeName, fit=(\tikzumlState@nodeName-body) (\tikzumlState@nodeName-texttmp) (\tikzumlState@nodeName-captiontmp)] {};%
+  \else%
+    \node[rounded corners, draw=\tikzumlStateDrawColor, fill=\tikzumlStateFillColor, name=\tikzumlState@nodeName, fit=(\tikzumlState@nodeName-body) (\tikzumlState@nodeName-captiontmp)] {};%
+  \fi%
+  \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, to be used inside umlstate environment
+\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=\tikzumlDefaultDrawColor, -triangle 45]%
+\tikzstyle{tikzuml asynchron-msg style}=[color=\tikzumlDefaultDrawColor, -angle 45]%
+\tikzstyle{tikzuml return-msg style}=[color=\tikzumlDefaultDrawColor, dashed, -angle 45]%
+\tikzstyle{tikzuml call return style}=[color=\tikzumlDefaultDrawColor, 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}%
+%
+\newif\iftikzumlobjectNoDDots%
+\newif\iftikzumlcreatecallNoDDots%
+%
+% 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%
+                                        \let\keyvalue=\pgfkeyscurrentvalue%
+                                        \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%
+                                        \let\keyvalue=\pgfkeyscurrentvalue%
+                                        \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=\tikzumlDefaultFont]%
+}{%
+  % 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 database 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 entity 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 boundary 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 control 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
+%            stereo: stereotype of the object (object, actor, database, boundary, control, entity, multiobject)
+%            class: class of the object
+%            scale: scale factor of the object symbol
+%            draw, fill, text; colors
+%            no ddots: when used, disable printing of double dots
+\newcommand{\umlobject}[2][]{
+  \stepcounter{tikzumlObjectNum}%
+  %
+  \edef\tikzumlobject@ddot{:}%
+  \pgfkeys{/tikzuml/obj/.cd, x/.initial=tikzumlEmpty, y/.initial=\tikzumlDefaultX, stereo/.initial=\tikzumlObjectDefaultStereo,%
+                             class/.initial={}, scale/.initial=1,%
+                             draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlObjectDefaultFillColor,%
+                             text/.initial=\tikzumlDefaultTextColor,%
+                             no ddots/.is if=tikzumlobjectNoDDots,%
+                             no ddots=false,%
+                             .unknown/.code={%
+                               \let\keyname=\pgfkeyscurrentname%
+                               \let\keyvalue=\pgfkeyscurrentvalue%
+                               \errmessage{TIKZUML ERROR : in umlobject, 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=\tikzumlObjectDrawColor, fill/.get=\tikzumlObjectFillColor,%
+                             text/.get=\tikzumlObjectTextColor%
+  }%
+  %
+  \iftikzumlobjectNoDDots%
+    \edef\tikzumlobject@ddot{}%
+  \fi%
+  %
+  \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%
+    \expandafter\xdef\expandafter\tikzumlIdList\expandafter{\tikzumlIdListOld,\tikzumlObjectName}%
+  \fi%
+  %
+  \tikzstyle{tikzuml object box style}=[rectangle, text=\tikzumlObjectTextColor, font=\tikzumlDefaultFont]%
+  %
+  \ifthenelse{\equal{\tikzumlObjectStereo}{object}}{%
+    \tikzstyle{tikzuml object box style}+=[draw=\tikzumlObjectDrawColor, fill=\tikzumlObjectFillColor]%
+  }{%
+    \ifthenelse{\equal{\tikzumlObjectStereo}{multi}}{%
+      \tikzstyle{tikzuml object box style}+=[fill=\tikzumlObjectFillColor]%
+    }{}%
+  }%
+  %
+  \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=\tikzumlObjectFillColor] (\tikzumlObjectName-ttl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-ttl) -- (\tikzumlObjectName-ttr) -- (\tikzumlObjectName-tbr) -- (\tikzumlObjectName-tbr -| \tikzumlObjectName.east) -- (\tikzumlObjectName.north east) -- (\tikzumlObjectName-ttl |- \tikzumlObjectName.north);
+    \draw[draw=\tikzumlObjectDrawColor] (\tikzumlObjectName-ttl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-ttl) -- (\tikzumlObjectName-ttr) -- (\tikzumlObjectName-tbr) -- (\tikzumlObjectName-tbr -| \tikzumlObjectName.east);
+    \fill[fill=\tikzumlObjectFillColor] (\tikzumlObjectName-tl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-tl) -- (\tikzumlObjectName-tr) -- (\tikzumlObjectName-br) -- (\tikzumlObjectName-br -| \tikzumlObjectName.east) -- (\tikzumlObjectName.north east) -- (\tikzumlObjectName-tl |- \tikzumlObjectName.north);
+    \draw[draw=\tikzumlObjectDrawColor] (\tikzumlObjectName-tl |- \tikzumlObjectName.north) -- (\tikzumlObjectName-tl) -- (\tikzumlObjectName-tr) -- (\tikzumlObjectName-br) -- (\tikzumlObjectName-br -| \tikzumlObjectName.east);
+    \draw[draw=\tikzumlObjectDrawColor] (\tikzumlObjectName.north west) rectangle (\tikzumlObjectName.south east);
+  }{%
+    \ifthenelse{\equal{\tikzumlObjectStereo}{object}}{}{%
+      \node[above=1ex, name=\tikzumlObjectName-picture] at (\tikzumlObjectName) {\csname pictured\tikzumlObjectStereo \endcsname{draw=\tikzumlObjectDrawColor, fill=\tikzumlObjectFillColor, scale=\tikzumlObjectScale}};
+    }%
+  }%
+}%
+%
+% shortcuts for objects
+\newcommand{\umlbasicobject}[2][]{%
+  \pgfkeys{/tikzuml/basicobj/.cd, .unknown/.code={%
+                                    \let\keyname=\pgfkeyscurrentname%
+                                    \let\keyvalue=\pgfkeyscurrentvalue%
+                                    \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%
+                                       \let\keyvalue=\pgfkeyscurrentvalue%
+                                       \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%
+                                     \let\keyvalue=\pgfkeyscurrentvalue%
+                                     \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%
+                                      \let\keyvalue=\pgfkeyscurrentvalue%
+                                      \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%
+                                       \let\keyvalue=\pgfkeyscurrentvalue%
+                                       \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%
+                                    \let\keyvalue=\pgfkeyscurrentvalue%
+                                    \ifthenelse{\equal{\keyname}{stereo}}{%
+                                      \errmessage{TIKZUML ERROR : in umlmulti, forbidden option stereo}%
+                                    }{}%
+                                  }%
+  }%
+  \pgfkeys{/tikzuml/multiobj/.cd, #1}%
+  \umlobject[stereo=multi, #1]{#2}%
+}%
+%
+\newcounter{tikzumlSDNodeNum}%
+%
+% define a hidden node to lengthen lifeline of a object
+% args : object node
+% optional : dt: distance between the sdnode and the last call defined on the lifeline of the object
+%            name: name of the sdnode
+\newcommand{\umlsdnode}[2][]{%
+  \pgfkeys{/tikzuml/sdnode/.cd, dt/.initial=0, name/.initial=tikzumlEmpty}%
+  \pgfkeys{/tikzuml/sdnode/.cd, #1}%
+  \pgfkeys{/tikzuml/sdnode/.cd, dt/.get=\tikzumlSDNodeDT, name/.get=\tikzumlSDNodeName}%
+  %
+  \ifthenelse{\equal{\tikzumlSDNodeName}{tikzumlEmpty}}{%
+    \expandafter\def\expandafter\tikzumlSDNode@nodeName{sdnode-\thetikzumlSDNodeNum}%
+  }{%
+    \expandafter\def\expandafter\tikzumlSDNode@nodeName{\tikzumlSDNodeName}%
+  }%
+  %
+  \stepcounter{tikzumlSDNodeNum}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlSDNode@objnodeName{#2}}\x%
+  %
+  \draw (\expandafter\csname tikzumlLastChild@\tikzumlSDNode@objnodeName \endcsname)+(0,-\tikzumlSDNodeDT ex) node[name=\tikzumlSDNode@nodeName,coordinate] {};%
+  %
+  % update last node drawn on sender lifeline
+  \expandafter\xdef\csname tikzumlLastChild@\tikzumlSDNode@objnodeName \endcsname{\tikzumlSDNode@nodeName}%
+}%
+%
+\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: name of the call
+%            op: operation name and input args
+%            return: return value
+%            type: type of the call (synchron, asynchron)
+%            draw, fill, text: colors
+%            padding: 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=\tikzumlCallDefaultDT, name/.initial={call-\thetikzumlCallNum},%
+                              op/.initial={}, return/.initial={}, type/.initial=\tikzumlCallDefaultType,%
+                              draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlCallDefaultFillColor,%
+                              text/.initial=\tikzumlDefaultTextColor,%
+                              padding/.initial=\tikzumlCallDefaultPadding,%
+                              .unknown/.code={%
+                                \let\keyname=\pgfkeyscurrentname%
+                                \let\keyvalue=\pgfkeyscurrentvalue%
+                                \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=\tikzumlCallDrawColor, fill/.get=\tikzumlCallFillColor,%
+                              text/.get=\tikzumlCallTextColor%
+  }%
+  %
+  \edef\tikzumlfillcall{\tikzumlCallFillColor}%
+  \edef\tikzumldrawcall{\tikzumlCallDrawColor}%
+  \edef\tikzumltextcall{\tikzumlCallTextColor}%
+  \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{\tikzumlCallDefaultFillColor}{\tikzumlCallFillColor}}{}{%
+    \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=\tikzumlDefaultFont, 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=\tikzumlDefaultFont, 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=\tikzumlDefaultFont, text=\tikzumltextcall, midway, above=-0.4ex, name=\tikzumlCall@nodeName-op] {\tikzumlCallOp};%
+    }{%
+      \draw[\tikzumlcallstyle, \tikzumldrawcall] (st-\tikzumlCall@nodeName.west) -- (et-\tikzumlCall@nodeName.east) %
+                                                 node[font=\tikzumlDefaultFont, 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=\tikzumlDefaultFont, 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=\tikzumlDefaultFont, 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: name of fragment
+%            type: type of fragment (opt, alt, break, loop, par, critical, ignore, consider, assert, neg, weak, strict, ref)
+%            label: label of fragment (ex : condition for opt, iterator for loop, ...)
+%            inner xsep, inner 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=\tikzumlFragmentDefaultType,%
+                                  label/.initial=tikzumlEmpty,%
+                                  inner xsep/.initial=\tikzumlFragmentDefaultXSep, inner ysep/.initial=\tikzumlFragmentDefaultYSep,%
+                                  draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlFragmentDefaultFillColor,%
+                                  text/.initial=\tikzumlDefaultTextColor,%
+                                  .unknown/.code={%
+                                    \let\keyname=\pgfkeyscurrentname%
+                                    \let\keyvalue=\pgfkeyscurrentvalue%
+                                    \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=\tikzumlFragmentDrawColor, fill/.get=\tikzumlFragmentFillColor,%
+                                  text/.get=\tikzumlFragmentTextColor%
+  }%
+  %
+  \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=\tikzumlFragmentTextColor, font=\tikzumlDefaultFont, anchor=north east, name=\tikzumlFragment@name-type] %
+                                   at (\tikzumlFragment@name-back.north west) {\tikzumlFragmentType};%
+  \node[text=\tikzumlFragmentTextColor, font=\tikzumlDefaultFont, anchor=north west, name=\tikzumlFragment@name-label] %
+                                   at (\tikzumlFragment@name-type.south west) {\tikzumlFragmentLabel};%
+  %
+  % draw final fragment box
+  \begin{pgfonlayer}{fragment\thetikzumlFragmentLevel}%
+  \node[draw=\tikzumlFragmentDrawColor, fill=\tikzumlFragmentFillColor, outer sep=0, inner sep=0, font=\tikzumlDefaultFont, fit=(\tikzumlFragment@name-back) (\tikzumlFragment@name-type) (\tikzumlFragment@name-label), name=\tikzumlFragment@name] {};%
+  \end{pgfonlayer}%
+  %
+  \draw[draw=\tikzumlFragmentDrawColor] (\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
+%            stereo: stereotype of the new object
+%            class: class type of the new object
+%            dt: time delay from last event
+%            name: name of the call
+%            draw, fill, text: colors
+%            no ddots: when used, disable printing of double dots
+\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=\tikzumlObjectDefaultStereo, class/.initial={},%
+                                    dt/.initial=\tikzumlCreateCallDefaultDT, name/.initial=call-\thetikzumlCallNum,%
+                                    draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlCallDefaultFillColor,%
+                                    text/.initial=\tikzumlDefaultTextColor,%
+                                    draw obj/.initial=\tikzumlDefaultDrawColor, fill obj/.initial=\tikzumlObjectDefaultFillColor,%
+                                    text obj/.initial=\tikzumlDefaultTextColor,%
+                                    no ddots/.is if=tikzumlcreatecallNoDDots,%
+                                    no ddots=false,%
+                                    .unknown/.code={%
+                                      \let\keyname=\pgfkeyscurrentname%
+                                      \let\keyvalue=\pgfkeyscurrentvalue%
+                                      \errmessage{TIKZUML ERROR : in umlcreatecall, invalid option \keyname}%
+                                    }%
+  }%
+  \pgfkeys{/tikzuml/createcall/.cd, #1}%
+  \pgfkeys{/tikzuml/createcall/.cd, x/.get=\tikzumlCreateCallX, stereo/.get=\tikzumlCreateCallStereo,%
+                                    class/.get=\tikzumlCreateCallClass,%
+                                    dt/.get=\tikzumlCreateCallDT, name/.get=\tikzumlCreateCallName,%
+                                    draw/.get=\tikzumlCreateCallDrawColor, fill/.get=\tikzumlCreateCallFillColor,%
+                                    text/.get=\tikzumlCreateCallTextColor,%
+                                    draw obj/.get=\tikzumlCreateCallObjectDrawColor, fill obj/.get=\tikzumlCreateCallObjectFillColor,%
+                                    text obj/.get=\tikzumlCreateCallObjectTextColor%
+  }%
+  %
+  \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\tikzumlCreateCallDTold\tikzumlCreateCallDT%
+    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCreateCallDTold}%
+    \edef\tikzumlCreateCallDT{\pgfmathresult}%
+    \addtocounter{tikzumlCallStartFragmentNum}{-1}
+  \fi%
+  \ifnum\thetikzumlCallEndFragmentNum>0%
+    \let\tikzumlCreateCallDTold\tikzumlCreateCallDT%
+    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCreateCallDTold}%
+    \edef\tikzumlCreateCallDT{\pgfmathresult}%
+    \addtocounter{tikzumlCallEndFragmentNum}{-1}
+  \fi%
+  \ifnum\thetikzumlFragmentPartNum>0%
+    \let\tikzumlCreateCallDTold\tikzumlCreateCallDT%
+    \pgfmathparse{0.5*\tikzumlFragment@paddingy+\tikzumlCreateCallDTold}%
+    \edef\tikzumlCreateCallDT{\pgfmathresult}%
+  \fi%
+  %
+  % managing parent-child structure
+  \ifnum\thetikzumlCallLevel>0%
+    \let\tikzumlCall@nameold\tikzumlCall@name%
+    \def\tikzumlCall@name{\tikzumlCreateCallName}%
+    \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{\tikzumlCreateCallName}%
+  \fi%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlCreateCall@nodeName{\tikzumlCall@name}}\x%
+  %
+  \draw (\csname tikzumlLastChild@\tikzumlCreateCallSrc@nodeName \endcsname)+(0,-\tikzumlCreateCallDT ex) node[name=st-\tikzumlCreateCall@nodeName, tikzuml activity style] {};%
+  %
+  \xdef\tikzumlCreateCallObjectSrc{st-\tikzumlCreateCall@nodeName}%
+  %
+  \iftikzumlcreatecallNoDDots%
+    \umlobject[x=\tikzumlCreateCallX, stereo=\tikzumlCreateCallStereo, class=\tikzumlCreateCallClass, draw=\tikzumlCreateCallObjectDrawColor, fill=\tikzumlCreateCallObjectFillColor, text=\tikzumlCreateCallObjectTextColor, no ddots]{#3}%
+  \else
+    \umlobject[x=\tikzumlCreateCallX, stereo=\tikzumlCreateCallStereo, class=\tikzumlCreateCallClass, draw=\tikzumlCreateCallObjectDrawColor, fill=\tikzumlCreateCallObjectFillColor, text=\tikzumlCreateCallObjectTextColor]{#3}%
+  \fi
+  %
+  \draw (\csname tikzumlLastChild@\tikzumlCreateCallSrc@nodeName \endcsname |- #3)+(0,-0.5*\tikzumlCreateCallDT 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, \tikzumlCreateCallDrawColor] (st-\tikzumlCreateCall@nodeName) -- (#3) node[midway, above, font=\tikzumlDefaultFont, text=\tikzumlCreateCallTextColor, name=\tikzumlCreateCall@nodeName-op] {create};%
+  \end{pgfonlayer}%
+  %
+  \ifnum\thetikzumlCallLevel=0%
+    \begin{pgfonlayer}{activity}%
+    \draw[draw=\tikzumlCreateCallDrawColor, fill=\tikzumlCreateCallFillColor] (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=\tikzumlDefaultDrawColor, -]%
+%
+\newcounter{tikzumlComponentLevel}%
+\newcounter{tikzumlComponentSubComponentNum}%
+\newcounter{tikzumlConnectorNum}%
+\setcounter{tikzumlConnectorNum}{1}%
+%
+\newif\iftikzumlcomponentWithoutCoords%
+%
+\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=\tikzumlDefaultX, y/.initial=\tikzumlDefaultX, width/.initial=\tikzumlComponentDefaultWidth, name/.initial={},%
+                                   draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlComponentDefaultFillColor,%
+                                   text/.initial=\tikzumlDefaultTextColor, style/.style={},%
+                                   no coords/.is if=tikzumlcomponentWithoutCoords,%
+                                   no coords=false,%
+                                   .unknown/.code={%
+                                     \let\keyname=\pgfkeyscurrentname%
+                                     \let\keyvalue=\pgfkeyscurrentvalue%
+                                     \ifthenelse{\equal{\keyname}{above}\OR%
+                                                 \equal{\keyname}{left}\OR%
+                                                 \equal{\keyname}{below}\OR%
+                                                 \equal{\keyname}{right}\OR%
+                                                 \equal{\keyname}{above left}\OR%
+                                                 \equal{\keyname}{above right}\OR%
+                                                 \equal{\keyname}{below left}\OR%
+                                                 \equal{\keyname}{below right}}{%
+                                       \IfSubStr{\keyvalue}{ of }{%
+                                         \pgfkeys{/tikzuml/component/.cd, no coords}%
+                                       }{}%
+                                     }{}%
+                                     \ifx\keyvalue\pgfkeysnovalue%
+                                       \pgfkeys{/tikzuml/component/.cd, style/.append style/.expand once={\keyname}}%
+                                     \else%
+                                       \pgfkeys{/tikzuml/component/.cd, style/.append style/.expand twice={\expandafter\keyname\expandafter=\keyvalue}}%
+                                     \fi%
+                                     %\errmessage{TIKZUML ERROR : in umlcomponent, invalid option \keyname}%
+                                   }%
+  }%
+  \pgfkeys{/tikzuml/component/.cd, #1}%
+  \pgfkeys{/tikzuml/component/.cd, x/.get=\tikzumlComponentXShift, y/.get=\tikzumlComponentYShift,%
+                                   width/.get=\tikzumlComponentMinimumWidth, name/.get=\tikzumlComponentName,%
+                                   draw/.get=\tikzumlComponentDrawColor, fill/.get=\tikzumlComponentFillColor,%
+                                   text/.get=\tikzumlComponentTextColor%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlComponentName}{}}{%
+    \edef\tikzumlComponent@name{#2}%
+  }{%
+    \edef\tikzumlComponent@name{\tikzumlComponentName}%
+  }%
+  %
+  \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=\tikzumlComponentXShift cm, yshift=\tikzumlComponentYShift 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%
+    \iftikzumlcomponentWithoutCoords%
+      \node[inner ysep=0.5ex, minimum width=\tikzumlComponentMinimumWidth, font=\tikzumlDefaultFont, /tikzuml/component/style] (\tikzumlComponent@nodeName-root)  {\phantom{\tikzumlComponent@nodeName}};%
+    \else%
+      \node[inner ysep=0.5ex, minimum width=\tikzumlComponentMinimumWidth, font=\tikzumlDefaultFont, /tikzuml/component/style] (\tikzumlComponent@nodeName-root) at (0,0) {\phantom{\tikzumlComponent@nodeName}};%
+    \fi%
+    \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=\tikzumlDefaultFont, fit = \csname tikzumlComponentFit\tikzumlComponent@parent @@\tikzumlComponent@fitname\endcsname] (\tikzumlComponent@nodeName-body) {};%
+  \node[above, font=\tikzumlDefaultFont] (\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=\tikzumlComponentDrawColor, fill=\tikzumlComponentFillColor, font=\tikzumlDefaultFont} };%
+  \node[draw=\tikzumlComponentDrawColor, fill=\tikzumlComponentFillColor, name=\tikzumlComponent@nodeName, /tikzuml/component/style, fit=(\tikzumlComponent@nodeName-body) (\tikzumlComponent@nodeName-captiontmp)] {};%
+  \node[font=\tikzumlDefaultFont] (\tikzumlComponent@nodeName-caption) at (\tikzumlComponent@nodeName-captiontmp) {\tikzumlComponent@caption};%
+  \draw (\tikzumlComponent@nodeName-caption.north -| \tikzumlComponent@nodeName.east) node[font=\tikzumlDefaultFont, xshift=-1ex, below=-1ex, name=\tikzumlComponent@nodeName-logo] {\picturedcomponent{draw=\tikzumlComponentDrawColor, fill=\tikzumlComponentFillColor, font=\tikzumlDefaultFont} };%
+  \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 component
+\newcommand{\umlbasiccomponent}[2][]{\begin{umlcomponent}[#1]{#2} \end{umlcomponent}}%
+%
+\newcommand{\umlrequiredinterface}[2][]{%
+  \def\tikzumlInterfaceWithPort{tikzumlFalse}%
+  \pgfkeys{/tikzuml/requiredinterfacerelation/.cd, interface/.initial={}, distance/.initial=\tikzumlRequiredInterfaceDefaultDistance,%
+                                                   name/.initial=tikzumlEmpty, width/.initial=\tikzumlRequiredInterfaceDefaultWidth,%
+                                                   padding/.initial=\tikzumlRequiredInterfaceDefaultPadding,%
+                                                   draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlComponentDefaultFillColor,%
+                                                   .unknown/.code={%
+                                                     \let\keyname=\pgfkeyscurrentname%
+                                                     \let\keyvalue=\pgfkeyscurrentvalue%
+                                                     \ifthenelse{\equal{\keyname}{with port}}{%
+                                                       \def\tikzumlInterfaceWithPort{tikzumlTrue}%
+                                                     }{}%
+                                                   }%
+  }%
+  \pgfkeys{/tikzuml/requiredinterfacerelation/.cd, #1}%
+  \pgfkeys{/tikzuml/requiredinterfacerelation/.cd, interface/.get=\tikzumlRequiredInterfaceLabel,%
+                                                   distance/.get=\tikzumlRequiredInterfaceDistance,%
+                                                   name/.get=\tikzumlRequiredInterfaceName,%
+                                                   width/.get=\tikzumlRequiredInterfaceWidth,%
+                                                   padding/.get=\tikzumlRequiredInterfacePadding,%
+                                                   draw/.get=\tikzumlRequiredInterfaceDrawColor,%
+                                                   fill/.get=\tikzumlRequiredInterfaceFillColor%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlRequiredInterfaceName}{tikzumlEmpty}}{%
+    \edef\tikzumlRequiredInterface@interfacename{#2-east-interface}%
+    \edef\tikzumlRequiredInterface@portname{#2-east-port}%
+    \edef\tikzumlRequiredInterface@paddingname{#2-east-padding}%
+  }{%
+    \edef\tikzumlRequiredInterface@interfacename{\tikzumlRequiredInterfaceName}%
+    \edef\tikzumlRequiredInterface@portname{\tikzumlRequiredInterfaceName-port}%
+    \edef\tikzumlRequiredInterface@paddingname{\tikzumlRequiredInterfaceName-padding}%
+  }%
+  %
+  \edef\tikzumlRequiredInterface@name{#2}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlRequiredInterface@nodeName{\tikzumlRequiredInterface@name}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlRequiredInterface@interfacenodeName{\tikzumlRequiredInterface@interfacename}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlRequiredInterface@portnodeName{\tikzumlRequiredInterface@portname}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlRequiredInterface@paddingnodeName{\tikzumlRequiredInterface@paddingname}}\x%
+  %
+  \ifthenelse{\equal{\tikzumlInterfaceWithPort}{tikzumlTrue}}{%
+    \node[inner sep=0.5*\tikzumlRequiredInterfaceWidth, rectangle, draw=\tikzumlRequiredInterfaceDrawColor, fill=\tikzumlRequiredInterfaceFillColor] (\tikzumlRequiredInterface@portnodeName) 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@interfacenodeName-tmp] {};%
+  \clip (\tikzumlRequiredInterface@interfacenodeName-tmp.north) rectangle (\tikzumlRequiredInterface@interfacenodeName-tmp.south -| \tikzumlRequiredInterface@interfacenodeName-tmp.west);%
+  \node[inner sep=0, text width=\tikzumlRequiredInterfaceWidth, circle, draw=\tikzumlRequiredInterfaceDrawColor] (\tikzumlRequiredInterface@interfacenodeName) at (\tikzumlRequiredInterface@interfacenodeName-tmp) {};%
+  \end{scope}%
+  \node[above] at (\tikzumlRequiredInterface@interfacenodeName.north) {\tikzumlRequiredInterfaceLabel};%
+  %
+  \umlrelation[style={tikzuml connector style}, #1]{\tikzumlRequiredInterface@portnodeName}{\tikzumlRequiredInterface@interfacenodeName}%
+  %
+  \draw (\tikzumlRequiredInterface@interfacenodeName)+(\tikzumlRequiredInterfacePadding,0) node[name=\tikzumlRequiredInterface@paddingnodeName] {};%
+  %
+  % 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@paddingnodeName) (\tikzumlRequiredInterface@portnodeName) }%
+  \fi%
+}%
+%
+\newcommand{\umlprovidedinterface}[2][]{%
+  \def\tikzumlInterfaceWithPort{tikzumlFalse}%
+  \pgfkeys{/tikzuml/providedinterfacerelation/.cd, interface/.initial={}, distance/.initial=\tikzumlProvidedInterfaceDefaultDistance,%
+                                                   name/.initial=tikzumlEmpty, width/.initial=\tikzumlProvidedInterfaceDefaultWidth,%
+                                                   padding/.initial=\tikzumlProvidedInterfaceDefaultPadding,%
+                                                   draw/.initial=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlComponentDefaultFillColor,%
+                                                   .unknown/.code={%
+                                                     \let\keyname=\pgfkeyscurrentname%
+                                                     \let\keyvalue=\pgfkeyscurrentvalue%
+                                                     \ifthenelse{\equal{\keyname}{with port}}{%
+                                                       \def\tikzumlInterfaceWithPort{tikzumlTrue}%
+                                                     }{}%
+                                                   }%
+  }%
+  \pgfkeys{/tikzuml/providedinterfacerelation/.cd, #1}%
+  \pgfkeys{/tikzuml/providedinterfacerelation/.cd, interface/.get=\tikzumlProvidedInterfaceLabel,%
+                                                   distance/.get=\tikzumlProvidedInterfaceDistance,%
+                                                   name/.get=\tikzumlProvidedInterfaceName,%
+                                                   width/.get=\tikzumlProvidedInterfaceWidth,%
+                                                   padding/.get=\tikzumlProvidedInterfacePadding,%
+                                                   draw/.get=\tikzumlProvidedInterfaceDrawColor,%
+                                                   fill/.get=\tikzumlProvidedInterfaceFillColor%
+  }%
+  %
+  \ifthenelse{\equal{\tikzumlProvidedInterfaceName}{tikzumlEmpty}}{%
+    \edef\tikzumlProvidedInterface@interfacename{#2-west-interface}%
+    \edef\tikzumlProvidedInterface@portname{#2-west-port}%
+    \edef\tikzumlProvidedInterface@paddingname{#2-west-padding}%
+  }{%
+    \edef\tikzumlProvidedInterface@interfacename{\tikzumlProvidedInterfaceName}%
+    \edef\tikzumlProvidedInterface@portname{\tikzumlProvidedInterfaceName-port}%
+    \edef\tikzumlProvidedInterface@paddingname{\tikzumlProvidedInterfaceName-padding}%
+  }%
+  %
+  \edef\tikzumlProvidedInterface@name{#2}%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlProvidedInterface@nodeName{\tikzumlProvidedInterface@name}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlProvidedInterface@interfacenodeName{\tikzumlProvidedInterface@interfacename}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlProvidedInterface@portnodeName{\tikzumlProvidedInterface@portname}}\x%
+  %
+  \begingroup%
+    \def\_{_}\edef\x{\endgroup%
+      \def\noexpand\tikzumlProvidedInterface@paddingnodeName{\tikzumlProvidedInterface@paddingname}}\x%
+  %
+  \ifthenelse{\equal{\tikzumlInterfaceWithPort}{tikzumlTrue}}{%
+    \node[inner sep=0.5*\tikzumlProvidedInterfaceWidth, rectangle, draw=\tikzumlProvidedInterfaceDrawColor, fill=\tikzumlProvidedInterfaceFillColor] (\tikzumlProvidedInterface@portnodeName) at (\tikzumlProvidedInterface@nodeName.west) {};%
+  }{%
+    \node[inner sep=0] (\tikzumlProvidedInterface@portnodeName) at (\tikzumlProvidedInterface@nodeName.west) {};%
+  }%
+  \draw (\tikzumlProvidedInterface@nodeName)+(-\tikzumlProvidedInterfaceDistance,0) node[inner sep=0, text width=\tikzumlProvidedInterfaceWidth, circle, draw=\tikzumlProvidedInterfaceDrawColor, fill=\tikzumlProvidedInterfaceFillColor, name=\tikzumlProvidedInterface@interfacenodeName] {};%
+  \node[above] at (\tikzumlProvidedInterface@interfacenodeName.north)
+ {\tikzumlProvidedInterfaceLabel};%
+  %
+  \umlrelation[style={tikzuml connector style}, #1]{\tikzumlProvidedInterface@portnodeName}{\tikzumlProvidedInterface@interfacenodeName}%
+  %
+  \draw (\tikzumlProvidedInterface@interfacenodeName)+(-\tikzumlProvidedInterfacePadding,0) node[name=\tikzumlProvidedInterface@paddingnodeName] {};%
+  %
+  % 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@paddingnodeName) (\tikzumlProvidedInterface@portnodeName) }%
+      \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=\tikzumlAssemblyConnectorDrawColor, fill=\tikzumlAssemblyConnectorFillColor] (\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=\tikzumlAssemblyConnectorDrawColor, fill=\tikzumlAssemblyConnectorFillColor] (\tikzuml@ACInterface@nodeName-ic) at (\tikzuml@AC@xic,\tikzuml@AC@yic) {};%
+  \end{scope}%
+  \node[above, font=\tikzumlDefaultFont] 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=\tikzumlDefaultDrawColor,%
+                                                   fill assembly connector/.initial=\tikzumlAssemblyConnectorDefaultFillColor,%
+                                                   fill port/.initial=\tikzumlPortDefaultFillColor,%
+                                                   .unknown/.code={%
+                                                     \let\keyname=\pgfkeyscurrentname%
+                                                     \let\keyvalue=\pgfkeyscurrentvalue%
+                                                     \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=\tikzumlAssemblyConnectorStartAnchorTmp,%
+                                                   anchor2/.get=\tikzumlAssemblyConnectorEndAnchorTmp,%
+                                                   draw/.get=\tikzumlAssemblyConnectorDrawColor,%
+                                                   fill assembly connector/.get=\tikzumlAssemblyConnectorFillColor,%
+                                                   fill port/.get=\tikzumlAssemblyConnectorPortFillColor%
+  }%
+  %
+  \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{\tikzumlAssemblyConnectorStartAnchorTmp}{}}{%
+  }{%
+    \def\tikzumlAssemblyConnectorStartAnchor{\tikzumlAssemblyConnectorStartAnchorTmp}%
+  }%
+  \ifthenelse{\equal{\tikzumlAssemblyConnectorEndAnchorTmp}{}}{%
+  }{%
+    \def\tikzumlAssemblyConnectorEndAnchor{\tikzumlAssemblyConnectorEndAnchorTmp}%
+  }%
+  %
+  \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=\tikzumlAssemblyConnectorDrawColor, fill=\tikzumlAssemblyConnectorPortFillColor] (\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port) at (\tikzumlAssemblyConnectorStart@nodeName-\tikzumlAssemblyConnectorLabel@nodeName-port-tmp) {};%
+    \node[inner sep=0.5*\tikzumlAssemblyConnectorWidth, rectangle, draw=\tikzumlAssemblyConnectorDrawColor, fill=\tikzumlAssemblyConnectorPortFillColor] (\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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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=\tikzumlDefaultDrawColor, fill/.initial=\tikzumlPortDefaultFillColor,%
+                              width/.initial=\tikzumlPortDefaultWidth,%
+                              .unknown/.code={%
+                                \let\keyname=\pgfkeyscurrentname%
+                                \let\keyvalue=\pgfkeyscurrentvalue%
+                                \errmessage{TIKZUML ERROR : in umlport forbidden option \keyname}%
+                              }%
+  }%
+  \pgfkeys{/tikzuml/port/.cd, #1}%
+  \pgfkeys{/tikzuml/port/.cd, width/.get=\tikzumlPortWidth,%
+                              draw/.get=\tikzumlPortDrawColor, fill/.get=\tikzumlPortFillColor}%
+  \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=\tikzumlPortDrawColor, fill=\tikzumlPortFillColor] (\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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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%
+             \let\keyvalue=\pgfkeyscurrentvalue%
+             \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