<?xml version="1.0" encoding="UTF-8"?>

<!-- XIG version 1.0beta by Daniel Volk 2001-->

<!-- The version of the stylesheet is set and as well as the prefix xsl is associated with the XSLT namespace, the prefix xlink is associated with the XLink namespace. -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="www.w3.org/1999/xlink">
	
	
	
	<!-- BEGIN: Definition part of the stylesheet -->
		
	<!-- The output of the stylesheet is set to XML, the character set is defined, and the produced XML code is linked with its DTD. -->
	<xsl:output method="xml" version="1.0" encoding="UTF-8" doctype-system="gxl.dtd" indent="yes"/>

	<!-- Some information for version-checking is stored in variables. -->
	<xsl:variable name="exporting_tool" select="/XMI/XMI.header/XMI.documentation/XMI.exporter/text()"/>
	<xsl:variable name="exporting_tool_version" select="/XMI/XMI.header/XMI.documentation/XMI.exporterVersion/text()"/>
	<xsl:variable name="metamodell" select="/XMI/XMI.header/XMI.metamodel/@xmi.name"/>
	<xsl:variable name="metamodell_version" select="/XMI/XMI.header/XMI.metamodel/@xmi.version"/>
	
	<!-- The ID references of the <<graph>> stereotype extended elements are stored. -->
	<xsl:variable name="stereotyped_graph" select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Extension_Mechanisms.Stereotype/Foundation.Extension_Mechanisms.Stereotype.extendedElement/node()[../../Foundation.Core.ModelElement.name/text()='graph']"/>

	<!-- The ID references of the <<edge>><stereotype extended elements are stored. -->
	<xsl:variable name="stereotyped_edge" select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Extension_Mechanisms.Stereotype/Foundation.Extension_Mechanisms.Stereotype.extendedElement/node()[../../Foundation.Core.ModelElement.name/text()='edge']"/>

	<!-- The ID references of the <<rel>> stereotype extended elements are stored. -->
	<xsl:variable name="stereotyped_rel" select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Extension_Mechanisms.Stereotype/Foundation.Extension_Mechanisms.Stereotype.extendedElement/node()[../../Foundation.Core.ModelElement.name/text()='rel']"/>
	
	<!-- All classes, which are attribute_types, are stored. -->
	<xsl:variable name="attribute_types" select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Core.Class[../Foundation.Core.Class/Foundation.Core.Classifier.feature/Foundation.Core.Attribute/Foundation.Core.StructuralFeature.type/Foundation.Core.Classifier/@xmi.idref = @xmi.id]"/>
	
	<!-- All used attributes are stored. -->
	<xsl:variable name="attributes" select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Core.Class/Foundation.Core.Classifier.feature/Foundation.Core.Attribute"/>
	
	<!-- END: Definition part of the stylesheet -->
	
	

	<!-- BEGIN: Transformation part of the Stylesheet-->
	
	<!-- The template for handling the root node - it is the start of the transformation. -->
	<xsl:template match="/">
				
		<!-- To prevent different problems, which can occur, if the wrong metamodel or wrong version of the properly metamodel is used, these files are not accepted here. -->
		<xsl:choose>
		
			<!-- If the XMI source is derived from the UML Metamodel in version 1.3 the transformation can begin. -->
			<xsl:when test="$metamodell='UML' and $metamodell_version='1.3'">
				
				<!-- But only one or no <<graph>> stereotyped element is allowed; if more are found, the transformation stops. -->
				<xsl:if test="count(($stereotyped_graph)) &gt; '1'">
					<xsl:message terminate="yes">Error: More than one &lt;&lt;graph&gt;&gt; stereotyped element has been found !</xsl:message>
				</xsl:if>
				
				<!-- A comment output into the target tree. -->
				<xsl:comment/>
				<xsl:comment/>
				<xsl:comment>GXL code built by XIG v1.0beta - Daniel Volk 2001</xsl:comment>
				<xsl:comment/>
				<xsl:comment/>
				
				<!-- The first step of the transformation is the creation of the root element. -->
				<xsl:element name="gxl">
					<!-- After that the graph has to be created, which contains the schema information. -->
					<xsl:element name="graph">
					
						<!-- The graph element gets the same ID the XMI code contains for the corresponding Model_Management.Model. -->
						<xsl:attribute name="id"><xsl:value-of select="/XMI/XMI.content/Model_Management.Model/@xmi.id"/></xsl:attribute>
						<!-- Furthermore it is typed as MetaSchema#GraphClass. -->
						<xsl:element name="type">
							<xsl:attribute name="href">MetaSchema#GraphClass</xsl:attribute>
						</xsl:element>
						
						<!-- NOTE -->
						<!-- Due to a problem with the XML processor the namespace prefix "xlink" is left out in the upper type-element. -->
						<!-- It could simply be inserted in front of the reference, e.g. <xsl:attribute name="xlink:href"/>. -->
						<!-- Of course, this could (and should) be done with all type-elements in the same way. -->
						<!-- NOTE -->
						
						<!-- BEGIN: Generic part of the transformation. -->
							
						<!--The first step is GraphClass derived node. -->
						<xsl:element name="node">
							<xsl:choose>
								<!-- If a <<graph>> stereotyped object exists, its ID and name are used. -->
								<xsl:when test="count(($stereotyped_graph)) &gt; '0'">							
									<xsl:attribute name="id">
										<xsl:value-of select="($stereotyped_graph)/@xmi.idref"/>
									</xsl:attribute>
									
									<xsl:element name="type">
										<xsl:attribute name="href">MetaSchema#GraphClass</xsl:attribute>
									</xsl:element>
					
									<xsl:element name="attr">
										<xsl:attribute name="name">name</xsl:attribute>
										<xsl:element name="string">
											
											<!-- If the name attribute is empty, the ID is set as the name. -->
											<xsl:choose>
												<xsl:when test="not((/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Core.Class/Foundation.Core.ModelElement.name[../@xmi.id=($stereotyped_graph)/@xmi.idref]) = '')">
													<xsl:value-of select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Core.Class/Foundation.Core.ModelElement.name[../@xmi.id=($stereotyped_graph)/@xmi.idref]"/>
												</xsl:when>
												<xsl:otherwise>
													<xsl:value-of select="($stereotyped_graph)/@xmi.idref"/>
												</xsl:otherwise>
											</xsl:choose>
											
										</xsl:element>
									</xsl:element>							
								</xsl:when>
								
								<!-- Otherwise, its ID is set to "xmi.0" and its name attribute is empty. -->
								<xsl:otherwise>
									<xsl:attribute name="id">xmi.0</xsl:attribute>
										
									<xsl:element name="type">
										<xsl:attribute name="href">MetaSchema#GraphClass</xsl:attribute>
									</xsl:element>
									
									<!-- Because no name is available, the ID is set as the name. -->
									<xsl:element name="attr">
										<xsl:attribute name="name">name</xsl:attribute>
										<xsl:element name="string">xmi.0</xsl:element>
									</xsl:element>
								</xsl:otherwise>
							</xsl:choose>
						</xsl:element>
						
						<!-- Second are the NodeClass derived nodes. -->
						<!-- All classes are selected for transformation, which are neither stereotyped <<graph>>, <<edge>>, or <<rel>>, nor attribute type classes. -->
						<xsl:apply-templates select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Core.Class[((count(($stereotyped_graph)) = '0') or (@xmi.id != ($stereotyped_graph)/@xmi.idref)) and ((count(($stereotyped_edge)) = '0') or (@xmi.id != ($stereotyped_edge)/@xmi.idref)) and ((count(($stereotyped_rel)) = '0') or (@xmi.id != ($stereotyped_rel)/@xmi.idref)) and not(@xmi.id = ($attribute_types)/@xmi.id)]" mode="node"/>
						
						<!-- Third are EdgeClass derived nodes, which are visualized as associations. -->
						<!-- All associations are selected for transformation, which do not link any <<graph>>, <<edge>>, or <<rel>> stereotyped class. -->
						<xsl:apply-templates select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Core.Association[not(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($stereotyped_graph)/@xmi.idref) and not(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($stereotyped_edge)/@xmi.idref) and  not(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($stereotyped_rel)/@xmi.idref)]" mode="edge"/>	
						
						<!-- Fourth are EdgeClass derived nodes, which are vizualized as <<edge>> stereotyped classes with two adjacent associations. -->
						<!-- Only <<edge>> stereotyped classes are selected for transformation. -->
						<xsl:apply-templates select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Core.Class[@xmi.id = ($stereotyped_edge)/@xmi.idref]" mode="extended_edge"/>
						
						<!-- Fifth are RelationClass derived nodes, which are vizualized as <<rel>> stereotyped classes with adjacent associations. -->
						<!-- Only <<rel>> stereotyped classes are selected for transformation.  -->
						<xsl:apply-templates select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Core.Class[@xmi.id = ($stereotyped_rel)/@xmi.idref]" mode="relation"/>

						<!-- Sixth are the used attributes. -->
						<!-- The attributes as origin, the attribute model is built up. -->
						<xsl:apply-templates select="($attributes)" mode="attributes"/>										
						
						<!-- END: Generic part of the transformation. -->
						
							
					</xsl:element>
				</xsl:element>
			</xsl:when>
			
			<!-- This message will be put out, if the used file is derived from a wrong metamodel. -->
			<xsl:when test="$metamodell!='UML'">
				<xsl:message terminate="yes">Error: Given XMI file is not derived from the UML Metamodel !</xsl:message>
			</xsl:when>
			
			<!-- This message will be put out, if the used file is derived from the UML Metamodel, but has not the right version. -->
			<xsl:when test="$metamodell_version!='1.3'">
				<xsl:message terminate="yes">Error: Given XMI file is not derived from version 1.3 of the UML Metamodel !</xsl:message>
			</xsl:when>
			
			<!-- This message will be put out, if other problems occur. -->
			<xsl:otherwise>
				<xsl:message terminate="yes">Error: Translation of given XMI file is impossible !</xsl:message>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	
	
	<!-- The template for creating the NodeClass derived nodes. -->
	<xsl:template match="Foundation.Core.Class" mode="node">
	
		<!-- The node object is created and ID and name are set as in the corresponding class. -->
		<xsl:element name="node">
			<xsl:attribute name="id"><xsl:value-of select="@xmi.id"/></xsl:attribute>
				
			<xsl:element name="type">
				<xsl:attribute name="href">MetaSchema#NodeClass</xsl:attribute>
			</xsl:element>
					
			<xsl:element name="attr">
				<xsl:attribute name="name">name</xsl:attribute>
				<xsl:element name="string">
					
					<!-- If the name attribute is empty, the ID is set as the name. -->
					<xsl:choose>
						<xsl:when test="not((Foundation.Core.ModelElement.name) = '')">
							<xsl:value-of select="Foundation.Core.ModelElement.name"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="@xmi.id"/>
						</xsl:otherwise>
					</xsl:choose>
					
				</xsl:element>
			</xsl:element>
		</xsl:element>
		
		<!-- Then the contains association to the graph node is created. -->
		<xsl:element name="edge">
			<xsl:choose>
				<xsl:when test="count(($stereotyped_graph)) &gt; '0'">
					<xsl:attribute name="from">
						<xsl:value-of select="($stereotyped_graph)/@xmi.idref"/>
					</xsl:attribute>
				</xsl:when>
				<xsl:otherwise>
					<xsl:attribute name="from">xmi.0</xsl:attribute>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:attribute name="to">
				<xsl:value-of select="@xmi.id"/>
			</xsl:attribute>
			
			<xsl:element name="type">
				<xsl:attribute name="href">MetaSchema#contains</xsl:attribute>
			</xsl:element>
		</xsl:element>
	</xsl:template>
	
	
	
	<!-- The template for creating EdgeClass derived nodes, which are visualized as associations. -->
	<xsl:template match="Foundation.Core.Association" mode="edge">
		
		<!-- The EdgeClass derived node is created and ID and name are set as in the corresponding association. -->
		<xsl:element name="node">
			<xsl:attribute name="id"><xsl:value-of select="@xmi.id"/></xsl:attribute>
				
			<xsl:element name="type">
				<xsl:attribute name="href">MetaSchema#EdgeClass</xsl:attribute>
			</xsl:element>
				
			<xsl:element name="attr">
				<xsl:attribute name="name">name</xsl:attribute>
				<xsl:element name="string">
								
				<!-- If the name attribute is empty, the ID is set as the name. -->
					<xsl:choose>
						<xsl:when test="not((Foundation.Core.ModelElement.name) = '')">
							<xsl:value-of select="Foundation.Core.ModelElement.name"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="@xmi.id"/>
						</xsl:otherwise>
					</xsl:choose>	
				
				</xsl:element>
			</xsl:element>
			
			<!-- The isDirected attribute is set. -->
			<xsl:choose>
				<!-- If both association ends are navigable, the association is not directed. -->
				<xsl:when test="count(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='true']) = '2'">
					<xsl:element name="attr">
						<xsl:attribute name="name">isDirected</xsl:attribute>
						<xsl:element name="bool">false</xsl:element>
					</xsl:element>
				</xsl:when>
				<!-- If only one association ends are navigable, the association is directed. -->
				<xsl:when test="count(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='true']) = '1'">
					<xsl:element name="attr">
						<xsl:attribute name="name">isDirected</xsl:attribute>
						<xsl:element name="bool">true</xsl:element>
					</xsl:element>
				</xsl:when>
				<!-- In any other case (both association ends are not navigable), the association is illegal. -->
				<xsl:otherwise>
					<xsl:message terminate="yes">Error: An association is neither directed, nor undirected !</xsl:message>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:element>
		
		<!-- The from- and to-edges are created. -->
		<xsl:choose>
			<!-- If the edge object is directed, the from- and to-edges have to follow navigability of the object. -->
			<!-- In this case exactly on association end is navigable. -->
			<xsl:when test="count(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='true']) = '1'">			
				<xsl:element name="edge">
					<xsl:attribute name="from">
						<xsl:value-of select="@xmi.id"/>
					</xsl:attribute>
					
					<!-- The edge derived ":from" links to the ID, the not navigable association end references as its target. -->
					<xsl:attribute name="to">
						<xsl:value-of select="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='false']/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref"/>
					</xsl:attribute>
							
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#from</xsl:attribute>
					</xsl:element>
					
					<!-- If the multiplicity of the association end differs from "1x1", the attribute limits is inserted. -->
					<xsl:if test="not((Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='false']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower = '1')  and (Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='false']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper = '1'))">
						<xsl:element name="attr">
							<xsl:attribute name="name">limits</xsl:attribute>
							<xsl:element name="tup">
								<xsl:element name="int">
									<xsl:value-of select="(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='false']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower)"/>
								</xsl:element>
								<xsl:element name="int">
									<xsl:value-of select="(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='false']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper)"/>
								</xsl:element>
							</xsl:element>						
						</xsl:element>
					</xsl:if>
					
					<!-- If the association end is ordered, the bool attribute isOrdered is inserted. -->
					<xsl:if test="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='false']/Foundation.Core.AssociationEnd.ordering/@xmi.value = 'ordered'">
						<xsl:element name="attr">
							<xsl:attribute name="name">isOrdered</xsl:attribute>
							<xsl:element name="bool">true</xsl:element>
						</xsl:element>
					</xsl:if>
				</xsl:element>
				
				<xsl:element name="edge">
					<xsl:attribute name="from">
						<xsl:value-of select="@xmi.id"/>
					</xsl:attribute>
					
					<!-- The edge derived ":to" links to the ID, the navigable association end references as its target. -->
					<xsl:attribute name="to">
						<xsl:value-of select="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='true']/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref"/>
					</xsl:attribute>
			
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#to</xsl:attribute>
					</xsl:element>
					
					<!-- If the multiplicity of the association end differs from "1x1", the attribute limits is inserted. -->
					<xsl:if test="not((Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='true']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower = '1')  and (Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='true']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper = '1'))">
						<xsl:element name="attr">
							<xsl:attribute name="name">limits</xsl:attribute>
							<xsl:element name="tup">
								<xsl:element name="int">
									<xsl:value-of select="(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='true']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower)"/>
								</xsl:element>
								<xsl:element name="int">
									<xsl:value-of select="(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='true']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper)"/>
								</xsl:element>
							</xsl:element>						
						</xsl:element>						
					</xsl:if>
					
					<!-- If the association end is ordered, the bool attribute isOrdered is inserted. -->
					<xsl:if test="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value='false']/Foundation.Core.AssociationEnd.ordering/@xmi.value = 'ordered'">
						<xsl:element name="attr">
							<xsl:attribute name="name">isOrdered</xsl:attribute>
							<xsl:element name="bool">true</xsl:element>
						</xsl:element>
					</xsl:if>
				</xsl:element>
			</xsl:when>
			
			<!-- Otherwise, it is unimport, which edge is linked with which node. -->
			<xsl:otherwise>
				<xsl:element name="edge">
					<xsl:attribute name="from">
						<xsl:value-of select="@xmi.id"/>
					</xsl:attribute>
					
					<!-- The edge derived ":from" links to an ID, one of the association ends references as its target. -->
					<xsl:attribute name="to">
						<xsl:value-of select="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[1]/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref"/>
					</xsl:attribute>
			
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#from</xsl:attribute>
					</xsl:element>

					<!-- If the multiplicity of the association end differs from "1x1", the attribute limits is inserted. -->
					<xsl:if test="not((Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[1]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower = '1')  and (Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[1]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper = '1'))">
						<xsl:element name="attr">
							<xsl:attribute name="name">limits</xsl:attribute>
							<xsl:element name="tup">
								<xsl:element name="int">
									<xsl:value-of select="(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[1]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower)"/>
								</xsl:element>
								<xsl:element name="int">
									<xsl:value-of select="(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[1]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper)"/>
								</xsl:element>
							</xsl:element>						
						</xsl:element>				
					</xsl:if>
					
					<!-- If the association end is ordered, the bool attribute isOrdered is inserted. -->
					<xsl:if test="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[1]/Foundation.Core.AssociationEnd.ordering/@xmi.value = 'ordered'">
						<xsl:element name="attr">
							<xsl:attribute name="name">isOrdered</xsl:attribute>
							<xsl:element name="bool">true</xsl:element>
						</xsl:element>
					</xsl:if>
				</xsl:element>
		
				<xsl:element name="edge">
					<xsl:attribute name="from">
						<xsl:value-of select="@xmi.id"/>
					</xsl:attribute>
					
					<!-- The edge derived ":to" links to the ID, the not navigable association end references as its target. -->
					<xsl:attribute name="to">
						<xsl:value-of select="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[2]/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref"/>
					</xsl:attribute>
			
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#to</xsl:attribute>
					</xsl:element>

					<!-- If the multiplicity of the association end differs from "1x1", the attribute limits is inserted. -->
					<xsl:if test="not((Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[2]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower = '1')  and (Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[2]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper = '1'))">
						<xsl:element name="attr">
							<xsl:attribute name="name">limits</xsl:attribute>
							<xsl:element name="tup">
								<xsl:element name="int">
									<xsl:value-of select="(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[2]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower)"/>
								</xsl:element>
								<xsl:element name="int">
									<xsl:value-of select="(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[2]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper)"/>
								</xsl:element>
							</xsl:element>						
						</xsl:element>						
					</xsl:if>

					<!-- If the association end is ordered, the bool attribute isOrdered is inserted. -->
					<xsl:if test="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[2]/Foundation.Core.AssociationEnd.ordering/@xmi.value = 'ordered'">
						<xsl:element name="attr">
							<xsl:attribute name="name">isOrdered</xsl:attribute>
							<xsl:element name="bool">true</xsl:element>
						</xsl:element>
					</xsl:if>
				</xsl:element>
			</xsl:otherwise>
		</xsl:choose>
				
		<!-- Then the contains edge to the graph node is created. -->
		<xsl:element name="edge">
			<xsl:choose>
				<xsl:when test="count(($stereotyped_graph)) &gt; '0'">
					<xsl:attribute name="from">
						<xsl:value-of select="($stereotyped_graph)/@xmi.idref"/>
					</xsl:attribute>
				</xsl:when>
				<xsl:otherwise>
					<xsl:attribute name="from">xmi.0</xsl:attribute>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:attribute name="to">
				<xsl:value-of select="@xmi.id"/>
			</xsl:attribute>
			
			<xsl:element name="type">
				<xsl:attribute name="href">MetaSchema#contains</xsl:attribute>
			</xsl:element>
		</xsl:element>
	</xsl:template>
	
	
	
	<!-- The template for creating EdgeClass derived nodes, which are visualized as a node, combined with associations. -->
	<xsl:template match="Foundation.Core.Class" mode="extended_edge">
		
		<!-- The ID of the class is stored.-->
		<xsl:variable name="class_id" select="@xmi.id"/>
		
		<!-- All association ends, which belong to the class, are stored.-->
		<xsl:variable name="association_ends" select="../Foundation.Core.Association[Foundation.Core.Association.connection/Foundation.Core.AssociationEnd/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)]/Foundation.Core.Association.connection/Foundation.Core.AssociationEnd"/>
		
		<!-- Only two adjacent associations are allowed, which must be navigable in the following ways: ->[]->, <-[]<-, or -[]- -->
		<xsl:choose>
			<xsl:when test="(count($association_ends) = '4') and ((count(($association_ends)[Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true']) = '4') or ((count(($association_ends)[Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true']) = '2') and (count(($association_ends)[(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true')]) = '1')))">
				
				<!-- The node object is created and ID and name are set as in the corresponding class. -->
				<xsl:element name="node">
					<xsl:attribute name="id"><xsl:value-of select="@xmi.id"/></xsl:attribute>
				
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#EdgeClass</xsl:attribute>
					</xsl:element>
				
					<xsl:element name="attr">
						<xsl:attribute name="name">name</xsl:attribute>
						<xsl:element name="string">		
						
							<!-- If the name attribute is empty, the ID is set as the name. -->
							<xsl:choose>
								<xsl:when test="not((Foundation.Core.ModelElement.name) = '')">
									<xsl:value-of select="Foundation.Core.ModelElement.name"/>
								</xsl:when>
								<xsl:otherwise>
									<xsl:value-of select="@xmi.id"/>
								</xsl:otherwise>
							</xsl:choose>
	
						</xsl:element>
					</xsl:element>
				
				
					<!-- The isDirected attribute is set. -->
					<xsl:choose>
						<!-- The association is undirected when all association ends are navigable. -->
						<xsl:when test="count(($association_ends)[Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true']) = '4'">
							<xsl:element name="attr">
								<xsl:attribute name="name">isDirected</xsl:attribute>
								<xsl:element name="bool">false</xsl:element>
							</xsl:element>
						</xsl:when>
						<!-- In all other valid cases it is directed. -->
						<xsl:otherwise>
							<xsl:element name="attr">
								<xsl:attribute name="name">isDirected</xsl:attribute>
								<xsl:element name="bool">true</xsl:element>
							</xsl:element>
						</xsl:otherwise>
					</xsl:choose>
				
				</xsl:element>
			</xsl:when>
			
			<!-- Otherwise, the <<edge>> derived class has been defined in an illegal way. -->
			<xsl:otherwise>
				<xsl:message terminate="yes">Error: An &lt;&lt;edge&gt;&gt; derived class has more than two connected associations or the navigabilities of the associations are illegal!					</xsl:message>
			</xsl:otherwise>
		</xsl:choose>

		<!-- The from- and to-edges are created. -->
		<xsl:choose>
			<!-- If the edge object is directed, the from- and to-edges have to follow navigability of the object. -->
			<xsl:when test="count(($association_ends)[Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true']) = '2'">	
				
				<xsl:element name="edge">
					<xsl:attribute name="from">
						<xsl:value-of select="@xmi.id"/>
					</xsl:attribute>
					
					<!-- The edge derived ":from" links to an ID, the non navigable association end, which is not linked to the current class, references as its target. -->
					<xsl:attribute name="to">
						<xsl:value-of select="($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'false')]/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref"/>
					</xsl:attribute>
			
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#from</xsl:attribute>
					</xsl:element>

					<!-- If the multiplicity of the association end differs from "1x1", the attribute limits is inserted. -->
					<xsl:if test="not((($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'false')]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower = '1')  and (($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'false')]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper = '1'))">
						<xsl:element name="attr">
							<xsl:attribute name="name">limits</xsl:attribute>
							<xsl:element name="tup">
								<xsl:element name="int">
									<xsl:value-of select="(($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'false')]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower)"/>
								</xsl:element>
								<xsl:element name="int">
									<xsl:value-of select="(($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'false')]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper)"/>
								</xsl:element>
							</xsl:element>						
						</xsl:element>
					</xsl:if>

					<!-- If the association end is ordered, the bool attribute isOrdered is inserted. -->
					<xsl:if test="($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'false')]/Foundation.Core.AssociationEnd.ordering/@xmi.value = 'ordered'">
						<xsl:element name="attr">
							<xsl:attribute name="name">isOrdered</xsl:attribute>
							<xsl:element name="bool">true</xsl:element>
						</xsl:element>
					</xsl:if>
				</xsl:element>
				
				<xsl:element name="edge">
					<xsl:attribute name="from">
						<xsl:value-of select="@xmi.id"/>
					</xsl:attribute>
					
					<!-- The edge derived ":to" links to an ID, the navigable association end, which is not linked to the current class, references as its target. -->
					<xsl:attribute name="to">
						<xsl:value-of select="($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true')]/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref"/>
					</xsl:attribute>
			
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#to</xsl:attribute>
					</xsl:element>

					<!-- If the multiplicity of the association end differs from "1x1", the attribute limits is inserted. -->
					<xsl:if test="not((($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true')]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower = '1')  and (($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true')]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper = '1'))">
						<xsl:element name="attr">
							<xsl:attribute name="name">limits</xsl:attribute>
							<xsl:element name="tup">
								<xsl:element name="int">
									<xsl:value-of select="(($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true')]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower)"/>
								</xsl:element>
								<xsl:element name="int">
									<xsl:value-of select="(($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true')]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper)"/>
								</xsl:element>
							</xsl:element>						
						</xsl:element>	
					</xsl:if>

					<!-- If the association end is ordered, the bool attribute isOrdered is inserted. -->
					<xsl:if test="($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and (Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true')]/Foundation.Core.AssociationEnd.ordering/@xmi.value = 'ordered'">
						<xsl:element name="attr">
							<xsl:attribute name="name">isOrdered</xsl:attribute>
							<xsl:element name="bool">true</xsl:element>
						</xsl:element>
					</xsl:if>
				</xsl:element>
				
			</xsl:when>
			
			<!-- Otherwise, it is unimport, which edge is linked with which node. -->
			<xsl:otherwise>
			
				<xsl:element name="edge">
					<xsl:attribute name="from">
						<xsl:value-of select="@xmi.id"/>
					</xsl:attribute>
					
					<!-- The edge derived ":from" links to an ID, the first association end, which is not linked to the current class, references as its target. -->
					<xsl:attribute name="to">
						<xsl:value-of select="($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &lt; '3']/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref"/>
					</xsl:attribute>
			
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#from</xsl:attribute>
					</xsl:element>

					<!-- If the multiplicity of the association end differs from "1x1", the attribute limits is inserted. -->
					<xsl:if test="not((($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &lt; '3']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower = '1')  and (($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &lt; '3']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper = '1'))">
						<xsl:element name="attr">
							<xsl:attribute name="name">limits</xsl:attribute>
							<xsl:element name="tup">
								<xsl:element name="int">
									<xsl:value-of select="(($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &lt; '3']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower)"/>
								</xsl:element>
								<xsl:element name="int">
									<xsl:value-of select="(($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &lt; '3']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper)"/>
								</xsl:element>
							</xsl:element>						
						</xsl:element>	
					</xsl:if>
					
					<!-- If the association end is ordered, the bool attribute isOrdered is inserted. -->
					<xsl:if test="($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &lt; '3']/Foundation.Core.AssociationEnd.ordering/@xmi.value = 'ordered'">
						<xsl:element name="attr">
							<xsl:attribute name="name">isOrdered</xsl:attribute>
							<xsl:element name="bool">true</xsl:element>
						</xsl:element>
					</xsl:if>
				</xsl:element>
				
				<xsl:element name="edge">
					<xsl:attribute name="from">
						<xsl:value-of select="@xmi.id"/>
					</xsl:attribute>
					
					<!-- The edge derived ":to" links to an ID, the second association end, which is not linked to the current class, references as its target. -->
					<xsl:attribute name="to">
						<xsl:value-of select="($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &gt; '2']/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref"/>
					</xsl:attribute>
			
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#to</xsl:attribute>
					</xsl:element>

					<!-- If the multiplicity of the association end differs from "1x1", the attribute limits is inserted. -->
					<xsl:if test="not((($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &gt; '2']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower = '1')  and (($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &gt; '2']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper = '1'))">
						<xsl:element name="attr">
							<xsl:attribute name="name">limits</xsl:attribute>
							<xsl:element name="tup">
								<xsl:element name="int">
									<xsl:value-of select="(($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &gt; '2']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower)"/>
								</xsl:element>
								<xsl:element name="int">
									<xsl:value-of select="(($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &gt; '2']/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper)"/>
								</xsl:element>
							</xsl:element>						
						</xsl:element>
					</xsl:if>

					<!-- If the association end is ordered, the bool attribute isOrdered is inserted. -->
					<xsl:if test="($association_ends)[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)) and position() &gt; '2']/Foundation.Core.AssociationEnd.ordering/@xmi.value = 'ordered'">
						<xsl:element name="attr">
							<xsl:attribute name="name">isOrdered</xsl:attribute>
							<xsl:element name="bool">true</xsl:element>
						</xsl:element>
					</xsl:if>
				</xsl:element>
				
			</xsl:otherwise>
		</xsl:choose>

		<!-- Then the contains edge to the graph node is created. -->
		<xsl:element name="edge">
			<xsl:choose>
				<xsl:when test="count(($stereotyped_graph)) &gt; '0'">
					<xsl:attribute name="from">
						<xsl:value-of select="($stereotyped_graph)/@xmi.idref"/>
					</xsl:attribute>
				</xsl:when>
				<xsl:otherwise>
					<xsl:attribute name="from">xmi.0</xsl:attribute>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:attribute name="to">
				<xsl:value-of select="@xmi.id"/>
			</xsl:attribute>
			
			<xsl:element name="type">
				<xsl:attribute name="href">MetaSchema#contains</xsl:attribute>
			</xsl:element>
		</xsl:element>
	</xsl:template>


	
	<!-- The template for creating RelationClass derived nodes, which are visualized as a node, combined with associations. -->
	<xsl:template match="Foundation.Core.Class" mode="relation">
		
		<!-- The ID of the class is stored.-->
		<xsl:variable name="class_id" select="@xmi.id"/>
		
		<!-- All associations, which belong to the class, are stored.-->
		<xsl:variable name="associations" select="../Foundation.Core.Association[Foundation.Core.Association.connection/Foundation.Core.AssociationEnd/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)]"/>
		
		<!-- The RelationClass derived node is created and ID and name are set as in the corresponding class. -->
		<xsl:element name="node">
			<xsl:attribute name="id"><xsl:value-of select="@xmi.id"/></xsl:attribute>
				
			<xsl:element name="type">
				<xsl:attribute name="href">MetaSchema#RelationClass</xsl:attribute>
			</xsl:element>
				
			<xsl:element name="attr">
				<xsl:attribute name="name">name</xsl:attribute>
				<xsl:element name="string">
	
					<!-- If the name attribute is empty, the ID is set as the name. -->
					<xsl:choose>
						<xsl:when test="not((Foundation.Core.ModelElement.name) = '')">
							<xsl:value-of select="Foundation.Core.ModelElement.name"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="@xmi.id"/>
						</xsl:otherwise>
					</xsl:choose>

				</xsl:element>
			</xsl:element>
		</xsl:element>
			
		<!-- The advanced structure for every adjacent association is created. -->
		<xsl:for-each select="($associations)">
		
			<!-- The RelationEndClass derived node is created and ID and name are set as in the corresponding association. -->
			<xsl:element name="node">
				<xsl:attribute name="id"><xsl:value-of select="@xmi.id"/></xsl:attribute>
				
				<xsl:element name="type">
					<xsl:attribute name="href">MetaSchema#RelationEndClass</xsl:attribute>
				</xsl:element>
								
				<!-- The association is tested for its validness and the attribute directedTo is set. -->
				<xsl:choose>
					<!-- If both association ends are navigable, the association is undirected. -->
					<xsl:when test="count(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true']) = '2'">
						<xsl:element name="attr">
							<xsl:attribute name="name">directedTo</xsl:attribute>
							<xsl:element name="string">undirected</xsl:element>
						</xsl:element>
					</xsl:when>
					
					<!-- If only one association end is navigable, the association is directed. -->
					<xsl:when test="count(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true']) = '1'">
						
						<xsl:choose>	
							<!-- If the association end is navigable, which references the relation, the tentacle is directed to the relation. -->
							<xsl:when test="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)]/Foundation.Core.AssociationEnd.isNavigable/@xmi.value = 'true'">
								<xsl:element name="attr">
									<xsl:attribute name="name">directedTo</xsl:attribute>
									<xsl:element name="string">relation</xsl:element>
								</xsl:element>
							</xsl:when>
							
							<!-- If the association end is navigable, which references a node, the tentacle is directed to the target. -->
							<xsl:otherwise>
								<xsl:element name="attr">
									<xsl:attribute name="name">directedTo</xsl:attribute>
									<xsl:element name="string">target</xsl:element>
								</xsl:element>
							</xsl:otherwise>
						</xsl:choose>
						
					</xsl:when>
					
					<!-- In any other case, the association is invalid. -->
					<xsl:otherwise>
						<xsl:message terminate="yes">Error: A tentacle is neither directed, nor undirected !</xsl:message>
					</xsl:otherwise>
				</xsl:choose>
								
				<!-- If the proper association end is ordered, the bool attribute isOrderedRelation is inserted. -->
				<xsl:if test="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id)]/Foundation.Core.AssociationEnd.ordering/@xmi.value = 'ordered'">
					<xsl:element name="attr">
						<xsl:attribute name="name">isOrderedRelation</xsl:attribute>
						<xsl:element name="bool">true</xsl:element>
					</xsl:element>
				</xsl:if>
				
			</xsl:element>
		
			<!-- The hasRelationEnd derived edge is created and linked to the RelationClass derived node and the RelationEndClass derived node. -->
			<xsl:element name="edge">
				<xsl:attribute name="from"><xsl:value-of select="($class_id)"/></xsl:attribute>
					
				<xsl:attribute name="to">
					<xsl:value-of select="@xmi.id"/>
				</xsl:attribute>
			
				<xsl:element name="type">
					<xsl:attribute name="href">MetaSchema#hasRelationEnd</xsl:attribute>
				</xsl:element>
			</xsl:element>
			
			<!-- The relatesTo derived edge is created and linked to the RelationEndClass derived node and the NodeClass derived node. -->
			<xsl:element name="edge">
				<xsl:attribute name="from">
					<xsl:value-of select="@xmi.id"/>
				</xsl:attribute>
				
				<!-- The edge derived ":relatesTo" links to the ID of the targeted node. -->
				<xsl:attribute name="to">
					<xsl:value-of select="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id))]/Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref"/>
				</xsl:attribute>
				
				<xsl:element name="type">
					<xsl:attribute name="href">MetaSchema#relatesTo</xsl:attribute>
				</xsl:element>

				<!-- If the multiplicity of the association end differs from "1x1", the attribute limits is inserted. -->
				<xsl:if test="not((Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id))]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower = '1')  and (Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id))]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper = '1'))">

					<xsl:element name="attr">
						<xsl:attribute name="name">limits</xsl:attribute>
						<xsl:element name="tup">
							<xsl:element name="int">
								<xsl:value-of select="(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id))]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.lower)"/>
							</xsl:element>
							<xsl:element name="int">
								<xsl:value-of select="(Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id))]/Foundation.Core.AssociationEnd.multiplicity/Foundation.Data_Types.Multiplicity/Foundation.Data_Types.Multiplicity.range/Foundation.Data_Types.MultiplicityRange/Foundation.Data_Types.MultiplicityRange.upper)"/>
							</xsl:element>
						</xsl:element>						
					</xsl:element>	
				</xsl:if>

				<xsl:element name="attr">
					<xsl:attribute name="name">role</xsl:attribute>
					<xsl:element name="string"><xsl:value-of select="Foundation.Core.ModelElement.name"/></xsl:element>
				</xsl:element>
				
				<!-- If the proper association end is ordered, the bool attribute isOrdered is inserted. -->
				<xsl:if test="Foundation.Core.Association.connection/Foundation.Core.AssociationEnd[not(Foundation.Core.AssociationEnd.type/Foundation.Core.Classifier/@xmi.idref = ($class_id))]/Foundation.Core.AssociationEnd.ordering/@xmi.value = 'ordered'">
					<xsl:element name="attr">
						<xsl:attribute name="name">isOrdered</xsl:attribute>
						<xsl:element name="bool">true</xsl:element>
					</xsl:element>
				</xsl:if>
	
			</xsl:element>			
		</xsl:for-each>

		<!-- Then the contains edge to the graph node is created. -->
		<xsl:element name="edge">
			<xsl:choose>
				<xsl:when test="count(($stereotyped_graph)) &gt; '0'">
					<xsl:attribute name="from">
						<xsl:value-of select="($stereotyped_graph)/@xmi.idref"/>
					</xsl:attribute>
				</xsl:when>
				<xsl:otherwise>
					<xsl:attribute name="from">xmi.0</xsl:attribute>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:attribute name="to">
				<xsl:value-of select="@xmi.id"/>
			</xsl:attribute>
			
			<xsl:element name="type">
				<xsl:attribute name="href">MetaSchema#contains</xsl:attribute>
			</xsl:element>
		</xsl:element>
	</xsl:template>
	
	
	
	<!-- The template for creating AttributeClass derived nodes, attribute type nodes and the corresponding edges. -->
	<xsl:template match="Foundation.Core.Attribute" mode="attributes">
		
		<!-- The ID of the used attribute type is stored.-->
		<xsl:variable name="attribute_type" select="Foundation.Core.StructuralFeature.type/Foundation.Core.Classifier/@xmi.idref"/>
		
		<!-- The AttributeClass derived node is created and ID and name are set as in the corresponding Foundation.Core.Attribute. -->
		<xsl:element name="node">
			<xsl:attribute name="id"><xsl:value-of select="@xmi.id"/></xsl:attribute>
				
			<xsl:element name="type">
				<xsl:attribute name="href">MetaSchema#AttributeClass</xsl:attribute>
			</xsl:element>
				
			<xsl:element name="attr">
				<xsl:attribute name="name">name</xsl:attribute>
				<xsl:element name="string">			
				
					<!-- If the name attribute is empty, the ID is set as the name. -->
					<xsl:choose>
						<xsl:when test="not((Foundation.Core.ModelElement.name) = '')">
							<xsl:value-of select="Foundation.Core.ModelElement.name"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="@xmi.id"/>
						</xsl:otherwise>
					</xsl:choose>
				
				</xsl:element>
			</xsl:element>
		</xsl:element>
		
		<!-- All Foundation.Core.DataTypes are stored. -->
		<xsl:variable name="data_types" select="/XMI/XMI.content/Model_Management.Model/Foundation.Core.Namespace.ownedElement/Foundation.Core.DataType"/>
		
		<!-- The attribute type node is created and ID and name are set. -->
		<xsl:choose>
		
			<!-- At first the atomic value types are translated. -->
		
			<!-- If the name of the attribute is bool, a BoolVal derived node is created.-->
			<xsl:when test="($attribute_types)[@xmi.id = ($attribute_type)]/Foundation.Core.ModelElement.name = 'bool'">
				<xsl:element name="node">
					<xsl:attribute name="id"><xsl:value-of select="concat(@xmi.id, (($attribute_types)[@xmi.id = ($attribute_type)]/@xmi.id))"/></xsl:attribute>
				
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#BoolVal</xsl:attribute>
					</xsl:element>
				</xsl:element>
			</xsl:when>
			
			<!-- If the name of the attribute is float, a FloatVal derived node is created.-->
			<xsl:when test="($data_types)[@xmi.id = ($attribute_type)]/Foundation.Core.ModelElement.name = 'float'">
				<xsl:element name="node">
					<xsl:attribute name="id"><xsl:value-of select="concat(@xmi.id, (($data_types)[@xmi.id = ($attribute_type)]/@xmi.id))"/></xsl:attribute>
				
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#FloatVal</xsl:attribute>
					</xsl:element>
				</xsl:element>
			</xsl:when>
			
			<!-- If the name of the attribute is int, an IntVal derived node is created.-->
			<xsl:when test="($data_types)[@xmi.id = ($attribute_type)]/Foundation.Core.ModelElement.name = 'int'">
				<xsl:element name="node">
					<xsl:attribute name="id"><xsl:value-of select="concat(@xmi.id, (($data_types)[@xmi.id = ($attribute_type)]/@xmi.id))"/></xsl:attribute>
				
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#IntVal</xsl:attribute>
					</xsl:element>
				</xsl:element>
			</xsl:when>
			
			<!-- If the name of the attribute is string, a StringVal derived node is created.-->
			<xsl:when test="($attribute_types)[@xmi.id = ($attribute_type)]/Foundation.Core.ModelElement.name = 'string'">
				<xsl:element name="node">
					<xsl:attribute name="id"><xsl:value-of select="concat(@xmi.id, (($attribute_types)[@xmi.id = ($attribute_type)]/@xmi.id))"/></xsl:attribute>
				
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#StringVal</xsl:attribute>
					</xsl:element>
				</xsl:element>
			</xsl:when>
			
			<!-- Followed by the locator value type. -->
			
			<!-- If the name of the attribute is locator, a locatorVal derived node is created.-->
			<xsl:when test="($attribute_types)[@xmi.id = ($attribute_type)]/Foundation.Core.ModelElement.name = 'locator'">
				<xsl:element name="node">
					<xsl:attribute name="id"><xsl:value-of select="concat(@xmi.id, (($attribute_types)[@xmi.id = ($attribute_type)]/@xmi.id))"/></xsl:attribute>
				
					<xsl:element name="type">
						<xsl:attribute name="href">MetaSchema#LocatorVal</xsl:attribute>
					</xsl:element>
				</xsl:element>
			</xsl:when>
		</xsl:choose>
	
		<!-- The hasAttributes derived edge is created and linked to the owner node and the AttributeClass derived node. -->
		<xsl:element name="edge">
			<xsl:attribute name="from">
				<xsl:value-of select="../../@xmi.id"/>
			</xsl:attribute>
				
			<xsl:attribute name="to">
				<xsl:value-of select="@xmi.id"/>
			</xsl:attribute>
				
			<xsl:element name="type">
				<xsl:attribute name="href">MetaSchema#hasAttribute</xsl:attribute>
			</xsl:element>
		</xsl:element>
		
		<!-- The hasDefaultValue derived edge is created and linked to the AttributeClass derived node and the attribute type node. -->
		<xsl:element name="edge">
			<xsl:attribute name="from">
				<xsl:value-of select="@xmi.id"/>
			</xsl:attribute>
				
			<xsl:attribute name="to">
				<xsl:value-of select="concat(@xmi.id, (($attribute_types)[@xmi.id = ($attribute_type)]/@xmi.id))"/>
			</xsl:attribute>
				
			<xsl:element name="type">
				<xsl:attribute name="href">MetaSchema#hasDefaultValue</xsl:attribute>
			</xsl:element>
		</xsl:element>	
	</xsl:template>
	
	<!-- END: Transformation part of the Stylesheet-->
	
	
	
</xsl:stylesheet>