diff --git a/.gitignore b/.gitignore
index a5b301de2e3f121b8dd7a09ea9fe0b667da4c369..5e142013c2bdbc64d4fe3558748328a282bbfc7a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -176,3 +176,8 @@ local.properties
 .project
 output/
 doc/
+[lL]ocal[tT]est*
+
+# ANTLR
+
+gen/
diff --git a/.gitmodules b/.gitmodules
index 5ed635731bd2541c2765d6ab654a00c411e18bbc..84f8c68c71d26f84896c11395e0cf33dad5ac73f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,9 +1,3 @@
-[submodule "lib/ModelSyncProvider"]
-	path = lib/ModelSyncProvider
-	url = https://git-st.inf.tu-dresden.de/cwerner/role_model_synchronization_provider.git
-[submodule "lib/SCROLL"]
-	path = lib/SCROLL
-	url = https://github.com/portux/SCROLL.git
 [submodule "src/main/asciidoc"]
 	path = src/main/doc
 	url = https://git-st.inf.tu-dresden.de/cwerner/code_generator.wiki.git
diff --git a/assets/Classdiagram_acr_model.pdf b/assets/Classdiagram_acr_model.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..53971a45fd0799ae231074a519fc6025c53a601a
Binary files /dev/null and b/assets/Classdiagram_acr_model.pdf differ
diff --git a/assets/model_join/complex.modeljoin b/assets/model_join/complex.modeljoin
new file mode 100644
index 0000000000000000000000000000000000000000..610f0771a034d528b50c58f2fcc84dc021435705
--- /dev/null
+++ b/assets/model_join/complex.modeljoin
@@ -0,0 +1,16 @@
+
+natural join imdbdatabase.Film with elib.VideoCassette as joins.JoinMovie {
+  keep attributes imdbdatabase.Film.year
+  keep aggregate avg(score) over Film.votes as Movie.averageRating
+  keep calculated attribute imdbdatabase.Film.votes->select(v|v.score==10)->size() as Movie.topratings:EInt
+  keep supertype elib.AudioVisualItem as type jointarget.MediaItem {
+    keep attributes elib.AudioVisualItem.minutesLength
+  }
+  keep outgoing imdbdatabase.Film.votes as type jointarget.Vote {
+    keep attributes imdbdatabase.Vote.score
+  }
+  keep outgoing elib.VideoCassette.cast as type jointarget.Person {
+    keep attributes elib.Person.lastName
+  }
+
+}
diff --git a/assets/model_join/libraryComplete.modeljoin b/assets/model_join/libraryComplete.modeljoin
new file mode 100644
index 0000000000000000000000000000000000000000..27db0faf62b4600552a15e3fd62cdfb0d7cdc55e
--- /dev/null
+++ b/assets/model_join/libraryComplete.modeljoin
@@ -0,0 +1,11 @@
+natural join lib.Library with lib.Library as lib.Library {
+   keep attributes lib.Library.name
+   keep outgoing lib.Library.employees as type lib.Employee {
+     keep attributes lib.Employee.salary
+     keep outgoing lib.Employee.manager as type lib.Employee {
+     }
+     keep supertype lib.Person as type lib.Person {
+       keep attributes lib.Person.name
+     }
+   }
+ }
\ No newline at end of file
diff --git a/assets/model_join/librarySimple.modeljoin b/assets/model_join/librarySimple.modeljoin
new file mode 100644
index 0000000000000000000000000000000000000000..db8daaed892dc182f0ba8d5eec3e967099ecdd65
--- /dev/null
+++ b/assets/model_join/librarySimple.modeljoin
@@ -0,0 +1,9 @@
+natural join lib.Library with lib.Library as lib.Library {
+   keep attributes lib.Library.name
+   keep outgoing lib.Library.employees as type lib.Employee {
+     keep attributes lib.Employee.salary
+     keep supertype lib.Person as type lib.Person {
+       keep attributes lib.Person.name
+     }
+   }
+ }
\ No newline at end of file
diff --git a/assets/model_join/manager.modeljoin b/assets/model_join/manager.modeljoin
new file mode 100644
index 0000000000000000000000000000000000000000..267f864506286730978bf97d5cdc5426438adf86
--- /dev/null
+++ b/assets/model_join/manager.modeljoin
@@ -0,0 +1,8 @@
+natural join lib.Employee with lib.Employee as lib.Employee {
+   keep attributes lib.Employee.salary
+   keep outgoing lib.Employee.manager as type lib.Employee {
+   }
+   keep supertype lib.Person as type lib.Person {
+     keep attributes lib.Person.name
+   }
+ }
\ No newline at end of file
diff --git a/assets/model_join/multiple_joins.modeljoin b/assets/model_join/multiple_joins.modeljoin
new file mode 100644
index 0000000000000000000000000000000000000000..dbee52d23a4a0c00ae7c0eb74a5d4989cdc611c7
--- /dev/null
+++ b/assets/model_join/multiple_joins.modeljoin
@@ -0,0 +1,10 @@
+
+natural join imdb.Film with library.VideoCassette as jointarget.Movie {
+  keep attributes imdb.Film.year
+  keep attributes library.AudioVisualItem.minutesLength
+}
+
+natural join imdb.Film with library.Author as jointarget.Director {
+  keep attributes imdb.Film.title
+  keep attributes library.Author.name
+}
diff --git a/assets/model_join/shrinking.modeljoin b/assets/model_join/shrinking.modeljoin
new file mode 100644
index 0000000000000000000000000000000000000000..427c5b2a8f8176f3aa78d3bc436dc9fa064b9b76
--- /dev/null
+++ b/assets/model_join/shrinking.modeljoin
@@ -0,0 +1,14 @@
+
+natural join shrinking.Class with shrinking.Class as shrinking.Class {
+  keep supertype shrinking.Classifier as type shrinking.Classifier {
+    keep attributes shrinking.Classifier.name
+  }
+  keep outgoing shrinking.StructuredClassifier.part as type shrinking.Property {
+    keep attributes shrinking.ConnectableElement.name
+  }
+  keep outgoing shrinking.StructuredClassifier.role as type shrinking.Property {
+    keep attributes shrinking.ConnectableElement.name
+  }
+  keep outgoing shrinking.StructuredClassifier.ownedAttribute as type shrinking.Property {
+  }
+}
diff --git a/assets/model_join/simple.modeljoin b/assets/model_join/simple.modeljoin
new file mode 100644
index 0000000000000000000000000000000000000000..5c22f623aa25cfc5361290c89310c984e7f7abf4
--- /dev/null
+++ b/assets/model_join/simple.modeljoin
@@ -0,0 +1,11 @@
+
+natural join imdbdatabase.Film with elib.VideoCassette as joins.JoinMovie {
+  keep attributes imdbdatabase.Film.year
+  keep attributes eclipselibrary.AudioVisualItem.minutesLength
+  keep outgoing imdbdatabase.Film.votes as type jointarget.Vote {
+    keep attributes imdbdatabase.Vote.score
+  }
+  keep outgoing elib.VideoCassette.cast as type jointarget.Person {
+    keep attributes elib.Person.lastName
+  }
+}
diff --git a/assets/model_join/theta_join.modeljoin b/assets/model_join/theta_join.modeljoin
new file mode 100644
index 0000000000000000000000000000000000000000..73a1d88b433b511fa8ad57ca9f74a867facaab6f
--- /dev/null
+++ b/assets/model_join/theta_join.modeljoin
@@ -0,0 +1,4 @@
+theta join imdb.Film with library.Movie where imdb.Film.title = library.Movie.name as jointarget.Movie {
+  keep attributes imdb.Film.title
+  keep attributes library.Author.name
+}
diff --git a/assets/models/AML.ecore b/assets/models/AML.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..a073b44ca3e0778a8a37fbd86c546b49da53a881
--- /dev/null
+++ b/assets/models/AML.ecore
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="AMLLanguage" nsURI="http://www.example.org/aml" nsPrefix="aml">
+  <eClassifiers xsi:type="ecore:EClass" name="CAEXObject" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Attribute" eSuperTypes="#//CAEXObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="SystemUnitClass" eSuperTypes="#//CAEXObject">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="attributes" upperBound="-1"
+        eType="#//Attribute" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="internalElements" upperBound="-1"
+        eType="#//InternalElement" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="InternalElement" eSuperTypes="#//SystemUnitClass">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="baseSystemUnit" eType="#//SystemUnitClass"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="InstanceHierarchy" eSuperTypes="#//CAEXObject">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="internalElements" upperBound="-1"
+        eType="#//InternalElement" containment="true"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/BDD.ecore b/assets/models/BDD.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..746b77f223ecbfcbc42d5f1d256f351869dd3d22
--- /dev/null
+++ b/assets/models/BDD.ecore
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+  <ecore:EPackage name="BDD" nsURI="https://www.transformation-tool-contest.eu/2019/bdd" xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+      nsPrefix="bdd">
+    <eClassifiers xsi:type="ecore:EClass" name="BDD">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" ordered="false"
+          unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ports" ordered="false"
+          lowerBound="1" upperBound="-1" eType="#/0/Port" containment="true" eOpposite="#/0/Port/owner"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="tree" ordered="false"
+          lowerBound="1" eType="#/0/Tree" containment="true" eOpposite="#/0/Tree/ownerBDD"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Port" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" ordered="false"
+          unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="owner" ordered="false"
+          lowerBound="1" eType="#/0/BDD" eOpposite="#/0/BDD/ports"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="InputPort" eSuperTypes="#/0/Port">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="subtrees" ordered="false"
+          upperBound="-1" eType="#/0/Subtree" eOpposite="#/0/Subtree/port"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OutputPort" eSuperTypes="#/0/Port">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="assignments" ordered="false"
+          upperBound="-1" eType="#/0/Assignment" eOpposite="#/0/Assignment/port"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Tree" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ownerBDD" ordered="false"
+          eType="#/0/BDD" eOpposite="#/0/BDD/tree"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ownerSubtreeForZero"
+          ordered="false" eType="#/0/Subtree" eOpposite="#/0/Subtree/treeForZero"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ownerSubtreeForOne" ordered="false"
+          eType="#/0/Subtree" eOpposite="#/0/Subtree/treeForOne"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Leaf" eSuperTypes="#/0/Tree">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="assignments" ordered="false"
+          lowerBound="1" upperBound="-1" eType="#/0/Assignment" containment="true"
+          eOpposite="#/0/Assignment/owner"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Assignment">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" ordered="false"
+          unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="port" ordered="false"
+          lowerBound="1" eType="#/0/OutputPort" eOpposite="#/0/OutputPort/assignments"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="owner" ordered="false"
+          lowerBound="1" eType="#/0/Leaf" eOpposite="#/0/Leaf/assignments"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Subtree" eSuperTypes="#/0/Tree">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="port" ordered="false"
+          lowerBound="1" eType="#/0/InputPort" eOpposite="#/0/InputPort/subtrees"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="treeForZero" ordered="false"
+          lowerBound="1" eType="#/0/Tree" containment="true" eOpposite="#/0/Tree/ownerSubtreeForZero"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="treeForOne" ordered="false"
+          lowerBound="1" eType="#/0/Tree" containment="true" eOpposite="#/0/Tree/ownerSubtreeForOne"/>
+    </eClassifiers>
+  </ecore:EPackage>
diff --git a/assets/models/BDDv2.ecore b/assets/models/BDDv2.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..451da6f04bf5b7609b80d69503beb024a6cc8a89
--- /dev/null
+++ b/assets/models/BDDv2.ecore
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="bddg" nsURI="https://www.transformation-tool-contest.eu/2019/bdd/graph"
+    nsPrefix="bddg">
+  <eClassifiers xsi:type="ecore:EClass" name="BDD">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" ordered="false" unique="false"
+        lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ports" ordered="false"
+        lowerBound="1" upperBound="-1" eType="#//Port" containment="true" eOpposite="#//Port/owner"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="root" ordered="false" lowerBound="1"
+        eType="#//Tree"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="trees" upperBound="-1"
+        eType="#//Tree" containment="true" eOpposite="#//Tree/ownerBDD"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Port" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" ordered="false" unique="false"
+        lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="owner" ordered="false"
+        lowerBound="1" eType="#//BDD" eOpposite="#//BDD/ports"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="InputPort" eSuperTypes="#//Port">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="subtrees" ordered="false"
+        upperBound="-1" eType="#//Subtree" eOpposite="#//Subtree/port"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="OutputPort" eSuperTypes="#//Port">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="assignments" ordered="false"
+        upperBound="-1" eType="#//Assignment" eOpposite="#//Assignment/port"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Tree" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ownerBDD" ordered="false"
+        eType="#//BDD" eOpposite="#//BDD/trees"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ownerSubtreeForZero" ordered="false"
+        upperBound="-1" eType="#//Subtree" eOpposite="#//Subtree/treeForZero"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ownerSubtreeForOne" ordered="false"
+        upperBound="-1" eType="#//Subtree" eOpposite="#//Subtree/treeForOne"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Leaf" eSuperTypes="#//Tree">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="assignments" ordered="false"
+        lowerBound="1" upperBound="-1" eType="#//Assignment" containment="true" eOpposite="#//Assignment/owner"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Assignment">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" ordered="false"
+        unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="port" ordered="false" lowerBound="1"
+        eType="#//OutputPort" eOpposite="#//OutputPort/assignments"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="owner" ordered="false"
+        lowerBound="1" eType="#//Leaf" eOpposite="#//Leaf/assignments"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Subtree" eSuperTypes="#//Tree">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="port" ordered="false" lowerBound="1"
+        eType="#//InputPort" eOpposite="#//InputPort/subtrees"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="treeForZero" ordered="false"
+        lowerBound="1" eType="#//Tree" eOpposite="#//Tree/ownerSubtreeForZero"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="treeForOne" ordered="false"
+        lowerBound="1" eType="#//Tree" eOpposite="#//Tree/ownerSubtreeForOne"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/ClassDiagram.ecore b/assets/models/ClassDiagram.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..f9051d9176d20d20ee263381e392d9830bd78026
--- /dev/null
+++ b/assets/models/ClassDiagram.ecore
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="classdiagram" nsURI="http://www.example.org/develop" nsPrefix="dev">
+  <eClassifiers xsi:type="ecore:EClass" name="ClassDiagram">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="classes" upperBound="-1"
+        eType="#//Class" containment="true" eOpposite="#//Class/diagram"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Class">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="className" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="diagram" lowerBound="1"
+        eType="#//ClassDiagram" eOpposite="#//ClassDiagram/classes"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="associations" upperBound="-1"
+        eType="#//Association" containment="true" eOpposite="#//Association/class"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="usedBy" upperBound="-1"
+        eType="#//Association" eOpposite="#//Association/type"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Association">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="lowerBound" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="upperBound" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="class" lowerBound="1" eType="#//Class"
+        eOpposite="#//Class/associations"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="type" lowerBound="1" eType="#//Class"
+        eOpposite="#//Class/usedBy"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/ClassDiagram.png b/assets/models/ClassDiagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..424064e2fca73ded663ccadd999cdbcf37c99356
Binary files /dev/null and b/assets/models/ClassDiagram.png differ
diff --git a/assets/models/EMFLibrary.ecore b/assets/models/EMFLibrary.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..9d9235783b17819f20b820f832c7d418cd00e833
--- /dev/null
+++ b/assets/models/EMFLibrary.ecore
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+  <ecore:EPackage xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="library"
+    nsURI="http://www.eclipse.org/emf/jcrm/samples/emf/sample/Library" nsPrefix="library">
+  <eClassifiers xsi:type="ecore:EClass" name="Book">
+    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+      <details key="name" value="Book"/>
+      <details key="kind" value="elementOnly"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="title" unique="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="title"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="pages" unique="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Int" unsettable="true">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="pages"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="author" lowerBound="1"
+        eType="#//Writer">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="author"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Library">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="name"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="books" upperBound="-1"
+        eType="#//Book" containment="true">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="books"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Writer">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="name"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="GuideBookWriter" eSuperTypes="#//Writer">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="countries" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="SpecialistBookWriter" eSuperTypes="#//Writer">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="subject" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+</ecore:EPackage>
\ No newline at end of file
diff --git a/assets/models/Family.ecore b/assets/models/Family.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..c2218c505028bedbc10a417e4747b371359b6da4
--- /dev/null
+++ b/assets/models/Family.ecore
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="Family" nsURI="http://www.example.org/ttc17" nsPrefix="ttc17">
+  <eClassifiers xsi:type="ecore:EClass" name="Member">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="firstName" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="familyMother" eType="#//Family"
+        eOpposite="#//Family/mother"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="familyFather" eType="#//Family"
+        eOpposite="#//Family/father"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="familySon" eType="#//Family"
+        eOpposite="#//Family/familySons"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="familyDaughter" eType="#//Family"
+        eOpposite="#//Family/familyDaugthers"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Family">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="lastName" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="mother" eType="#//Member"
+        containment="true" eOpposite="#//Member/familyMother"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="father" eType="#//Member"
+        containment="true" eOpposite="#//Member/familyFather"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="familyDaugthers" upperBound="-1"
+        eType="#//Member" containment="true" eOpposite="#//Member/familyDaughter"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="familySons" upperBound="-1"
+        eType="#//Member" containment="true" eOpposite="#//Member/familySon"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/Family.png b/assets/models/Family.png
new file mode 100644
index 0000000000000000000000000000000000000000..c69c975b06872def2dc68f2e3a58f9a3f39bc7c3
Binary files /dev/null and b/assets/models/Family.png differ
diff --git a/assets/models/Family.sync.json b/assets/models/Family.sync.json
new file mode 100644
index 0000000000000000000000000000000000000000..202c10d84384bf8d1509c8e0b4a9cca6927a774a
--- /dev/null
+++ b/assets/models/Family.sync.json
@@ -0,0 +1 @@
+{"name":"Family","init":{"name":"FamilyModel","primaryClass":"Family.Family","image":"Family.png","nested":[{"name":"MemberModel","primaryClass":"Family.Member"}]}}
\ No newline at end of file
diff --git a/assets/models/IMDBDatabase.ecore b/assets/models/IMDBDatabase.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..e97c1c4f8c409e15d51506b80cadaea050dcec16
--- /dev/null
+++ b/assets/models/IMDBDatabase.ecore
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="IMDBdatabase" nsURI="http://www.example.org/database" nsPrefix="imdbdatabase">
+  <eClassifiers xsi:type="ecore:EClass" name="IMDB">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="users" upperBound="-1"
+        eType="#//User" containment="true" eOpposite="#//User/library"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="actors" upperBound="-1"
+        eType="#//Actor" containment="true" eOpposite="#//Actor/library"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="films" upperBound="-1"
+        eType="#//Film" containment="true" eOpposite="#//Film/library"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="votes" upperBound="-1"
+        eType="#//Vote" containment="true" eOpposite="#//Vote/library"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Film">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="title" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="year" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="library" eType="#//IMDB"
+        eOpposite="#//IMDB/films"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="figures" lowerBound="1"
+        upperBound="-1" eType="#//Figure" containment="true" eOpposite="#//Figure/film"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="votes" upperBound="-1"
+        eType="#//Vote" eOpposite="#//Vote/film"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Vote">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="score" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="library" lowerBound="1"
+        eType="#//IMDB" eOpposite="#//IMDB/votes"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="film" lowerBound="1" eType="#//Film"
+        eOpposite="#//Film/votes"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="user" lowerBound="1" eType="#//User"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Figure">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="film" eType="#//Film" eOpposite="#//Film/figures"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="playedBy" lowerBound="1"
+        upperBound="-1" eType="#//Actor" eOpposite="#//Actor/playsIn"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Person">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="dob" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Actor" eSuperTypes="#//Person">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="playsIn" upperBound="-1"
+        eType="#//Figure" eOpposite="#//Figure/playedBy"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="library" eType="#//IMDB"
+        eOpposite="#//IMDB/actors"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="User" eSuperTypes="#//Person">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="userName" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="email" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="library" lowerBound="1"
+        eType="#//IMDB" eOpposite="#//IMDB/users"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/IMDBDatabase.png b/assets/models/IMDBDatabase.png
new file mode 100644
index 0000000000000000000000000000000000000000..72a34d444e259f6bff9dc2b43565511c599740d4
Binary files /dev/null and b/assets/models/IMDBDatabase.png differ
diff --git a/assets/models/JavaSourceCode.ecore b/assets/models/JavaSourceCode.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..053bc0ec25186580a8109aed96da82b242c3b73a
--- /dev/null
+++ b/assets/models/JavaSourceCode.ecore
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="javasourcecode" nsURI="http://www.example.org/develop" nsPrefix="dev">
+  <eClassifiers xsi:type="ecore:EClass" name="Method">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="class" lowerBound="1" eType="#//ClassType"
+        eOpposite="#//ClassType/methods"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="calling" upperBound="-1"
+        eType="#//Method" eOpposite="#//Method/calledBy"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="calledBy" upperBound="-1"
+        eType="#//Method" eOpposite="#//Method/calling"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ClassType">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="asg" lowerBound="1" eType="#//JavaASG"
+        eOpposite="#//JavaASG/classes"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="methods" upperBound="-1"
+        eType="#//Method" containment="true" eOpposite="#//Method/class"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="JavaASG">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="classes" upperBound="-1"
+        eType="#//ClassType" containment="true" eOpposite="#//ClassType/asg"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/JavaSourceCode.png b/assets/models/JavaSourceCode.png
new file mode 100644
index 0000000000000000000000000000000000000000..76ff96ce43f8956fd24cbcd4e6bc7776bfb600b9
Binary files /dev/null and b/assets/models/JavaSourceCode.png differ
diff --git a/assets/models/Library.ecore b/assets/models/Library.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..c281ccd51d05716e4033331b02b2f4ee4bc561ce
--- /dev/null
+++ b/assets/models/Library.ecore
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="Library" nsURI="http://www.example.org/library" nsPrefix="lib">
+  <eClassifiers xsi:type="ecore:EClass" name="Library">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="employees" upperBound="-1"
+        eType="#//Employee" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Employee" eSuperTypes="#//Person">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="salary" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDouble"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="manager" eType="#//Employee"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Person" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/Library.png b/assets/models/Library.png
new file mode 100644
index 0000000000000000000000000000000000000000..8216f945be7da29639bf2b3f56d4f8a5189de6e0
Binary files /dev/null and b/assets/models/Library.png differ
diff --git a/assets/models/Library.sync.json b/assets/models/Library.sync.json
new file mode 100644
index 0000000000000000000000000000000000000000..99a95134654a9aa038ce37aa92e3d92283222794
--- /dev/null
+++ b/assets/models/Library.sync.json
@@ -0,0 +1 @@
+{"name":"Library","init":{"name":"Library","primaryClass":"sync.lib.Library","image":"Library.png","nested":[{"name":"Person","primaryClass":"sync.lib.Person","additionalClasses":["sync.lib.Employee"]}]}}
\ No newline at end of file
diff --git a/assets/models/ModelJoinLibrary.ecore b/assets/models/ModelJoinLibrary.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..e5669ac1ca777b8cc9bd5df581aba778559cd473
--- /dev/null
+++ b/assets/models/ModelJoinLibrary.ecore
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="Eclipselibrary" nsURI="http://www.example.org/eclipselibrary"
+    nsPrefix="elib">
+  <eClassifiers xsi:type="ecore:EClass" name="Item" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="publicationDate" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDate"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="title" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Periodical" eSuperTypes="#//Item">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="issuesPerYear" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="BookCategory">
+    <eLiterals name="Mystery"/>
+    <eLiterals name="ScienceFiction" value="1"/>
+    <eLiterals name="Biography" value="2"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="CirculatingItem" abstract="true" eSuperTypes="#//Item"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Book" eSuperTypes="#//CirculatingItem">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="pages" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="category" eType="#//BookCategory"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="author" lowerBound="1"
+        eType="#//Writer" eOpposite="#//Writer/books"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="AudioVisualItem" abstract="true" eSuperTypes="#//CirculatingItem">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="minutesLength" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="damaged" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="VideoCassette" eSuperTypes="#//AudioVisualItem">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="cast" upperBound="-1" eType="#//Person"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="BookOnTape" eSuperTypes="#//AudioVisualItem">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="reader" eType="#//Person"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="author" eType="#//Writer"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Person">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="firstName" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="lastName" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Writer" eSuperTypes="#//Person">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="books" upperBound="-1"
+        eType="#//Book" eOpposite="#//Book/author"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Library">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="stock" upperBound="-1"
+        eType="#//Item" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="books" upperBound="-1"
+        eType="#//Book"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="writers" upperBound="-1"
+        eType="#//Writer" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="borrowers" upperBound="-1"
+        eType="#//Borrower" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="employees" upperBound="-1"
+        eType="#//Employee" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="branches" upperBound="-1"
+        eType="#//Library" containment="true" eOpposite="#//Library/parentBranch"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="parentBranch" eType="#//Library"
+        eOpposite="#//Library/branches"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Borrower" eSuperTypes="#//Person"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Employee" eSuperTypes="#//Person">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="manager" eType="#//Employee"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/ModelJoinLibrary.png b/assets/models/ModelJoinLibrary.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ce2618b59b87a2db3858a8163f776d01d25de08
Binary files /dev/null and b/assets/models/ModelJoinLibrary.png differ
diff --git a/assets/models/Person.ecore b/assets/models/Person.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..73f31165bb4ea87cd28a9bf068d6b6790513f440
--- /dev/null
+++ b/assets/models/Person.ecore
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="Person" nsURI="http://www.example.org/ttc17" nsPrefix="ttc17">
+  <eClassifiers xsi:type="ecore:EClass" name="Person" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="fullName" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="birthday" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDate"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Male" eSuperTypes="#//Person"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Female" eSuperTypes="#//Person"/>
+</ecore:EPackage>
diff --git a/assets/models/Person.png b/assets/models/Person.png
new file mode 100644
index 0000000000000000000000000000000000000000..d314a2f697308b0274dc7a2afba6e8bcc02701cf
Binary files /dev/null and b/assets/models/Person.png differ
diff --git a/assets/models/Person.sync.json b/assets/models/Person.sync.json
new file mode 100644
index 0000000000000000000000000000000000000000..89261e87d297cef41b2e778c0abe059170882ce4
--- /dev/null
+++ b/assets/models/Person.sync.json
@@ -0,0 +1,12 @@
+{
+  "name":"Person",
+  "init": {
+    "name": "PersonModel",
+    "primaryClass": "Person.Person",
+    "additionalClasses": [
+      "Person.Female",
+      "Person.Male"
+    ],
+    "image": "Person.png"
+    }
+  }
diff --git a/assets/models/Requirements.ecore b/assets/models/Requirements.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..17e6976840685f233b603a091c8b029b1960f054
--- /dev/null
+++ b/assets/models/Requirements.ecore
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="requirement" nsURI="http://www.example.org/develop" nsPrefix="dev">
+  <eClassifiers xsi:type="ecore:EClass" name="RequirementsSpecification">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="content" upperBound="-1"
+        eType="#//Requirement" containment="true" eOpposite="#//Requirement/container"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Requirement">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="author" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="text" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="container" lowerBound="1"
+        eType="#//RequirementsSpecification" eOpposite="#//RequirementsSpecification/content"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/Requirements.png b/assets/models/Requirements.png
new file mode 100644
index 0000000000000000000000000000000000000000..a1209c325f357267ab95f7c52ed178322f8181c3
Binary files /dev/null and b/assets/models/Requirements.png differ
diff --git a/assets/models/SUMM.ecore b/assets/models/SUMM.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..e499ca3b6a09510e6b958ed7f84a6e4eab803829
--- /dev/null
+++ b/assets/models/SUMM.ecore
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="summ" nsURI="http://www.example.org/develop" nsPrefix="dev">
+  <eClassifiers xsi:type="ecore:EClass" name="Class">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="className" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="associations" upperBound="-1"
+        eType="#//ClassUseClass" containment="true" eOpposite="#//ClassUseClass/class"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="usedBy" upperBound="-1"
+        eType="#//ClassUseClass" eOpposite="#//ClassUseClass/type"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="methods" upperBound="-1"
+        eType="#//Method" containment="true" eOpposite="#//Method/class"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ClassUseClass">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="lowerBound" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="upperBound" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="class" lowerBound="1" eType="#//Class"
+        eOpposite="#//Class/associations"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="type" lowerBound="1" eType="#//Class"
+        eOpposite="#//Class/usedBy"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Requirement">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="author" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="text" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="fullfilledBy" upperBound="-1"
+        eType="#//Method" eOpposite="#//Method/fulfills"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Method">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="fulfills" upperBound="-1"
+        eType="#//Requirement" eOpposite="#//Requirement/fullfilledBy"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="class" lowerBound="1" eType="#//Class"
+        eOpposite="#//Class/methods"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="calling" upperBound="-1"
+        eType="#//Method" eOpposite="#//Method/calledBy"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="calledBy" upperBound="-1"
+        eType="#//Method" eOpposite="#//Method/calling"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/SUMM.png b/assets/models/SUMM.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa373bdda84fb922581b4c5dbfa9cebc9ca81096
Binary files /dev/null and b/assets/models/SUMM.png differ
diff --git a/assets/models/ShrinkingModel.ecore b/assets/models/ShrinkingModel.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..d44b9ff720cb84f014937ec94e9ccaa3fbfad0bd
--- /dev/null
+++ b/assets/models/ShrinkingModel.ecore
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="shrinking" nsURI="http://www.example.org/shrinking" nsPrefix="shr">
+  <eClassifiers xsi:type="ecore:EClass" name="Classifier" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="StructuredClassifier" eSuperTypes="#//Classifier">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="part" upperBound="-1" eType="#//Property"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ownedAttribute" upperBound="-1"
+        eType="#//Property" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="EncapsulatedClassifier" abstract="true"
+      eSuperTypes="#//StructuredClassifier"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Class" eSuperTypes="#//EncapsulatedClassifier #//BehavioredClassifier">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="superClass" eType="#//Class"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ConnectableElement" abstract="true">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="role" eType="#//StructuredClassifier"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="BehavioredClassifier" interface="true"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Property" eSuperTypes="#//ConnectableElement"/>
+</ecore:EPackage>
diff --git a/assets/models/ShrinkingModel.sync.json b/assets/models/ShrinkingModel.sync.json
new file mode 100644
index 0000000000000000000000000000000000000000..e6dcdcf38101f8ee3d5ce4ce3d346c5206a3ca04
--- /dev/null
+++ b/assets/models/ShrinkingModel.sync.json
@@ -0,0 +1 @@
+{"name":"ShrinkingModel","init":{"name":"Classifier","primaryClass":"ShrinkingExample.Classifier","additionalClasses":["ShrinkingExample.StructuredClassifier","ShrinkingExample.EncapsulatedClassifier","ShrinkingExample.Class"],"image":"Library.png","nested":[{"name":"ConnectableElement","primaryClass":"ShrinkingExample.ConnectableElement","additionalClasses":["ShrinkingExample.Property"]}]}}
\ No newline at end of file
diff --git a/assets/models/SimplePerson.ecore b/assets/models/SimplePerson.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..cb4f8dc86b28fe96760c3ee294a14c8efbd5591c
--- /dev/null
+++ b/assets/models/SimplePerson.ecore
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="SimplePerson" nsURI="http://www.example.org/ttc17" nsPrefix="ttc17">
+  <eClassifiers xsi:type="ecore:EClass" name="SimplePerson">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="completeName" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="male" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/SimplePerson.png b/assets/models/SimplePerson.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2c5139e37949c47f9dea1a042ecdb2659131de1
Binary files /dev/null and b/assets/models/SimplePerson.png differ
diff --git a/assets/models/SimplePerson.sync.json b/assets/models/SimplePerson.sync.json
new file mode 100644
index 0000000000000000000000000000000000000000..b6900ae53c4feeb6c35c8a27fa4f18993ec9dc19
--- /dev/null
+++ b/assets/models/SimplePerson.sync.json
@@ -0,0 +1 @@
+{"name":"SimplePerson","init":{"name":"SimplePersonModel","primaryClass":"SimplePerson.SimplePerson","image":"SimplePerson.png"}}
\ No newline at end of file
diff --git a/assets/models/TT.ecore b/assets/models/TT.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..14372089b3c2543ab0d6338499ab14d4cf9421dc
--- /dev/null
+++ b/assets/models/TT.ecore
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+  <ecore:EPackage name="TT" nsURI="https://www.transformation-tool-contest.eu/2019/tt" xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+      nsPrefix="tt">
+    <eClassifiers xsi:type="ecore:EClass" name="LocatedElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="location" ordered="false"
+          unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="TruthTable" eSuperTypes="#/0/LocatedElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" ordered="false"
+          unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ports" ordered="false"
+          lowerBound="1" upperBound="-1" eType="#/0/Port" containment="true" eOpposite="#/0/Port/owner"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rows" ordered="false"
+          lowerBound="2" upperBound="-1" eType="#/0/Row" containment="true" eOpposite="#/0/Row/owner"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Port" abstract="true" eSuperTypes="#/0/LocatedElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" ordered="false"
+          unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="owner" ordered="false"
+          lowerBound="1" eType="#/0/TruthTable" eOpposite="#/0/TruthTable/ports"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="cells" ordered="false"
+          upperBound="-1" eType="#/0/Cell" eOpposite="#/0/Cell/port"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="InputPort" eSuperTypes="#/0/Port"/>
+    <eClassifiers xsi:type="ecore:EClass" name="OutputPort" eSuperTypes="#/0/Port"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Row" eSuperTypes="#/0/LocatedElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="owner" ordered="false"
+          lowerBound="1" eType="#/0/TruthTable" eOpposite="#/0/TruthTable/rows"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="cells" ordered="false"
+          lowerBound="1" upperBound="-1" eType="#/0/Cell" containment="true" eOpposite="#/0/Cell/owner"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Cell" eSuperTypes="#/0/LocatedElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" ordered="false"
+          unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="owner" ordered="false"
+          lowerBound="1" eType="#/0/Row" eOpposite="#/0/Row/cells"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="port" ordered="false"
+          lowerBound="1" eType="#/0/Port" eOpposite="#/0/Port/cells"/>
+    </eClassifiers>
+  </ecore:EPackage>
diff --git a/assets/models/TTC 17.sync.json b/assets/models/TTC 17.sync.json
new file mode 100644
index 0000000000000000000000000000000000000000..37cd3aa9ec431bfc1458019efa7652eee1dcb1b7
--- /dev/null
+++ b/assets/models/TTC 17.sync.json	
@@ -0,0 +1 @@
+{"name":"TTC 17","init":{"name":"ModelB","primaryClass":"ttc17.Family","image":"family.png","nested":[{"name":"Model B - members","primaryClass":"ttc17.Member"}]},"integration":[{"name":"ModelA","primaryClass":"ttc17.Person","additionalClasses":["ttc17.Female","ttc17.Male"],"rule":"person.atl"},{"name":"ModelC","primaryClass":"ttc17.SimplePerson"}]}
\ No newline at end of file
diff --git a/assets/models/oldSUMM.ecore b/assets/models/oldSUMM.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..3a497027f4682eb2c58f1d672bfa598a92fcc1ba
--- /dev/null
+++ b/assets/models/oldSUMM.ecore
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="oldSUMM" nsURI="http://www.example.org/develop" nsPrefix="dev">
+  <eClassifiers xsi:type="ecore:EClass" name="Method">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="class" lowerBound="1" eType="#//ClassType"
+        eOpposite="#//ClassType/methods"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="calling" upperBound="-1"
+        eType="#//Method" eOpposite="#//Method/calledBy"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="calledBy" upperBound="-1"
+        eType="#//Method" eOpposite="#//Method/calling"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="fulfilled" upperBound="-1"
+        eType="#//Requirement" eOpposite="#//Requirement/fulfilledBy"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ClassType">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="asg" eType="#//JavaASG"
+        eOpposite="#//JavaASG/classes"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="methods" upperBound="-1"
+        eType="#//Method" containment="true" eOpposite="#//Method/class"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="diagram" eType="#//ClassDiagram"
+        eOpposite="#//ClassDiagram/classes"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="associations" upperBound="-1"
+        eType="#//Association" containment="true" eOpposite="#//Association/class"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="usedBy" upperBound="-1"
+        eType="#//Association" eOpposite="#//Association/type"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="JavaASG">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="classes" upperBound="-1"
+        eType="#//ClassType" containment="true" eOpposite="#//ClassType/asg"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="integrator" eType="#//ProjectData"
+        eOpposite="#//ProjectData/containsJavaASG"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="RequirementsSpecification">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="content" upperBound="-1"
+        eType="#//Requirement" containment="true" eOpposite="#//Requirement/container"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="integrator" eType="#//ProjectData"
+        eOpposite="#//ProjectData/containsRequirements"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Requirement">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="author" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="text" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="container" lowerBound="1"
+        eType="#//RequirementsSpecification" eOpposite="#//RequirementsSpecification/content"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="fulfilledBy" upperBound="-1"
+        eType="#//Method" eOpposite="#//Method/fulfilled"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ClassDiagram">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="classes" upperBound="-1"
+        eType="#//ClassType" containment="true" eOpposite="#//ClassType/diagram"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="integrator" eType="#//ProjectData"
+        eOpposite="#//ProjectData/containsClassDiagram"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Association">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="lowerBound" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="upperBound" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="class" lowerBound="1" eType="#//ClassType"
+        eOpposite="#//ClassType/associations"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="type" lowerBound="1" eType="#//ClassType"
+        eOpposite="#//ClassType/usedBy"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ProjectData">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containsRequirements" upperBound="-1"
+        eType="#//RequirementsSpecification" containment="true" eOpposite="#//RequirementsSpecification/integrator"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containsJavaASG" upperBound="-1"
+        eType="#//JavaASG" containment="true" eOpposite="#//JavaASG/integrator"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="containsClassDiagram" upperBound="-1"
+        eType="#//ClassDiagram" containment="true" eOpposite="#//ClassDiagram/integrator"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/assets/models/oldSUMM.png b/assets/models/oldSUMM.png
new file mode 100644
index 0000000000000000000000000000000000000000..75b79b7d7a6fa7a044d07e6ca53e26e7708d32e7
Binary files /dev/null and b/assets/models/oldSUMM.png differ
diff --git a/assets/ttc17.modeljoin b/assets/ttc17.modeljoin
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/build.sbt b/build.sbt
index 39aae81e9e9a67cb23e38f3459c7d59f7f2fe092..674c017ea6bfa76b4ab3825761a22ee43e7cb797 100644
--- a/build.sbt
+++ b/build.sbt
@@ -5,8 +5,14 @@ val emfecoreVersion = "2.12.0"
 val scrollVersion = "1.8"
 val scoptVersion = "3.7.0"
 val liftVersion = "3.3.0"
+val gsonVersion = "2.8.5"
 
-val syncProvider = RootProject(file("lib/ModelSyncProvider"))
+val modelmanagementprovider = ProjectRef(uri("https://git-st.inf.tu-dresden.de/cwerner/role_model_management_provider.git#master"), "modelmanagementprovider")
+val uiProvider = ProjectRef(uri("https://git-st.inf.tu-dresden.de/cwerner/role_ui_provider.git#master"), "uiprovider")
+//val modeljoin = ProjectRef(uri("https://git-st.inf.tu-dresden.de/cwerner/model_join.git#master"), "model_join")
+
+
+javacOptions ++= Seq("-encoding", "UTF-8")
 
 lazy val generator = (project in file("."))
   .settings(
@@ -20,7 +26,17 @@ lazy val generator = (project in file("."))
       "org.eclipse.emf" % "org.eclipse.emf.common" % emfcommonVersion,
       "org.eclipse.emf" % "org.eclipse.emf.ecore" % emfecoreVersion,
       "com.github.scopt" %% "scopt" % scoptVersion,
-      "net.liftweb" %% "lift-json" % liftVersion
+      "net.liftweb" %% "lift-json" % liftVersion,
+      "com.google.code.gson" % "gson" % gsonVersion,
+
+      //"org.antlr" % "antlr4-runtime" % "4.7.2",
+
+      "org.junit.platform" % "junit-platform-runner" % "1.0.0" % "test",
+      "org.junit.jupiter" % "junit-jupiter-engine" % "5.0.0" % "test",
+      "org.junit.vintage" % "junit-vintage-engine" % "4.12.0" % "test",
+      "org.assertj" % "assertj-core" % "3.12.2" % "test",
+
+      "net.aichler" % "jupiter-interface" % JupiterKeys.jupiterVersion.value % Test
     ),
     scalacOptions ++= Seq(
       "-language:implicitConversions"
@@ -37,5 +53,9 @@ lazy val generator = (project in file("."))
       case x =>
         val oldStrategy = (assemblyMergeStrategy in assembly).value
         oldStrategy(x)
-    }
-  ).dependsOn(syncProvider)
+    },
+  ).dependsOn(
+    //modeljoin,
+    modelmanagementprovider,
+    uiProvider
+  )
diff --git a/lib/ModelSyncProvider b/lib/ModelSyncProvider
deleted file mode 160000
index 619bbf1efcfee406a134412275928322d9d28e05..0000000000000000000000000000000000000000
--- a/lib/ModelSyncProvider
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 619bbf1efcfee406a134412275928322d9d28e05
diff --git a/project/build.properties b/project/build.properties
index 8db5ca22266ea113c2b39c92dddb73c83e61ffee..cabf73b45107a5feb964e2c564c9687faafffdbe 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version = 1.2.1
\ No newline at end of file
+sbt.version = 1.2.7
diff --git a/project/plugins.sbt b/project/plugins.sbt
index 45a6f02d1880ea4c9bff889a194ab87adf467611..4a65abadaf7e792155072db22cce49a4abbf4d54 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,2 +1,6 @@
+
+resolvers += Resolver.jcenterRepo
+
+addSbtPlugin("net.aichler" % "sbt-jupiter-interface" % "0.8.2")
 addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4")
 addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0")
diff --git a/src/main/doc b/src/main/doc
index 89e2af4e060ae7c39c261fde55ba9140caf85853..ab624d1ae7196ac06fb3e9cef2f585552bee38e9 160000
--- a/src/main/doc
+++ b/src/main/doc
@@ -1 +1 @@
-Subproject commit 89e2af4e060ae7c39c261fde55ba9140caf85853
+Subproject commit ab624d1ae7196ac06fb3e9cef2f585552bee38e9
diff --git a/src/main/java/org/rosi_project/model_sync/modelrepresentation/JCreateJSONModels.java b/src/main/java/org/rosi_project/model_sync/modelrepresentation/JCreateJSONModels.java
new file mode 100644
index 0000000000000000000000000000000000000000..c946e9442f0e60113cd69b12f5b1d7b09a249316
--- /dev/null
+++ b/src/main/java/org/rosi_project/model_sync/modelrepresentation/JCreateJSONModels.java
@@ -0,0 +1,144 @@
+package org.rosi_project.model_sync.modelrepresentation;
+
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+
+import com.google.gson.Gson;
+
+public class JCreateJSONModels {
+	
+	private static Gson gson = new Gson();
+
+	public static void main(String[] args) {
+		//Type t = gson.fromJson(bytesRead, Type.class);
+		JCreateJSONModels creation = new JCreateJSONModels();
+		
+		//Create old TTC Model
+		JModelConfig ttc = creation.createOldTTCModel();
+		creation.writeJModelConfigToFile(ttc);
+		
+		//Create Family Model
+		JModelConfig family = creation.createFamilyModel();
+		creation.writeJModelConfigToFile(family);
+		
+		//Create Person Model
+		JModelConfig person = creation.createPersonModel();
+		creation.writeJModelConfigToFile(person);
+		
+		//Create SimplePerson Model
+		JModelConfig simplePerson = creation.createSimplePersonModel();
+		creation.writeJModelConfigToFile(simplePerson);		
+		
+		//Create Library Model
+		JModelConfig library = creation.createLibraryModel();
+		creation.writeJModelConfigToFile(library);
+		
+		//Create Shrinking Model
+		JModelConfig shrinking = creation.createShrinkingModel();
+		creation.writeJModelConfigToFile(shrinking);
+
+	}
+	
+	public void writeJModelConfigToFile (JModelConfig value) {
+		String s = gson.toJson(value);
+		//System.out.println(s);
+		try {
+			PrintWriter p = new PrintWriter("assets/models/" + value.getName() + ".sync.json");
+			p.write(s);
+			p.flush();
+			p.close();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public JModelConfig createShrinkingModel () {
+		JModelConfig conf = new JModelConfig("ShrinkingModel");
+		
+		JModel classifier = new JModel("Classifier", "ShrinkingExample.Classifier");
+		classifier.setImage("Library.png");	
+		classifier.addAdditionalClass("ShrinkingExample.StructuredClassifier");
+		classifier.addAdditionalClass("ShrinkingExample.EncapsulatedClassifier");
+		classifier.addAdditionalClass("ShrinkingExample.Class");
+		
+		JModel element = new JModel("ConnectableElement", "ShrinkingExample.ConnectableElement");
+		element.addAdditionalClass("ShrinkingExample.Property");
+		classifier.addNested(element);
+		
+		conf.setInit(classifier);
+		return conf;
+	}
+	
+	public JModelConfig createLibraryModel () {
+		JModelConfig conf = new JModelConfig("Library");
+		
+		JModel library = new JModel("Library", "LibraryExample.Library");
+		library.setImage("Library.png");		
+		
+		JModel person = new JModel("Person", "LibraryExample.Person");
+		person.addAdditionalClass("LibraryExample.Employee");
+		library.addNested(person);
+		
+		conf.setInit(library);
+		return conf;
+	}
+	
+	public JModelConfig createOldTTCModel () {
+		JModelConfig conf = new JModelConfig("TTC 17");
+		
+		JModel family = new JModel("ModelB", "ttc17.Family");
+		family.setImage("family.png");
+		JModel member = new JModel("Model B - members", "ttc17.Member");
+		family.addNested(member);
+		
+		JModel person = new JModel("ModelA", "ttc17.Person");
+		person.setRule("person.atl");
+		person.addAdditionalClass("ttc17.Female");
+		person.addAdditionalClass("ttc17.Male");
+		
+		JModel simpleperson = new JModel("ModelC", "ttc17.SimplePerson");
+		
+		conf.setInit(family);
+		conf.addIntegration(person);
+		conf.addIntegration(simpleperson);
+		return conf;
+	}
+	
+	public JModelConfig createFamilyModel () {
+		JModelConfig conf = new JModelConfig("Family");
+		
+		JModel family = new JModel("FamilyModel", "Family.Family");
+		family.setImage("Family.png");
+		
+		//family.addAdditionalClass("Family.Member");		
+		JModel member = new JModel("MemberModel", "Family.Member");
+		family.addNested(member);
+		
+		conf.setInit(family);
+		return conf;
+	}
+	
+	public JModelConfig createPersonModel () {
+		JModelConfig conf = new JModelConfig("Person");
+				
+		JModel person = new JModel("PersonModel", "Person.Person");
+		person.setImage("Person.png");
+		person.addAdditionalClass("Person.Female");
+		person.addAdditionalClass("Person.Male");		
+		
+		conf.setInit(person);
+		return conf;
+	}
+	
+	public JModelConfig createSimplePersonModel () {
+		JModelConfig conf = new JModelConfig("SimplePerson");
+				
+		JModel simpleperson = new JModel("SimplePersonModel", "SimplePerson.SimplePerson");
+		simpleperson.setImage("SimplePerson.png");
+		
+		conf.setInit(simpleperson);
+		return conf;
+	}	
+	
+
+}
diff --git a/src/main/java/org/rosi_project/model_sync/modelrepresentation/JModel.java b/src/main/java/org/rosi_project/model_sync/modelrepresentation/JModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..878e3e83870454a8a1840b73cfbf2bf9ce63397c
--- /dev/null
+++ b/src/main/java/org/rosi_project/model_sync/modelrepresentation/JModel.java
@@ -0,0 +1,69 @@
+package org.rosi_project.model_sync.modelrepresentation;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class JModel {
+	
+	public JModel(String name, String primaryClass) {
+		this.name = name;
+		this.primaryClass = primaryClass;
+	}
+
+	private String name;	
+	private String primaryClass;
+	private List<String> additionalClasses;
+	private String image;
+	private List<JModel> nested;
+	private String rule;
+		
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getPrimaryClass() {
+		return primaryClass;
+	}
+	public void setPrimaryClass(String primaryClass) {
+		this.primaryClass = primaryClass;
+	}
+	
+	public String getImage() {
+		return image;
+	}
+	public void setImage(String image) {
+		this.image = image;
+	}
+	
+	public List<String> getAdditionalClasses() {
+		return additionalClasses;
+	}
+	public boolean addAdditionalClass(String value) {
+		if (value == null)
+			return false;
+		if (additionalClasses == null)
+			this.additionalClasses = new LinkedList<String>();
+		return additionalClasses.add(value);
+	}
+	
+	public List<JModel> getNested() {
+		return nested;
+	}
+	public boolean addNested(JModel value) {
+		if (value == null)
+			return false;
+		if (nested == null)
+			this.nested = new LinkedList<JModel>();
+		return nested.add(value);
+	}
+	
+	public String getRule() {
+		return rule;
+	}
+	public void setRule(String rule) {
+		this.rule = rule;
+	}
+}
diff --git a/src/main/java/org/rosi_project/model_sync/modelrepresentation/JModelConfig.java b/src/main/java/org/rosi_project/model_sync/modelrepresentation/JModelConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..e65900a57a2f36d6f2553595c94950cf376089a9
--- /dev/null
+++ b/src/main/java/org/rosi_project/model_sync/modelrepresentation/JModelConfig.java
@@ -0,0 +1,41 @@
+package org.rosi_project.model_sync.modelrepresentation;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class JModelConfig {
+	
+	public JModelConfig(String name) {
+		this.name = name;		 
+	}
+	
+	private String name;
+	private JModel init;
+	private List<JModel> integration;
+	
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public JModel getInit() {
+		return init;
+	}
+	public void setInit(JModel init) {
+		this.init = init;
+	}
+	
+	public List<JModel> getIntegration() {
+		return integration;
+	}
+	public boolean addIntegration(JModel value) {
+		if (value == null)
+			return false;
+		if (integration == null)
+			this.integration = new LinkedList<JModel>();
+		return integration.add(value);
+	}
+
+}
diff --git a/src/main/java/org/rosi_project/model_sync/util/EMFUtilForGenerator.java b/src/main/java/org/rosi_project/model_sync/util/EMFUtilForGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..7038aa7e14f0a0fc5aac84e39765ebe4223415f4
--- /dev/null
+++ b/src/main/java/org/rosi_project/model_sync/util/EMFUtilForGenerator.java
@@ -0,0 +1,20 @@
+package org.rosi_project.model_sync.util;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreEList;
+
+public class EMFUtilForGenerator {
+	
+	static public List<EObject> getList(Object obj) {
+		List<EObject> newList = new LinkedList<EObject>();
+		EcoreEList<EObject> list = (EcoreEList<EObject>) obj;	
+		for (EObject l : list) {
+			newList.add(l);
+		}
+		return newList;
+	}
+
+}
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/CLIGenerator.scala b/src/main/scala/org/rosi_project/model_sync/generator/CLIGenerator.scala
index 9f6af4d784e94a44459d35eb17e5c33159c54a02..fce0ed34bb6d2b532cfa870975a0cae31810c3d1 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/CLIGenerator.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/CLIGenerator.scala
@@ -20,8 +20,8 @@ object CLIGenerator extends App {
   val parser = new OptionParser[GeneratorConfig](programName="modelgen") {
     head("modelgen", "0.1")
 
-    arg[jio.File]("ecore").required().action( (ef, conf) =>
-      conf.copy(source = ef.getAbsolutePath)
+    arg[Seq[jio.File]]("ecore").required().action( (ef, conf) =>
+      conf.copy(sources = ef.map(f => f.getAbsolutePath))
     ).text("The ecore (XML) file of the model")
 
     opt[jio.File]('o', "outdir").optional().action( (dir, conf) =>
@@ -32,13 +32,17 @@ object CLIGenerator extends App {
       conf.copy(workDir = dir)
     ).text("The directory to place the generated .scala files in (temp dir by default)")
 
-    opt[jio.File]('m', "model").optional().action( (mj, conf) =>
-      conf.copy(modelFile = mj.getAbsolutePath)
-    ).text("The description of the model's components (mapped to the name of the ecore with .sync.json extension by default)")
-
-    opt[Unit]('c', "cleanup").optional().action( (_, conf) =>
-      conf.copy(cleanUp = true)
+    opt[Boolean]('c', "cleanup").optional().action( (c, conf) =>
+      conf.copy(cleanUp = c)
     ).text("Remove the generated .scala files and only keep the compiled .class files")
+    
+    opt[jio.File]('j', "modelJoin").optional().action( (m, conf) =>
+      conf.copy(modelJoin = m.getAbsolutePath)
+    ).text("The description of a model join query to generate a view from.")
+    
+    opt[jio.File]('s', "syncLanguage").optional().action( (s, conf) =>
+      conf.copy(syncLanguage = s.getAbsolutePath)
+    ).text("The description of a synchronisation query to generate a synchronization behaviour from.")
   }
 
   parser.parse(args, GeneratorConfig()) match {
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/Creation.scala b/src/main/scala/org/rosi_project/model_sync/generator/Creation.scala
new file mode 100644
index 0000000000000000000000000000000000000000..c4813104f105308fdb226c38d8164855b4aaae96
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/Creation.scala
@@ -0,0 +1,6 @@
+package org.rosi_project.model_sync.generator
+
+object Creation extends Enumeration {
+  val rolesum, rolesync, rolecomb = Value
+  //val rsum, rsync = Value
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/EcoreLoader.scala b/src/main/scala/org/rosi_project/model_sync/generator/EcoreLoader.scala
index 350de718158c9b7cd5516c26ebca0695ac1a80e5..9824ab763b0c5e02f0e62bb6dd6a7abfecdfe3e3 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/EcoreLoader.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/EcoreLoader.scala
@@ -4,34 +4,53 @@ import org.eclipse.emf.common.util.URI
 import org.eclipse.emf.ecore.resource.Resource
 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
 import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl
-import org.eclipse.emf.ecore.{EObject, EPackage}
+import org.eclipse.emf.ecore.{ EObject, EPackage }
+import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl
+import scala.collection.JavaConverters._
+import java.io.File
+import org.rosi_project.model_sync.generator.util.ClassAndInstance
 
-/** Simple service to load an ECORE model from a file.
-  *
-  * @author Rico Bergmann
-  */
+/**
+ * Simple service to load an ECORE model from a file.
+ *
+ * @author Rico Bergmann
+ */
 class EcoreLoader {
 
-  /** Fetches an ecore model from XML.
-    *
-    * @param path where to find the model
-    * @return the model described by the XML
-    */
-  def loadEcore(path: String = "assets/ttc17.ecore"): EPackage = {
-    // see https://github.com/max-leuthaeuser/SCROLL/blob/dd269d5620257be1ea2f2044f398c090e9755fb3/core/src/main/scala/scroll/internal/ecore/ECoreImporter.scala
+  /**
+   * Fetches an ecore model from XML.
+   *
+   * @param path where to find the model
+   * @return the model described by the XML
+   */
+  def loadEcore(path: String = "assets/ttc17.ecore"): ClassAndInstance = {
     require(null != path && path.nonEmpty)
     val resourceSet = new ResourceSetImpl()
-    val _ = resourceSet.getResourceFactoryRegistry.getExtensionToFactoryMap.put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl())
+
+    resourceSet.getResourceFactoryRegistry.getExtensionToFactoryMap.put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl())
+
+    //resourceSet.getResourceFactoryRegistry.getExtensionToFactoryMap.put("ecore", new EcoreResourceFactoryImpl())
+    //resourceSet.getResourceFactoryRegistry.getExtensionToFactoryMap.put("xmi", new XMIResourceFactoryImpl())
     val res = resourceSet.getResource(URI.createFileURI(path), true)
     require(null != res)
     require(!res.getContents.isEmpty)
-    res.getContents.toArray(new Array[EObject](0)).toList.find(_.isInstanceOf[EPackage]).map((p: EObject) => p.asInstanceOf[EPackage]).orNull
+
+    val f = new File(path.replace(".ecore", ".ttmodel"))
+    if (f != null && f.exists()) {
+      val univEPackage = res.getContents().get(0);
+      resourceSet.getPackageRegistry().put("https://www.transformation-tool-contest.eu/2019/tt", univEPackage);
+      val myModel = resourceSet.getResource(URI.createURI(path.replace(".ecore", ".ttmodel")), true);
+      return new ClassAndInstance(res.getContents.toArray(new Array[EObject](0)).toList.find(_.isInstanceOf[EPackage]).map((p: EObject) => p.asInstanceOf[EPackage]).orNull,
+          myModel.getContents().toArray(new Array[EObject](0)).toList.head)
+    }
+    return new ClassAndInstance(res.getContents.toArray(new Array[EObject](0)).toList.find(_.isInstanceOf[EPackage]).map((p: EObject) => p.asInstanceOf[EPackage]).orNull, null)
   }
 
 }
 
-/** Exception to indicate that the model images may not be copied into the JAR.
-  *
-  * @param cause the causing exception
-  */
+/**
+ * Exception to indicate that the model images may not be copied into the JAR.
+ *
+ * @param cause the causing exception
+ */
 class EcoreLoadException(cause: Exception) extends RuntimeException(cause)
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/Generator.scala b/src/main/scala/org/rosi_project/model_sync/generator/Generator.scala
index 69c91044992b22cb5d4733834f2136c4360e7409..e27f9fd70f612f009c9a7a37b35f564231a2d42a 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/Generator.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/Generator.scala
@@ -1,72 +1,162 @@
 package org.rosi_project.model_sync.generator
 
-import net.liftweb.json._
 import org.eclipse.emf.ecore._
 import org.rosi_project.model_sync.generator.conversion.SModelGenerator
-import org.rosi_project.model_sync.generator.env.{CompilationException, JarPackaginException}
-import org.rosi_project.model_sync.generator.io.{ClassWritingException, ModelImagePreparationException, SModelFSWriter}
+import org.rosi_project.model_sync.generator.env.{ CompilationException, JarPackaginException }
+import org.rosi_project.model_sync.generator.io.{ ClassWritingException, ModelImagePreparationException, SModelFSWriter }
 
-import scala.io.Source
 import scala.reflect.io.File
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.acr_model.STypeRegistry
+import org.rosi_project.model_sync.model_join.representation.parser.antlr.AntlrBackedModelJoinParser
+import org.rosi_project.model_sync.generator.util.ClassAndInstance
 
-/** The `Generator` runs the whole workflow of generating a JAR of compiled Scala source files
-  * based on an ECORE file of some sync model.
-  *
-  * @param config the configuration that tells the generator where to locate the necessary files.
-  *
-  * @author Rico Bergmann
-  */
+/**
+ * The `Generator` runs the whole workflow of generating a JAR of compiled Scala source files
+ * based on an ECORE file of some sync model.
+ *
+ * @param config the configuration that tells the generator where to locate the necessary files.
+ *
+ * @author Rico Bergmann
+ */
 class Generator(config: GeneratorConfig) {
 
   /**
-    * Starts the generation.
-    */
+   * Starts the generation.
+   */
   def run(): Unit = {
+    //set package name of scala model files
+    if (config.create == Creation.rolesum)
+      PackageNames.sourcePkgPrefix = "sum."
+    if (config.create == Creation.rolesync)
+      PackageNames.sourcePkgPrefix = "sync."
+    if (config.create == Creation.rolecomb)
+      PackageNames.sourcePkgPrefix = ""
+        
     try {
-      val modelJson = Source.fromFile(config.getModelFile).getLines.mkString
-      implicit val jsonFormats: Formats = DefaultFormats
-      val modelCfg = parse(modelJson).extract[ModelConfig]
+      if (config.sources.isEmpty) {
+        println("Error: There must be any source file to generate something!!!")
+        return
+      }
 
-      var ecoreModel: EPackage = null
+      //read the ecore models
+      var ecoreModels: Map[String, ClassAndInstance] = Map.empty
       try {
-        ecoreModel = new EcoreLoader loadEcore config.source
-      }  catch {
+        config.sources.foreach(s => {
+          ecoreModels = ecoreModels + (s -> (new EcoreLoader loadEcore s))
+        })
+      } catch {
         case e: Exception => throw new EcoreLoadException(e)
       }
 
-      val sModel = new SModelGenerator convert ecoreModel
-      new SModelSyncPreparationService prepareModel(sModel, modelCfg)
+      //create s models from the incoming ecore models
+      var sModels: Map[SModel, ClassAndInstance] = Map.empty
+      ecoreModels.foreach(ec => {
+        sModels = sModels + ((new SModelGenerator convert (ec._2.pkg, ec._1)) -> ec._2)
+      })
+
+      sModels.foreach(sm => {
+        /*general stuff, that should always be created */
+        //create relational compartments (are only write out if not rolesync)          
+        new SModelRelationalCompartmentPreparationService prepareModel (sm._1)
+
+        //create the new classes for rsum and rsync
+        if (config.create == Creation.rolesync) {
+          //instance generation for rsync
+          if (sm._2.obj != null) {
+            new SModelSyncInstanceService prepareModel (sm._1, sm._2)
+          }
+          //add getter and setter for all methods
+          new SModelGetterSetterAllPreparationService prepareModel (sm._1)
+          //create the EMF Ecore reading models
+          new SModelSUMReadEMFService prepareModel (sm._1, config)
+          //add sync stuff
+          new SModelOnlySyncService prepareModel (sm._1)
+          //add ui provider stuff
+          new SModelSyncUiPreparationService prepareModel (sm._1, config.getModelConfigFromEcore(sm._1.getSourceName))
+        } else {
+          //add basic setter and getter
+          new SModelGetterSetterAttrPreparationService prepareModel (sm._1)
+          if (config.create == Creation.rolecomb) {
+            //add sync stuff
+            new SModelOnlySyncService prepareModel (sm._1)
+          }
+          //create the EMF Ecore reading models
+          new SModelSUMReadEMFService prepareModel (sm._1, config)
+          //instance generation for combi means rsum
+          if (sm._2.obj != null) {
+            new SModelCombiInstanceService prepareModel (sm._1, sm._2)
+          }
+          if (config.create == Creation.rolecomb) {
+            //add ref methods
+            new SModelCombiRefMethodService prepareModel (sm._1)
+          }
+          //remove references
+          new SModelSUMRemoveRefService prepareModel (sm._1)
+          //create view and query stuff
+          new SModelSUMPreparationService prepareModel (sm._1)
+        }
+
+      })
+
       // write the model and create the JAR
       println("... Writing model")
 
+      var finalModel: SModel = null
+      sModels.foreach(s => {
+        if (finalModel == null) {
+          finalModel = s._1
+        } else {
+          finalModel.addOtherModel(s._1)
+        }
+      })
+
+      if (config.create != Creation.rolesync) {
+        //create join stuff
+        val modelJoinFile = config.getModelJoinFile
+        if (modelJoinFile != null && modelJoinFile.exists()) {
+          var modelJoin = new AntlrBackedModelJoinParser().readOrThrow(modelJoinFile);
+          println(modelJoin);
+          //val modelJoin = DefaultModelJoinParser.read(modelJoinFile).get
+          modelJoin.setName(config.getModelJoinName)
+          new SModelJoinPreparationService prepareModel (finalModel, modelJoin)
+        }
+      }
+
       if (config.hasWorkDir) {
-        sModel.accept(
+        finalModel.accept(
           new SModelFSWriter(
+            config,
             outputDir = File(config.outDir).toDirectory,
             workingDir = File(config.workDir),
             keepClassFiles = !config.cleanUp,
-            modelCfg = modelCfg,
-            currentDir = config.getModelPath))
+            modelCfgs = config.getAllModelConfigs,
+            currentDir = config.getModelPath(finalModel.getSourceName)))
       } else {
-        sModel.accept(
+        finalModel.accept(
           new SModelFSWriter(
+            config,
             outputDir = File(config.outDir).toDirectory,
             keepClassFiles = !config.cleanUp,
-            modelCfg = modelCfg,
-            currentDir = config.getModelPath))
+            modelCfgs = config.getAllModelConfigs,
+            currentDir = config.getModelPath(finalModel.getSourceName)))
       }
-
-    }
-    catch {
+      println("... Done")
+    } catch {
       case ele: EcoreLoadException =>
+        throw ele
         println(s"** ERROR ** could not load ecore model: $ele")
       case mipe: ModelImagePreparationException =>
+        throw mipe
         println(s"** ERROR ** could not prepare model images: $mipe")
       case cwe: ClassWritingException =>
+        throw cwe
         println(s"** ERROR ** could not write classes: $cwe")
       case ce: CompilationException =>
+        throw ce
         println(s"** ERROR ** could not compile classes: $ce")
       case jpe: JarPackaginException =>
+        throw jpe
         println(s"** ERROR ** could not package JAR: $jpe")
     }
   }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/GeneratorConfig.scala b/src/main/scala/org/rosi_project/model_sync/generator/GeneratorConfig.scala
index 2d1a971fc94cf9febb32cd153100518c26525d98..3a21bea23333ace6a4d033e7c7b4c7a291f02e92 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/GeneratorConfig.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/GeneratorConfig.scala
@@ -1,17 +1,54 @@
 package org.rosi_project.model_sync.generator
 
 import java.io.File
+import scala.io.Source
+import net.liftweb.json._
 
 /** Wrapper for the different command line options for the [[Generator]]
   *
   * @author Rico Bergmann
   */
-case class GeneratorConfig(source: String = "", cleanUp: Boolean = false, outDir: File = new File(System.getProperty("user.dir")), workDir: File = null, modelFile: String = "") {
-
+case class GeneratorConfig(sources: Seq[String] = Seq(), 
+    cleanUp: Boolean = false, 
+    outDir: File = new File(System.getProperty("user.dir")), 
+    workDir: File = null,
+    modelJoin: String = null, //can be more than one
+    syncLanguage: String = null, //can be more than one
+    create: Creation.Value = Creation.rolesync) {
+  
   def hasWorkDir: Boolean = workDir != null
+  
+  private def getEcoreNames: Seq[String] = sources.map(_.split("/").last.replace(".ecore", ""))
+  
+  def getCombinedEcoreName: String = getEcoreNames.mkString
+  
+  def getModelConfigFromEcore(source: String): ModelConfig = { 
+    var modelCfgs: ModelConfig = null
+    var f = new File(source.replace(".ecore", ".sync.json"))
+    //println("---File: " + f.exists())
+    if (f == null || !f.exists()) return null
+    val modelJson = Source.fromFile(f).getLines.mkString
+    implicit val jsonFormats: Formats = DefaultFormats
+    parse(modelJson).extract[ModelConfig]
+  }
+  
+  def getAllModelConfigs: Set[ModelConfig] = { 
+    var configs: Set[ModelConfig] = Set.empty
+    sources.foreach(s => {
+      var modelCfg = getModelConfigFromEcore(s)
+      if (modelCfg != null) {
+        configs += modelCfg
+      }
+    })
+    configs
+  }
 
-  def getModelFile: File = if (modelFile.isEmpty) new File(source.replace(".ecore", ".sync.json")) else new File(modelFile)
-
-  def getModelPath: File = new File(source).getParentFile
+  def getModelPath(source: String): File = new File(source).getParentFile
+  
+  def getModelJoinFile: File = if(modelJoin == null) null else new File(modelJoin) 
+  
+  def getModelJoinName: String = modelJoin.split("/").last.replace(".modeljoin", "").capitalize
+  
+  def getSnchronizationFile: File = if(syncLanguage == null) null else new File(syncLanguage)
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/ModelConfig.scala b/src/main/scala/org/rosi_project/model_sync/generator/ModelConfig.scala
index abcd564426912f437e3bdb022225dcd0a16e372f..681ed98699eb040a9ee54995ed4e157c85fc167a 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/ModelConfig.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/ModelConfig.scala
@@ -1,8 +1,5 @@
 package org.rosi_project.model_sync.generator
 
-import org.rosi_project.model_sync.provider.DisplayableModel
-import org.rosi_project.model_sync.provider.ModelSyncProvider
-
 /** Representation of a model configuration (i.e. a number of corresponding models). It tells the
   * generator how the model looks like, which types are needed, etc.
   *
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/PackageNames.scala b/src/main/scala/org/rosi_project/model_sync/generator/PackageNames.scala
new file mode 100644
index 0000000000000000000000000000000000000000..60e87abbbfda997b4e850fba0f649a5c4985c1ef
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/PackageNames.scala
@@ -0,0 +1,24 @@
+package org.rosi_project.model_sync.generator
+
+object PackageNames {
+  
+  val multiInhertitanceWithTraits = false
+  
+  var sourcePkgPrefix: String = "" //sync. , sum.
+  
+  val viewPkgName: String = "view"
+  val viewPostName: String = "View"
+  val viewRolePostName: String = "Role"
+  
+  val queryPkgName: String = "query"
+  val queryPostName: String = "Query"
+  val queryRolePostName: String = "Role"
+  val queryHelperPrefix: String = "Helper"
+  
+  val joinPkgName: String = "join"
+  
+  val examplePkgName: String = "example"
+  
+  val creationPkgName: String = "creation"
+  
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiInstanceService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiInstanceService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..348b2e34752a81d9d5115f95fc17c519ecc20ad6
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiInstanceService.scala
@@ -0,0 +1,22 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.util.ClassAndInstance
+import org.rosi_project.model_sync.generator.sync.InstanceCombiGenerator
+
+/** Simple service to create instances.
+  * For the combination of sum and sync.
+  * 
+  * @author Christopher Werner
+  */
+class SModelCombiInstanceService {
+  
+  /** Add a new class to the [[SModel]] to instantiate it.
+    *
+    * @param sModel the model to augment
+    */
+  def prepareModel(sModel: SModel, clsAins: ClassAndInstance): Unit = {
+    val insgenerator = new InstanceCombiGenerator(clsAins)
+    sModel.accept(insgenerator)   
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiRefMethodService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiRefMethodService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..e83e64902196fc30fbee8052a520ec9240f52819
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelCombiRefMethodService.scala
@@ -0,0 +1,23 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.sync.ReferenceMethodCreationVisitor
+
+/**
+ * Add a method to get all references in the RSUM case.
+ *  Sync functions necessary because we need compartment functions in the naturals.
+ *
+ * @author Christopher Werner
+ */
+class SModelCombiRefMethodService {
+
+  /**
+   * Remove reference from model classes.
+   *
+   * @param sModel the model to augment
+   */
+  def prepareModel(sModel: SModel): Unit = {
+    val refMethodVisitor = new ReferenceMethodCreationVisitor
+    sModel.accept(refMethodVisitor)
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAllPreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAllPreparationService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..8978200b02c671162c24a2d813b21ae62ab2eb33
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAllPreparationService.scala
@@ -0,0 +1,21 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.sync.GetterSetterGeneratingVisitor
+
+/** Simple service that adds getter and setter for Attributes and References.
+  *
+  * @author Christopher Werner
+  */
+class SModelGetterSetterAllPreparationService {
+
+  /** Adds getter and setter for Attributes and References.
+    *
+    * @param sModel the model to augment
+    */
+  def prepareModel(sModel: SModel): Unit = {
+    val getterSetterVisitor = new GetterSetterGeneratingVisitor
+    sModel.accept(getterSetterVisitor)
+  }
+
+}
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAttrPreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAttrPreparationService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..0826de0a411ce9cc99125f7f788d11a5764bf874
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelGetterSetterAttrPreparationService.scala
@@ -0,0 +1,16 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.sync.BasicTypeGetterSetterGeneratingVisitor
+import org.rosi_project.model_sync.generator.acr_model.SModel
+
+class SModelGetterSetterAttrPreparationService {
+  
+  /** Adds getter and setter for Attributes.
+    *
+    * @param sModel the model to augment
+    */
+  def prepareModel(sModel: SModel): Unit = {
+    val getterSetterVisitor = new BasicTypeGetterSetterGeneratingVisitor   
+    sModel.accept(getterSetterVisitor)
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelJoinPreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelJoinPreparationService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..bef7cb7b7664f90a9990c21159f8c24ec4b70c1a
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelJoinPreparationService.scala
@@ -0,0 +1,26 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.model_join.representation.grammar.ModelJoinExpression
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.sync.JoinGeneratingVisitor
+import org.rosi_project.model_sync.generator.sync.ModelJoinViewGeneratingVisitor
+
+/** Simple service to create join classes and objects for ModelJoin.
+  *
+  * @author Christopher Werner
+  */
+class SModelJoinPreparationService {
+  
+  /** Augments a [[SModel]] with new JoinClasses and JoinObjects.
+    *
+    * @param sModel the model to augment
+    * modelJoin input
+    */
+  def prepareModel(sModel: SModel, joinExpression: ModelJoinExpression): Unit = {
+    val joinVisitor = new JoinGeneratingVisitor(joinExpression)
+    val modelJoinVisitor = new ModelJoinViewGeneratingVisitor(joinExpression)
+    //order is important !!!!    
+    sModel.accept(joinVisitor)
+    sModel.accept(modelJoinVisitor)
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelOnlySyncService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelOnlySyncService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..9963e8d0b122f566f5c7fe5a3e77f72ac674f249
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelOnlySyncService.scala
@@ -0,0 +1,21 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.sync.SyncEnhancingVisitor
+
+/** Simple service to perform only extension and method statement add.
+  *
+  * @author Christopher Werner
+  */
+class SModelOnlySyncService {
+  
+  /** Augments a [[SModel]] with the necessary methods and statements to make it usable in a
+    * synchronization context.
+    *
+    * @param sModel the model to augment
+    */
+  def prepareModel(sModel: SModel): Unit = {
+    val syncNotificationVisitor = new SyncEnhancingVisitor
+    sModel.accept(syncNotificationVisitor)    
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelRelationalCompartmentPreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelRelationalCompartmentPreparationService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..8efb2081eaf7c844d8c71024c0ff21c455f9056c
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelRelationalCompartmentPreparationService.scala
@@ -0,0 +1,20 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.sync._
+
+/** Simple service to create relational compartments for each relation.
+  *
+  * @author Christopher Werner
+  */
+class SModelRelationalCompartmentPreparationService {
+  
+  /** Create relational compartments for each relation.
+    *
+    * @param sModel the model to augment
+    */
+  def prepareModel(sModel: SModel): Unit = {
+    val relationCompartmentVisitor = new RelationCompartmentGeneratingVisitor
+    sModel.accept(relationCompartmentVisitor)
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMPreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMPreparationService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..9fb7454efa83d0739814bc265a87344a44c598e0
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMPreparationService.scala
@@ -0,0 +1,26 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.sync._
+
+/** Add functionality for Queries and Views to the RSUM.
+  *
+  * @author Christopher Werner
+  */
+class SModelSUMPreparationService {
+  
+  /** Add functionality for Queries and Views to the RSUM.
+    *
+    * @param sModel the model to augment
+    */
+  def prepareModel(sModel: SModel): Unit = {
+    val queryHelperVisitor = new GenerateQueryHelperVisitor
+    val viewGenerationVisitor = new ViewGeneratingVisitor
+    val queryGenerationVisitor = new QueryGeneratingVisitor
+
+    //order is important !!!!
+    sModel.accept(viewGenerationVisitor)
+    sModel.accept(queryHelperVisitor)
+    sModel.accept(queryGenerationVisitor)
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMReadEMFService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMReadEMFService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..c23ffa0fc0094e3a3beccb31ec4ab0fd784bc6df
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMReadEMFService.scala
@@ -0,0 +1,20 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.sync.SumModelReadingVisitor
+import org.rosi_project.model_sync.generator.acr_model.SModel
+
+/** Simple service to create the new emf ecore model instances.
+  *
+  * @author Christopher Werner
+  */
+class SModelSUMReadEMFService {
+  
+  /** Add classes to read emf and ecore models.
+    *
+    * @param sModel the model to augment
+    */
+  def prepareModel(sModel: SModel, config: GeneratorConfig): Unit = {
+    val sumModelReadingVisitor = new SumModelReadingVisitor(config)
+    sModel.accept(sumModelReadingVisitor)    
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMRemoveRefService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMRemoveRefService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..b389f9f65c9a28e0c9ba15e801c411fc448a29fd
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelSUMRemoveRefService.scala
@@ -0,0 +1,22 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.sync.ReferenceRemoveVisitor
+
+/** Remove references from model classes.
+  *
+  * @author Christopher Werner
+  */
+class SModelSUMRemoveRefService {
+  
+  /** Remove reference from model classes.
+    *
+    * @param sModel the model to augment
+    */
+  def prepareModel(sModel: SModel): Unit = {
+    val removeReferencesVisitor = new ReferenceRemoveVisitor
+
+    //order is important !!!!    
+    sModel.accept(removeReferencesVisitor)
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelSyncInstanceService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelSyncInstanceService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..7d7d7be4265f3c0451e55b8fbde053d8692a28b1
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelSyncInstanceService.scala
@@ -0,0 +1,21 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.util.ClassAndInstance
+import org.rosi_project.model_sync.generator.sync.InstanceGenerator
+
+/** Simple service to create instances.
+  *
+  * @author Christopher Werner
+  */
+class SModelSyncInstanceService {
+  
+  /** Add a new class to the [[SModel]] to instantiate it.
+    *
+    * @param sModel the model to augment
+    */
+  def prepareModel(sModel: SModel, clsAins: ClassAndInstance): Unit = {
+    val insgenerator = new InstanceGenerator(clsAins)
+    sModel.accept(insgenerator)   
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelSyncPreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelSyncPreparationService.scala
deleted file mode 100644
index 130f2527eae224b7fed30dcf4295e0b1ed7fa876..0000000000000000000000000000000000000000
--- a/src/main/scala/org/rosi_project/model_sync/generator/SModelSyncPreparationService.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.rosi_project.model_sync.generator
-
-import org.rosi_project.model_sync.generator.acr_model.SModel
-import org.rosi_project.model_sync.generator.sync.{GetterSetterGeneratingVisitor, SyncEnhancingVisitor}
-
-/** Simple service to perform all the necessary adaptions of an [[SModel]] to make applicable for
-  * synchronization.
-  *
-  * @author Rico Bergmann
-  */
-class SModelSyncPreparationService {
-
-  /** Augments a [[SModel]] with the necessary methods and statements to make it usable in a
-    * synchronization context.
-    *
-    * @param sModel the model to augment
-    */
-  def prepareModel(sModel: SModel, modelCfg: ModelConfig): Unit = {
-    val getterSetterVisitor = new GetterSetterGeneratingVisitor
-    val syncNotificationVisitor = new SyncEnhancingVisitor(modelCfg)
-
-    sModel.accept(getterSetterVisitor)
-    sModel.accept(syncNotificationVisitor)
-  }
-
-}
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/SModelSyncUiPreparationService.scala b/src/main/scala/org/rosi_project/model_sync/generator/SModelSyncUiPreparationService.scala
new file mode 100644
index 0000000000000000000000000000000000000000..ec0615efb44ae122e3c9eb27d52edbe6947d6f2b
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/SModelSyncUiPreparationService.scala
@@ -0,0 +1,24 @@
+package org.rosi_project.model_sync.generator
+
+import org.rosi_project.model_sync.generator.acr_model.SModel
+import org.rosi_project.model_sync.generator.ui.SyncUiVisitor
+
+/** Simple service to add all the necessary adaption classes of an [[SModel]] to make applicable for
+  * synchronization user interface.
+  *
+  * @author Christopher Werner
+  */
+class SModelSyncUiPreparationService {
+  
+  /** Add UI provider functionality too a [[SModel]] with the necessary methods and statements to make it usable
+    * in the user interface.
+    *
+    * @param sModel the model to augment
+    */
+  def prepareModel(sModel: SModel, modelCfg: ModelConfig): Unit = {
+    if (modelCfg != null) {
+      val syncUiVisitor = new SyncUiVisitor(modelCfg)
+      sModel.accept(syncUiVisitor)
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/ComplexSModel.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/ComplexSModel.scala
new file mode 100644
index 0000000000000000000000000000000000000000..442b904cc1b67a5b1951d8db6bab0906f265e683
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/ComplexSModel.scala
@@ -0,0 +1,133 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+import org.rosi_project.model_sync.generator.support.Assert
+
+/**
+ * Complex implementation of the [[SModel]].
+ *
+ * @author Christopher Werner
+ */
+class ComplexSModel(name: String, sourceName: String, nsUri: String) extends SModel(name, sourceName, nsUri) {
+
+  private var modelClasses: Set[SClass] = Set.empty
+  private var providerClasses: Set[SClass] = Set.empty
+  private var relationalCompartments: Set[SClass] = Set.empty
+  private var viewCompartments: Set[SClass] = Set.empty
+  private var joinClasses: Set[SClass] = Set.empty
+  private var sEnums: Set[SEnum] = Set.empty
+
+  /** Provides all model classes in `this` model. */
+  override def getModelClasses: Set[SClass] = modelClasses
+
+  /** Provides all provider classes in `this` model. */
+  override def getProviderClasses: Set[SClass] = providerClasses
+
+  /** Provides all relational compartments in `this` model. */
+  override def getRelationalCompartments: Set[SClass] = relationalCompartments
+
+  /** Provides all view compartments in `this` model. */
+  override def getViewCompartments: Set[SClass] = viewCompartments
+
+  /** Provides all the classes in `this` model. */
+  override def getAllClasses: Set[SClass] = modelClasses ++ providerClasses ++ relationalCompartments ++ viewCompartments
+
+  /** Provides all join classes in `this` model. */
+  override def getJoinClasses: Set[SClass] = joinClasses
+
+  /** Provides all model enums in `this` model. */
+  override def getModelEnums: Set[SEnum] = sEnums
+
+  /**
+   * Extends the model by a new provder class.
+   *
+   * @param mClass the class to add. May never `null`.
+   */
+  override def addProviderClass(mClass: SClass): Unit = {
+    Assert.notNull(mClass, "Class may not be null")
+    providerClasses += mClass
+  }
+
+  /**
+   * Extends the model by a new relational compartment.
+   *
+   * @param mClass the class to add. May never `null`.
+   */
+  override def addRelationalCompartment(mClass: SClass): Unit = {
+    Assert.notNull(mClass, "Class may not be null")
+    relationalCompartments += mClass
+  }
+
+  /**
+   * Extends the model by a new view compartment.
+   *
+   * @param mClass the class to add. May never `null`.
+   */
+  override def addViewCompartment(mClass: SClass): Unit = {
+    Assert.notNull(mClass, "Class may not be null")
+    viewCompartments += mClass
+  }
+
+  /**
+   * Extends the model by a new class.
+   *
+   * @param mClass the class to add. May never `null`.
+   */
+  override def addModelClass(mClass: SClass): Unit = {
+    Assert.notNull(mClass, "Class may not be null")
+    modelClasses += mClass
+  }
+
+  /**
+   * Extends the model by a new join class.
+   *
+   * @param mClass the class to add. May never `null`.
+   */
+  override def addJoinClass(mClass: SClass): Unit = {
+    Assert.notNull(mClass, "Class may not be null")
+    joinClasses += mClass
+  }
+
+  /**
+   * Extends the model by a new enum.
+   *
+   * @param mEnum the enum to add. May never `null`.
+   */
+  override def addModelEnums(mEnum: SEnum): Unit = {
+    Assert.notNull(mEnum, "Enum may not be null")
+    sEnums += mEnum
+  }
+
+  override def accept(visitor: SModelVisitor): Unit = {
+    getAllClasses.foreach(_.accept(visitor))
+    visitor.visit(this)
+  }
+
+  def canEqual(other: Any): Boolean = other.isInstanceOf[SimpleSModel]
+
+  override def equals(other: Any): Boolean = other match {
+    case that: ComplexSModel =>
+      (that canEqual this) &&
+        modelClasses == that.modelClasses &&
+        providerClasses == that.providerClasses &&
+        relationalCompartments == that.relationalCompartments &&
+        viewCompartments == that.viewCompartments &&
+        joinClasses == that.joinClasses &&
+        sEnums == that.sEnums
+    case _ => false
+  }
+
+  override def addOtherModel(model: SModel): SModel = {
+    modelClasses = modelClasses ++ model.getModelClasses
+    providerClasses = providerClasses ++ model.getProviderClasses
+    relationalCompartments = relationalCompartments ++ model.getRelationalCompartments
+    viewCompartments = viewCompartments ++ model.getViewCompartments
+    joinClasses = joinClasses ++ model.getJoinClasses
+    sEnums = sEnums ++ model.getModelEnums
+    return this
+  }
+
+  override def hashCode(): Int = {
+    val state = Seq(getAllClasses)
+    state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b)
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/GenericSType.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/GenericSType.scala
index 0a1cb48ef2b5a2fbbf3b46639e6ffc2a0e6f81ab..e43dda49bd7ebf717667f51d26cc4fb28e3b7f2b 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/GenericSType.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/GenericSType.scala
@@ -11,6 +11,8 @@ package org.rosi_project.model_sync.generator.acr_model
 class GenericSType(name: String, sPackage: String = "", val typeParam: STypedElement) extends SType(name, sPackage) {
 
   override def getName: String = s"$name[${typeParam.getName}]"
+  
+  override def getDeepName: String = s"$name[${typeParam.getDeepName}]"
 
   override def getNecessaryImports: Set[SImport] = if (typeParam.getPackage.isEmpty || typeParam.getPackage == sPackage)
     typeParam.getNecessaryImports + SImport(typeParam.getPackage, typeParam.getName) else typeParam.getNecessaryImports
@@ -20,6 +22,6 @@ class GenericSType(name: String, sPackage: String = "", val typeParam: STypedEle
   */
 object GenericSType {
 
-  def unapply(arg: GenericSType): Option[(String, String, STypedElement)] = Some((arg.name, arg.sPackage, arg.typeParam))
+  def unapply(arg: GenericSType): Option[(String, String, STypedElement)] = Some((arg.getName, arg.sPackage, arg.typeParam))
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/MethodVisibility.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/MethodVisibility.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f06d8cfb99145309fe34fe68aaf5213176e9aaaa
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/MethodVisibility.scala
@@ -0,0 +1,5 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+object MethodVisibility extends Enumeration {
+  val privateVis, protectedVis, publicVis, privateExternalClass = Value
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SAttribute.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SAttribute.scala
index 72c7beaace32d66527a258b06268b1361bdb40dc..fb622e47c81e358fcc8f993fc97876542941c262 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SAttribute.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SAttribute.scala
@@ -6,16 +6,10 @@ package org.rosi_project.model_sync.generator.acr_model
   *
   * @author Rico Bergmann
   */
-case class SAttribute(name: String, attrType: STypedElement) extends SModelElement {
-
-  /** Provides the type of `this` attribute as a `String`.
-    *
-    * @return the type. Will never be `null` nor empty.
-    */
-  def getType: String = attrType.getName
+case class SAttribute(_name: String, _type: STypedElement, val unique: Boolean = false) extends SStructuralFeature(_name, _type) {
 
   override def accept(visitor: SModelVisitor): Unit = visitor.visit(this)
 
-  override def toString: String = s"$name: $getType"
+  override def toString: String = s"$getName: ${getTypeElement.getName} $unique"
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala
index fe3882754e85ae49eef024d526df59bf15d71a73..8344eb7a214fe5c6e49f0bea675984bc107fb921 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClass.scala
@@ -1,44 +1,101 @@
 package org.rosi_project.model_sync.generator.acr_model
 
 import java.util.Objects
+import org.rosi_project.model_sync.generator.acr_model.types.SSeq
+import org.rosi_project.model_sync.generator.acr_model.types.GenericSequence
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.rosi_project.model_sync.generator.sync.ToStringMethods
+
+/**
+ * Representation of Scala classes. Attributes, methods, etc. have their own wrappers which should
+ * be used to modify these individual parts of the class.
+ *
+ * @see [[SType]]
+ * @author Rico Bergmann
+ */
+class SClass(_name: String,
+             _sPackage: String = "",
+             _sClassType: SClassType.Value = SClassType.normalClass) extends STypedElement(_name, _sPackage, _sClassType) {
+
+  protected var parentClass: STypedElement = null
+  protected var parentInterfaces: Seq[STypedElement] = Seq.empty
+  protected var internalClasses: Seq[SInnerClass] = Seq.empty
+
+  protected var attributes: Seq[SAttribute] = Seq.empty
+  protected var references: Seq[SReference] = Seq.empty
+
+  protected var methods: Seq[SMethod] = Seq.empty
+  protected var constructorStatements: Seq[SMethodStatement] = Seq.empty
 
-/** Representation of Scala classes. Attributes, methods, etc. have their own wrappers which should
-  * be used to modify these individual parts of the class.
-  *
-  * @see [[SType]]
-  * @author Rico Bergmann
-  */
-class SClass(val name: String,
-             val sPackage: String = "",
-             var attributes: Seq[SAttribute] = Seq.empty,
-             var parent: STypedElement = null,
-             protected var methods: Seq[SMethod] = Seq.empty)
-  extends STypedElement {
+  def getClassParent: STypedElement = parentClass
 
-  protected var constructorStatements: Seq[SMethodStatement] = Seq.empty
+  def getInterfaceParents: Seq[STypedElement] = parentInterfaces
 
-  /** Provides code that should be executed when invoking the constructor.
-    */
-  def getAdditionalConstructorStatements: Seq[SMethodStatement] = constructorStatements
+  def getStructuralFeatures: Seq[SStructuralFeature] = attributes ++ references
 
-  /** Checks, whether `this` is part of the default package
-    */
-  def isDefaultPackage: Boolean = sPackage == ""
+  def getInternalClasses: Seq[SInnerClass] = internalClasses
 
-  /** Checks, whether `this` extends any other classes. If this is the case, it is '''not'''
-    * considered a ''root class'', otherwise it is.
-    */
-  def isRootClass: Boolean = parent == null
+  def getDeepStructuralFeatures: Seq[SStructuralFeature] = {
+    val cls = getClassParent
+    if (cls == null) {
+      attributes ++ references
+    } else {
+      cls match {
+        case parentAsSClass: SClass =>
+          attributes ++ references ++ parentAsSClass.getDeepStructuralFeatures
+        case _ =>
+          attributes ++ references
+      }
+    }
+  }
 
-  /** Provides the set of all symbols that have to be imported in order to use `this` complete
-    * class.
-    */
-  def collectImports: Set[String] = getNecessaryImports.map(imp => s"${imp.pckg}.${imp.name}")
+  def getOnlyDeepAttributes: Seq[SAttribute] = {
+    val cls = getClassParent
+    if (cls == null) {
+      attributes
+    } else {
+      cls match {
+        case parentAsSClass: SClass =>
+          attributes ++ parentAsSClass.getOnlyDeepAttributes
+        case _ =>
+          attributes
+      }
+    }
+  }
+
+  def getOnlyDeepReferences: Seq[SReference] = {
+    val cls = getClassParent
+    if (cls == null) {
+      references
+    } else {
+      cls match {
+        case parentAsSClass: SClass =>
+          references ++ parentAsSClass.getOnlyDeepReferences
+        case _ =>
+          references
+      }
+    }
+  }
+  
+  override def proofHierarchicalEquality(sType: STypedElement): Boolean = {
+    if (sType == this) {
+      return true
+    } else {
+      this.getAllParents().foreach(p => {
+        if (p.proofHierarchicalEquality(sType)) {
+          return true
+        }
+      })
+      return false
+    }
+    
+  }
 
-  /** Augments `this` class with another method.
-    *
-    * @param m the additional method. May not be `null`
-    */
+  /**
+   * Augments `this` class with another method.
+   *
+   * @param m the additional method. May not be `null`
+   */
   def addMethod(m: SMethod): Unit = {
     Objects.requireNonNull(m, "Method to add may not be null")
     if (methods.contains(m)) {
@@ -47,48 +104,96 @@ class SClass(val name: String,
     methods = methods :+ m
   }
 
+  /**
+   * Gets the methods of `this` class.
+   *  And adds a to String if not exists.
+   */
   def getMethods: Seq[SMethod] = {
-    if (methods.exists(_.name == "toString")) {
+    if (methods.exists(_.getName == "toString")) {
       methods
     } else {
-      methods :+ new SMethod(
-        name = "toString",
-        result = SType.String,
-        params = Seq.empty,
-        implementation = Seq(SMethodStatement((List(s"""  "$name: " """) ++ attributes.map(attr => s""" "${attr.name}=" + ${attr.name} + " " """)).mkString(" + "))),
-        overrides = true
-      )
+      methods :+ ToStringMethods.normalToStringMethod(this)
     }
   }
 
-  /** Augments the constructor by another statement. The statement will be executed lastly (though
-    * this may change due to further modifications of the constructor).
-    *
-    * @param statement the new statement. May not be `null`
-    */
-  def augmentConstructor(statement: SMethodStatement): Unit = {
-    Objects.requireNonNull(statement, "Statement to add may not be null")
-    constructorStatements = constructorStatements :+ statement
+  /** Gets the parents of `this` class. */
+  def getAllParents(): Seq[STypedElement] = {
+    if (parentInterfaces.isEmpty && parentClass == null) {
+      return Seq.empty
+    }
+    if (parentInterfaces.isEmpty) {
+      return Seq(parentClass)
+    }
+    if (parentClass == null) {
+      return parentInterfaces
+    }
+    parentInterfaces :+ parentClass
+  }
+
+  /**
+   * Adds a internal class to `this` class.
+   *
+   * If `parent == this or null` nothing will happen.
+   */
+  def addInternalClass(internal: SInnerClass): Unit = {
+    if (internal == null || internal == this) {
+      return
+    }
+    if (internalClasses.contains(internal)) {
+      return
+    }
+    internalClasses = internalClasses :+ internal
   }
 
-  /** Makes `this` class a subclass of `parent`.
-    *
-    * If `parent == this` nothing will happen.
-    *
-    * @param parent the superclass. May be `null` to indicate that there is no superclass (other
-    *               than `AnyRef`)
-    */
-  def setParent(parent: STypedElement): Unit = {
-    if (parent == this) {
+  /**
+   * Makes `this` class a subclass of `parent`.
+   *
+   * If `parent == this` nothing will happen.
+   *
+   * @param parent the superclass. May be `null` to indicate that there is no superclass (other
+   *               than `AnyRef`)
+   */
+  def addParent(parent: STypedElement): Unit = {
+    if (parent == null || parent == this || parentClass == parent || parentInterfaces.contains(parent)) {
       return
     }
-    this.parent = parent
+    if (parent.isInterface) {
+      parentInterfaces = parentInterfaces :+ parent
+    } else {
+      if (parentClass == null) {
+        parentClass = parent
+      } else {
+        //print error message here
+        println("!!!Cannot add parent because their is one parent that is no interface!!!")
+      }
+    }
+    
+  }
+
+  /** Gets the references of `this` class. */
+  def getReferences(): Seq[SReference] = references
+
+  /**
+   * Sets the references of `this` class.
+   *
+   * @param refs the references. May be `null` to remove all current references.
+   */
+  def setReferences(refs: Seq[SReference]): Unit = {
+    if (refs == null) {
+      this.references = Seq.empty
+    } else {
+      this.references = refs
+    }
   }
 
-  /** Sets the attributes of `this` class.
-    *
-    * @param attrs the attributes. May be `null` to remove all current attributes.
-    */
+  /** Gets the attributes of `this` class. */
+  def getAttributes(): Seq[SAttribute] = attributes
+
+  /**
+   * Sets the attributes of `this` class.
+   *
+   * @param attrs the attributes. May be `null` to remove all current attributes.
+   */
   def setAttributes(attrs: Seq[SAttribute]): Unit = {
     if (attrs == null) {
       this.attributes = Seq.empty
@@ -97,123 +202,204 @@ class SClass(val name: String,
     }
   }
 
-  /** Provides all types `this` classes accesses in some way.
-    */
-  def getUsedTypes: Set[STypedElement] = {
-    val parentImport: Seq[STypedElement] = if (isRootClass) List() else List(parent)
+  /** Provides code that should be executed when invoking the constructor. */
+  def getAdditionalConstructorStatements: Seq[SMethodStatement] = constructorStatements
 
-    val parentConstructorParamImports: Seq[STypedElement] = if (isRootClass) List() else parent match {
-      case parent: SClass => parent.attributes.map(_.attrType)
+  /**
+   * Checks, whether `this` extends any other classes. If this is the case, it is '''not'''
+   * considered a ''root class'', otherwise it is.
+   * Interfaces are not checked.
+   */
+  def isRootClass: Boolean = parentClass == null
+  
+  def isAbsoluteRootClassOrInterface: Boolean = parentClass == null && parentInterfaces.isEmpty
+
+  def getRootClassWithNameAndPackage(n: String, p: String): SClass = {
+    var parent = this
+    while (!parent.isRootClass) {
+      if (parent.getClassParent.isInstanceOf[SClass]) {
+        parent = parent.getClassParent.asInstanceOf[SClass]
+        if (parent.getName == n && parent.getPackage == p) {
+          return parent
+        }
+      }
+    }
+    return null
+  }
+
+  /**
+   * Provides the set of all symbols that have to be imported in order to use `this` complete
+   * class.
+   */
+  def collectImports: Set[String] = getNecessaryImports.map(imp => s"${imp.pckg}.${imp.name}")
+
+  /**
+   * Augments the constructor by another statement. The statement will be executed lastly (though
+   * this may change due to further modifications of the constructor).
+   *
+   * @param statement the new statement. May not be `null`
+   */
+  def augmentConstructor(statement: SMethodStatement): Unit = {
+    Objects.requireNonNull(statement, "Statement to add may not be null")
+    constructorStatements = constructorStatements :+ statement
+  }
+
+  override def getAllConstructorParameters: Seq[SMethodParameter] = {
+    val ownParams = getStructuralFeatures.map(attr => SMethodParameter(attr.getName, attr.getTypeElement))
+    val parentParams = if (isRootClass) List() else getClassParent.getAllConstructorParameters
+    ownParams ++ parentParams
+  }
+
+  override def getAttributeConstructorParameters: Seq[SMethodParameter] = {
+    val ownParams = getAttributes.map(attr => SMethodParameter(attr.getName, attr.getTypeElement))
+    val parentParams = if (isRootClass) List() else getClassParent.getAttributeConstructorParameters
+    ownParams ++ parentParams
+  }
+
+  override def getInheritanceHierarchy: Seq[STypedElement] = if (isRootClass) List(this) else this +: getClassParent.getInheritanceHierarchy
+
+  /** Provides all types `this` classes accesses in some way. */
+  def getUsedTypes: Set[STypedElement] = {
+    //iterate over construction features of parent types
+    val parentConstructorParamImports: Seq[STypedElement] = if (isRootClass) List() else getClassParent match {
+      case parent: SClass =>
+        parent.getDeepStructuralFeatures.map(_.getTypeElement)
       case _ => List()
     }
 
-    val attrTypeImports: Seq[STypedElement] = attributes.map(_.attrType)
+    //attribute types
+    val attrTypeImports: Seq[STypedElement] = attributes.map(_.getTypeElement)
 
+    //reference types
+    val refTypeImports: Seq[STypedElement] = references.map(_.getTypeElement)
+
+    //method types
     val methodResultImports: Seq[STypedElement] = methods.map(_.result)
 
-    val methodParamImports: Seq[STypedElement] = methods.flatMap(_.params).map(_.paramType)
+    val methodParamImports: Seq[STypedElement] = methods.flatMap(_.params).map(_.getType)
 
     val methodImplImports: Seq[STypedElement] = methods.flatMap(_.getUsedTypes.toList)
 
-    // create a set to eliminate duplicates
-    (parentImport
+    val allImports: Seq[STypedElement] = (getAllParents
       ++ parentConstructorParamImports
       ++ attrTypeImports
+      ++ refTypeImports
       ++ methodResultImports
       ++ methodParamImports
-      ++ methodImplImports).toSet
-  }
+      ++ methodImplImports)
 
-  override def getName: String = name
+    var allCleanImports: Seq[STypedElement] = Seq.empty
 
-  override def getPackage: String = sPackage
+    allImports.foreach(i => {
+      i match {
+        case seq: GenericSequence =>
+          allCleanImports = allCleanImports :+ seq.typeParam
+        case t: STypedElement =>
+          allCleanImports = allCleanImports :+ t
+        //case _ => 
+      }
+    })
 
-  override def getConstructorParameters: Seq[SMethodParameter] = {
-    val ownParams = attributes.map(attr => SMethodParameter(attr.name, attr.attrType))
-    val parentParams = if (isRootClass) List() else parent.getConstructorParameters
-    ownParams ++ parentParams
+    // create a set to eliminate duplicates
+    allCleanImports.toSet
   }
 
-  override def getInheritanceHierarchy: Seq[STypedElement] = if (isRootClass) List(this) else this +: parent.getInheritanceHierarchy
-
   override def getNecessaryImports: Set[SImport] = {
-    val parentImport: List[SImport] = if (isRootClass) List() else includeImportIfNecessary(parent.getPackage, parent.getName)
-
-    val parentConstructorParamImports: List[SImport] = if (isRootClass) List() else parent match {
-      case parent: SClass =>
-        parent.attributes
-          .map(attr => includeImportIfNecessary(attr.attrType.getPackage, attr.attrType.getName))
-          .fold(List())((l1, l2) => l1 ++ l2)
-      case _ => List()
+    var allImports: List[SImport] = List.empty
+    //iterate over all parent types
+    getAllParents().foreach(p => {
+      allImports = includeImportIfNecessary(p, allImports)
+    })
+
+    //iterate over construction features of parent types
+    if (!isRootClass) {
+      getClassParent match {
+        case parent: SClass =>
+          parent.getDeepStructuralFeatures.foreach(p => {
+            allImports = includeImportIfNecessary(p.getTypeElement, allImports)
+          })
+        case _ =>
+      }
     }
 
-    val attrTypeImports: List[SImport] =
-      attributes
-        .map(attr => includeImportIfNecessary(attr.attrType.getPackage, attr.getType))
-        .fold(List())((l1, l2) => l1 ++ l2)
-
-    val methodResultImports: List[SImport] =
-      methods
-        .map(_.result)
-        .map(res => includeImportIfNecessary(res.getPackage, res.getName))
-        .fold(List())((l1, l2) => l1 ++ l2)
-
-    val methodParamImports: List[SImport] =
-      methods
-        .map(_.params)
-        .fold(List())((l1, l2) => l1 ++ l2)
-        .map(param => includeImportIfNecessary(param.paramType.getPackage, param.paramType.getName))
-        .fold(List())((l1, l2) => l1 ++ l2)
-
-    val methodImplImports: List[SImport] =
-      methods
-        .map(_.getUsedTypes.toList)
-        .fold(List())((l1, l2) => l1 ++ l2)
-        .map(typ => includeImportIfNecessary(typ.getPackage, typ.getName))
-        .fold(List())((l1, l2) => l1 ++ l2)
+    //iterate over all attributes
+    attributes.foreach(a => {
+      allImports = includeImportIfNecessary(a.getTypeElement, allImports)
+    })
+
+    //iterate over all references
+    references.foreach(r => {
+      allImports = includeImportIfNecessary(r.getTypeElement, allImports)
+    })
+
+    //iterated over all methods
+    methods.foreach(m => {
+      //iterate over result types
+      allImports = includeImportIfNecessary(m.result, allImports)
+      //iterate over parameter types
+      m.params.foreach(p => {
+        allImports = includeImportIfNecessary(p.getType, allImports)
+      })
+      //iterate over used types in the method
+      m.getUsedTypes.foreach(t => {
+        allImports = includeImportIfNecessary(t, allImports)
+      })
+    })
+
+    //iterate over all construction statements
+    constructorStatements.foreach(s => {
+      s.usedTypes.foreach(t => {
+        allImports = includeImportIfNecessary(t, allImports)
+      })
+    })
 
     // create a set to eliminate duplicates
-    (parentImport
-      ++ parentConstructorParamImports
-      ++ attrTypeImports
-      ++ methodResultImports
-      ++ methodParamImports
-      ++ methodImplImports).toSet
+    (allImports).toSet
   }
 
   override def accept(visitor: SModelVisitor): Unit = {
     attributes.foreach(_.accept(visitor))
+    references.foreach(_.accept(visitor))
     methods.foreach(_.accept(visitor))
     visitor.visit(this)
   }
 
   protected def canEqual(other: Any): Boolean = other.isInstanceOf[SClass]
 
-  /** Checks if some class has to be imported in order to be usable from `this` class. If this
-    * is the case it will wrap the necessary import in a `List` for further usage.
-    *
-    * @param sPackage the package of the class
-    * @param sClass the class
-    * @return an empty list if the class does not need to be imported, or the necessary import
-    *         otherwise
-    */
-  private def includeImportIfNecessary(sPackage: String, sClass: String): List[SImport] = {
-    if (sPackage != this.sPackage && sPackage != "") List(SImport(sPackage, sClass)) else List()
+  /**
+   * Checks if some class has to be imported in order to be usable from `this` class. If this
+   * is the case it will wrap the necessary import in a `List` for further usage.
+   *
+   * @param sPackage the package of the class
+   * @param sClass the class
+   * @return an empty list if the class does not need to be imported, or the necessary import
+   *         otherwise
+   */
+  private def includeImportIfNecessary(sTypeElement: STypedElement, list: List[SImport]): List[SImport] = {
+    //catch GenericSequence types and there use internal type param
+    var t = sTypeElement
+    sTypeElement match {
+      case seq: GenericSequence =>
+        t = seq.typeParam
+      case _ =>
+    }
+    //return only if new package
+    if (t.sPackage != this.sPackage && t.sPackage != "") list :+ SImport(t.sPackage, t.getName) else list
   }
 
   override def equals(other: Any): Boolean = other match {
     case that: SClass =>
       (that canEqual this) &&
-        name == that.name &&
+        getName == that.getName &&
         sPackage == that.sPackage
     case _ => false
   }
 
   override def hashCode(): Int = {
-    val state = Seq(name, sPackage)
+    val state = Seq(getName, sPackage)
     state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b)
   }
 
-  override def toString: String = s"$name(${attributes.map(_.name).mkString(", ")})"
+  override def toString: String = s"SC: $getName($sPackage, ${attributes.map(_.getName).mkString(", ")} ## ${getOnlyDeepAttributes.map(_.getName).mkString(", ")} || $isAbstract, $isInterface)"
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClassType.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClassType.scala
new file mode 100644
index 0000000000000000000000000000000000000000..50ad1d74a477abf4cd9106759470ce269141301a
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SClassType.scala
@@ -0,0 +1,5 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+object SClassType extends Enumeration {
+  val normalClass, caseClass, abstactClass, normalTrait, normalObject = Value
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SEnum.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SEnum.scala
new file mode 100644
index 0000000000000000000000000000000000000000..a0f6271b6a30005d3e23ee878d1120bf79891e7b
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SEnum.scala
@@ -0,0 +1,10 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+class SEnum (_name: String, _sPackage: String, val enums: Set[String]) extends STypedElement(_name, _sPackage, SClassType.normalClass) {
+    
+  override def getDeepName: String = _name + ".Value"
+  
+  override def accept(visitor: SModelVisitor): Unit = {
+    //pass never change an incoming enum
+  }  
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SGetter.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SGetter.scala
index 3cb1dce28b2cca0c736031693bc0c10a392f6988..4adcadcceffcb876d0296d889f42e2ae78e9f009 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SGetter.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SGetter.scala
@@ -7,10 +7,10 @@ import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExte
   *
   * @author Rico Bergmann
   */
-class SGetter(attr: SAttribute) extends SMethod(
-  name = s"get${attr.name.firstLetterToUpperCase}",
-  result = attr.attrType,
+class SGetter(struc: SStructuralFeature) extends SMethod(
+  name = s"get${struc.getName.firstLetterToUpperCase}",
+  result = struc.getTypeElement,
   params = Seq.empty,
-  implementation = Seq(SMethodStatement(content = attr.name, usedTypes = Set(attr.attrType)))) {
+  implementation = Seq(SMethodStatement(content = struc.getName, usedTypes = Set(struc.getTypeElement)))) {
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SInnerClass.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SInnerClass.scala
new file mode 100644
index 0000000000000000000000000000000000000000..a9433f70e8a196db8ea96f576aac2dcf3e2eebe0
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SInnerClass.scala
@@ -0,0 +1,13 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+import java.util.Objects
+
+class SInnerClass(_name: String,
+             _sPackage: String = "",
+             _sClassType: SClassType.Value = SClassType.normalClass,
+             val externalClass: SClass) extends SClass(_name, _sPackage, _sClassType) {
+  
+  Objects.requireNonNull(externalClass, "External class may not be null")
+  
+  override def getDeepName: String = externalClass.getName + "#" + _name
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SInnerViewNaturalClass.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SInnerViewNaturalClass.scala
new file mode 100644
index 0000000000000000000000000000000000000000..38fe319e6469452bec98b0b22d6773f8062eadbc
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SInnerViewNaturalClass.scala
@@ -0,0 +1,13 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+import java.util.Objects
+
+class SInnerViewNaturalClass(_name: String,
+             _sPackage: String = "",
+             _sClassType: SClassType.Value = SClassType.normalClass,
+             _externalClass: SClass,
+             val sumSource: SClass) extends SInnerClass(_name, _sPackage, _sClassType, _externalClass) {
+  
+  Objects.requireNonNull(sumSource, "SUM Source class may not be null")
+  
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SInnerViewRelationalClass.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SInnerViewRelationalClass.scala
new file mode 100644
index 0000000000000000000000000000000000000000..97feb240a538d46c4b06bc042838070aee814b1d
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SInnerViewRelationalClass.scala
@@ -0,0 +1,16 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+import java.util.Objects
+
+class SInnerViewRelationalClass(_name: String,
+             _sPackage: String = "",
+             _sClassType: SClassType.Value = SClassType.normalClass,
+             _externalClass: SClass,
+             val sumSource: SRelationalCompartmentClass,
+             val viewSource: SInnerViewNaturalClass,
+             val viewTarget: SInnerViewNaturalClass) extends SInnerClass(_name, _sPackage, _sClassType, _externalClass) {
+  
+  Objects.requireNonNull(sumSource, "SUM Source class may not be null")
+  Objects.requireNonNull(viewSource, "View Source class may not be null")
+  Objects.requireNonNull(viewTarget, "View Target class may not be null")
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SJoinClass.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SJoinClass.scala
new file mode 100644
index 0000000000000000000000000000000000000000..a9c9dcdc4185afe946ca50386ca9bb8b5ac9ba26
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SJoinClass.scala
@@ -0,0 +1,23 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+import org.rosi_project.model_management.sum.join.RsumJoinType
+
+class SJoinClass(_name: String,
+             _sPackage: String,
+             val base: SClass,
+             val other: SClass,
+             val joinType: RsumJoinType.Value,
+             val joinAttributes: Set[SStructuralFeature],
+             val innerAttributes: Set[SStructuralFeature],
+             val joinObject: SClass) extends SClass(_name, _sPackage) {
+    
+  override def getRootClassWithNameAndPackage(n: String, p: String): SClass = {
+    val bparent = base.getRootClassWithNameAndPackage(n, p)
+    val oparent = other.getRootClassWithNameAndPackage(n, p)
+    if (bparent != null) {
+      return bparent
+    }
+    oparent
+  }
+  
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethod.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethod.scala
index e17dd79cbe0f5b8a3c2f1e88c1e14bc994cd9526..76e4cfec6e86a4d189a20406195270e1e34172b8 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethod.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethod.scala
@@ -1,6 +1,7 @@
 package org.rosi_project.model_sync.generator.acr_model
 
 import java.util.Objects
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
 
 // TODO use a simple DSL to represent the method body?
 
@@ -8,18 +9,26 @@ import java.util.Objects
   *
   * @author Rico Bergmann
   */
-class SMethod(val name: String,
+class SMethod(name: String,
               val result: STypedElement,
               val params: Seq[SMethodParameter],
               var implementation: Seq[SMethodStatement],
               var overrides: Boolean = false)
-  extends SModelElement {
+  extends SNamedModelElement(name) {
+  
+  private var visibility = MethodVisibility.publicVis
+  
+  def setVisibility(v: MethodVisibility.Value): Unit = {
+    visibility = v
+  }
+  
+  def getVisibility: MethodVisibility.Value = visibility;
 
   /** Provides the return-type as a `String`.
     *
     * @return the type. Will never be `null` nor empty.
     */
-  def getResultType: String = result.getName
+  def getResultType: String = result.getDeepName
 
   /** Replaces the current body of `this` method.
     *
@@ -48,10 +57,10 @@ class SMethod(val name: String,
   def getUsedTypes: Set[STypedElement] = {
     val resultType = result match {
       case GenericSType(_, _, typeParam) => Seq(result, typeParam)
-      case SType.Unit => Seq.empty
+      case PredefTypes.Unit => Seq.empty
       case _ => Seq(result)
     }
-    val paramTypes = params.map(_.paramType)
+    val paramTypes = params.map(_.getType)
     val implementationTypes = implementation.map(_.usedTypes).fold(Set.empty)((s1, s2) => s1 ++ s2)
     (resultType ++ paramTypes).toSet ++ implementationTypes
   }
@@ -63,17 +72,17 @@ class SMethod(val name: String,
   override def equals(other: Any): Boolean = other match {
     case that: SMethod =>
       (that canEqual this) &&
-        name == that.name &&
+        getName == that.getName &&
         result == that.result &&
         params == that.params
     case _ => false
   }
 
   override def hashCode(): Int = {
-    val state = Seq(name, result, params)
+    val state = Seq(getName, result, params)
     state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b)
   }
 
-  override def toString: String = s"$name(${params.map(_.name).mkString(", ")}): $getResultType"
+  override def toString: String = s"$getName(${params.map(_.getName).mkString(", ")}): ${result.getName}"
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethodParameter.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethodParameter.scala
index 6ac68dd5e24b1733742e43a3fbbf5f1dc7f2b3bb..ea4026309b5b80588b2887f0cf28635be599c5c4 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethodParameter.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethodParameter.scala
@@ -4,14 +4,32 @@ package org.rosi_project.model_sync.generator.acr_model
   *
   * @author Rico Bergmann
   */
-case class SMethodParameter(name: String, paramType: STypedElement) {
+case class SMethodParameter(private val name: String, private val paramType: STypedElement) {
 
   /** Provides the type of `this` parameter as a `String`.
     *
     * @return the type. Will never be `null` nor empty.
     */
-  def getType: String = paramType.getName
+  def getTypeName: String = paramType.getName
+  
+  /** Provides the deep type name of `this` parameter as a `String`.
+    *
+    * @return the type. Will never be `null` nor empty.
+    */
+  def getDeepTypeName: String = paramType.getDeepName
+  
+  /** Provides the type of `this` parameter as a `STypedElement`.
+    *
+    * @return the type. Will never be `null` nor empty.
+    */
+  def getType: STypedElement = paramType
+  
+  /** Provides the name of `this` parameter as a `String`.
+    *
+    * @return the name. Will never be `null` nor empty.
+    */
+  def getName: String = name
 
-  override def toString: String = s"$name: $getType"
+  override def toString: String = s"$getName: $getTypeName"
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethodStatement.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethodStatement.scala
index c3b7c213d9fec9f83b1947f9d3b9c4dbf54b0677..294b33a4e2b71de878a86f64134fa322bacd5f15 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethodStatement.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SMethodStatement.scala
@@ -12,7 +12,7 @@ package org.rosi_project.model_sync.generator.acr_model
   *
   * @author Rico Bergmann
   */
-case class SMethodStatement(content: String, usedTypes: Set[STypedElement] = Set.empty) {
+case class SMethodStatement(private val content: String, usedTypes: Set[STypedElement] = Set.empty) {
 
   /** The actual statement as a `String`.
     *
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SModel.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SModel.scala
index 280d69f0f4631ce8f75a2845ed3ec768d9fb7e5f..7412f6eb5b6d8072c7c697a4e0187bb1c04c4f5e 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SModel.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SModel.scala
@@ -5,17 +5,80 @@ package org.rosi_project.model_sync.generator.acr_model
   *
   * @author Rico Bergmann
   */
-trait SModel extends SModelElement {
-
-  /** Provides all the classes in `this` model.
-    */
+abstract class SModel(private val name: String, private val sourceName: String, private val nsUri: String) extends SModelElement {
+  
+  /** Get NsURI from the model. */
+  def getNsURI: String = nsUri
+  
+  /** Get source name from the model. */
+  def getSourceName: String = sourceName
+  
+  /** Get the name from the model. */
+  def getName: String = name
+  
+  /** Provides all the classes in `this` model. */
   def getAllClasses: Set[SClass]
-
+  
+  /** Provides all model classes in `this` model. */
+  def getModelClasses: Set[SClass]
+  
+  /** Provides all model enums in `this` model. */
+  def getModelEnums: Set[SEnum]
+  
+  /** Provides all provider classes in `this` model. */
+  def getProviderClasses: Set[SClass]
+  
+  /** Provides all relational compartments in `this` model. */
+  def getRelationalCompartments: Set[SClass]
+  
+  /** Provides all view compartments in `this` model. */
+  def getViewCompartments: Set[SClass]
+  
+  /** Provides all join classes in `this` model. */
+  def getJoinClasses: Set[SClass]
+  
+  
+  
+  /** Extends the model by a new provder class.
+    *
+    * @param mClass the class to add. May never `null`.
+    */
+  def addProviderClass(mClass: SClass): Unit
+  
+  /** Extends the model by a new relational compartment.
+    *
+    * @param mClass the class to add. May never `null`.
+    */
+  def addRelationalCompartment(mClass: SClass): Unit
+  
+  /** Extends the model by a new view compartment.
+    *
+    * @param mClass the class to add. May never `null`.
+    */
+  def addViewCompartment(mClass: SClass): Unit
+  
   /** Extends the model by a new class.
     *
     * @param mClass the class to add. May never `null`.
     */
   def addModelClass(mClass: SClass): Unit
+  
+  /** Extends the model by a new join class.
+    *
+    * @param mClass the class to add. May never `null`.
+    */
+  def addJoinClass(mClass: SClass): Unit
+  
+  /** Extends the model by a new enum.
+    *
+    * @param mEnum the enum to add. May never `null`.
+    */
+  def addModelEnums(mEnum: SEnum): Unit
+  
+  /**
+   * Add another model to this on and return this one.
+   */
+  def addOtherModel(model: SModel): SModel
 
   override def toString: String = s"SModel: classes=$getAllClasses"
 
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SModelVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SModelVisitor.scala
index f4c43e6c3dbe89fdeadb23a54a2cedbad6d434ab..29eca86369976c4cb1350365d6b06a32010998ef 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SModelVisitor.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SModelVisitor.scala
@@ -28,6 +28,13 @@ trait SModelVisitor {
     *              specific.
     */
   def visit(sAttr: SAttribute): Unit
+  
+  /** Runs the algorithm as appropriate for a reference of a model class.
+    *
+    * @param sRef the reference to run the algorithm on. Whether it may be `null` is implementation
+    *             specific.
+    */
+  def visit(sRef: SReference): Unit
 
   /** Runs the algorithm as appropriate for a method of a model class.
     *
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SNamedModelElement.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SNamedModelElement.scala
new file mode 100644
index 0000000000000000000000000000000000000000..4c2251540517110826a720c35754b1e75e32d53b
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SNamedModelElement.scala
@@ -0,0 +1,21 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+/** Representation of named element like class, types, attributes and references.
+  *
+  * @author Christopher Werner
+  */
+abstract class SNamedModelElement (name: String) extends SModelElement {
+  
+  /** The name of 'this' element.
+    *
+    * @return the name. Will never be `null` nor empty.
+    */
+  def getName: String = name
+  
+  /** The deep name with external class name + # + this class name.
+   * If there is no external class then only the name is returned.
+   * 
+   *  @return the name. Will never be `null` nor empty.
+   */
+  def getDeepName: String = name
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SReference.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SReference.scala
new file mode 100644
index 0000000000000000000000000000000000000000..275337162cae16c2847db9a45f4f149db661e895
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SReference.scala
@@ -0,0 +1,55 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+/** Representation of class reference. This abstraction is a simplification of an actual scala
+  * reference: it is impossible to distinguish between ''final'' and ''non-final'' fields. Instead,
+  * all attributes will be treated mutable.
+  *
+  * @author Christopher Werner
+  */
+case class SReference(_name: String, /*val stype: STypedElement,*/ _ttype: STypedElement, upperBound: Int, lowerBound: Int, containment: Boolean = false, var oppositeRef: SReference = null) extends SStructuralFeature (_name, _ttype) {
+  
+  def hasOpposite: Boolean = oppositeRef != null
+  
+  def getImportant: SReference = {
+    //return if one is containment
+    if (containment) {
+      return this
+    }
+    if (oppositeRef.containment) {
+      return oppositeRef
+    }
+    //return if one has bigger lowerBound
+    if (lowerBound > oppositeRef.lowerBound) {
+      return this
+    }
+    if (lowerBound < oppositeRef.lowerBound) {
+      return oppositeRef
+    }
+    //return if one has smaller upperBound but bigger than -1
+    if (upperBound > -1 && oppositeRef.upperBound > -1 && upperBound > oppositeRef.upperBound) {
+      return oppositeRef
+    }    
+    this
+  }
+  
+  def getMinimalConnection: SReference = {
+    if (lowerBound == 0 && upperBound == 1) {
+      return this
+    }
+    if (hasOpposite && oppositeRef.lowerBound == 0 && oppositeRef.upperBound == 1) {
+      return oppositeRef
+    }
+    if (lowerBound == 1 && upperBound == 1) {
+      return this
+    }
+    if (hasOpposite && oppositeRef.lowerBound == 1 && oppositeRef.upperBound == 1) {
+      return oppositeRef
+    }
+    return null
+  }
+
+  override def accept(visitor: SModelVisitor): Unit = visitor.visit(this)
+
+  override def toString: String = s"$getName: ${getTypeElement.getName} $containment $lowerBound $upperBound"
+
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SRelationalCompartmentClass.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SRelationalCompartmentClass.scala
new file mode 100644
index 0000000000000000000000000000000000000000..2a311e6667394ce8b1ad6413dd0917abd625df69
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SRelationalCompartmentClass.scala
@@ -0,0 +1,13 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+import java.util.Objects
+
+class SRelationalCompartmentClass(_name: String,
+             _sPackage: String = "",
+             _sClassType: SClassType.Value = SClassType.normalClass,
+             val connectedRef: SReference,
+             val sClass: STypedElement,
+             val tClass: STypedElement) extends SClass(_name, _sPackage, _sClassType) {
+  
+  Objects.requireNonNull(connectedRef, "Connected Reference may not be null")
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SSetter.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SSetter.scala
index 563c9a8d114b1d7752a059ae79dba181286885e4..1553ac043d83abb298b7322d66b5802b3069aab4 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SSetter.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SSetter.scala
@@ -1,15 +1,22 @@
 package org.rosi_project.model_sync.generator.acr_model
 
 import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
 
 /** Simple representation of a setter method.
   *
   * @author Rico Bergmann
   */
-class SSetter(attr: SAttribute) extends SMethod(
-  name = s"set${attr.name.firstLetterToUpperCase}",
-  result = SType.Unit,
-  params = Seq(SMethodParameter(attr.name.head.toString, attr.attrType)),
-  implementation = Seq(SMethodStatement(content = s"${attr.name} = ${attr.name.head}", usedTypes = Set(attr.attrType)))) {
+class SSetter(struc: SStructuralFeature) extends SMethod(
+  name = s"set${struc.getName.firstLetterToUpperCase}",
+  result = PredefTypes.Unit,
+  params = Seq(SMethodParameter(struc.getName.head.toString, struc.getTypeElement)),
+  implementation = Seq(SMethodStatement(content = s"${struc.getName} = ${struc.getName.head}", usedTypes = Set(struc.getTypeElement)))) {
 
+  /*if (!STypeRegistry.isDefaultNotNullType(struc.getTypeElement.getName)) {
+    implementation = Seq(SMethodStatement(content = s"require(${struc.getName.head} != null)"),
+      SMethodStatement(content = s"${struc.getName} = ${struc.getName.head}", usedTypes = Set(struc.getTypeElement)))
+  } else {
+    implementation = Seq(SMethodStatement(content = s"${struc.getName} = ${struc.getName.head}", usedTypes = Set(struc.getTypeElement)))
+  } */
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SSetterAdd.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SSetterAdd.scala
new file mode 100644
index 0000000000000000000000000000000000000000..ff9aa456fc1aa70bf9c2ee317be547f040f0260c
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SSetterAdd.scala
@@ -0,0 +1,23 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+
+/** Add an element to a Set of elements.
+  *
+  * @author Christopher Werner
+  */
+class SSetterAdd(struc: SStructuralFeature, inner: STypedElement) extends SMethod(
+  name = s"add${struc.getName.firstLetterToUpperCase}",
+  result = PredefTypes.Unit,
+  params = Seq(SMethodParameter(struc.getName.head.toString, inner)),
+  implementation = Seq(SMethodStatement(content = s"${struc.getName} += ${struc.getName.head}", usedTypes = Set(struc.getTypeElement)))) {
+
+  if (!STypeRegistry.isDefaultNotNullType(struc.getTypeElement.getName)) {
+    implementation = Seq(SMethodStatement(content = s"require(${struc.getName.head} != null)"),
+      SMethodStatement(content = s"require(!${struc.getName}.contains(${struc.getName.head}))"),
+      SMethodStatement(content = s"${struc.getName} += ${struc.getName.head}", usedTypes = Set(struc.getTypeElement)))
+  } else {
+    implementation = Seq(SMethodStatement(content = s"${struc.getName} += ${struc.getName.head}", usedTypes = Set(struc.getTypeElement)))
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SSetterRemove.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SSetterRemove.scala
new file mode 100644
index 0000000000000000000000000000000000000000..7d2599fcf11c3167a9a8d9da10cc8123bc1a050f
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SSetterRemove.scala
@@ -0,0 +1,23 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+
+/** Remove an element from a Set of elements.
+  *
+  * @author Christopher Werner
+  */
+class SSetterRemove(struc: SStructuralFeature, inner: STypedElement) extends SMethod(
+  name = s"remove${struc.getName.firstLetterToUpperCase}",
+  result = PredefTypes.Unit,
+  params = Seq(SMethodParameter(struc.getName.head.toString, inner)),
+  implementation = Seq(SMethodStatement(content = s"${struc.getName} -= ${struc.getName.head}", usedTypes = Set(struc.getTypeElement)))) {
+
+  if (!STypeRegistry.isDefaultNotNullType(struc.getTypeElement.getName)) {
+    implementation = Seq(SMethodStatement(content = s"require(${struc.getName.head} != null)"),
+      SMethodStatement(content = s"require(${struc.getName}.contains(${struc.getName.head}))"),
+      SMethodStatement(content = s"${struc.getName} -= ${struc.getName.head}", usedTypes = Set(struc.getTypeElement)))
+  } else {
+    implementation = Seq(SMethodStatement(content = s"${struc.getName} -= ${struc.getName.head}", usedTypes = Set(struc.getTypeElement)))
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SStructuralFeature.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SStructuralFeature.scala
new file mode 100644
index 0000000000000000000000000000000000000000..91afb3973a4760c887a671c36b32471246334af2
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SStructuralFeature.scala
@@ -0,0 +1,24 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+/** Representation of structural features like attributes and references.
+  *
+  * @author Christopher Werner
+  */
+abstract class SStructuralFeature (_name: String, private val sType: STypedElement) extends SNamedModelElement(_name) {
+  
+  var isFinal: Boolean = false 
+  private var visibility = MethodVisibility.publicVis
+  
+  def setVisibility(v: MethodVisibility.Value): Unit = {
+    visibility = v
+  }
+  
+  def getVisibility: MethodVisibility.Value = visibility;
+  
+  /** The type of 'this' structural feature.
+    *
+    * @return
+    */
+  def getTypeElement: STypedElement = sType
+  
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SType.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SType.scala
index a3a15f4f511ef046fa9fad55d026a46c5566828f..ad0470e4e58497855daab94bd119517addf58f58 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SType.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SType.scala
@@ -11,30 +11,9 @@ package org.rosi_project.model_sync.generator.acr_model
   * @see [[SClass]]
   * @author Rico Bergmann
   */
-case class SType(name: String, sPackage: String = "") extends STypedElement {
-
-  override def getName: String = name
-
-  override def getPackage: String = sPackage
+case class SType(_name: String, _sPackage: String = "", _sClassType: SClassType.Value = SClassType.normalTrait) extends STypedElement (_name, _sPackage, _sClassType) {
 
   override def accept(visitor: SModelVisitor): Unit = visitor.visit(this)
-
-}
-
-/** The companion defines frequently used types.
-  */
-object SType {
-
-  /** The empty type.
-    */
-  val Unit = SType("Unit")
-
-  /** Wrapper for `AnyRef`.
-    */
-  val AnyRef = SType("AnyRef")
-
-  /** Wrapper for `String`.
-    */
-  val String = SType("String")
-
+  
+  override def toString: String = s"ST: $getName($sPackage, $isInterface)"
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypeRegistry.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypeRegistry.scala
index 345d9b8b7b13d8a2c53fdde1423736865ddad4f6..bfa7fefca86bec5b3e3b43a2723e89dba38783f0 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypeRegistry.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypeRegistry.scala
@@ -1,5 +1,9 @@
 package org.rosi_project.model_sync.generator.acr_model
 
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.eclipse.emf.ecore.EClass
+import org.rosi_project.model_sync.generator.acr_model.types.PredefEcoreTypes
+
 /** Repository to keep track of all types and classes of model. It ensures that all attributes,
   * methods, etc. reference the same type instances and thus prevent duplication and conflicting
   * states. The registry should be treated as "''single point of truth''".
@@ -7,20 +11,88 @@ package org.rosi_project.model_sync.generator.acr_model
   * @author Rico Bergmann
   */
 object STypeRegistry {
+  
+  private var registeredTypes: Map[STypedElement, EClass] = Map.empty
+  
+  private val defaultTypesNull: Map[STypedElement, EClass] = Map(
+    PredefTypes.Date -> null,
+    PredefTypes.Object -> null,
+    PredefTypes.String -> null,
+  )
+  
+  private val defaultTypesNotNull: Map[STypedElement, EClass] = Map(
+    PredefTypes.Boolean -> null,
+    PredefTypes.Byte -> null,
+    PredefTypes.Char -> null,
+    PredefTypes.Double -> null,
+    PredefTypes.Float -> null,
+    PredefTypes.Integer -> null,
+    PredefTypes.Long -> null,
+    PredefTypes.Short -> null,
+  )
+  
+  /*private val ecoreTypes: Map[STypedElement, EClass] = Map(
+    PredefEcoreTypes.EcoreObject -> null,
+    PredefEcoreTypes.EcoreStructuralFeature -> null,
+  )*/
+  
+  def getFromClass(cls: EClass): STypedElement = {
+    registeredTypes.foreach(r => {
+      if (r._2 == cls) {
+        return r._1
+      }
+    })
+    null
+  }
 
-  private var registeredTypes: Set[STypedElement] = Set()
-
-  registerDefaultTypes()
+  registeredTypes ++= defaultTypesNull
+  registeredTypes ++= defaultTypesNotNull
+  //registeredTypes ++= ecoreTypes
+  
+  /**
+   * Return true if this name comes from a standard null type.
+   * 
+   * @param name the name that must be proven.
+   * @return `true` if it is a default type. Otherwise return false.
+   */
+  def isDefaultNullType(name: String): Boolean = {
+    val existingNull: Option[STypedElement] = defaultTypesNull.keySet.find(existing => existing.getName == name)
+    return !existingNull.isEmpty
+  }
+  
+  /**
+   * Return true if this name comes from a standard not null type.
+   * 
+   * @param name the name that must be proven.
+   * @return `true` if it is a default type. Otherwise return false.
+   */
+  def isDefaultNotNullType(name: String): Boolean = {
+    val existingNotNull: Option[STypedElement] = defaultTypesNotNull.keySet.find(existing => existing.getName == name)
+    return !existingNotNull.isEmpty
+  }
+  
+  /**
+   * Return true if this name comes from a standard type.
+   * 
+   * @param name the name that must be proven.
+   * @return `true` if it is a default type. Otherwise return false.
+   */
+  def isDefaultType(name: String): Boolean = {
+    val existingNotNull: Option[STypedElement] = defaultTypesNotNull.keySet.find(existing => existing.getName == name)
+    val existingNull: Option[STypedElement] = defaultTypesNull.keySet.find(existing => existing.getName == name)
+    return !existingNotNull.isEmpty || !existingNull.isEmpty
+  }
 
   /** Registers a type if it is not already known.
     *
     * @param theType the new type. May never be `null`.
     * @return `theType` if it was indeed unknown before. Otherwise the currently registered type.
     */
-  def addType(theType: STypedElement): STypedElement = {
-    val existing: Option[STypedElement] = registeredTypes.find(existing => existing.getName == theType.getName && existing.getPackage == theType.getPackage)
+  def addType(theType: STypedElement, cls: EClass): STypedElement = {
+    val existing: Option[STypedElement] = registeredTypes.keySet.find(existing => existing.getName == theType.getName && existing.getPackage == theType.getPackage)
     if (existing.isEmpty) {
-      registeredTypes += theType
+      registeredTypes = registeredTypes + (theType -> cls)
+      //registeredTypes += theType
       theType
     } else {
       existing.get
@@ -33,36 +105,13 @@ object STypeRegistry {
     * @param sPackage the package that contains the type
     * @return the type if it was found
     */
-  def query(name: String, sPackage: String): Option[STypedElement] = {
-    registeredTypes.find(t => t.getName == name && t.getPackage == sPackage)
-  }
-
-  /** Searches for a type based on its name. It may reside in any package.
-    *
-    * @param name the type's name
-    * @return the type if it was found
-    */
-  def queryForName(name: String): Option[STypedElement] = {
-    registeredTypes.find(_.getName == name)
+  def query(name: String, sPackage: String): Option[STypedElement] = {  
+    registeredTypes.keySet.find(t => t.getName == name && t.getPackage == sPackage)
   }
 
   /** Provides all types that are currently in the repository.
     */
-  def allTypes: Set[STypedElement] = registeredTypes
-
-  private def registerDefaultTypes(): Unit = {
-    registeredTypes ++= Seq(
-      SType("Boolean"),
-      SType("Byte"),
-      SType("Short"),
-      SType("Integer"),
-      SType("Long"),
-      SType("Float"),
-      SType("Double"),
-      SType("String"),
-    )
-  }
+  def allTypes: Set[STypedElement] = registeredTypes.keySet
 
   override def toString: String = s"Registry: $registeredTypes"
-
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala
index d89878c254515cac3bf962435253300052e1135f..0579ff7b2c1bc36bbd79bc8ecf2bc9c99e9f49a9 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/STypedElement.scala
@@ -10,32 +10,50 @@ package org.rosi_project.model_sync.generator.acr_model
   *
   * @author Rico Bergmann
   */
-trait STypedElement extends SModelElement {
-
-  /** The name of `this` type.
-    *
-    * @return the name. Will never be `null` nor empty.
-    */
-  def getName: String
+abstract class STypedElement (_name: String,
+             val sPackage: String,
+             val sClassType: SClassType.Value) extends SNamedModelElement(_name) {
+  
+  /** Checks, whether `this` is part of the default package */
+  def isDefaultPackage: Boolean = sPackage == ""
 
   /** The package containing `this` type.
     *
     * @return
     */
-  def getPackage: String
+  def getPackage: String = sPackage
 
-  /** The parameters necessary to create an instance of `this` type.
-    */
-  def getConstructorParameters: Seq[SMethodParameter] = Seq.empty
+  /** The constructor with all parameters of `this` type for construction. */
+  def getAllConstructorParameters: Seq[SMethodParameter] = Seq.empty
+  
+  /** The constructor with only attribute parameters of `this` type for construction. */
+  def getAttributeConstructorParameters: Seq[SMethodParameter] = Seq.empty
 
   /** The inheritance hierarchy provides information about the types `this` extends. It will start
     * with `this` (thus the hierarchy will 'never' be empty) and end with the root type. `AnyRef`
     * will be ignored however.
     */
   def getInheritanceHierarchy: Seq[STypedElement] = Seq.empty
+  
+  /**
+   * Proof the hierarchical equality between two STypedElement
+   */
+  def proofHierarchicalEquality(sType: STypedElement): Boolean = sType == this
 
   /** Provides all classes that need to be imported for `this` type.
     */
   def getNecessaryImports: Set[SImport] = Set.empty
+  
+  def isInterface: Boolean = sClassType == SClassType.normalTrait
+  
+  def isAbstract: Boolean = sClassType == SClassType.abstactClass
+  
+  def isObject: Boolean = sClassType == SClassType.normalObject
+  
+  def isCaseClass: Boolean = sClassType == SClassType.caseClass
+  
+  def isNormalClass: Boolean = sClassType == SClassType.normalClass
+  
+  override def toString: String = s"STE: $getName($sPackage, $isInterface)"
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SViewClass.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SViewClass.scala
new file mode 100644
index 0000000000000000000000000000000000000000..fb2e69f86be8751677ad386d8ec6fbda67ad93e5
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SViewClass.scala
@@ -0,0 +1,14 @@
+package org.rosi_project.model_sync.generator.acr_model
+
+class SViewClass(_name: String,
+             _sPackage: String) extends SClass(_name, _sPackage) {
+  
+  private var joinObjects: Set[SJoinClass] = Set.empty
+  
+  def getJoinObject(): Set[SJoinClass] = joinObjects
+  
+  def addJoinObject(v: SJoinClass): Unit = {
+    require(v != null)
+    joinObjects += v
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SimpleSModel.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SimpleSModel.scala
index 4722a9ad758e180a69e4fc59cf9c92ffa927471c..c5ac6720b057b4d23be47ffe451d94beb4522977 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SimpleSModel.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/SimpleSModel.scala
@@ -6,16 +6,82 @@ import org.rosi_project.model_sync.generator.support.Assert
   *
   * @author Rico Bergmann
   */
-class SimpleSModel extends SModel {
-
+class SimpleSModel(name: String, sourceName: String, nsUri: String) extends SModel(name, sourceName, nsUri) {
+  
   private var sClasses: Set[SClass] = Set.empty
+  private var sEnums: Set[SEnum] = Set.empty
+
+  /** Provides all the classes in `this` model. */
+  override def getAllClasses: Set[SClass] = sClasses
+  
+  /** Provides all model classes in `this` model. */
+  override def getModelClasses: Set[SClass] = sClasses
+  
+  /** Provides all provider classes in `this` model. */
+  override def getProviderClasses: Set[SClass] = sClasses
+  
+  /** Provides all relational compartments in `this` model. */
+  override def getRelationalCompartments: Set[SClass] = sClasses
+  
+  /** Provides all view compartments in `this` model. */
+  override def getViewCompartments: Set[SClass] = sClasses
+  
+  /** Provides all join classes in `this` model. */
+  override def getJoinClasses: Set[SClass] = Set.empty
+  
+  /** Provides all model enums in `this` model. */
+  override def getModelEnums: Set[SEnum] = sEnums
 
+  /** Extends the model by a new class.
+    *
+    * @param mClass the class to add. May never `null`.
+    */
   override def addModelClass(mClass: SClass): Unit = {
     Assert.notNull(mClass, "Class may not be null")
     sClasses += mClass
   }
-
-  override def getAllClasses: Set[SClass] = sClasses
+  
+  /** Extends the model by a new provder class.
+    *
+    * @param mClass the class to add. May never `null`.
+    */
+  override def addProviderClass(mClass: SClass): Unit = {
+    Assert.notNull(mClass, "Class may not be null")
+    sClasses += mClass
+  }
+  
+  /** Extends the model by a new enum.
+    *
+    * @param mEnum the enum to add. May never `null`.
+    */
+  override def addModelEnums(mEnum: SEnum): Unit = {
+    Assert.notNull(mEnum, "Enum may not be null")
+    sEnums += mEnum
+  }
+  
+  /** Extends the model by a new relational compartment.
+    *
+    * @param mClass the class to add. May never `null`.
+    */
+  override def addRelationalCompartment(mClass: SClass): Unit = {
+    Assert.notNull(mClass, "Class may not be null")
+    sClasses += mClass
+  }
+  
+  /** Extends the model by a new view compartment.
+    *
+    * @param mClass the class to add. May never `null`.
+    */
+  override def addViewCompartment(mClass: SClass): Unit = {
+    Assert.notNull(mClass, "Class may not be null")
+    sClasses += mClass
+  }
+  
+  /** Extends the model by a new join class.
+    *
+    * @param mClass the class to add. May never `null`.
+    */
+  override def addJoinClass(mClass: SClass): Unit = {/*pass*/}
 
   override def accept(visitor: SModelVisitor): Unit = {
     sClasses.foreach(_.accept(visitor))
@@ -27,13 +93,19 @@ class SimpleSModel extends SModel {
   override def equals(other: Any): Boolean = other match {
     case that: SimpleSModel =>
       (that canEqual this) &&
+        sEnums == that.sEnums &&
         sClasses == that.sClasses
     case _ => false
   }
+  
+  override def addOtherModel(model: SModel): SModel = {
+    sClasses = sClasses ++ model.getModelClasses
+    sEnums = sEnums ++ model.getModelEnums
+    return this
+  }
 
   override def hashCode(): Int = {
     val state = Seq(sClasses)
     state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b)
   }
-
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/GenericSequence.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/GenericSequence.scala
new file mode 100644
index 0000000000000000000000000000000000000000..aa964a5f65e14200879f657cd352c1e802d237e7
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/GenericSequence.scala
@@ -0,0 +1,10 @@
+package org.rosi_project.model_sync.generator.acr_model.types
+
+import org.rosi_project.model_sync.generator.acr_model.{GenericSType, SMethodParameter, STypedElement}
+
+abstract class GenericSequence(name: String, elemType: STypedElement) extends GenericSType(name, typeParam = elemType) {
+  
+  override def getAllConstructorParameters: Seq[SMethodParameter] = Seq(SMethodParameter("elems", elemType))
+
+  override def toString: String = s"Generic Sequence: ${elemType}"
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/PredefEcoreTypes.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/PredefEcoreTypes.scala
new file mode 100644
index 0000000000000000000000000000000000000000..34aff0138b75dc363d457eb8b449639770b01f60
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/PredefEcoreTypes.scala
@@ -0,0 +1,33 @@
+package org.rosi_project.model_sync.generator.acr_model.types
+
+import org.rosi_project.model_sync.generator.acr_model.SType
+
+/** Contains a number of types that are part of the Ecore package.
+  *
+  * This should prevent creating them over and over again every time a `SType` should be set to any
+  * of these types.
+  *
+  * @author Christopher Werner
+  */
+object PredefEcoreTypes {
+  
+  /**  `org.eclipse.emf.common.util.URI` */
+  val URI = SType("URI", "org.eclipse.emf.common.util")
+  
+  /**  `org.eclipse.emf.ecore.resource.Resource` */
+  val Resource = SType("Resource", "org.eclipse.emf.ecore.resource")
+  
+  /**  `org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl` */
+  val XMIResourceFactoryImpl = SType("XMIResourceFactoryImpl", "org.eclipse.emf.ecore.xmi.impl")
+  
+  /**  `org.eclipse.emf.ecore.EObject` */
+  val EcoreObject = SType("EObject", "org.eclipse.emf.ecore")
+  
+  /**  `org.eclipse.emf.ecore.EStructuralFeature` */
+  val EcoreStructuralFeature = SType("EStructuralFeature", "org.eclipse.emf.ecore")
+  
+  /**  `org.eclipse.emf.ecore.EOperation` */
+  val EcoreOperation = SType("EOperation", "org.eclipse.emf.ecore")
+  
+  val ResourceSetImpl = SType("ResourceSetImpl", "org.eclipse.emf.ecore.resource.impl")
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/PredefTypes.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/PredefTypes.scala
index d181569e09da6186cb0ba1aa877b4d1e4f586a3a..08cf1c007fe95beda2933b6fd0e1396b64abde48 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/PredefTypes.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/PredefTypes.scala
@@ -10,18 +10,60 @@ import org.rosi_project.model_sync.generator.acr_model.{GenericSType, SType, STy
   * @author Rico Bergmann
   */
 object PredefTypes {
+  
+  /** `Convert Java list to Scala listApp` */
+  val ScalaConverter = SType("_", "scala.collection.JavaConverters")
+  
+  /** `App` */
+  val App = SType("App")
+  
+  /** `Char` */
+  val Char = SType("Char")
+  
+  /** `Byte` */
+  val Byte = SType("Byte")
+  
+  /** `Short` */
+  val Short = SType("Short")
+    
+  /** `Integer` */
+  val Integer = SType("Int")
+    
+  /** `Long` */
+  val Long = SType("Long")
+    
+  /** `Float` */
+  val Float = SType("Float")
+    
+  /** `Double` */
+  val Double = SType("Double")
+  
+  /** `Boolean` */
+  val Boolean = SType("Boolean")
+  
+  /** `String` */
+  val String = SType("String")  
 
-  /** `java.lang.Object`
-    */
+  /** `java.lang.Object` */
   val Object = SType("Object")
 
-  /** `java.io.File`
-    */
+  /** `java.io.File` */
   val File = SType("File", "java.io")
+    
+  /** `java.util.Date` */
+  val Date = SType("Date", "java.util")
 
-  /**  `java.lang.reflect.Parameter`
-    */
+  /**  `java.lang.reflect.Parameter` */
   val Parameter = SType("Parameter", "java.lang.reflect")
+  
+  /** `Unit` The empty type. */
+  val Unit = SType("Unit")
+
+  /** Wrapper for `AnyRef`. */
+  val AnyRef = SType("AnyRef")
+  
+  /** Wrapper for `Any`. */
+  val Any = SType("Any")
 
   /** `java.lang.Class[typ]`
     *
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SList.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SList.scala
index a7d11b35fa3045539727f7d5ddc5df9ea01603f8..a8be05b28beecbe1e832611b57c40e78e675417b 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SList.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SList.scala
@@ -4,9 +4,7 @@ import org.rosi_project.model_sync.generator.acr_model._
 
 /** Wraps a Scala `List` for some type.
   */
-class SList(elemType: STypedElement) extends SSeq(elemType) {
-
-  override def getConstructorParameters: Seq[SMethodParameter] = Seq(SMethodParameter("elems", elemType))
+class SList(elemType: STypedElement) extends GenericSequence("List", elemType) {
 
 }
 
@@ -16,6 +14,6 @@ object SList {
 
   def apply(elemType: STypedElement): SList = new SList(elemType)
 
-  def unapply(arg: SList): Option[STypedElement] = Some(arg.elemType)
+  def unapply(arg: SList): Option[STypedElement] = Some(arg.typeParam)
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSeq.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSeq.scala
index e6a9f5ded7b0d289ec384126b9a20c07481f26aa..ff4b3c58717872c813ae93991aa368d3ffdebba2 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSeq.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSeq.scala
@@ -4,9 +4,7 @@ import org.rosi_project.model_sync.generator.acr_model.{GenericSType, SMethodPar
 
 /** Wraps a Scala `Seq` for some type.
   */
-class SSeq(val elemType: STypedElement) extends GenericSType(name = "Seq", sPackage = "", typeParam = elemType) {
-
-  override def getConstructorParameters: Seq[SMethodParameter] = Seq(SMethodParameter("elems", elemType))
+class SSeq(elemType: STypedElement) extends GenericSequence("Seq", elemType) {
 
 }
 
@@ -16,6 +14,6 @@ object SSeq {
 
   def apply(elemType: STypedElement): SSeq = new SSeq(elemType)
 
-  def unapply(arg: SSeq): Option[STypedElement] = Some(arg.elemType)
+  def unapply(arg: SSeq): Option[STypedElement] = Some(arg.typeParam)
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSet.scala b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSet.scala
new file mode 100644
index 0000000000000000000000000000000000000000..64519bb45c73755e57532636d58f95f1a50925ea
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/acr_model/types/SSet.scala
@@ -0,0 +1,19 @@
+package org.rosi_project.model_sync.generator.acr_model.types
+
+import org.rosi_project.model_sync.generator.acr_model._
+
+/** Wraps a Scala `Set` for some type.
+  */
+class SSet(elemType: STypedElement) extends GenericSequence("Set", elemType) {
+
+}
+
+/** The companion provides `apply` and `unapply` methods.
+  */
+object SSet {
+
+  def apply(elemType: STypedElement): SSet = new SSet(elemType)
+
+  def unapply(arg: SSet): Option[STypedElement] = Some(arg.typeParam)
+
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/conversion/Converter.scala b/src/main/scala/org/rosi_project/model_sync/generator/conversion/Converter.scala
index 502465439eda93fe71934b67d95cc9eca6fd1d0e..b4aaa14268e7ec82018367ca28c7aa0d5f60384d 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/conversion/Converter.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/conversion/Converter.scala
@@ -13,6 +13,6 @@ trait Converter[S, T] {
     * @param source the object to convert
     * @return the converted object
     */
-  def convert(source: S): T
+  def convert(source: S, sourceName: String): T
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/conversion/EmfTypeTranslator.scala b/src/main/scala/org/rosi_project/model_sync/generator/conversion/EmfTypeTranslator.scala
index 716e851ce938be96a22c2dc072cf257a0a29ce75..0fb4d447e4edf8c1181c9ba359f5d5168ee3392b 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/conversion/EmfTypeTranslator.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/conversion/EmfTypeTranslator.scala
@@ -4,6 +4,8 @@ import java.util.Objects
 
 import org.eclipse.emf.ecore.EDataType
 import org.rosi_project.model_sync.generator.acr_model.SType
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.rosi_project.model_sync.generator.acr_model.types.PredefEcoreTypes
 
 /** Service to map an instance of [[EDataType]] to its corresponding [[SType]] (which wrap Scala's
   * native types).
@@ -13,17 +15,29 @@ import org.rosi_project.model_sync.generator.acr_model.SType
 object EmfTypeTranslator {
 
   private val typeMap: Map[String, SType] = Map(
-    "EBoolean" -> SType("Boolean"),
-    "EByte" -> SType("Byte"),
-    "EChar" -> SType("Char"),
-    "EDate" -> SType(name = "Date", sPackage = "java.util"),
-    "EDouble" -> SType("Double"),
-    "EFloat" -> SType("Float"),
-    "EInt" -> SType("Int"),
-    "EJavaObject" -> SType("Object"),
-    "ELong" -> SType("Long"),
-    "EShort" -> SType("Short"),
-    "EString" -> SType("String"),
+    "Double" -> PredefTypes.Double, //map normal data types to its normal data types
+    "Float" -> PredefTypes.Float,
+    "Int" -> PredefTypes.Integer,
+    "Char" -> PredefTypes.Char,
+    "Byte" -> PredefTypes.Byte,
+    "Boolean" -> PredefTypes.Boolean,
+    "Long" -> PredefTypes.Long,
+    "Short" -> PredefTypes.Short,
+    "String" -> PredefTypes.String,      
+    "EBoolean" -> PredefTypes.Boolean, //map EMF data types to its normal data types
+    "EByte" -> PredefTypes.Byte,
+    "EChar" -> PredefTypes.Char,
+    "EDate" -> PredefTypes.Date,
+    "EDouble" -> PredefTypes.Double,    
+    "EFloat" -> PredefTypes.Float,
+    "EInt" -> PredefTypes.Integer,
+    "EJavaObject" -> PredefTypes.Object,
+    "ELong" -> PredefTypes.Long,
+    "EShort" -> PredefTypes.Short,
+    "EString" -> PredefTypes.String,
+    "EObject" -> PredefTypes.Object,
+    "EStructuralFeature" -> PredefEcoreTypes.EcoreStructuralFeature,
+    "EOperation" -> PredefEcoreTypes.EcoreOperation,
   )
 
   /** Maps an EMF data type to its corresponding Scala type.
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/conversion/SClassConverter.scala b/src/main/scala/org/rosi_project/model_sync/generator/conversion/SClassConverter.scala
index 76b10c5c96d06b597cdbe8ec78dbe3896b66e75a..34573306ef182f24140e1ed2e8fb9996eef3a613 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/conversion/SClassConverter.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/conversion/SClassConverter.scala
@@ -3,6 +3,8 @@ package org.rosi_project.model_sync.generator.conversion
 import org.eclipse.emf.ecore.{EAttribute, EClass, EReference}
 import org.rosi_project.model_sync.generator.acr_model._
 import org.rosi_project.model_sync.generator.acr_model.types.SList
+import org.rosi_project.model_sync.generator.acr_model.types.SSet
+import org.rosi_project.model_sync.generator.PackageNames
 
 /** Converter to generate instances of [[SClass]] based on [[EClass EClasses]].
   *
@@ -10,94 +12,105 @@ import org.rosi_project.model_sync.generator.acr_model.types.SList
   */
 class SClassConverter extends Converter[EClass, SClass] {
 
-  override def convert(source: EClass): SClass = {
+  override def convert(source: EClass, sourceName: String): SClass = {
     var attrs: List[SAttribute] = List.empty
+    var refs: List[SReference] = List.empty
+    var pars: List[STypedElement] = List.empty
 
     // fetch the attributes of the SClass
-    (source.getEAttributes: List[EAttribute]).foreach(eAttr => {
+    (source.getEAttributes: List[EAttribute]).foreach(eAttr => { 
+      //println("Attribute: " +  eAttr.getEAttributeType.getName + " pkg: " + eAttr.getEAttributeType.getEPackage.getNsPrefix + " pre: " + PackageNames.sourcePkgPrefix)
       val attrType: STypedElement = STypeRegistry
-
         // check if the attribute type is already known and registered
-        .query(eAttr.getEAttributeType.getName, eAttr.getEAttributeType.getEPackage.getName)
-
+        .query(eAttr.getEAttributeType.getName, PackageNames.sourcePkgPrefix + eAttr.getEAttributeType.getEPackage.getNsPrefix)
         // otherwise create a new type
         .getOrElse {
           val newAttr = EmfTypeTranslator
-
             // if the type is wrapped by EMF (such as EString), use the corresponding scala type
             .getSClassFromEmf(eAttr.getEAttributeType)
-
             // otherwise create a new class (as the attribute should instance of a class rather than a type in this case)
-            .getOrElse(new SClass(eAttr.getEAttributeType.getName, sPackage = eAttr.getEAttributeType.getEPackage.getName))
+            .getOrElse(new SClass(eAttr.getEAttributeType.getName, PackageNames.sourcePkgPrefix + eAttr.getEAttributeType.getEPackage.getNsPrefix))
 
           // finally save the type
-          STypeRegistry.addType(newAttr)
+          STypeRegistry.addType(newAttr, null)
         }
-
-      attrs ::= SAttribute(eAttr.getName, attrType)
+      
+      attrs ::= SAttribute(eAttr.getName, attrType, eAttr.isUnique())
     })
 
-    // TODO add support for multiple inheritance
-
+    //fetch the references of the SClass
     (source.getEReferences: List[EReference])
-      .filter(_.isContainment)
       .foreach(eRef => {
-        val attrName = eRef.getName
-        val attrType = eRef.getEReferenceType.getName
-        val attrPckg = eRef.getEReferenceType.getEPackage.getName
-
-        var sAttrType: STypedElement = STypeRegistry
-
+        val refName: String = eRef.getName //Attribute name       
+        val refType: String = eRef.getEReferenceType.getName //Name of the attribute type
+        val refTypePckg: String = PackageNames.sourcePkgPrefix + eRef.getEReferenceType.getEPackage.getNsPrefix //Package name of the attribute type
+        val containment: Boolean = eRef.isContainment() //Containment relation or not
+        val oppositeERef: EReference = eRef.getEOpposite() //Opposite reference
+        var oppositeRef: SReference = null //Opposite reference
+        val upperBound: Int = eRef.getUpperBound() //Upper bound
+        val lowerBound: Int = eRef.getLowerBound() //Lower bound
+        
+        var newTypeCreated: Boolean = false
+        
+        //println("Referenz: " +  refType + " pkg: " + refTypePckg)
+
+        var sRefType: STypedElement = STypeRegistry
           // check if the attribute type is already known and registered
-          .query(attrType, attrPckg)
-
+          .query(refType, refTypePckg)
           // otherwise create a new type
           .getOrElse {
+            newTypeCreated = true
+            
             val newAttr = EmfTypeTranslator
-
               // if the type is wrapped by EMF (such as EString), use the corresponding scala type
-              .getSClassFromEmf(attrType)
-
+              .getSClassFromEmf(refType)
               // otherwise create a new class (as the attribute should instance of a class rather than a type in this case)
-              .getOrElse(new SClass(attrType, sPackage = attrPckg))
-
+              .getOrElse(new SClass(refType, refTypePckg))
+              
             // finally save the type
-            STypeRegistry.addType(newAttr)
+            STypeRegistry.addType(newAttr, null)            
+          }
+        
+        //handle opposite ref
+        if (oppositeERef != null) {          
+          //if the ref has an opposite
+          var classRef = sRefType.asInstanceOf[SClass]
+          if (!classRef.getReferences.isEmpty) {
+            //opposite class type exists and has references
+            classRef.getReferences.foreach { r =>
+              if (r.getName == oppositeERef.getName) {
+                oppositeRef = r
+              }
+            }
           }
+        }
 
         if (eRef.getUpperBound > 1 || eRef.getUpperBound == -1) {
-          sAttrType = SList(sAttrType)
+          sRefType = SSet(sRefType)
+        }        
+        
+        var newReference = SReference(refName, sRefType, upperBound, lowerBound, containment, oppositeRef) 
+        if (oppositeRef != null) {
+          oppositeRef.oppositeRef = newReference
         }
-
-        attrs ::= SAttribute(attrName, sAttrType)
-
+        
+        refs ::= newReference       
     })
 
-    val parents: List[EClass] = source.getESuperTypes.toArray(new Array[EClass](0)).toList
-
-    // we may not convert class hierarchies that utilize multiple inheritance yet
-    if (violatesSingleInheritance(parents)) {
-      throw new UnconvertibleEmfException(source.getEPackage, s"For class: $source")
-    }
-
-    val parent: STypedElement = parents.headOption.map((p: EClass) => {
-      STypeRegistry
-
+    val eClassParents: List[EClass] = source.getESuperTypes.toArray(new Array[EClass](0)).toList
+    
+    eClassParents.foreach { p =>
+      pars ::= STypeRegistry
         // check if we already know the parent
-        .queryForName(p.getName)
-
+        .query(p.getName, PackageNames.sourcePkgPrefix + p.getEPackage.getNsPrefix)
         // otherwise we need to create and register it
         .getOrElse {
-          val parentSClass: SClass = new SClass(p.getName, sPackage = p.getEPackage.getName)
-
+          val parentSClass: SClass = new SClass(p.getName, PackageNames.sourcePkgPrefix + p.getEPackage.getNsPrefix)
           // register the parent (it will be visited and completely inflated later on)
-          STypeRegistry.addType(parentSClass)
+          STypeRegistry.addType(parentSClass, null)
           parentSClass
         }
-    }).orNull
-
-
-    // TODO add methods to SClass
+    }
 
     /* `convert` may be called on two different occasions: either for a completely new type or
      * for a type that was already created before when another type was being inflated by `convert`.
@@ -109,18 +122,33 @@ class SClassConverter extends Converter[EClass, SClass] {
      *  have the type known). Therefore we will set these now.
      */
 
-    val currentClass: Option[STypedElement] = STypeRegistry.query(source.getName, source.getEPackage.getName)
+    val currentClass: Option[STypedElement] = STypeRegistry.query(source.getName, PackageNames.sourcePkgPrefix + source.getEPackage.getNsPrefix)
 
     currentClass.map {
       case clazz: SClass =>
-        clazz.attributes = attrs
-        clazz.parent = parent
+        clazz.setAttributes(attrs)
+        clazz.setReferences(refs)
+        pars.foreach(p => {
+            clazz.addParent(p)
+          })
         clazz
       case sType =>
         sys.error(s"sType should have been a class: $sType")
     }.getOrElse {
-      val createdClass: SClass = new SClass(source.getName, source.getEPackage.getName, attrs, parent)
-      STypeRegistry.addType(createdClass)
+      var sClassType = SClassType.normalClass
+      if (source.isAbstract) {
+        sClassType = SClassType.abstactClass
+      }
+      if (source.isInterface) {
+        sClassType = SClassType.normalTrait
+      }
+      val createdClass: SClass = new SClass(source.getName, PackageNames.sourcePkgPrefix + source.getEPackage.getNsPrefix, sClassType)
+      createdClass.setAttributes(attrs)
+      createdClass.setReferences(refs)
+      pars.foreach(p => {
+          createdClass.addParent(p)
+        })
+      STypeRegistry.addType(createdClass, null)
       createdClass
     }
 
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/conversion/SEnumConverter.scala b/src/main/scala/org/rosi_project/model_sync/generator/conversion/SEnumConverter.scala
new file mode 100644
index 0000000000000000000000000000000000000000..64578dfdc03267bff40e086168e94628fd54984c
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/conversion/SEnumConverter.scala
@@ -0,0 +1,24 @@
+package org.rosi_project.model_sync.generator.conversion
+
+import org.eclipse.emf.ecore.EEnum
+import org.rosi_project.model_sync.generator.acr_model.SEnum
+import org.eclipse.emf.ecore.EEnumLiteral
+import org.rosi_project.model_sync.generator.acr_model.STypeRegistry
+import org.rosi_project.model_sync.generator.PackageNames
+
+class SEnumConverter extends Converter[EEnum, SEnum] {
+
+  override def convert(source: EEnum, sourceName: String): SEnum = {
+
+    var strings: Set[String] = Set.empty 
+    
+    //fetch the name from the literals
+    (source.getELiterals: List[EEnumLiteral]).foreach(elit => {
+      strings += elit.getName
+    }) 
+    
+    val createdEnum: SEnum = new SEnum(source.getName, PackageNames.sourcePkgPrefix + source.getEPackage.getNsPrefix, strings)
+    STypeRegistry.addType(createdEnum, null)
+    createdEnum
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/conversion/SModelGenerator.scala b/src/main/scala/org/rosi_project/model_sync/generator/conversion/SModelGenerator.scala
index 51057830ce435267e5f7f8b15f34cb14b4ef870e..76a4cfeb57da0728560e252ccfefc55c0baf68f7 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/conversion/SModelGenerator.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/conversion/SModelGenerator.scala
@@ -1,30 +1,53 @@
 package org.rosi_project.model_sync.generator.conversion
 
-import org.eclipse.emf.ecore.{EClass, EGenericType, EPackage}
-import org.rosi_project.model_sync.generator.acr_model.{SModel, SType, STypeRegistry, SimpleSModel}
+import org.eclipse.emf.ecore.{ EClass, EGenericType, EPackage }
+import org.rosi_project.model_sync.generator.acr_model.{ SModel, SType, STypeRegistry, ComplexSModel }
 
 import scala.collection.JavaConverters._
-
-/** Converter to generate an [[SModel]] from ecore.
-  *
-  * @author Rico Bergmann
-  */
+import org.rosi_project.model_sync.generator.acr_model.SClass
+import org.eclipse.emf.ecore.EEnum
+import org.rosi_project.model_sync.generator.PackageNames
+import org.rosi_project.model_sync.generator.acr_model.SClassType
+
+/**
+ * Converter to generate an [[SModel]] from ecore.
+ *
+ * @author Rico Bergmann
+ */
 class SModelGenerator extends Converter[EPackage, SModel] {
 
-  override def convert(source: EPackage): SModel = {
-    val packageName = if (source.getName != null) source.getName else ""
-    val contents = source.eAllContents().asScala
-
-    val model = new SimpleSModel
+  override def convert(source: EPackage, sourceName: String): SModel = {
+    //val packageName = if (source.getName != null) source.getName else ""
+    var contents = source.eAllContents().asScala
+    val model = new ComplexSModel(source.getName, sourceName, source.getNsURI)
 
     println("... Converting ecore model")
+    println("First run creates all classes, important for abstract and interface relations")
+    contents.foreach {
+      case ec: EClass =>
+        var sClassType = SClassType.normalClass
+        if (ec.isAbstract) {
+          sClassType = SClassType.abstactClass
+        }
+        if (ec.isInterface || PackageNames.multiInhertitanceWithTraits) {
+          sClassType = SClassType.normalTrait
+        }
+        STypeRegistry.addType(new SClass(ec.getName, PackageNames.sourcePkgPrefix + ec.getEPackage.getNsPrefix, sClassType), ec)
+      case ee: EEnum =>
+        model.addModelEnums(new SEnumConverter convert (ee, sourceName))
+      case _ =>
+      // we only care about classes. Types will be registered as soon as they are needed as
+      // attributes
+    }
+    contents = source.eAllContents().asScala
+    println("Second run add references, attributes, and class hierarchies")
     contents.foreach {
       case ec: EClass =>
-        model.addModelClass(new SClassConverter convert ec)
-        STypeRegistry.addType(SType(ec.getName, packageName))
+        //println(ec)
+        model.addModelClass(new SClassConverter convert (ec, sourceName))
       case _ =>
-        // we only care about classes. Types will be registered as soon as they are needed as
-        // attributes
+      // we only care about classes. Types will be registered as soon as they are needed as
+      // attributes
     }
     println("... Conversion finished")
     println(s"Generated model: $model")
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/conversion/SModelGeneratorTest.scala b/src/main/scala/org/rosi_project/model_sync/generator/conversion/SModelGeneratorTest.scala
deleted file mode 100644
index 16cee3fbd4f8dee34a5278703d94aa3dc352bc64..0000000000000000000000000000000000000000
--- a/src/main/scala/org/rosi_project/model_sync/generator/conversion/SModelGeneratorTest.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.rosi_project.model_sync.generator.conversion
-
-import org.eclipse.emf.ecore.{EObject, EPackage}
-import org.eclipse.emf.ecore.resource.Resource
-import scroll.internal.ecore.ECoreImporter
-
-/**
-  * @author Rico Bergmann
-  */
-object SModelGeneratorTest/* extends App */{
-
-  val importer = new ECoreImporter {
-    def lm(): Resource = loadModel()
-  }
-  importer.path = "assets/ttc17.ecore"
-  val res = importer.lm()
-  println(s"We done: $res")
-
-  res.getContents.toArray(new Array[EObject](0)).toList.find(_.isInstanceOf[EPackage]).foreach(e => (new SModelGenerator).convert(e.asInstanceOf[EPackage]))
-
-}
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/env/FilesCompiler.scala b/src/main/scala/org/rosi_project/model_sync/generator/env/FilesCompiler.scala
index 516f2859e01e910e66f57eaeef2d17b0a28f814c..706a6022af9788cad2a331bd737f4e56e7c4d2db 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/env/FilesCompiler.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/env/FilesCompiler.scala
@@ -22,7 +22,7 @@ class FilesCompiler(outDir: File) {
       val compilationSettings: Settings = new GenericRunnerSettings(out.println)
       // just re-use the whole classpath
       compilationSettings.classpath.value = JClassPath.adaptClassPathToOSEnv(JClassPath.fetchCurrentClassPath).distinct.mkString(File.pathSeparator)
-      println(s"Using classpath ${compilationSettings.classpath.value}")
+      //println(s"Using classpath ${compilationSettings.classpath.value}")
       compilationSettings.outdir.value = outDir.toAbsolute.toString
       val reporter = new ConsoleReporter(compilationSettings)
       val compiler = new Global(compilationSettings, reporter)
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/env/JarPackager.scala b/src/main/scala/org/rosi_project/model_sync/generator/env/JarPackager.scala
index 3d1478f542696ad245c92c73ba770637a9f0ad6b..4016620ae280d05834a40d38c9b54f34fc7b2278 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/env/JarPackager.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/env/JarPackager.scala
@@ -30,7 +30,7 @@ class JarPackager(inputDir: File, outputDir: File, jarName: String = "model.jar"
       while (filesToAdd.nonEmpty) {
         val file = filesToAdd.head
         var fname = file.getAbsolutePath.replace(inputDir.jfile.getAbsolutePath + File.separator, "").replaceAll("\\\\", "/")
-        println(s"Adding to JAR: $fname")
+        //println(s"Adding to JAR: $fname")
         if (file.isDirectory) {
           if (!fname.endsWith("/")) {
             fname += "/"
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala b/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala
index ca1d49cefc4bcbb85b8656b7c42ac925366eb984..8609dbf491fe2587b18bcb6a66eb9cb316fbdfd5 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriter.scala
@@ -1,71 +1,262 @@
 package org.rosi_project.model_sync.generator.io
 
-import org.rosi_project.model_sync.generator.acr_model.{SAttribute, SMethod, SClass}
+import org.rosi_project.model_sync.generator.acr_model._
 import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
+import org.rosi_project.model_sync.generator.sync.PredefRsumTypes
+import org.rosi_project.model_sync.generator.acr_model.types.GenericSequence
+import org.rosi_project.model_sync.generator.sync.HelperFunctions
+import org.rosi_project.model_sync.generator.PackageNames
 
-/** The `Writer` generates the source code of a [[SClass]] and provides it as a `String`.
-  *
-  * @author Rico Bergmann
-  */
+/**
+ * The `Writer` generates the source code of a [[SClass]] and provides it as a `String`.
+ *
+ * @author Rico Bergmann
+ */
 class SClassWriter(val modelClass: SClass) {
 
+  private val isView: Boolean = modelClass.isInstanceOf[SViewClass]
   private val pckg: String = if (modelClass.isDefaultPackage) "" else s"package ${modelClass.sPackage}"
   private val imports: Seq[String] = modelClass.collectImports.toSeq
+  private val viewImports: String = {
+    if (isView) {
+      s"""
+        | import ${PredefRsumTypes.VIEWTYPE_INFO_STYPE.getPackage}.${PredefRsumTypes.VIEWTYPE_INFO_STYPE.getName}
+        | import ${PredefRsumTypes.JOIN_INFO_STYPE.getPackage}.${PredefRsumTypes.JOIN_INFO_STYPE.getName}
+        | ${modelClass.asInstanceOf[SViewClass].getJoinObject().map(j => s"import ${j.joinObject.getPackage}.${j.joinObject.getName}").mkString(" \n")}
+        """.stripMargin
+    } else {
+      ""
+    }
+  }
 
   private val clazzFixture: String = generateClassFixture
+  private val internalClazzFixture: String = generateInternalClazzFixture
+  private val companionObject: String = generateCompanionFixture
 
-  /** Provides a source code representation of the `modelClass` as a `String`.
-    *
-    * When writing it to a file it will be able to be compiled with the `scalac` (assuming the
-    * ''classpath'' is set-up correctly).
-    */
+  /**
+   * Provides a source code representation of the `modelClass` as a `String`.
+   *
+   * When writing it to a file it will be able to be compiled with the `scalac` (assuming the
+   * ''classpath'' is set-up correctly).
+   */
   def stringify: String = {
     s"""$pckg
        |
        |${imports.map(i => s"import $i").mkString("\n")}
+       |${viewImports}
+       |
+       |/**
+       | * This file is automatically generated from the code generator
+       | * for the role-based model management framework.
+       | */
+       |${clazzFixture} {
        |
-       |class $clazzFixture {
+       |  ${if (PackageNames.multiInhertitanceWithTraits) s"${generateAttributeFixture}" else ""}
        |
        |  ${modelClass.getAdditionalConstructorStatements.map(_.getContent).mkString("\n")}
        |
        |  ${modelClass.getMethods.map(stringifyMethod).mkString("\n")}
        |
+       |  ${internalClazzFixture}
        |}
+       |
+       |${if (isView) companionObject else ""}
+       |
     """.stripMargin
   }
 
-  /** Writes a method as source code.
-    *
-    * @param m the method to write
-    * @return the `String` representation of `m`
-    */
+  /**
+   * Provides a source code representation of an internal class used as role in SCROLL.
+   */
+  def internalStringify: String = {
+    s"""
+       |$clazzFixture {
+       |
+       |  ${modelClass.getAdditionalConstructorStatements.map(_.getContent).mkString("\n")}
+       |
+       |  ${modelClass.getMethods.map(stringifyMethod).mkString("\n")}
+       |
+       |}
+    """.stripMargin
+  }
+
+  /**
+   * Writes a method as source code.
+   *
+   * @param m the method to write
+   * @return the `String` representation of `m`
+   */
   protected def stringifyMethod(m: SMethod): String = {
-    s"""${if (m.overrides) "override" else ""} def ${m.name}(${m.params.map(param => s"${param.name}: ${param.getType}").mkString(", ")}): ${m.getResultType} = {
-       |  ${m.implementation.map(_.getContent).mkString("\n")}
+    var result = s"""${if (m.overrides) "override " else ""}${getVisibilityString(m.getVisibility)}def ${m.getName}(${m.params.map(param => s"${param.getName}: ${param.getDeepTypeName}").mkString(", ")}): ${m.getResultType} """
+    if (!m.implementation.isEmpty) {
+      result = result + s""" = {
+         |  ${m.implementation.map(_.getContent).mkString("\n")}
+         |}
+        """
+    }
+    result.stripMargin
+  }
+
+  /**
+   * Writes the "''companion fixture''" for views.
+   */
+  protected def generateCompanionFixture: String = {
+    if (isView) {
+      val viewClass = modelClass.asInstanceOf[SViewClass]
+      s"""
+       |/**
+       | * This file is automatically generated from the code generator
+       | * for the role-based model management framework.
+       | */
+       |object ${modelClass.getName} extends ${PredefRsumTypes.VIEWTYPE_INFO_STYPE.getName} {  
+       |
+       |  override def getViewName(): String = "${modelClass.getName}"
+       |  
+       |  def getJoinInfos(): Set[${PredefRsumTypes.JOIN_INFO_STYPE.getName}] = ${if (viewClass.getJoinObject.isEmpty) "Set.empty" else s"Set(${viewClass.getJoinObject.map(_.joinObject.getName).mkString(", ")})"}
+       |
+       |  protected def getNewInstance(): ${PredefRsumTypes.IVIEW_COMPARTMENT_STYPE.getName} = new ${modelClass.getName}()
+       |
+       |  def getNewView(): ${modelClass.getName} = getNewViewTypeInstance().asInstanceOf[${modelClass.getName}]
        |}
-     """.stripMargin
+      """.stripMargin
+    } else {
+      ""
+    }
+  }
+
+  /**
+   * Writes the internal classes.
+   */
+  protected def generateInternalClazzFixture: String = {
+    var result = "";
+    modelClass.getInternalClasses.foreach(intCls => {
+      var sw: SClassWriter = new SClassWriter(intCls)
+      var s = sw.internalStringify;
+      result = result + s + "\n";
+    })
+    result
+  }
+
+  private def getVisibilityString(vis: MethodVisibility.Value): String = {
+    var visibility = ""
+    vis match {
+      case MethodVisibility.privateVis   => visibility = "private "
+      case MethodVisibility.protectedVis => visibility = "protected "
+      case MethodVisibility.privateExternalClass =>
+        if (modelClass.isInstanceOf[SInnerClass]) {
+          visibility = s"private[${modelClass.asInstanceOf[SInnerClass].externalClass.getName}] "
+        }
+      case _ =>
+    }
+    visibility
   }
 
-  /** Writes the "''class fixture''", i.e. the `class` identifier followed by the constructor and
-    * optionally a parent class. The parent constructor will be called correctly.
-    */
+  /**
+   * Generate the attribute fixtures to add them in the body.
+   */
+  protected def generateAttributeFixture: String = {
+    modelClass.getStructuralFeatures.map(attr => {
+      val finalS: String = if (attr.isFinal) "val" else "var"
+      val instanziationS: String = if (attr.getTypeElement.isInstanceOf[GenericSequence]) "= Set.empty" else s"= ${HelperFunctions.classEmptyType(attr.getTypeElement.getName)}"
+      s"${getVisibilityString(attr.getVisibility)}${finalS} ${attr.getName}: ${attr.getTypeElement.getDeepName} ${instanziationS} \n"
+    }).mkString(" \n")
+  }
+
+  /**
+   * Writes the "''class fixture''", i.e. the `class` identifier followed by the constructor and
+   * optionally a parent class. The parent constructor will be called correctly.
+   */
   protected def generateClassFixture: String = {
-    var params: List[String] = modelClass.attributes.map(attr => s"var ${attr.name}: ${attr.getType}").toList
-    val parentConstructorParams: String =
-      if (modelClass.isRootClass)
-        ""
-      else
-        modelClass.parent.getConstructorParameters.map(param => s"${param.name}: ${param.getType}").mkString(", ")
+    //println("**************************************************")
+    var params: Seq[String] = modelClass.getStructuralFeatures.map(attr => {
+      val finalS: String = if (attr.isFinal) "val" else "var"
+      s"${getVisibilityString(attr.getVisibility)}${finalS} ${attr.getName}: ${attr.getTypeElement.getDeepName}"
+    }).toList
+    var baseFixture: String = ""
+    var parentConstructorParams: String = ""
+    var parentConstructor: String = ""
+    var allInterfaces: String = ""
+    val parent: STypedElement = modelClass.getClassParent
+
+    if (!modelClass.isRootClass) {
+      parentConstructorParams = parent.getAllConstructorParameters.map(param => s"${constructorParamForParentConstructor(parent, param)}: ${param.getDeepTypeName}").mkString(", ")
+      parentConstructor = s"(${parent.getAllConstructorParameters.map(constructorParamForParentConstructor(parent, _)).mkString(", ")})"
+    }
+
+    if (!modelClass.getInterfaceParents.isEmpty) {
+      allInterfaces = s"${modelClass.getInterfaceParents.map(namesOfInterfaces(_)).mkString(" with ")}"
+    }
 
-    val parentConstructor: String = if (modelClass.isRootClass) "" else s"(${modelClass.parent.getConstructorParameters.map(_.name).toList.mkString(", ")})"
+    if (parentConstructorParams != "") {
+      params = params :+ parentConstructorParams
+    }
 
-    if (parentConstructorParams != "")
-      params ::= parentConstructorParams
+    val constructor: String = if (params.isEmpty) "" else s"(${params.mkString(", ")})"
 
-    val constructor = s"(${params.mkString(", ")})"
-    val baseFixture = s"${modelClass.getName}$constructor"
+    if (modelClass.isInterface) {
+      baseFixture = s"trait ${modelClass.getName}"
+    } else if (modelClass.isObject) {
+      baseFixture = s"object ${modelClass.getName}"
+    } else {
+      baseFixture = s"class ${modelClass.getName}"
+      if (!PackageNames.multiInhertitanceWithTraits) {
+        baseFixture = s"$baseFixture$constructor"
+      }
+      if (modelClass.isAbstract) {
+        baseFixture = s"abstract $baseFixture"
+      }
+    }
+
+    if (modelClass.isRootClass) {
+      if (allInterfaces != "") {
+        if (isView) {
+          baseFixture = s"$baseFixture private"
+        }
+        baseFixture = s"$baseFixture extends $allInterfaces"
+      }
+    } else {
+      baseFixture = s"$baseFixture extends ${parent.getName}"
+      if (!PackageNames.multiInhertitanceWithTraits) {
+        baseFixture = s"${baseFixture}${parentConstructor}"
+      }
+      if (allInterfaces != "") {
+        baseFixture = s"$baseFixture with $allInterfaces"
+      }
+    }
+    baseFixture
+  }
+
+  /**
+   * Generates a ''class parameter's'' name that will be used to initialize a field of the super class.
+   *
+   * This is purely to prevent naming conflicts and shadowing when trying to access a parent's field
+   * from the subclass.
+   */
+  private def constructorParamForParentConstructor(parent: STypedElement, param: SMethodParameter): String = {
+    var parName = s"${parent.getName.head.toLower}_${param.getName.firstLetterToUpperCase}"
+
+    // we need to make sure that the generate name does not by chance appear as a regular attribute
+    // of the model class. If this is the case we add some number to make it unique again.
+    if (modelClass.getDeepStructuralFeatures.exists(_.getName == parName)) {
+      var uniqueIdx = 2
+      var uniqueParName = parName + uniqueIdx
+
+      while (modelClass.getDeepStructuralFeatures.exists(_.getName == uniqueParName)) {
+        uniqueIdx += 1
+        uniqueParName = parName + uniqueIdx
+      }
+
+      parName = uniqueParName
+    }
+
+    parName
+  }
 
-    if (modelClass.isRootClass) baseFixture else s"$baseFixture extends ${modelClass.parent.getName}$parentConstructor"
+  /**
+   * Returns the name of the interface.
+   */
+  private def namesOfInterfaces(interface: STypedElement): String = {
+    interface.getName
   }
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/io/SEnumWriter.scala b/src/main/scala/org/rosi_project/model_sync/generator/io/SEnumWriter.scala
new file mode 100644
index 0000000000000000000000000000000000000000..b9e21dc5fccb925f2a6a86c0483267cebc0a4034
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/io/SEnumWriter.scala
@@ -0,0 +1,28 @@
+package org.rosi_project.model_sync.generator.io
+
+import org.rosi_project.model_sync.generator.acr_model.SEnum
+
+class SEnumWriter(val modelEnum: SEnum) {
+
+  private val pckg: String = if (modelEnum.isDefaultPackage) "" else s"package ${modelEnum.sPackage}"
+
+  /** Provides a source code representation of the `modelEnums` as a `String`.
+    *
+    * When writing it to a file it will be able to be compiled with the `scalac` (assuming the
+    * ''classpath'' is set-up correctly).
+    */  
+  def stringify: String = {
+    s"""$pckg
+       |
+       |/**
+       | * This file is automatically generated from the code generator
+       | * for the role-based model management framework.
+       | */
+       |object ${modelEnum.getName} extends Enumeration {
+       |
+       |  val ${modelEnum.enums.mkString(", ")} = Value
+       |}
+       |
+    """.stripMargin
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriter.scala b/src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriter.scala
index 5a42da3e582afb901a5f5bcca1955b888d58f829..b63bda8d1453df724e9482ce7cb71f4ae7c9a139 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriter.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriter.scala
@@ -8,6 +8,8 @@ import org.rosi_project.model_sync.generator.acr_model._
 import org.rosi_project.model_sync.generator.env.{FilesCompiler, JarPackager}
 
 import scala.reflect.io.{Directory, File, Path}
+import org.rosi_project.model_sync.generator.GeneratorConfig
+import org.rosi_project.model_sync.generator.Creation
 
 /** The `FSWriter` writes a [[SModel]] as a single compiled ''JAR'' file to the File System.
   *
@@ -18,10 +20,11 @@ import scala.reflect.io.{Directory, File, Path}
   * @author Rico Bergmann
   */
 class SModelFSWriter(
+    generatorConfig: GeneratorConfig,
     workingDir: File = File(Files.createTempDirectory("model").toFile),
     outputDir: Directory = File("output").toDirectory,
     keepClassFiles: Boolean = false,
-    modelCfg: ModelConfig,
+    modelCfgs: Set[ModelConfig],
     currentDir: jio.File = new jio.File("").getAbsoluteFile) extends SModelVisitor {
 
   workingDir.jfile.mkdirs()
@@ -33,13 +36,21 @@ class SModelFSWriter(
   println(s"Output dir is $outputDir")
 
   println("... Copying model images")
-  private var images: List[jio.File] = _
+  private var images: List[jio.File] = List.empty
   private var imagesTargetDir: jio.File = _
-  try {
-    images = collectAllModelImages(modelCfg, currentDir)
+  try {    
+    if (modelCfgs.isEmpty) {
+      //TODO: get files  with same source Name
+      images = List.empty
+    } else {      
+      modelCfgs.foreach(con => {
+        images = images ++ collectAllModelImages(con, currentDir)        
+      })
+    }
     imagesTargetDir = new jio.File(workingDir.toAbsolute.toString() + File.separator + "res")
     imagesTargetDir.mkdirs()
     images.foreach(img => {
+      //println("##########Images: " + img.getName)
       Files.copy(img.toPath, imagesTargetDir.toPath.resolve(img.getName), StandardCopyOption.REPLACE_EXISTING)
     })
   } catch {
@@ -48,7 +59,15 @@ class SModelFSWriter(
 
 
   override def visit(sModel: SModel): Unit = {
-    println(s"... Wrote files (sources) $sFilesToCompile")
+    sModel.getModelEnums.foreach(writeEnum(_))
+    sModel.getModelClasses.foreach(writeClass(_))
+    sModel.getProviderClasses.foreach(writeClass(_))
+    if (generatorConfig.create != Creation.rolesync) {
+      sModel.getJoinClasses.foreach(writeClass(_))
+      sModel.getRelationalCompartments.foreach(writeClass(_))
+      sModel.getViewCompartments.foreach(writeClass(_))
+    }
+    //println(s"... Wrote files (sources) $sFilesToCompile")
 
     println("... Starting compilation")
     new FilesCompiler(workingDir).run(sFilesToCompile)
@@ -64,14 +83,31 @@ class SModelFSWriter(
     }
 
     println("... Generating JAR")
-    new JarPackager(workingDir, outputDir.toFile).run()
-    println("... Done")
+    println(s"... Successfully wrote JAR ${outputDir + File.separator + generatorConfig.getCombinedEcoreName + ".jar"}")    
+    new JarPackager(workingDir, outputDir.toFile, generatorConfig.getCombinedEcoreName + ".jar").run()
+    println(s"... Successfully wrote JAR ${outputDir + File.separator + generatorConfig.getCombinedEcoreName + ".jar"}")
   }
+  
+  private def writeEnum(sEnum: SEnum): Unit = {
+    try {
+      println(s"Writing class $sEnum")
+      val classNameWithPath = workingDir.toAbsolute.toString() + File.separator + pckg2Path(sEnum.getPackage) + File.separator + s"${sEnum.getName}.scala"
+      val writer = new SEnumWriter(sEnum)
 
-  override def visit(sClass: SClass): Unit = {
+      val classFile = File(classNameWithPath)
+
+      classFile.jfile.getParentFile.mkdirs()
+      classFile.writeAll(writer.stringify)
+      sFilesToCompile ::= classFile
+    } catch {
+      case e: Exception => throw new ClassWritingException(e)
+    }
+  }
+  
+  private def writeClass(sClass: SClass): Unit = {
     try {
       println(s"Writing class $sClass")
-      val classNameWithPath = workingDir.toAbsolute.toString() + File.separator + pckg2Path(sClass.getPackage) + File.separator + s"${sClass.name}.scala"
+      val classNameWithPath = workingDir.toAbsolute.toString() + File.separator + pckg2Path(sClass.getPackage) + File.separator + s"${sClass.getName}.scala"
       val writer = new SClassWriter(sClass)
 
       val classFile = File(classNameWithPath)
@@ -84,9 +120,17 @@ class SModelFSWriter(
     }
   }
 
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
   override def visit(sAttr: SAttribute): Unit = {
     // pass
   }
+  
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
 
   override def visit(sMethod: SMethod): Unit = {
     // pass
@@ -124,7 +168,7 @@ class SModelFSWriter(
         })
       })
     })
-
+    println(modelConfig + " I: " + images)
     images
   }
 
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/BasicTypeGetterSetterGeneratingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/BasicTypeGetterSetterGeneratingVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..1bdfde2ce77c1798744658895d18b61bac7f206c
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/BasicTypeGetterSetterGeneratingVisitor.scala
@@ -0,0 +1,39 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+
+class BasicTypeGetterSetterGeneratingVisitor extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    sModel.getModelClasses.foreach(cls => {
+      //add all getter and setter for each normal attribute
+      cls.getAttributes.foreach(attr => {
+        attr.setVisibility(MethodVisibility.protectedVis)
+        val getter = new SGetter(attr)
+        val setter = new SSetter(attr)
+        cls.addMethod(getter)
+        cls.addMethod(setter)
+      })
+    })
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/GenerateQueryHelperVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/GenerateQueryHelperVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..3018c8f3b324af53276385c1aab3baeb164f4f0a
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/GenerateQueryHelperVisitor.scala
@@ -0,0 +1,48 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.rosi_project.model_sync.generator.PackageNames
+
+class GenerateQueryHelperVisitor extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    var newClasses: Set[SClass] = Set.empty
+    //iterate over all abstract classes or interfaces
+    sModel.getModelClasses.foreach(cls => {
+      if (cls.isAbstract || cls.isInterface) {
+        val newClass = new SClass(PackageNames.queryHelperPrefix + cls.getName, cls.getPackage)
+        newClass.addParent(cls)
+        newClass.addParent(PredefRsumTypes.QUERY_HELPER_STYPE)
+        newClass.addMethod(new SMethod(
+          name = "equals",
+          result = PredefTypes.Boolean,
+          params = Seq(SMethodParameter("that", PredefTypes.Any)),
+          implementation = Seq(SMethodStatement(content = s"that.isInstanceOf[${cls.getName}]", usedTypes = Set.empty)), 
+          true))
+        newClasses += newClass
+      }
+    })
+    newClasses.foreach(sModel.addModelClass(_))
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+  
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/GetterSetterGeneratingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/GetterSetterGeneratingVisitor.scala
index dd6fd38c5c7cc1da67789de45328b9a876637bfb..b9285aaa2d94636ebd428c2348c8d959b85ef84e 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/sync/GetterSetterGeneratingVisitor.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/GetterSetterGeneratingVisitor.scala
@@ -1,30 +1,47 @@
 package org.rosi_project.model_sync.generator.sync
+
 import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.acr_model.types.GenericSequence
 
-/** Service to extend [[SClass SClasses]] with getter and setter methods for all attributes.
-  *
-  * @author Rico Bergmann
-  */
+/**
+ * Service to extend [[SClass SClasses]] with getter and setter methods for all attributes.
+ *
+ * @author Rico Bergmann
+ */
 class GetterSetterGeneratingVisitor extends SModelVisitor {
 
   override def visit(sModel: SModel): Unit = {
-    // pass
+    sModel.getModelClasses.foreach(cls => {
+      //add all getter and setter for all structural features
+      cls.getStructuralFeatures.foreach(attr => {
+        attr.setVisibility(MethodVisibility.protectedVis)
+        val getter = new SGetter(attr)
+        cls.addMethod(getter)
+        if (attr.getTypeElement.isInstanceOf[GenericSequence]) {
+          val adder = new SSetterAdd(attr, attr.getTypeElement.asInstanceOf[GenericSequence].typeParam)
+          cls.addMethod(adder)
+          val remover = new SSetterRemove(attr, attr.getTypeElement.asInstanceOf[GenericSequence].typeParam)
+          cls.addMethod(remover)
+        } else {
+          val setter = new SSetter(attr)
+          cls.addMethod(setter)
+        }
+      })
+    })
   }
 
   override def visit(sClass: SClass): Unit = {
-    sClass.attributes.foreach(attr => {
-      val getter = new SGetter(attr)
-      val setter = new SSetter(attr)
-      sClass.addMethod(getter)
-      sClass.addMethod(setter)
-    })
-
+    // pass
   }
 
   override def visit(sAttr: SAttribute): Unit = {
     // pass
   }
 
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
   override def visit(sMethod: SMethod): Unit = {
     // pass
   }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/HelperFunctions.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/HelperFunctions.scala
new file mode 100644
index 0000000000000000000000000000000000000000..7b00cf31870c5011bd1ed7cdc3572e5ffe196f14
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/HelperFunctions.scala
@@ -0,0 +1,37 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
+
+object HelperFunctions {
+  def classNameCreation(t: STypedElement): String = s"className.isInstanceOf[${t.getName}]"
+  
+  def initialAttributeDoing(mp: SMethodParameter, sfs: Seq[SStructuralFeature]): String = {
+    sfs.foreach(s => {
+      if (s.getName == mp.getName) {
+        return mp.getName
+      }
+    })
+    return classEmptyConstructorParameterCreation(mp)
+  }
+  
+  def attributeEqualCreation(a: SStructuralFeature): String = s"base.get${a.getName.firstLetterToUpperCase}() == other.get${a.getName.firstLetterToUpperCase}()"
+  
+  def classEmptyConstructorParameterCreation(t: SMethodParameter): String = {
+    classEmptyType(t.getTypeName)
+  }
+  
+  def classEmptyType(s: String): String = {
+    s match {
+      case "Boolean" => return "false"
+      case "Double" => return "0"
+      case "Float" => return "0"
+      case "Long" => return "0"
+      case "Integer" => return "0"
+      case "Int" => return "0"
+      case "Short" => return "0"
+      case "Byte" => return "0"
+      case _ => return "null"
+    } 
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/Imports.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/Imports.scala
deleted file mode 100644
index bf4ba3cf8cda50fdef4ec5f8b52bc201d1ae2d78..0000000000000000000000000000000000000000
--- a/src/main/scala/org/rosi_project/model_sync/generator/sync/Imports.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.rosi_project.model_sync.generator.sync
-
-import org.rosi_project.model_sync.generator.acr_model.SImport
-
-/** Contains a number of imports which are used throughout the sync infrastructure.
-  *
-  * @author Rico Bergmann
-  */
-object Imports {
-
-  /** Import for the `ModelRegistry` type.
-    */
-  val ModelRegistry = SImport(PredefTypes.ModelRegistry.sPackage, PredefTypes.ModelRegistry.name)
-
-}
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceCombiGenerator.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceCombiGenerator.scala
new file mode 100644
index 0000000000000000000000000000000000000000..73a31185eb74b6b2a5a20cf56a1e57aab299d143
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceCombiGenerator.scala
@@ -0,0 +1,126 @@
+package org.rosi_project.model_sync.generator.sync
+
+import scala.collection.JavaConverters._
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.util.ClassAndInstance
+import org.eclipse.emf.ecore.EObject
+import org.rosi_project.model_sync.generator.util.InstanceLine
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.eclipse.emf.ecore.EStructuralFeature
+import org.eclipse.emf.common.util.EList
+import org.rosi_project.model_sync.util.EMFUtilForGenerator
+import java.util.List
+import org.rosi_project.model_sync.generator.PackageNames
+
+class InstanceCombiGenerator(val clsins: ClassAndInstance) extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    //println("++++++++++++++++++++++++++++++++++++++++++++++")
+    val example = new SClass("ExampleCombiCase", PackageNames.examplePkgName, SClassType.normalObject)
+    val contents = clsins.obj.eAllContents().asScala
+    var counter = 0
+    var lines: Seq[InstanceLine] = Seq.empty
+    var generationLines: Seq[InstanceLine] = Seq.empty
+    var sType = STypeRegistry.getFromClass(clsins.obj.eClass())
+    if (sType != null) {
+      lines = lines :+ new InstanceLine(counter, clsins.obj, sType)
+      counter += 1
+    }
+    contents.foreach(o => {
+      sType = STypeRegistry.getFromClass(o.eClass())
+      if (sType != null) {
+        lines = lines :+ new InstanceLine(counter, o, sType)
+        counter += 1
+      }
+    })    
+    //add values for instances    
+    lines.foreach(l => {
+      l.usedType.getAllConstructorParameters.foreach(cp => {
+        if (!STypeRegistry.isDefaultType(cp.getType.getName)) {
+          val structs: Seq[EStructuralFeature] = l.obj.eClass().getEAllStructuralFeatures.asScala
+          structs.foreach(att => {
+            if (att.getName == cp.getName) {
+              val obj = l.obj.eGet(att)
+              if (obj.isInstanceOf[EObject]) {
+                lines.foreach(lnow => {
+                  if (lnow.obj == obj.asInstanceOf[EObject]) {
+                    //println("Found: " + lnow.counter) .filter(_.isInstanceOf[SRelationalCompartmentClass])
+                    sModel.getRelationalCompartments.foreach(rc => {
+                      val realRc = rc.asInstanceOf[SRelationalCompartmentClass]
+                      //println(" AN: " + att.getName + " l1: " + l.usedType.getName + " l2: " + lnow.usedType.getName + " RC: " + realRc.connectedRef.getName + " SN: " + realRc.sClass.getName + " TN: " + realRc.tClass.getName)
+                      if (realRc.connectedRef.getName == att.getName && l.usedType.proofHierarchicalEquality(realRc.sClass) && lnow.usedType.proofHierarchicalEquality(realRc.tClass)) {
+                        val s = s"(new ${realRc.getName}(${l.getName()}, ${lnow.getName()})).initialize()"
+                        generationLines = generationLines :+ new InstanceLine(0, null, realRc, s)
+                      }
+                    })
+                  }
+                })
+              } else {
+                val listi: List[EObject] = EMFUtilForGenerator.getList(obj)
+                val liste = listi.asScala
+                liste.foreach(eo => {
+                  lines.foreach(lnow => {
+                    if (lnow.obj == eo) {
+                      sModel.getRelationalCompartments.foreach(rc => {
+                        val realRc = rc.asInstanceOf[SRelationalCompartmentClass]
+                        //println(" AN: " + att.getName + " l1: " + l.usedType.getName + " l2: " + lnow.usedType.getName + " RC: " + realRc.connectedRef.getName + " SN: " + realRc.sClass.getName + " TN: " + realRc.tClass.getName)
+                        if (realRc.connectedRef.getName == att.getName && l.usedType.proofHierarchicalEquality(realRc.sClass) && lnow.usedType.proofHierarchicalEquality(realRc.tClass)) {
+                          val s = s"(new ${realRc.getName}(${l.getName()}, ${lnow.getName()})).initialize()"
+                          generationLines = generationLines :+ new InstanceLine(0, null, realRc, s)
+                        }
+                      })
+                    }
+                  })
+                })
+              }
+            }
+          })
+        }
+      })
+    })
+    
+    //construction of instances
+    lines.foreach(l => {
+      example.augmentConstructor(new SMethodStatement(l.getLine(), Set(l.usedType)))
+    })
+    
+    //construction of connections
+    generationLines.foreach(l => {
+      example.augmentConstructor(new SMethodStatement(l.getLine(), Set(l.usedType)))
+    })
+    
+    
+    example.addParent(PredefTypes.App)
+    sModel.addProviderClass(example)
+  }
+
+  def setValues(eo: EObject, lines: Seq[InstanceLine]): String = {
+    lines.foreach(lnow => {
+      if (lnow.obj == eo) {
+        return lnow.getName()
+      }
+    })
+    ""
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceGenerator.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceGenerator.scala
new file mode 100644
index 0000000000000000000000000000000000000000..241f424cb0c2c1baa56978180d6199e17b76e66c
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/InstanceGenerator.scala
@@ -0,0 +1,108 @@
+package org.rosi_project.model_sync.generator.sync
+
+import scala.collection.JavaConverters._
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.util.ClassAndInstance
+import org.eclipse.emf.ecore.EObject
+import org.rosi_project.model_sync.generator.util.InstanceLine
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.eclipse.emf.ecore.EStructuralFeature
+import org.eclipse.emf.common.util.EList
+import org.rosi_project.model_sync.util.EMFUtilForGenerator
+import java.util.List
+import org.rosi_project.model_sync.generator.PackageNames
+
+/**
+ * Service to create an instance creation object.
+ *
+ * @author Christopher Werner
+ */
+class InstanceGenerator(val clsins: ClassAndInstance) extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    //println("++++++++++++++++++++++++++++++++++++++++++++++")
+    val example = new SClass("ExampleCase", PackageNames.examplePkgName, SClassType.normalObject)
+    val contents = clsins.obj.eAllContents().asScala
+    var counter = 0
+    var lines: Seq[InstanceLine] = Seq.empty
+    var sType = STypeRegistry.getFromClass(clsins.obj.eClass())
+    if (sType != null) {
+      lines = lines :+ new InstanceLine(counter, clsins.obj, sType)
+      counter += 1
+    }
+    contents.foreach(o => {
+      sType = STypeRegistry.getFromClass(o.eClass())
+      if (sType != null) {
+        lines = lines :+ new InstanceLine(counter, o, sType)
+        counter += 1
+      }
+    })
+    //construction of instances
+    lines.foreach(l => {
+      example.augmentConstructor(new SMethodStatement(l.getLine(), Set(l.usedType)))
+    })
+    //add values for instances
+    lines.foreach(l => {
+      l.usedType.getAllConstructorParameters.foreach(cp => {
+        if (!STypeRegistry.isDefaultType(cp.getType.getName)) {
+          var structs: Seq[EStructuralFeature] = l.obj.eClass().getEAllStructuralFeatures.asScala
+          structs.foreach(att => {
+            if (att.getName == cp.getName) {
+              val obj = l.obj.eGet(att)
+              //println("### " + att.getName)
+              if (obj.isInstanceOf[EObject]) {
+                lines.foreach(lnow => {
+                  if (lnow.obj == obj.asInstanceOf[EObject]) {
+                    //println("Found: " + lnow.counter)
+                    var s = s"${l.getName()}.set${att.getName.capitalize}(${lnow.getName()})"
+                    example.augmentConstructor(new SMethodStatement(s))
+                  }
+                })
+              } else {
+                val listi: List[EObject] = EMFUtilForGenerator.getList(obj)
+                val liste = listi.asScala
+                val s = s"${l.getName()}.set${att.getName.capitalize}(Set(${liste.map(setValues(_, lines)).mkString(", ")}))"
+                example.augmentConstructor(new SMethodStatement(s))
+              }
+            }
+          })
+        }
+      })
+    })
+    example.addParent(PredefTypes.App)
+    sModel.addProviderClass(example)
+    //println("++++++++++++++++++++++++++++++++++++++++++++++")
+    // pass
+
+  }
+
+  def setValues(eo: EObject, lines: Seq[InstanceLine]): String = {
+    lines.foreach(lnow => {
+      if (lnow.obj == eo) {
+        return lnow.getName()
+      }
+    })
+    ""
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/JoinGeneratingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/JoinGeneratingVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..d3c9b884e1cfae0040219ce86bb14d2f93adf5eb
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/JoinGeneratingVisitor.scala
@@ -0,0 +1,152 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.model_join.representation.grammar.ModelJoinExpression
+import org.rosi_project.model_management.sum.join.RsumJoinType
+import org.rosi_project.model_sync.model_join.representation.grammar.JoinExpression.JoinType
+import org.rosi_project.model_sync.model_join.representation.grammar.ThetaJoinExpression
+
+class JoinGeneratingVisitor(joinExpression: ModelJoinExpression) extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+
+    joinExpression.getJoins.forEach(j => {
+      println("Type: " + j.getType + " Base: " + j.getBaseModel.getResourcePath + " " + j.getBaseModel.getResourceName + " Other: " + j.getOtherModel + " Target: " + j.getTarget)
+      println(j)
+      j.getKeeps.forEach(k => {
+        println(k)
+      })
+    })
+
+    joinExpression.getJoins.forEach(j => {
+      val baseType: Option[STypedElement] = STypeRegistry.query(j.getBaseModel().getResourceName, j.getBaseModel().getResourcePath)
+      val otherType: Option[STypedElement] = STypeRegistry.query(j.getOtherModel().getResourceName, j.getOtherModel().getResourcePath)
+      var targetType: Option[STypedElement] = STypeRegistry.query(j.getTarget().getResourceName, j.getTarget().getResourcePath)
+      
+      println("B: " + baseType + " O: " + otherType + " T: " + targetType + " Same: " + j.isSameElement)
+      
+      if (j.isSameElement || baseType.isEmpty || otherType.isEmpty || !targetType.isEmpty) {
+        return
+      }
+
+      val baseClass = baseType.get.asInstanceOf[SClass]
+      val otherClass = otherType.get.asInstanceOf[SClass]
+      
+      var rsumJoinType = RsumJoinType.natural
+      var compareString: String = null 
+      
+      j.getType match {
+        case JoinType.NATURAL => rsumJoinType = RsumJoinType.natural
+        case JoinType.OUTER => rsumJoinType = RsumJoinType.outer
+        case JoinType.THETA => 
+          rsumJoinType = RsumJoinType.theta
+          compareString = j.asInstanceOf[ThetaJoinExpression].getCondition.get
+      }
+      
+      var otherAttsBase: Set[SStructuralFeature] = Set.empty
+      var otherAttsOther: Set[SStructuralFeature] = Set.empty
+      var joinAtts: Set[SStructuralFeature] = Set.empty
+
+      baseClass.getDeepStructuralFeatures.foreach(ba => {
+        var foundOne = false
+        otherClass.getDeepStructuralFeatures.foreach(oa => {
+          if (oa.getName == ba.getName && oa.getTypeElement.getName == ba.getTypeElement.getName) {
+            joinAtts += ba
+            foundOne = true
+          }
+        })
+        if (!foundOne) {
+          otherAttsBase += ba
+        }
+      })
+
+      otherClass.getDeepStructuralFeatures.foreach(oa => {
+        var foundOne = false
+        joinAtts.foreach(ba => {
+          if (oa.getName == ba.getName && oa.getTypeElement.getName == ba.getTypeElement.getName) {
+            foundOne = true
+          }
+        })
+        if (!foundOne) {
+          otherAttsOther += oa
+        }
+      })
+      
+      println("J: " + joinAtts + " T: " + rsumJoinType)
+      println("B: " + otherAttsBase)
+      println("O: " + otherAttsOther)
+      
+      val joinObject = new SClass(j.getTarget().getResourceName + "Object", j.getTarget().getResourcePath, SClassType.normalObject)
+      val joinClass = new SJoinClass(j.getTarget().getResourceName, j.getTarget().getResourcePath, 
+          base = baseClass, other = otherClass, joinType = rsumJoinType, 
+          joinAttributes = joinAtts, innerAttributes = joinAtts ++ otherAttsBase ++ otherAttsOther, joinObject)
+
+      //add parents
+      joinClass.addParent(PredefRsumTypes.IJOIN_COMPARTMENT_STYPE)
+      joinObject.addParent(PredefRsumTypes.JOIN_INFO_STYPE)     
+
+      //add functions to the join object
+      joinObject.addMethod(JoinMethods.getJoinTypeMethod(j.getType))
+      joinObject.addMethod(JoinMethods.getInstanceBaseModelMethod(baseClass))
+      joinObject.addMethod(JoinMethods.getInstanceOtherModelMethod(otherClass))
+      joinObject.addMethod(JoinMethods.getNewInstanceMethod(joinClass))
+      joinObject.addMethod(JoinMethods.getInstanceOfMethod(joinClass))
+      joinObject.addMethod(JoinMethods.getMatchMethod(baseClass, otherClass, joinAtts, compareString))
+      joinObject.addMethod(ToStringMethods.onlyStringToStringMethod(joinObject.getName))
+      
+      //add functions to the join class
+      val attributesJoinClass = Seq(new SAttribute("base", baseClass), new SAttribute("other", otherClass))
+      attributesJoinClass.foreach(a => {
+        a.setVisibility(MethodVisibility.privateVis)
+        a.isFinal = true
+      })
+
+      joinClass.setAttributes(attributesJoinClass)
+      //add base functions
+      joinClass.augmentConstructor(new SMethodStatement("initialize(base, other)", Set()))
+      joinClass.addMethod(JoinMethods.getJoinInfoMethod(joinObject))
+      //add getter and setter functions
+      joinAtts.foreach(a => {
+        joinClass.addMethod(JoinMethods.getBaseAttributeGetter(a))
+        joinClass.addMethod(JoinMethods.getMixedAttributeSetter(a))
+      })
+      otherAttsBase.foreach(a => {
+        joinClass.addMethod(JoinMethods.getBaseAttributeGetter(a))
+        joinClass.addMethod(JoinMethods.getBaseAttributeSetter(a))
+      })
+      otherAttsOther.foreach(a => {
+        joinClass.addMethod(JoinMethods.getOtherAttributeGetter(a))
+        joinClass.addMethod(JoinMethods.getOtherAttributeSetter(a))
+      })
+      //add to String method
+      joinClass.addMethod(ToStringMethods.joinToStringMethod(joinClass.getName))
+
+      sModel.addJoinClass(joinClass)
+      sModel.addJoinClass(joinObject)
+      
+      //add in Type Registry
+      STypeRegistry.addType(joinClass, null)
+    })
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/JoinMethods.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/JoinMethods.scala
new file mode 100644
index 0000000000000000000000000000000000000000..335b5b3e9e001d16227442c17fb385bb994e0dda
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/JoinMethods.scala
@@ -0,0 +1,137 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.model_join.representation.grammar.JoinExpression.JoinType
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
+
+object JoinMethods {
+
+  //JOIN OBJECT METHODS
+  def getJoinTypeMethod(joinType: JoinType): SMethod = {
+    val met = new SMethod(
+      name = "getJoinType",
+      result = PredefRsumTypes.RSUM_JOIN_TYPE_STYPE,
+      params = Seq.empty,
+      implementation = Seq())
+    if (joinType == JoinType.NATURAL) {
+      met.implementation = Seq(SMethodStatement(content = s"RsumJoinType.natural", usedTypes = Set()))
+    }
+    if (joinType == JoinType.OUTER) {
+      met.implementation = Seq(SMethodStatement(content = s"RsumJoinType.outer", usedTypes = Set()))
+    }
+    if (joinType == JoinType.THETA) {
+      met.implementation = Seq(SMethodStatement(content = s"RsumJoinType.theta", usedTypes = Set()))
+    }
+    met
+  }
+
+  def getInstanceBaseModelMethod(cls: SClass): SMethod = {
+    new SMethod(
+      name = "isInstanceBaseModel",
+      result = PredefTypes.Boolean,
+      params = Seq(SMethodParameter("obj", PredefTypes.Object)),
+      implementation = Seq(SMethodStatement(content = s"obj.isInstanceOf[${cls.getName}]", usedTypes = Set(cls))))
+  }
+
+  def getInstanceOtherModelMethod(cls: SClass): SMethod = {
+    new SMethod(
+      name = "isInstanceOtherModel",
+      result = PredefTypes.Boolean,
+      params = Seq(SMethodParameter("obj", PredefTypes.Object)),
+      implementation = Seq(SMethodStatement(content = s"obj.isInstanceOf[${cls.getName}]", usedTypes = Set(cls))))
+  }
+
+  def getInstanceOfMethod(cls: SClass): SMethod = {
+    new SMethod(
+      name = "isInstanceOf",
+      result = PredefTypes.Boolean,
+      params = Seq(SMethodParameter("obj", PredefTypes.Object)),
+      implementation = Seq(SMethodStatement(content = s"obj.isInstanceOf[${cls.getName}]", usedTypes = Set(cls))))
+  }
+
+  def getNewInstanceMethod(cls: SClass): SMethod = {
+    new SMethod(
+      name = "getNewInstance",
+      result = PredefRsumTypes.IJOIN_COMPARTMENT_STYPE,
+      params = Seq(SMethodParameter("b", PredefTypes.Object), SMethodParameter("o", PredefTypes.Object)),
+      implementation = Seq(SMethodStatement(content = s"val j = new ${cls.getName}(null, null)", usedTypes = Set(cls)),
+        SMethodStatement(content = "objectInitialize(j, b, o)", usedTypes = Set()),
+        SMethodStatement(content = "j", usedTypes = Set())))
+  }
+
+  def getMatchMethod(base: SClass, other: SClass, joinAtts: Set[SStructuralFeature], joinString: String): SMethod = {
+    val met = new SMethod(
+      name = "matchTwoObjects",
+      result = PredefTypes.Boolean,
+      params = Seq(SMethodParameter("b", PredefTypes.Object), SMethodParameter("o", PredefTypes.Object)),
+      implementation = Seq())
+    met.implementation = Seq(SMethodStatement(content = s"val base = b.asInstanceOf[${base.getName}]", usedTypes = Set(base)),
+      SMethodStatement(content = s"val other = o.asInstanceOf[${other.getName}]", usedTypes = Set(other)))
+    if (joinString == null) {
+      met.implementation = met.implementation :+ SMethodStatement(content = s"${joinAtts.map(HelperFunctions.attributeEqualCreation(_)).mkString(" && ")}")
+    } else {
+      met.implementation = met.implementation :+ SMethodStatement(content = joinString)
+    }
+    met
+  }
+
+  //JOIN CLASS METHODS
+  def getJoinInfoMethod(obj: SClass): SMethod = {
+    new SMethod(
+      name = "getJoinInfo",
+      result = PredefRsumTypes.JOIN_INFO_STYPE,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement(content = s"${obj.getName}", usedTypes = Set(obj))))
+  }
+
+  //GETTER
+  def getBaseAttributeGetter(struc: SStructuralFeature): SMethod = {
+    new SMethod(
+      name = s"get${struc.getName.firstLetterToUpperCase}",
+      result = struc.getTypeElement,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement(content = s"+baseRole get${struc.getName.firstLetterToUpperCase}()", usedTypes = Set(struc.getTypeElement))))
+  }
+
+  def getOtherAttributeGetter(struc: SStructuralFeature): SMethod = {
+    new SMethod(
+      name = s"get${struc.getName.firstLetterToUpperCase}",
+      result = struc.getTypeElement,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement(content = "if (otherObj != null) {", usedTypes = Set()),
+        SMethodStatement(content = s"return +otherRole get${struc.getName.firstLetterToUpperCase}()", usedTypes = Set(struc.getTypeElement)),
+        SMethodStatement(content = "}", usedTypes = Set()),
+        SMethodStatement(content = s"return ${HelperFunctions.classEmptyType(struc.getTypeElement.getName)}", usedTypes = Set())))
+  }
+
+  //SETTER  
+  def getBaseAttributeSetter(struc: SStructuralFeature): SMethod = {
+    new SMethod(
+      name = s"set${struc.getName.firstLetterToUpperCase}",
+      result = PredefTypes.Unit,
+      params = Seq(SMethodParameter(struc.getName.toLowerCase(), struc.getTypeElement)),
+      implementation = Seq(SMethodStatement(content = s"+baseRole set${struc.getName.firstLetterToUpperCase}(${struc.getName.toLowerCase()})", usedTypes = Set(struc.getTypeElement))))
+  }
+
+  def getMixedAttributeSetter(struc: SStructuralFeature): SMethod = {
+    new SMethod(
+      name = s"set${struc.getName.firstLetterToUpperCase}View",
+      result = PredefTypes.Unit,
+      params = Seq(SMethodParameter(struc.getName.toLowerCase(), struc.getTypeElement)),
+      implementation = Seq(SMethodStatement(content = s"+baseRole set${struc.getName.firstLetterToUpperCase}(${struc.getName.toLowerCase()})", usedTypes = Set(struc.getTypeElement)),
+        SMethodStatement(content = "if (otherObj != null) {", usedTypes = Set()),
+        SMethodStatement(content = s"+otherRole set${struc.getName.firstLetterToUpperCase}(${struc.getName.toLowerCase()})", usedTypes = Set(struc.getTypeElement)),
+        SMethodStatement(content = "}", usedTypes = Set.empty)))
+  }
+
+  def getOtherAttributeSetter(struc: SStructuralFeature): SMethod = {
+    new SMethod(
+      name = s"set${struc.getName.firstLetterToUpperCase}View",
+      result = PredefTypes.Unit,
+      params = Seq(SMethodParameter(struc.getName.toLowerCase(), struc.getTypeElement)),
+      implementation = Seq(SMethodStatement(content = "if (otherObj != null) {", usedTypes = Set()),
+        SMethodStatement(content = s"+otherRole set${struc.getName.firstLetterToUpperCase}(${struc.getName.toLowerCase()})", usedTypes = Set(struc.getTypeElement)),
+        SMethodStatement(content = "}", usedTypes = Set.empty)))
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/ModelJoinViewGeneratingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/ModelJoinViewGeneratingVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..9cea21c63baf358e2a26168561af82376dc8bea3
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/ModelJoinViewGeneratingVisitor.scala
@@ -0,0 +1,262 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.acr_model.types._
+import org.rosi_project.model_sync.model_join.representation.grammar._
+import scala.collection.JavaConverters._
+import scala.collection.convert.AsScalaConverters
+import org.rosi_project.model_management.sum.join.RsumJoinType
+import org.rosi_project.model_sync.generator.PackageNames
+
+class ModelJoinViewGeneratingVisitor(joinExpression: ModelJoinExpression) extends SModelVisitor {
+
+  var viewCompartment: SViewClass = null
+  var refClasses: Seq[SClass] = Seq.empty
+  var refRelationalClasses: Seq[SClass] = Seq.empty
+  var newInternalRoles: Seq[SInnerViewNaturalClass] = Seq.empty
+  var newInternalRelationalRoles: Seq[SInnerViewRelationalClass] = Seq.empty
+  var allImportClasses: Set[STypedElement] = Set.empty
+
+  override def visit(sModel: SModel): Unit = {
+    var counter = 0
+    joinExpression.getJoins.forEach(j => {
+      refClasses = Seq.empty
+      refRelationalClasses = Seq.empty
+      newInternalRoles = Seq.empty
+      newInternalRelationalRoles = Seq.empty
+      allImportClasses = Set.empty
+      viewCompartment = new SViewClass(joinExpression.getName() + counter, PackageNames.viewPkgName)
+      counter += 1
+      viewCompartment.addParent(PredefRsumTypes.IVIEW_COMPARTMENT_STYPE)
+
+      val joinType = STypeRegistry.query(j.getTarget.getResourceName, j.getTarget.getResourcePath)
+      if (!joinType.isEmpty) {
+        if (joinType.get.isInstanceOf[SJoinClass]) {
+          viewCompartment.addJoinObject(joinType.get.asInstanceOf[SJoinClass])
+        }
+        createClasses(asScalaBuffer(j.getKeepsList).toSet, joinType.get.asInstanceOf[SClass], sModel)
+      }
+
+      //Now fill all natural internal roles with functionality
+      newInternalRoles.foreach(inner => {
+        //set inheritance to abstract view role
+        if (inner.isRootClass) {
+          inner.addParent(PredefRsumTypes.AVIEW_ROLE_STYPE)
+        }
+        //add initialize method if necessary
+        if (!inner.isAbstract && !inner.isInterface) {
+          inner.addMethod(ViewMethods.getIsRelationalMethod(false))
+          inner.addMethod(ViewMethods.getCreationObjectMethod(inner))
+        }
+        //add to string method
+        inner.addMethod(ToStringMethods.onlyStringToStringMethod("VNR: " + inner.getName))
+        //add delete method
+        inner.addMethod(ViewMethods.getDeleteElementNaturalMethod(inner))
+        //add getter and setter for attributes in the inner class
+        inner.getAttributes.foreach(attr => {
+          inner.addMethod(ViewMethods.getViewAttributeGetter(attr))
+          inner.addMethod(ViewMethods.getViewAttributeSetter(attr))
+        })
+      })
+
+      //add methods that must be override from the view trait
+      viewCompartment.addMethod(ViewMethods.getIsViewableMethod((refClasses ++ refRelationalClasses).toSet))
+      viewCompartment.addMethod(ViewMethods.getViewNameMethod(viewCompartment))
+      viewCompartment.addMethod(ViewMethods.getGetNaturalRoleMethod(newInternalRoles.toSet))
+      viewCompartment.addMethod(ViewMethods.getGetRelationalRoleMethod(newInternalRelationalRoles.toSet))
+      viewCompartment.addMethod(ToStringMethods.onlyStringToStringMethod("VC: " + viewCompartment.getName))
+      //Create methods to create elements from the view
+      ViewMethods.getCreateNaturalRoleMethods(newInternalRoles.toSet).foreach(viewCompartment.addMethod(_))
+
+      viewCompartment.augmentConstructor(new SMethodStatement("", allImportClasses))
+
+      //add the view to the list for generating views
+      sModel.addViewCompartment(viewCompartment)
+    })
+  }
+
+  def createClasses(keeps: Set[KeepExpression], cls: SClass, sModel: SModel): SInnerViewNaturalClass = {
+    var internalClass: SInnerViewNaturalClass = null
+    var newAtts: Seq[SAttribute] = Seq.empty
+    if (refClasses.contains(cls)) {
+      newInternalRoles.foreach(nir => {
+        if (nir.sumSource == cls) {
+          internalClass = nir
+          newAtts = nir.getAttributes()
+        }
+      })
+    } else {
+      refClasses = refClasses :+ cls
+      internalClass = new SInnerViewNaturalClass(cls.getName + PackageNames.viewRolePostName,
+        _sClassType = cls.sClassType,
+        _externalClass = viewCompartment,
+        sumSource = cls)
+      newInternalRoles = newInternalRoles :+ internalClass
+      allImportClasses = allImportClasses + cls
+      viewCompartment.addInternalClass(internalClass)
+    }
+
+    //without keep lists
+    //KeepAggregateExpression KeepAttributesExpression KeepCalculatedExpression
+    //sets the attributes from the source class
+    var features: Set[SStructuralFeature] = Set.empty
+    if (cls.isInstanceOf[SJoinClass]) {
+      val jCls = cls.asInstanceOf[SJoinClass]
+      features = jCls.innerAttributes
+      if (jCls.joinType != RsumJoinType.theta) {
+        //if natural or outer join add all join attributes
+        jCls.joinAttributes.foreach(a => {
+          var newAtt = SAttribute(a.getName, a.getTypeElement)
+          newAtt.setVisibility(MethodVisibility.protectedVis)
+          newAtt.isFinal = true
+          newAtts = newAtts :+ newAtt
+        })
+      }
+    } else {
+      features = cls.getDeepStructuralFeatures.toSet
+    }
+
+    //println("+++ KeepAttributesExpression")
+    keeps.filter(_.isInstanceOf[KeepAttributesExpression]).foreach(ja => {
+      val keepAtt = ja.asInstanceOf[KeepAttributesExpression]
+      keepAtt.getAttributes.forEach(attExp => {
+        //println("N: " + attExp.getAttributeName + " P: " + attExp.getContainingClass.getPackage + " CN: " + attExp.getContainingClass.getClassName)
+        features.filter(_.getName == attExp.getAttributeName).foreach(a => {
+          var isIn = false
+          internalClass.getAttributes().foreach(ain => {
+            if (ain.getName == a.getName && ain.getTypeElement.getName == a.getTypeElement.getName) {
+              isIn = true
+            }
+          })
+          if (!isIn) {
+            //Proof if attribute must be in then add it to view class   
+            var newAtt = SAttribute(a.getName, a.getTypeElement)
+            newAtt.setVisibility(MethodVisibility.protectedVis)
+            newAtt.isFinal = true
+            newAtts = newAtts :+ newAtt
+          }
+        })
+      })
+    })
+    internalClass.setAttributes(newAtts)
+    //println("+++ KeepAggregateExpression")
+    keeps.filter(_.isInstanceOf[KeepAggregateExpression]).foreach(ja => {
+      //TODO: later
+    })
+    //println("+++ KeepCalculatedExpression")
+    keeps.filter(_.isInstanceOf[KeepCalculatedExpression]).foreach(ja => {
+      //TODO: later
+    })
+    //println("+++ KeepSubTypeExpression")
+    //with keep lists
+    //KeepSubTypeExpression KeepSuperTypeExpression KeepReferenceExpression (List of Keeps)
+    keeps.filter(_.isInstanceOf[KeepSubTypeExpression]).foreach(ja => {
+      val keepAtt = ja.asInstanceOf[KeepSubTypeExpression]
+      sModel.getModelClasses.filter(m => m.getName == keepAtt.getType.getClassName && m.getPackage == keepAtt.getType.getPackage).foreach(mc => {
+        val parent = mc.getRootClassWithNameAndPackage(cls.getName, cls.getPackage)
+        if (parent != null) {
+          val innerParent = createClasses(asScalaBuffer(keepAtt.getKeeps).toSet, mc, sModel)
+          innerParent.addParent(internalClass)
+        }
+      })
+    })
+    //println("+++ KeepSuperTypeExpression")
+    keeps.filter(_.isInstanceOf[KeepSuperTypeExpression]).foreach(ja => {
+      val keepAtt = ja.asInstanceOf[KeepSuperTypeExpression]
+      //println("TC: " + keepAtt.getTarget + " TC: " + keepAtt.getType)
+      val parent = cls.getRootClassWithNameAndPackage(keepAtt.getType.getClassName, keepAtt.getType.getPackage)
+      if (parent != null) {
+        val innerParent = createClasses(asScalaBuffer(keepAtt.getKeeps).toSet, parent, sModel)
+        internalClass.addParent(innerParent)
+      }
+    })
+    //println("+++ KeepReferenceExpression")
+    keeps.filter(_.isInstanceOf[KeepReferenceExpression]).foreach(ja => {
+      val keepAtt = ja.asInstanceOf[KeepReferenceExpression]
+      //println("AN: " + keepAtt.getAttribute.getAttributeName + " " + keepAtt.getAttribute.getContainingClass.getPackage + " " + keepAtt.getAttribute.getContainingClass.getClassName)
+      sModel.getRelationalCompartments.foreach(me => {
+        var rc = me.asInstanceOf[SRelationalCompartmentClass]
+        if (rc.getPackage == keepAtt.getAttribute.getContainingClass.getPackage) {
+          if (rc.sClass.getName == keepAtt.getAttribute.getContainingClass.getClassName || rc.tClass.getName == keepAtt.getAttribute.getContainingClass.getClassName) {
+            if (rc.connectedRef.getName == keepAtt.getAttribute.getAttributeName || (rc.connectedRef.hasOpposite && rc.connectedRef.oppositeRef.getName == keepAtt.getAttribute.getAttributeName)) {
+              var sourceRole: SInnerViewNaturalClass = null
+              var targetRole: SInnerViewNaturalClass = null
+              var sourceAtt: SAttribute = null
+              var targetAtt: SAttribute = null
+              var createNormal = false
+              var createOpposite = false
+              if (rc.sClass.getName == keepAtt.getAttribute.getContainingClass.getClassName) {
+                //current is source
+                sourceRole = internalClass
+                var tClass = rc.tClass.asInstanceOf[SClass]
+                sModel.getModelClasses.filter(m => m.getName == keepAtt.getTarget.getClassName && m.getPackage == keepAtt.getTarget.getPackage).foreach(cs => {
+                  val parent = cs.getRootClassWithNameAndPackage(rc.tClass.getName, rc.tClass.getPackage)
+                  if (parent != null) {
+                    tClass = cs
+                  }
+                })
+                targetRole = createClasses(asScalaBuffer(keepAtt.getKeeps).toSet, tClass, sModel)
+                createNormal = true
+              } else {
+                //current is target
+                var sClass = rc.sClass.asInstanceOf[SClass]
+                sModel.getModelClasses.filter(m => m.getName == keepAtt.getTarget.getClassName && m.getPackage == keepAtt.getTarget.getPackage).foreach(cs => {
+                  val parent = cs.getRootClassWithNameAndPackage(rc.sClass.getName, rc.sClass.getPackage)
+                  if (parent != null) {
+                    sClass = cs
+                  }
+                })
+                sourceRole = createClasses(asScalaBuffer(keepAtt.getKeeps).toSet, sClass, sModel)
+                targetRole = internalClass
+                createOpposite = true
+              }
+              sourceAtt = new SAttribute("source", sourceRole)
+              targetAtt = new SAttribute("target", targetRole)
+              sourceAtt.isFinal = true
+              sourceAtt.setVisibility(MethodVisibility.privateVis)
+              targetAtt.isFinal = true
+              targetAtt.setVisibility(MethodVisibility.privateVis)
+              //now find the right relational compartment
+              refRelationalClasses = refRelationalClasses :+ rc
+              //Iterate over all Relational compartments and create relational internal role classes
+              val internalRelClass = new SInnerViewRelationalClass(rc.getName + PackageNames.viewRolePostName, _externalClass = viewCompartment,
+                sumSource = rc, viewSource = sourceRole, viewTarget = targetRole)
+              internalRelClass.setAttributes(sourceAtt ++ targetAtt)
+              internalRelClass.addMethod(ViewMethods.getIsRelationalMethod(true))
+              internalRelClass.addMethod(ViewMethods.getCreationObjectMethod(internalRelClass, createNormal, createOpposite))
+              internalRelClass.addMethod(ViewMethods.getDeleteElementRelationMethod(internalRelClass, createNormal, createOpposite))
+              internalRelClass.addMethod(ToStringMethods.onlyStringToStringMethod("VRR: " + internalRelClass.getName))
+              ViewMethods.getSourceAndTargetGetter(internalRelClass).foreach(internalRelClass.addMethod(_))
+              internalRelClass.addParent(PredefRsumTypes.AVIEW_ROLE_STYPE)
+              ViewMethods.createAllReferenceLinks(internalRelClass, createNormal, createOpposite)
+              newInternalRelationalRoles = newInternalRelationalRoles :+ internalRelClass
+              allImportClasses = allImportClasses + sourceRole.sumSource + targetRole.sumSource + rc.tClass + rc.sClass
+              viewCompartment.addInternalClass(internalRelClass)
+            }
+          }
+        }
+      })
+    })
+    internalClass
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/PredefRsumTypes.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/PredefRsumTypes.scala
new file mode 100644
index 0000000000000000000000000000000000000000..5a3b9f745bd5b0b1adaa79934ac9d8989e6e264a
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/PredefRsumTypes.scala
@@ -0,0 +1,104 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model.SType
+import org.rosi_project.model_sync.generator.acr_model.SEnum
+import org.rosi_project.model_management.sum.IViewCompartment
+import org.rosi_project.model_management.sum.IViewTypeInfo
+import org.rosi_project.model_management.sum.query._
+import org.rosi_project.model_management.sum.join._
+import org.rosi_project.model_management.sum.compartments._
+import org.rosi_project.model_management.sum.roles.IRelationRole
+
+object PredefRsumTypes {
+
+  //JOIN TYPES
+  private val IJOIN_COMPARTMENT_CLASS = classOf[IJoinCompartment]
+  val         IJOIN_COMPARTMENT_STYPE = SType(IJOIN_COMPARTMENT_CLASS.getSimpleName, IJOIN_COMPARTMENT_CLASS.getPackage.getName) 
+  
+  private val JOIN_INFO_CLASS = classOf[IJoinInfo]
+  val         JOIN_INFO_STYPE = SType(JOIN_INFO_CLASS.getSimpleName, JOIN_INFO_CLASS.getPackage.getName)
+  
+  private val RSUM_JOIN_TYPE_CLASS = RsumJoinType.getClass
+  val         RSUM_JOIN_TYPE_STYPE = new SEnum(RSUM_JOIN_TYPE_CLASS.getSimpleName.replace("$", ""), RSUM_JOIN_TYPE_CLASS.getPackage.getName, Set.empty)
+    
+  //VIEW TYPES
+  private val IVIEW_COMPARTMENT_CLASS = classOf[IViewCompartment]
+  val         IVIEW_COMPARTMENT_STYPE = SType(IVIEW_COMPARTMENT_CLASS.getSimpleName, IVIEW_COMPARTMENT_CLASS.getPackage.getName) 
+  
+  private val VIEWTYPE_INFO_CLASS = classOf[IViewTypeInfo]
+  val         VIEWTYPE_INFO_STYPE = SType(VIEWTYPE_INFO_CLASS.getSimpleName, VIEWTYPE_INFO_CLASS.getPackage.getName) 
+    
+  private val AVIEW_ROLE_CLASS = classOf[IViewCompartment#AViewRole]
+  val         AVIEW_ROLE_STYPE = SType(AVIEW_ROLE_CLASS.getSimpleName)//AVIEW_ROLE_CLASS.getPackage.getName)  
+  
+  //QUERY TYPES
+  private val CHECKING_OPTION_CLASS = CheckingOption.getClass
+  val         CHECKING_OPTION_STYPE = new SEnum(CHECKING_OPTION_CLASS.getSimpleName.replace("$", ""), CHECKING_OPTION_CLASS.getPackage.getName, Set.empty)
+  
+  private val QUERY_HELPER_CLASS = classOf[QueryHelper]
+  val         QUERY_HELPER_STYPE = SType(QUERY_HELPER_CLASS.getSimpleName, QUERY_HELPER_CLASS.getPackage.getName) 
+  
+  private val IQUERY_VIEW_COMPARTMENT_CLASS = classOf[QueryFactory]
+  val         IQUERY_VIEW_COMPARTMENT_STYPE = SType(IQUERY_VIEW_COMPARTMENT_CLASS.getSimpleName, IQUERY_VIEW_COMPARTMENT_CLASS.getPackage.getName) 
+  
+  private val AQUERY_VIEW_ROLE_CLASS = classOf[QueryFactory#QueryFactoryElement]
+  val         AQUERY_VIEW_ROLE_STYPE = SType(AQUERY_VIEW_ROLE_CLASS.getSimpleName) //, AQUERY_VIEW_ROLE_CLASS.getPackage.getName) 
+
+  //RELATIONAL COMPARTMENT TYPES
+  private val IRELATIONROLE_CLASS = classOf[IRelationRole]
+  val         IRELATIONROLE_STYPE = SType(IRELATIONROLE_CLASS.getSimpleName, IRELATIONROLE_CLASS.getPackage.getName)
+  
+  private val IAGGREGTATION_CLASS = classOf[IAggregation]
+  val         IAGGREGTATION_STYPE = SType(IAGGREGTATION_CLASS.getSimpleName, IAGGREGTATION_CLASS.getPackage.getName)
+  
+  private val IAGGREGTATION_SOURCE_CLASS = classOf[IAggregation#IAggregationSource]
+  val         IAGGREGTATION_SOURCE_STYPE = SType(IAGGREGTATION_SOURCE_CLASS.getSimpleName, IAGGREGTATION_SOURCE_CLASS.getPackage.getName)
+  
+  private val IAGGREGTATION_TARGET_CLASS = classOf[IAggregation#IAggregationTarget]
+  val         IAGGREGTATION_TARGET_STYPE = SType(IAGGREGTATION_TARGET_CLASS.getSimpleName, IAGGREGTATION_TARGET_CLASS.getPackage.getName)
+  
+  private val IASSOCIATION_CLASS = classOf[IAssociation]
+  val         IASSOCIATION_STYPE = SType(IASSOCIATION_CLASS.getSimpleName, IASSOCIATION_CLASS.getPackage.getName)
+  
+  private val IASSOCIATION_SOURCE_CLASS = classOf[IAssociation#IAssociationSource]
+  val         IASSOCIATION_SOURCE_STYPE = SType(IASSOCIATION_SOURCE_CLASS.getSimpleName, IASSOCIATION_SOURCE_CLASS.getPackage.getName)
+  
+  private val IASSOCIATION_TARGET_CLASS = classOf[IAssociation#IAssociationTarget]
+  val         IASSOCIATION_TARGET_STYPE = SType(IASSOCIATION_TARGET_CLASS.getSimpleName, IASSOCIATION_TARGET_CLASS.getPackage.getName)
+  
+  private val ICOMPOSITION_CLASS = classOf[IComposition]
+  val         ICOMPOSITION_STYPE = SType(ICOMPOSITION_CLASS.getSimpleName, ICOMPOSITION_CLASS.getPackage.getName)
+  
+  private val ICOMPOSITION_SOURCE_CLASS = classOf[IComposition#ICompositionSource]
+  val         ICOMPOSITION_SOURCE_STYPE = SType(ICOMPOSITION_SOURCE_CLASS.getSimpleName, ICOMPOSITION_SOURCE_CLASS.getPackage.getName)
+  
+  private val ICOMPOSITION_TARGET_CLASS = classOf[IComposition#ICompositionTarget]
+  val         ICOMPOSITION_TARGET_STYPE = SType(ICOMPOSITION_TARGET_CLASS.getSimpleName, ICOMPOSITION_TARGET_CLASS.getPackage.getName)
+  
+  private val IDIRECT_AGGREGATION_CLASS = classOf[IDirectAggregation]
+  val         IDIRECT_AGGREGATION_STYPE = SType(IDIRECT_AGGREGATION_CLASS.getSimpleName, IDIRECT_AGGREGATION_CLASS.getPackage.getName)
+  
+  private val IDIRECT_AGGREGATION_SOURCE_CLASS = classOf[IDirectAggregation#IDirectAggregationSource]
+  val         IDIRECT_AGGREGATION_SOURCE_STYPE = SType(IDIRECT_AGGREGATION_SOURCE_CLASS.getSimpleName, IDIRECT_AGGREGATION_SOURCE_CLASS.getPackage.getName)
+  
+  private val IDIRECT_AGGREGATION_TARGET_CLASS = classOf[IDirectAggregation#IDirectAggregationTarget]
+  val         IDIRECT_AGGREGATION_TARGET_STYPE = SType(IDIRECT_AGGREGATION_TARGET_CLASS.getSimpleName, IDIRECT_AGGREGATION_TARGET_CLASS.getPackage.getName)
+  
+  private val IDIRECT_ASSOCIATION_CLASS = classOf[IDirectAssoziation]
+  val         IDIRECT_ASSOCIATION_STYPE = SType(IDIRECT_ASSOCIATION_CLASS.getSimpleName, IDIRECT_ASSOCIATION_CLASS.getPackage.getName)
+  
+  private val IDIRECT_ASSOCIATION_SOURCE_CLASS = classOf[IDirectAssoziation#IDirectAssoziationSource]
+  val         IDIRECT_ASSOCIATION_SOURCE_STYPE = SType(IDIRECT_ASSOCIATION_SOURCE_CLASS.getSimpleName, IDIRECT_ASSOCIATION_SOURCE_CLASS.getPackage.getName)
+  
+  private val IDIRECT_ASSOCIATION_TARGET_CLASS = classOf[IDirectAssoziation#IDirectAssoziationTarget]
+  val         IDIRECT_ASSOCIATION_TARGET_STYPE = SType(IDIRECT_ASSOCIATION_TARGET_CLASS.getSimpleName, IDIRECT_ASSOCIATION_TARGET_CLASS.getPackage.getName)
+  
+  private val IDIRECT_COMPOSITION_CLASS = classOf[IDirectComposition]
+  val         IDIRECT_COMPOSITION_STYPE = SType(IDIRECT_COMPOSITION_CLASS.getSimpleName, IDIRECT_COMPOSITION_CLASS.getPackage.getName)
+  
+  private val IDIRECT_COMPOSITION_SOURCE_CLASS = classOf[IDirectComposition#IDirectCompositionSource]
+  val         IDIRECT_COMPOSITION_SOURCE_STYPE = SType(IDIRECT_COMPOSITION_SOURCE_CLASS.getSimpleName, IDIRECT_COMPOSITION_SOURCE_CLASS.getPackage.getName)
+  
+  private val IDIRECT_COMPOSITION_TARGET_CLASS = classOf[IDirectComposition#IDirectCompositionTarget]
+  val         IDIRECT_COMPOSITION_TARGET_STYPE = SType(IDIRECT_COMPOSITION_TARGET_CLASS.getSimpleName, IDIRECT_COMPOSITION_TARGET_CLASS.getPackage.getName)
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/PredefSyncTypes.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/PredefSyncTypes.scala
new file mode 100644
index 0000000000000000000000000000000000000000..052a048a75df3a860bb2f8ad3381fafffd4942fe
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/PredefSyncTypes.scala
@@ -0,0 +1,10 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model.SType
+import org.rosi_project.model_management.core.PlayerSync
+
+object PredefSyncTypes {
+  
+  private val PLAYER_SYNC_CLASS = classOf[PlayerSync]
+  val         PLAYER_SYNC_STYPE = SType(PLAYER_SYNC_CLASS.getSimpleName, PLAYER_SYNC_CLASS.getPackage.getName)
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/PredefTypes.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/PredefTypes.scala
deleted file mode 100644
index 0491c444f2512bada9edabbedf5f803c9ab01ca2..0000000000000000000000000000000000000000
--- a/src/main/scala/org/rosi_project/model_sync/generator/sync/PredefTypes.scala
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.rosi_project.model_sync.generator.sync
-
-import org.rosi_project.model_sync.generator.acr_model.SType
-
-/** Contains a number of types which are used throughout the synchronization.
-  *
-  * Equivalent to [[org.rosi_project.model_sync.generator.acr_model.types.PredefTypes]], just for
-  * the sync types.
-  *
-  * @author Rico Bergmann
-  */
-object PredefTypes {
-
-  /** `org.rosi_project.model_sync.provider.DisplayableModel`
-    */
-  val DisplayableModel = SType("DisplayableModel", "org.rosi_project.model_sync.provider")
-
-  /** `org.rosi_project.model_sync.provider.DisplayableModelForInitialization`
-    */
-  val DisplayableModelForInitialization = SType("DisplayableModelForInitialization", "org.rosi_project.model_sync.provider")
-
-  /** `org.rosi_project.model_sync.provider.DisplayableModelForIntegration`
-    */
-  val DisplayableModelForIntegration = SType("DisplayableModelForIntegration", "org.rosi_project.model_sync.provider")
-
-  /** `org.rosi_project.model_sync.provider.ModelSyncProvider`
-    */
-  val ModelProvider = SType("ModelSyncProvider", "org.rosi_project.model_sync.provider")
-
-  /** `org.rosi_project.model_sync.provider.ModelRegistry`
-    */
-  val ModelRegistry = SType("ModelRegistry", "org.rosi_project.model_sync.provider")
-
-  /** `org.rosi_project.model_sync.provider.instances.ModelInstanceConstructor`
-    */
-  val ModelInstanceConstructor = SType("ModelInstanceConstructor", "org.rosi_project.model_sync.instances")
-
-  /** `org.rosi_project.model_sync.provider.instances.ModelInstanceModifier`
-    */
-  val ModelInstanceModifier = SType("ModelInstanceModifier", "org.rosi_project.model_sync.instances")
-
-}
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/QueryGeneratingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/QueryGeneratingVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..2f7f50fcc006cd92c12896e904db1f4b11545b29
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/QueryGeneratingVisitor.scala
@@ -0,0 +1,134 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.acr_model.types._
+import org.rosi_project.model_sync.generator.PackageNames
+
+class QueryGeneratingVisitor extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    
+    val viewCompartment = new SClass(sModel.getName.capitalize + PackageNames.queryPostName, PackageNames.queryPkgName)
+    var newInternalRoles: Seq[SInnerViewNaturalClass] = Seq.empty
+    var newInternalRelationalRoles: Seq[SInnerViewRelationalClass] = Seq.empty
+    viewCompartment.addParent(PredefRsumTypes.IQUERY_VIEW_COMPARTMENT_STYPE)
+    
+    var allTypes: Set[STypedElement] = sModel.getModelClasses ++ sModel.getRelationalCompartments ++ PredefRsumTypes.CHECKING_OPTION_STYPE ++ sModel.getModelEnums
+    sModel.getModelClasses.foreach(_.getStructuralFeatures.foreach(s => {
+      if (s.getTypeElement.sPackage != "")
+        allTypes += s.getTypeElement
+    }))    
+        
+    viewCompartment.augmentConstructor(SMethodStatement(s"""init("${viewCompartment.getName}")""", allTypes))     
+    
+    //Iterate over all Model classes and create natural internal role classes
+    sModel.getModelClasses.filter(!_.getName.startsWith(PackageNames.queryHelperPrefix)).foreach(cls => {
+      val internalClass = new SInnerViewNaturalClass(cls.getName + PackageNames.queryRolePostName,
+          _externalClass = viewCompartment, 
+          sumSource = cls)
+      //sets the attributes from the source class
+      var newAtts: Set[SAttribute] = Set.empty
+      cls.getAttributes.foreach(attr => {
+        var newAtt = SAttribute(attr.getName, attr.getTypeElement, attr.unique)
+        newAtt.setVisibility(MethodVisibility.protectedVis)
+        newAtt.isFinal = true
+        newAtts += newAtt
+      })
+      internalClass.setAttributes(newAtts.toSeq)  
+      newInternalRoles = newInternalRoles :+ internalClass
+      viewCompartment.addInternalClass(internalClass)
+    })
+    
+    //TODO: can be necessary to add all parents in one loop first
+    //Now fill all natural internal roles with functionality
+    newInternalRoles.foreach(inner => {
+      val cls = inner.sumSource
+      //set inheritance to abstract view role
+      if (cls.isRootClass) {
+        inner.addParent(PredefRsumTypes.AQUERY_VIEW_ROLE_STYPE)
+      }
+      //add initialize method if necessary
+      inner.addMethod(ViewMethods.getIsRelationalMethod(false))
+      inner.addMethod(QueryMethods.getInitializeMethod(inner))
+      //add delete method
+      inner.addMethod(ViewMethods.getDeleteElementNaturalMethod(inner))
+      //add parents
+      cls.getAllParents().foreach(p => {
+        val existing: Option[STypedElement] = newInternalRoles.find(existing => existing.getName == p.getName + PackageNames.queryRolePostName)
+        if (!existing.isEmpty) {
+          inner.addParent(existing.get)
+        }
+      })      
+      //add getter and setter for attributes in the inner class
+      inner.getAttributes.foreach(attr => {
+        inner.addMethod(ViewMethods.getViewAttributeGetter(attr))
+        inner.addMethod(QueryMethods.getViewAttributeSetter(attr))
+      })
+      //remove all attributes
+      inner.setAttributes(Seq.empty)
+    })
+    
+    //Iterate over all Relational compartments and create relational internal role classes
+    sModel.getRelationalCompartments.foreach(r => {
+      var sourceAtt: SAttribute = null
+      var targetAtt: SAttribute = null
+      //set as attributes the other classes
+      var sourceRole: SInnerViewNaturalClass = null
+      var targetRole: SInnerViewNaturalClass = null
+      r.getAttributes.foreach(attr => {
+        newInternalRoles.foreach(inte => {
+          if (inte.getName == attr.getTypeElement.getName + PackageNames.queryRolePostName) {
+            if (attr.getName == "sInstance") {
+              sourceRole = inte
+              sourceAtt = new SAttribute("source", inte)
+              sourceAtt.isFinal = true
+              sourceAtt.setVisibility(MethodVisibility.privateVis)
+            } else {
+              targetRole = inte
+              targetAtt = new SAttribute("target", inte)
+              targetAtt.isFinal = true
+              targetAtt.setVisibility(MethodVisibility.privateVis)
+            }
+          }
+        })
+      })
+      val internalClass = new SInnerViewRelationalClass(r.getName + PackageNames.queryRolePostName, _externalClass = viewCompartment, 
+          sumSource = r.asInstanceOf[SRelationalCompartmentClass], viewSource = sourceRole, viewTarget = targetRole)      
+      internalClass.setAttributes(sourceAtt ++ targetAtt)
+      internalClass.addMethod(ViewMethods.getIsRelationalMethod(true))
+      internalClass.addMethod(QueryMethods.getInitializeMethod(internalClass))
+      internalClass.addMethod(ViewMethods.getDeleteElementRelationMethod(internalClass, true, true))
+      ViewMethods.getSourceAndTargetGetter(internalClass).foreach(internalClass.addMethod(_))
+      internalClass.addParent(PredefRsumTypes.AQUERY_VIEW_ROLE_STYPE)
+      QueryMethods.createAllReferenceLinks(internalClass)
+      newInternalRelationalRoles = newInternalRelationalRoles :+ internalClass
+      viewCompartment.addInternalClass(internalClass)
+    })
+    
+    //Create methods to create elements from the view
+    QueryMethods.getCreateNaturalRoleMethods(newInternalRoles.toSet).foreach(viewCompartment.addMethod(_))
+    
+    //add the view to the list for generating views
+    sModel.addProviderClass(viewCompartment)
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+  
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  } 
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/QueryMethods.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/QueryMethods.scala
new file mode 100644
index 0000000000000000000000000000000000000000..ff6d5ecf37b6d444369568c6494cca2cfac4e45e
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/QueryMethods.scala
@@ -0,0 +1,202 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.acr_model.types.SSet
+
+object QueryMethods  {
+  
+  /**
+   * Special because of Helper classes. 
+   */
+  def getCreateNaturalRoleMethods(naturalRoles: Set[SInnerViewNaturalClass]): Seq[SMethod] = {
+    var methods: Seq[SMethod] = Seq.empty
+    naturalRoles.foreach(nr => {
+      if (!nr.getName.startsWith("Helper")) {
+        val method = new SMethod(
+            name = s"create${nr.sumSource.getName}",
+            result = nr,
+            params = Seq.empty,
+            implementation = Seq(SMethodStatement(content = s"return new ${nr.getName}()")))
+        methods = methods :+ method
+      }
+    })
+    methods
+  }
+  
+  /**
+   * Is also split here now.
+   */
+  def getInitializeMethod(nat: SInnerViewNaturalClass): SMethod = {
+    var helper = ""
+    if (nat.sumSource.isAbstract || nat.sumSource.isInterface) helper = "Helper"
+    val method = new SMethod(
+      name = "getCreationObject",
+      result = PredefTypes.Object,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement(content = s"return new $helper${nat.sumSource.getName}(" + 
+          s"${nat.sumSource.getAllConstructorParameters.map(HelperFunctions.classEmptyConstructorParameterCreation(_)).mkString(", ")})")), 
+      true)    
+    method.setVisibility(MethodVisibility.protectedVis)
+    method
+  }
+    
+  /**
+   * Is also split here now.
+   */
+  def getInitializeMethod(ref: SInnerViewRelationalClass): SMethod = {
+    val method = new SMethod(
+      name = "getCreationObject",
+      result = PredefTypes.Object,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement(content = "return")), 
+      true)
+    var statements: Seq[SMethodStatement] = Seq.empty
+    if (ref.sumSource.connectedRef.hasOpposite) {
+      statements = Seq(SMethodStatement(content = s"target.set${ref.sumSource.connectedRef.oppositeRef.getName.capitalize}Intern(this)"))
+    }
+    statements = statements ++ Seq(SMethodStatement(content = s"source.set${ref.sumSource.connectedRef.getName.capitalize}Intern(this)"),
+        SMethodStatement(content = s"val sp: ${ref.viewSource.sumSource.getName} = source.player.right.get.asInstanceOf[${ref.viewSource.sumSource.getName}]",
+            usedTypes = Set(ref.viewSource.sumSource)),
+        SMethodStatement(content = s"val tp: ${ref.viewTarget.sumSource.getName} = target.player.right.get.asInstanceOf[${ref.viewTarget.sumSource.getName}]",
+            usedTypes = Set(ref.viewTarget.sumSource)),
+        SMethodStatement(content = s"val v: ${ref.sumSource.getName} = new ${ref.sumSource.getName}(sp, tp)",
+            usedTypes = Set(ref.sumSource)),
+        SMethodStatement(content = "return v",
+            usedTypes = Set.empty))    
+    method.implementation = statements
+    method.setVisibility(MethodVisibility.protectedVis)
+    method
+  }
+  
+  /**
+   * Special are the attribute filter options.
+   */
+  def getViewAttributeSetter(struc: SStructuralFeature): SMethod = {
+    new SMethod(
+      name = s"set${struc.getName.firstLetterToUpperCase}View",
+      result = PredefTypes.Unit,
+      params = Seq(SMethodParameter(struc.getName.toLowerCase(), struc.getTypeElement), SMethodParameter("check", PredefRsumTypes.CHECKING_OPTION_STYPE)),
+      implementation = Seq(SMethodStatement(content = s"+this set${struc.getName.firstLetterToUpperCase}(${struc.getName.toLowerCase()})", usedTypes = Set(struc.getTypeElement)), 
+          SMethodStatement(content = s"""connected.addAttributeFilter("${struc.getName}", ${struc.getName.toLowerCase()}.toString(), check)""")))
+  }
+  
+  def createAllReferenceLinks(refClass: SInnerViewRelationalClass): Unit = {
+    val targetClass: SInnerViewNaturalClass = refClass.viewTarget
+    val sourceClass: SInnerViewNaturalClass = refClass.viewSource
+    val realRef: SReference = refClass.sumSource.connectedRef 
+    val oppoRef: SReference = refClass.sumSource.connectedRef.oppositeRef
+    createReferenceLinks(refClass, realRef, sourceClass, targetClass, true)
+    if (oppoRef != null) {
+      createReferenceLinks(refClass, oppoRef, targetClass, sourceClass, false)
+    }      
+  }
+  
+  private def createReferenceLinks(refClass: SInnerViewRelationalClass, realRef: SReference, sourceClass: SInnerViewNaturalClass, targetClass: SInnerViewNaturalClass, isReal: Boolean): Unit = {
+    val getStatement: String = if (isReal) "getTarget" else "getSource"
+    val thisStatement: String = if (isReal) "(this, v)" else "(v, this)"  
+    if (realRef.upperBound == 1) {
+      //add delete role for attributes because query is not connected with RSUM
+      sourceClass.getMethods.foreach(m => {
+        if (m.getName == "deleteElement") {
+          m.implementation = m.implementation :+ SMethodStatement(s"if (${realRef.getName} != null) ${realRef.getName}.deleteElement()")
+        }
+      })      
+      
+      //upper Bound = 1
+      //variable settings
+      sourceClass.augmentConstructor(SMethodStatement(s"private var ${realRef.getName}: ${refClass.getDeepName} = null"))
+      //internal variables
+      val removeMethodInternal = new SMethod(
+        name = s"remove${realRef.getName.capitalize}Intern",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("v", refClass)), //TODO: remove this then each remove internal method has different input parameters
+        implementation = Seq(SMethodStatement(content = s"${realRef.getName} = null")))
+      removeMethodInternal.setVisibility(MethodVisibility.privateExternalClass)
+      sourceClass.addMethod(removeMethodInternal)
+      val setMethodInternal = new SMethod(
+        name = s"set${realRef.getName.capitalize}Intern",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("v", refClass)),
+        implementation = Seq(SMethodStatement(content = s"${realRef.getName} = v")))
+      setMethodInternal.setVisibility(MethodVisibility.privateExternalClass)
+      sourceClass.addMethod(setMethodInternal)
+      //external variables
+      sourceClass.addMethod(new SMethod(
+        name = s"get${realRef.getName.capitalize}",
+        result = targetClass,
+        params = Seq.empty,
+        implementation = Seq(SMethodStatement(content = s"return ${realRef.getName}.${getStatement}()"))))
+      sourceClass.addMethod(new SMethod(
+        name = s"set${realRef.getName.capitalize}",
+        result = PredefTypes.Boolean,
+        params = Seq(SMethodParameter("v", targetClass)),
+        implementation = Seq(SMethodStatement(content = "if (v == null) return false"),
+            SMethodStatement(content = s"if (!containsRole(v.asInstanceOf[${PredefRsumTypes.AQUERY_VIEW_ROLE_STYPE.getName}])) return false"),
+            SMethodStatement(content = s"if (${realRef.getName} != null) {"),
+            SMethodStatement(content = s"if (${realRef.getName}.${getStatement}() == v) return false"),
+            SMethodStatement(content = s"${realRef.getName}.deleteElement()"),
+            SMethodStatement(content = "}"),
+            SMethodStatement(content = s"new ${refClass.getName}${thisStatement}"),
+            SMethodStatement(content = "return true"))))
+    } else {
+      //add delete role for attributes
+      sourceClass.getMethods.foreach(m => {
+        if (m.getName == "deleteElement") {
+          m.implementation = m.implementation :+ SMethodStatement(s"${realRef.getName}.foreach(_.deleteElement())")
+        }
+      })     
+      
+      //upper Bound = endless
+      //variable settings
+      sourceClass.augmentConstructor(SMethodStatement(s"private var ${realRef.getName}: Set[${refClass.getDeepName}] = Set.empty"))
+      //internal variables
+      val removeMethodInternal = new SMethod(
+        name = s"remove${realRef.getName.capitalize}Intern",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("v", refClass)),
+        implementation = Seq(SMethodStatement(content = s"${realRef.getName} -= v")))
+      removeMethodInternal.setVisibility(MethodVisibility.privateExternalClass)
+      sourceClass.addMethod(removeMethodInternal)
+      val setMethodInternal = new SMethod(
+        name = s"set${realRef.getName.capitalize}Intern",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("v", refClass)),
+        implementation = Seq(SMethodStatement(content = s"${realRef.getName} += v")))
+      setMethodInternal.setVisibility(MethodVisibility.privateExternalClass)
+      sourceClass.addMethod(setMethodInternal)
+      //external variables
+      sourceClass.addMethod(new SMethod(
+        name = s"get${realRef.getName.capitalize}",
+        result = SSet(targetClass),
+        params = Seq.empty,
+        implementation = Seq(SMethodStatement(content = s"var vs: Set[${targetClass.getDeepName}] = Set.empty"), 
+            SMethodStatement(content = s"${realRef.getName}.foreach{ v => vs += v.${getStatement}()}"), 
+            SMethodStatement(content = "return vs"))))
+      sourceClass.addMethod(new SMethod(
+        name = s"has${realRef.getName.capitalize}",
+        result = PredefTypes.Boolean,
+        params = Seq(SMethodParameter("v", targetClass)),
+        implementation = Seq(SMethodStatement(content = s"return get${realRef.getName.capitalize}.contains(v)"))))
+      sourceClass.addMethod(new SMethod(
+        name = s"add${realRef.getName.capitalize}",
+        result = PredefTypes.Boolean,
+        params = Seq(SMethodParameter("v", targetClass)),
+        implementation = Seq(SMethodStatement(content = s"if (has${realRef.getName.capitalize}(v) || !containsRole(v.asInstanceOf[${PredefRsumTypes.AQUERY_VIEW_ROLE_STYPE.getName}])) return false"),
+            SMethodStatement(content = s"new ${refClass.getName}${thisStatement}"),
+            SMethodStatement(content = "return true"))))
+      sourceClass.addMethod(new SMethod(
+        name = s"remove${realRef.getName.capitalize}",
+        result = PredefTypes.Boolean,
+        params = Seq(SMethodParameter("v", targetClass)),
+        implementation = Seq(SMethodStatement(content = s"if (!has${realRef.getName.capitalize}(v)) return false"),
+            SMethodStatement(content = s"${realRef.getName}.foreach{ h =>"),
+            SMethodStatement(content = s"if (h.${getStatement}() == v) {"),
+            SMethodStatement(content = "h.deleteElement()"),
+            SMethodStatement(content = "return true"),
+            SMethodStatement(content = "}}"),
+            SMethodStatement(content = "return true"))))
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/ReferenceMethodCreationVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/ReferenceMethodCreationVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..257523f0826ad8466a8e814e3263b68311385354
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/ReferenceMethodCreationVisitor.scala
@@ -0,0 +1,93 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.acr_model.types.GenericSequence
+
+/**
+ * Create the methods to get the references from each instance. Is only possible in combination with sync, because of role functionality.
+ */
+class ReferenceMethodCreationVisitor extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    var typeName = "Set.empty"
+    var addElement = "result +="
+
+    sModel.getRelationalCompartments.foreach(cls => {
+      val relComp = cls.asInstanceOf[SRelationalCompartmentClass]
+      //iterate over all relational compartments
+      val methodSrc = new SMethod(
+        name = s"get${relComp.connectedRef.getName.capitalize}",
+        result = relComp.connectedRef.getTypeElement,
+        params = Seq.empty,
+        implementation = Seq.empty)
+
+      //proof return type
+      if (relComp.connectedRef.getTypeElement.isInstanceOf[GenericSequence]) {
+        typeName = "Set.empty"
+        addElement = "result +="
+      } else {
+        typeName = "null"
+        addElement = "result ="
+      }
+      //make impl
+      var implSrc: Seq[SMethodStatement] = Seq.empty
+      implSrc = implSrc :+ SMethodStatement(content = s"var result: ${relComp.connectedRef.getTypeElement.getName} = ${typeName}", usedTypes = Set(PredefRsumTypes.IRELATIONROLE_STYPE))
+      implSrc = implSrc :+ SMethodStatement(content = s"""this.roles.filter(r => r.isInstanceOf[${PredefRsumTypes.IRELATIONROLE_STYPE.getName}] && 
+        r.asInstanceOf[${PredefRsumTypes.IRELATIONROLE_STYPE.getName}].getOuterCompartment.isInstanceOf[${relComp.getName}])
+        .foreach(r => {
+          ${addElement} r.asInstanceOf[${PredefRsumTypes.IRELATIONROLE_STYPE.getName}].getOuterCompartment.getTargetIns.asInstanceOf[${relComp.tClass.getName}]
+        })""")
+      implSrc = implSrc :+ SMethodStatement(content = "result")
+      methodSrc.implementation = implSrc
+      relComp.sClass.asInstanceOf[SClass].addMethod(methodSrc)
+      //proof opposite reference
+      if (relComp.connectedRef.hasOpposite) {
+        val methodTrg = new SMethod(
+          name = s"get${relComp.connectedRef.oppositeRef.getName.capitalize}",
+          result = relComp.connectedRef.oppositeRef.getTypeElement,
+          params = Seq.empty,
+          implementation = Seq.empty)
+
+        //proof return type
+        if (relComp.connectedRef.oppositeRef.getTypeElement.isInstanceOf[GenericSequence]) {
+          typeName = "Set.empty"
+          addElement = "result +="
+        } else {
+          typeName = "null"
+          addElement = "result ="
+        }
+        //make impl
+        var implTrg: Seq[SMethodStatement] = Seq.empty
+        implTrg = implTrg :+ SMethodStatement(content = s"var result: ${relComp.connectedRef.oppositeRef.getTypeElement.getName} = ${typeName}", usedTypes = Set(PredefRsumTypes.IRELATIONROLE_STYPE))
+        implTrg = implTrg :+ SMethodStatement(content = s"""this.roles.filter(r => r.isInstanceOf[${PredefRsumTypes.IRELATIONROLE_STYPE.getName}] && 
+          r.asInstanceOf[${PredefRsumTypes.IRELATIONROLE_STYPE.getName}].getOuterCompartment.isInstanceOf[${relComp.getName}])
+          .foreach(r => {
+            ${addElement} r.asInstanceOf[${PredefRsumTypes.IRELATIONROLE_STYPE.getName}].getOuterCompartment.getSourceIns.asInstanceOf[${relComp.sClass.getName}]
+          })""")
+        implTrg = implTrg :+ SMethodStatement(content = "result")
+        methodTrg.implementation = implTrg
+        relComp.tClass.asInstanceOf[SClass].addMethod(methodTrg)
+      }
+    })
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/ReferenceRemoveVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/ReferenceRemoveVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..4d0a9abb274f973ca4077bfaf6068d67cc5f5cb8
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/ReferenceRemoveVisitor.scala
@@ -0,0 +1,34 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+
+class ReferenceRemoveVisitor extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    sModel.getModelClasses.foreach(cls => {      
+      //remove all references from the class
+      cls.setReferences(null)
+    })
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+  
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/RelationCompartmentGeneratingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/RelationCompartmentGeneratingVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..c4bdc7d4590851a32e7f408a02ef3a19264692db
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/RelationCompartmentGeneratingVisitor.scala
@@ -0,0 +1,165 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.acr_model.types.SList
+import org.rosi_project.model_sync.generator.acr_model.types.GenericSequence
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+
+class RelationCompartmentGeneratingVisitor extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    var allReferences: Seq[SReference] = Seq.empty
+    var newClasses: Seq[SRelationalCompartmentClass] = Seq.empty
+    sModel.getModelClasses.foreach(cls => {      
+      cls.getReferences.foreach(ref => {        
+        //he should only create a relational compartment for one relation and not for both directions
+        var shouldRun = true
+        if (ref.hasOpposite) {          
+          //has opposite
+          if (!allReferences.contains(ref.oppositeRef) && !allReferences.contains(ref)) {
+            //did not handle this reference yet
+            if (ref.getImportant == ref.oppositeRef) {
+              //should run the other one
+              shouldRun = false         
+              //add this element to the list
+              allReferences = allReferences ++ ref
+            } else {
+              //should run this one
+              shouldRun = true   
+              //add the other one to the list
+              allReferences = allReferences ++ ref.oppositeRef
+            }
+          } else if (allReferences.contains(ref)) {
+            //this reference is in the list so he should not work with it
+            shouldRun = false
+          }     
+        }                
+        
+        if (shouldRun) { 
+          var attType = ref.getTypeElement
+          if (attType.isInstanceOf[GenericSequence])
+          {
+            attType = (attType.asInstanceOf[GenericSequence]).typeParam
+          }
+            
+          val className = cls.getName + ref.getName.capitalize + attType.getName;
+          //println("ClassName: " + className)                                
+          val newClass = new SRelationalCompartmentClass(className, cls.getPackage, connectedRef = ref, sClass = cls, tClass = attType)
+          
+          //attributes
+          val sourceAtt = SAttribute("sInstance", cls)
+          val targetAtt = SAttribute("tInstance", attType)
+          sourceAtt.setVisibility(MethodVisibility.privateVis)
+          sourceAtt.isFinal = true
+          targetAtt.setVisibility(MethodVisibility.privateVis)
+          targetAtt.isFinal = true
+          newClass.setAttributes(sourceAtt ++ targetAtt)
+                      
+          //internal classes
+          val sourceClass = new SInnerClass("Source", externalClass = newClass)
+          val targetClass = new SInnerClass("Target", externalClass = newClass)
+          
+          //create own toString Method
+          sourceClass.addMethod(new SMethod(
+            name = "toString",
+            result = PredefTypes.String,
+            params = Seq.empty,
+            implementation = Seq(SMethodStatement(s"""  "S: (" + sInstance + ")" """)),
+            overrides = true))          
+          targetClass.addMethod(new SMethod(
+            name = "toString",
+            result = PredefTypes.String,
+            params = Seq.empty,
+            implementation = Seq(SMethodStatement(s"""  "T: (" + tInstance + ")" """)),
+            overrides = true))  
+                    
+          //relation types with containment and opposite values
+          if (ref.containment) {
+            if (ref.hasOpposite) {
+              sourceClass.addParent(PredefRsumTypes.ICOMPOSITION_SOURCE_STYPE)
+              targetClass.addParent(PredefRsumTypes.ICOMPOSITION_TARGET_STYPE)
+              newClass.addParent(PredefRsumTypes.ICOMPOSITION_STYPE)
+            } else {
+              sourceClass.addParent(PredefRsumTypes.IDIRECT_COMPOSITION_SOURCE_STYPE)
+              targetClass.addParent(PredefRsumTypes.IDIRECT_COMPOSITION_TARGET_STYPE)
+              newClass.addParent(PredefRsumTypes.IDIRECT_COMPOSITION_STYPE)
+            }
+          } else {  
+            if (ref.hasOpposite) {
+              sourceClass.addParent(PredefRsumTypes.IASSOCIATION_SOURCE_STYPE)
+              targetClass.addParent(PredefRsumTypes.IASSOCIATION_TARGET_STYPE)
+              newClass.addParent(PredefRsumTypes.IASSOCIATION_STYPE)
+            } else {
+              sourceClass.addParent(PredefRsumTypes.IDIRECT_ASSOCIATION_SOURCE_STYPE)
+              targetClass.addParent(PredefRsumTypes.IDIRECT_ASSOCIATION_TARGET_STYPE)
+              newClass.addParent(PredefRsumTypes.IDIRECT_ASSOCIATION_STYPE)
+            }
+          }
+            
+          newClass.addInternalClass(sourceClass)
+          newClass.addInternalClass(targetClass)
+            
+          //method implementation
+          val impl: Seq[SMethodStatement] = (SMethodStatement("this.source = new Source()")
+            ++ SMethodStatement("this.target = new Target()")
+            ++ SMethodStatement("sInstance play this.source")
+            ++ SMethodStatement("tInstance play this.target"))
+                   
+          //add methods to relational compartment
+          newClass.addMethod(new SMethod (
+            name = "internalInitialize", 
+            result = PredefTypes.Unit, 
+            params = Seq.empty, 
+            implementation = impl, 
+            overrides = true))            
+          newClass.addMethod(new SMethod(
+            name = "toString",
+            result = PredefTypes.String,
+            params = Seq.empty,
+            implementation = Seq(SMethodStatement(s"""  "[$className " + source + ", " + target + "]" """)),
+            overrides = true))
+            
+          newClass.addMethod(new SMethod (
+            name = "getSourceIns", 
+            result = cls, 
+            params = Seq.empty, 
+            implementation = Seq(SMethodStatement(s"return sInstance")), 
+            overrides = false))
+            
+          newClass.addMethod(new SMethod (
+            name = "getTargetIns", 
+            result = attType, 
+            params = Seq.empty, 
+            implementation = Seq(SMethodStatement(s"return tInstance")), 
+            overrides = false))
+                        
+          newClasses = newClasses :+ newClass
+        }
+      })
+    })
+    newClasses.foreach(classe => {      
+      sModel.addRelationalCompartment(classe)
+    })
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+  
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/SumModelReadingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/SumModelReadingVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..30b22945d4735762505011b3159c7da2f643dd92
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/SumModelReadingVisitor.scala
@@ -0,0 +1,230 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.PackageNames
+import org.rosi_project.model_sync.generator.acr_model.types.PredefEcoreTypes
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.rosi_project.model_sync.generator.acr_model.types.GenericSequence
+import org.rosi_project.model_sync.generator.GeneratorConfig
+import org.rosi_project.model_sync.generator.Creation
+
+/**
+ * Read EMF and Ecore models.
+ *
+ * @author Christopher Werner
+ */
+class SumModelReadingVisitor(config: GeneratorConfig) extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    //println("++++++++++++++++++++++++++++++++++++++++++++++")
+    val creatorSum = new SClass("Creation" + sModel.getName + "Sum", PackageNames.creationPkgName)
+    val creatorSync = new SClass("Creation" + sModel.getName + "Sync", PackageNames.creationPkgName)
+    val creatorInterface = new SClass("ICreation" + sModel.getName, PackageNames.creationPkgName, SClassType.normalTrait)
+    val loader = new SClass("Loader" + sModel.getName, PackageNames.creationPkgName)
+    
+    creatorSum.addParent(creatorInterface)
+    creatorSync.addParent(creatorInterface)
+
+    val loadEcore = new SMethod(
+      name = "loadEcore",
+      result = PredefEcoreTypes.EcoreObject,
+      params = Seq(SMethodParameter("pathMeta", PredefTypes.String), SMethodParameter("pathInstance", PredefTypes.String)),
+      implementation = Seq(
+        SMethodStatement(content = s"require(null != pathMeta && pathMeta.nonEmpty && null != pathInstance && pathInstance.nonEmpty)"),
+        SMethodStatement(content = s"val resourceSet = new ResourceSetImpl()", usedTypes = Set(PredefEcoreTypes.ResourceSetImpl)),
+        SMethodStatement(content = s"resourceSet.getResourceFactoryRegistry.getExtensionToFactoryMap.put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl())", usedTypes = Set(PredefEcoreTypes.XMIResourceFactoryImpl, PredefEcoreTypes.Resource)),
+        SMethodStatement(content = s"val ressourceMeta = resourceSet.getResource(URI.createFileURI(pathMeta), true)", usedTypes = Set(PredefEcoreTypes.URI)),
+        SMethodStatement(content = s"val packageMeta = ressourceMeta.getContents().get(0)"),
+        SMethodStatement(content = s"require(null != ressourceMeta)"),
+        SMethodStatement(content = s"require(!ressourceMeta.getContents.isEmpty)"),
+        SMethodStatement(content = s"""resourceSet.getPackageRegistry().put("${sModel.getNsURI}", packageMeta);"""),
+        SMethodStatement(content = s"val ressourceModel = resourceSet.getResource(URI.createURI(pathInstance), true);"),
+        SMethodStatement(content = s"return ressourceModel.getContents().get(0)")))
+    loader.addMethod(loadEcore)
+
+    val createModelInstanceSum = new SMethod(
+      name = s"create${sModel.getName}Instance",
+      result = PredefTypes.Unit,
+      params = Seq(SMethodParameter("obj", PredefEcoreTypes.EcoreObject), SMethodParameter("creator", creatorInterface)),
+      implementation = Seq(
+        SMethodStatement(content = s"createObj(obj, creator)"),
+        SMethodStatement(content = s"obj.eAllContents().asScala.foreach(o => {", usedTypes = Set(PredefTypes.ScalaConverter)),
+        SMethodStatement(content = s"createObj(o, creator)"),
+        SMethodStatement(content = s"})"),
+        SMethodStatement(content = s"createRef(obj, creator)"),
+        SMethodStatement(content = s"obj.eAllContents().asScala.foreach(o => {"),
+        SMethodStatement(content = s"createRef(o, creator)"),
+        SMethodStatement(content = s"})")))
+    loader.addMethod(createModelInstanceSum)
+
+    val createObj = new SMethod(
+      name = "createObj",
+      result = PredefTypes.Unit,
+      params = Seq(SMethodParameter("obj", PredefEcoreTypes.EcoreObject), SMethodParameter("creator", creatorInterface)),
+      implementation = Seq.empty)
+    createObj.setVisibility(MethodVisibility.privateVis)
+    var createObjImpl = Seq(SMethodStatement(content = s"var objName = obj.eClass.getName"),
+      SMethodStatement(content = s"objName match {"))
+
+    val createRef = new SMethod(
+      name = "createRef",
+      result = PredefTypes.Unit,
+      params = Seq(SMethodParameter("o1", PredefEcoreTypes.EcoreObject), SMethodParameter("creator", creatorInterface)),
+      implementation = Seq.empty)
+    createRef.setVisibility(MethodVisibility.privateVis)
+    var stringList: Set[String] = Set.empty
+    var createRefImpl = Seq(SMethodStatement(content = s"val o2 = o1.eGet(sf).asInstanceOf[EObject]"),
+      SMethodStatement(content = s"val o1Name = o1.eClass().getName"),
+      SMethodStatement(content = s"val o2Name = o2.eClass().getName"))
+
+    creatorSum.augmentConstructor(SMethodStatement(content = s"var mapping: Map[EObject, Object] = Map.empty", usedTypes = Set(PredefEcoreTypes.EcoreObject)))
+    creatorSync.augmentConstructor(SMethodStatement(content = s"var mapping: Map[EObject, Object] = Map.empty", usedTypes = Set(PredefEcoreTypes.EcoreObject)))
+
+    sModel.getModelClasses.filter(c => !c.isAbstract && !c.isInterface).foreach(c => {
+      //method for trait
+      val methodTrait = new SMethod(
+        name = s"create${c.getName}",
+        result = PredefTypes.Unit,
+        params = c.getAttributeConstructorParameters :+ SMethodParameter("id", PredefEcoreTypes.EcoreObject),
+        implementation = Seq.empty)
+      creatorInterface.addMethod(methodTrait)
+
+      //method for sync
+      val methodSum = new SMethod(
+        name = s"create${c.getName}",
+        result = PredefTypes.Unit,
+        params = c.getAttributeConstructorParameters :+ SMethodParameter("id", PredefEcoreTypes.EcoreObject),
+        implementation = Seq(
+          SMethodStatement(content = s"mapping += (id -> new ${c.getName}(${c.getAttributeConstructorParameters.map(m => m.getName).mkString(", ")}))", usedTypes = Set(c))),
+        overrides = true)
+      creatorSum.addMethod(methodSum)
+
+      //method for sync
+      val methodSync = new SMethod(
+        name = s"create${c.getName}",
+        result = PredefTypes.Unit,
+        params = c.getAttributeConstructorParameters :+ SMethodParameter("id", PredefEcoreTypes.EcoreObject),
+        implementation = Seq(
+          SMethodStatement(content = s"mapping += (id -> new ${c.getName}(${c.getAllConstructorParameters.map(m => if (m.getType.isInstanceOf[GenericSequence]) "Set.empty" else if (m.getType.isInstanceOf[SClass]) "null" else m.getName).mkString(", ")}))", usedTypes = Set(c))), //TODO
+        overrides = true)
+      creatorSync.addMethod(methodSync)
+
+      var types = c.getAttributeConstructorParameters.map(m => m.getType)
+      var s = c.getAttributeConstructorParameters.map(m => s"""obj.eGet(obj.eClass().getEStructuralFeature("${m.getName}"))${if (m.getTypeName == "String") ".toString()" else s".asInstanceOf[${m.getTypeName}${if(m.getType.isInstanceOf[SEnum]) ".Value" else ""}]"} """).mkString(", ")
+      if (s.isEmpty()) {
+        s = "obj"
+      } else {
+        s = s + ", obj"
+      }
+      createObjImpl = createObjImpl :+ SMethodStatement(content = s"""case "${c.getName}" => creator.create${c.getName}(${s})""", types.toSet)
+    })
+
+    sModel.getRelationalCompartments.foreach(r => {
+      var rc = r.asInstanceOf[SRelationalCompartmentClass]
+      //method for trait
+      val methodTrait = new SMethod(
+        name = s"create${r.getName}",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("s", PredefEcoreTypes.EcoreObject), SMethodParameter("t", PredefEcoreTypes.EcoreObject)),
+        implementation = Seq.empty)
+      creatorInterface.addMethod(methodTrait)
+
+      //sum method
+      val methodSum = new SMethod(
+        name = s"create${r.getName}",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("s", PredefEcoreTypes.EcoreObject), SMethodParameter("t", PredefEcoreTypes.EcoreObject)),
+        implementation = Seq(
+          SMethodStatement(content = s"val s1 = mapping.get(s).get.asInstanceOf[${rc.sClass.getName}]"),
+          SMethodStatement(content = s"val t1 = mapping.get(t).get.asInstanceOf[${rc.tClass.getName}]"),
+          SMethodStatement(content = s"(new ${rc.getName}(s1, t1)).initialize()", usedTypes = Set(rc, rc.sClass, rc.tClass))),
+        overrides = true)
+      creatorSum.addMethod(methodSum)
+
+      //sync method
+      val methodSync = new SMethod(
+        name = s"create${r.getName}",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("s", PredefEcoreTypes.EcoreObject), SMethodParameter("t", PredefEcoreTypes.EcoreObject)),
+        implementation = Seq.empty,
+        overrides = true)
+      var implMethodSync = Seq(SMethodStatement(content = s"val s1 = mapping.get(s).get.asInstanceOf[${rc.sClass.getName}]", usedTypes = Set(rc.sClass, rc.tClass)),
+        SMethodStatement(content = s"val t1 = mapping.get(t).get.asInstanceOf[${rc.tClass.getName}]"))
+      if (rc.connectedRef.getTypeElement.isInstanceOf[GenericSequence]) {
+        //add -> add method
+        implMethodSync = implMethodSync :+ SMethodStatement(content = s"s1.add${rc.connectedRef.getName.capitalize}(t1)")
+      } else {
+        //add -> set method
+        implMethodSync = implMethodSync :+ SMethodStatement(content = s"s1.set${rc.connectedRef.getName.capitalize}(t1)")
+      }
+      if (rc.connectedRef.hasOpposite) {
+        if (rc.connectedRef.oppositeRef.getTypeElement.isInstanceOf[GenericSequence]) {
+          //add -> add method
+          implMethodSync = implMethodSync :+ SMethodStatement(content = s"t1.add${rc.connectedRef.oppositeRef.getName.capitalize}(s1)")
+        } else {
+          //add -> set method
+          implMethodSync = implMethodSync :+ SMethodStatement(content = s"t1.set${rc.connectedRef.oppositeRef.getName.capitalize}(s1)")
+        }
+      }
+      methodSync.implementation = implMethodSync
+      creatorSync.addMethod(methodSync)
+
+      //TODO: anpassen
+      val reference = rc.connectedRef.getMinimalConnection
+      if (reference != null) {
+        if (reference == rc.connectedRef) {
+          createRefImpl = createRefImpl :+ SMethodStatement(content = s"""if (o1Name.contains("${rc.sClass.getName}") && sfName == "${reference.getName}" && o2Name.contains("${rc.tClass.getName}")) {""")
+          createRefImpl = createRefImpl :+ SMethodStatement(content = s"creator.create${rc.getName}(o1, o2)")
+          createRefImpl = createRefImpl :+ SMethodStatement(content = "}")
+        } else {
+          createRefImpl = createRefImpl :+ SMethodStatement(content = s"""if (o1Name.contains("${rc.tClass.getName}") && sfName == "${reference.getName}" && o2Name.contains("${rc.sClass.getName}")) {""")
+          createRefImpl = createRefImpl :+ SMethodStatement(content = s"creator.create${rc.getName}(o2, o1)")
+          createRefImpl = createRefImpl :+ SMethodStatement(content = "}")
+        }
+        stringList += reference.getName
+      }
+    })
+
+    createObjImpl = createObjImpl :+ SMethodStatement(content = "case _ =>")
+    createObjImpl = createObjImpl :+ SMethodStatement(content = "}")
+    createObj.implementation = createObjImpl
+    loader.addMethod(createObj)    
+
+    createRefImpl = createRefImpl :+ SMethodStatement(content = "}})")
+    createRefImpl = Seq(SMethodStatement(content = s"o1.eClass().getEAllReferences.forEach(sf => {"),
+      SMethodStatement(content = s"val sfName = sf.getName"),
+      SMethodStatement(content = s"""if(${stringList.map(str => s"""sfName == "${str}" """).mkString(" || ")}) {""")) ++ createRefImpl
+    createRef.implementation = createRefImpl
+    loader.addMethod(createRef)
+
+    //add the new classes as model classes
+    if (config.create == Creation.rolesync) {
+      sModel.addProviderClass(creatorSync)
+    } else {
+      sModel.addProviderClass(creatorSum)
+    }
+    sModel.addProviderClass(creatorInterface)
+    sModel.addProviderClass(loader)
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/SyncEnhancingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/SyncEnhancingVisitor.scala
index 23e433740969af76c2c8dff3b0ff702283d61443..b4c550d133b63881f06ddd750718644770bbc759 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/sync/SyncEnhancingVisitor.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/SyncEnhancingVisitor.scala
@@ -1,77 +1,75 @@
 package org.rosi_project.model_sync.generator.sync
 
-import org.rosi_project.model_sync.generator.ModelConfig
 import org.rosi_project.model_sync.generator.acr_model._
-import org.rosi_project.model_sync.sync.PlayerSync
-import org.rosi_project.model_sync.sync.ISynchronizationCompartment
 
-/** Augments [[SClass SClasses]] with the necessary method calls to make it usable in a
-  * synchronization context.
-  *
-  * The following modifications are performed:
-  *  - the class (or its furthest parent) becomes a subclass of [[PlayerSync]]
-  *  - [[PlayerSync.buildClass()]] will be called in the constructor
-  *  - each setter will notify the synchronization context about the change
-  *
-  * @see [[ISynchronizationCompartment]]
-  * @author Rico Bergmann
-  */
-class SyncEnhancingVisitor(val modelCfg: ModelConfig) extends SModelVisitor {
-
-  private var additionalSyncClasses: Seq[SClass] = Seq.empty
+/**
+ * Augments [[SClass SClasses]] with the necessary method calls to make it usable in a
+ * synchronization context.
+ *
+ * The following modifications are performed:
+ *  - the class (or its furthest parent) becomes a subclass of [[PlayerSync]]
+ *  - [[PlayerSync.buildClass()]] will be called in the constructor
+ *  - each setter will notify the synchronization context about the change
+ *
+ * @see [[ISynchronizationCompartment]]
+ * @author Rico Bergmann
+ */
+class SyncEnhancingVisitor() extends SModelVisitor {
 
   override def visit(sModel: SModel): Unit = {
-    additionalSyncClasses.foreach(sModel.addModelClass)
-
-    modelCfg.init.nested.foreach(_.foreach(model => sModel.addModelClass(new InitialModelTemplate(model))))
-    sModel.addModelClass(new InitialModelTemplate(modelCfg.init))
-    sModel.addModelClass(new ModelProviderTemplate(modelCfg.init))
-
+    sModel.getModelClasses.foreach(cls => {
+      //TODO: do not have in mind trait extends abstract extends trait hierarchy    
+      if (cls.isAbsoluteRootClassOrInterface) {
+        cls.addParent(PredefSyncTypes.PLAYER_SYNC_STYPE)
+      }
+      cls.getMethods.foreach(m => {
+        extractSetterAttr(m).foreach(attr => m.augmentImplementation(SMethodStatement(s"+this $attr")))
+      })
+    })
   }
 
   override def visit(sClass: SClass): Unit = {
-    sClass.getInheritanceHierarchy.reverse.headOption.foreach{
-      case root: SClass => root.setParent(SyncEnhancingVisitor.PLAYER_SYNC_STYPE)
-      case tp => sys.error(s"May not enhance $tp as it is a type and not a class")
-    }
-
-    sClass.augmentConstructor(SyncEnhancingVisitor.PLAYER_SYNC_INIT)
-
-    additionalSyncClasses = additionalSyncClasses :+ new ConstructorTemplate(sClass)
-    sClass.attributes.foreach(attr => {
-      additionalSyncClasses = additionalSyncClasses :+ new ModifierTemplate(sClass, attr)
-    })
+    // pass
   }
 
   override def visit(sAttr: SAttribute): Unit = {
     // pass
   }
 
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
   override def visit(sMethod: SMethod): Unit = {
-    extractSetterAttr(sMethod).foreach(attr => sMethod.augmentImplementation(SMethodStatement(s"+this change$attr ()")))
+    // pass
   }
 
   override def visit(sType: SType): Unit = {
     // pass
   }
 
-  /** Tries to get the attribute's name from a setter method.
-    *
-    * A ''valid'' setter will have the following signature: `setXyz(x: T): Unit` (the parameter's
-    * name does not matter).
-    *
-    * Mind that the first letter will be left uppercase (i.e. `Xyz` will be returned although the
-    * actual attribute may be `xyz`)
-    *
-    * @param sMethod the method to analyze. May be any method (not necessarily a setter) but never
-    *                `null`.
-    * @return the attribute's name if `sMethod` was a valid setter. '''The first letter will be left
-    *         uppercase.'''
-    */
+  /**
+   * Tries to get the attribute's name from a setter method.
+   *
+   * A ''valid'' setter will have the following signature: `setXyz(x: T): Unit` (the parameter's
+   * name does not matter).
+   *
+   * Mind that the first letter will be left uppercase (i.e. `Xyz` will be returned although the
+   * actual attribute may be `xyz`)
+   *
+   * @param sMethod the method to analyze. May be any method (not necessarily a setter) but never
+   *                `null`.
+   * @return the attribute's name if `sMethod` was a valid setter. '''The first letter will be left
+   *         uppercase.'''
+   */
   private def extractSetterAttr(sMethod: SMethod): Option[String] = {
-    sMethod.name match {
+    sMethod.getName match {
       case SyncEnhancingVisitor.Setter(attrName) =>
-        Option(attrName)
+        Option("syncSet" + attrName + " ()")
+      case SyncEnhancingVisitor.Adder(attrName) =>
+        Option("syncAdd" + attrName + s" (${attrName.charAt(0).toLower})")
+      case SyncEnhancingVisitor.Remover(attrName) =>
+        Option("syncRemove" + attrName + s" (${attrName.charAt(0).toLower})")
       case _ =>
         None
     }
@@ -80,15 +78,12 @@ class SyncEnhancingVisitor(val modelCfg: ModelConfig) extends SModelVisitor {
 
 }
 
-/** The companion contains some static values.
-  */
+/**
+ * The companion contains some static values.
+ */
 object SyncEnhancingVisitor {
-
   private val Setter = """set([A-Z][a-zA-z0-9]*)""".r
-
-  private val PLAYER_SYNC_CLASS = classOf[PlayerSync]
-  private val PLAYER_SYNC_STYPE = SType(PLAYER_SYNC_CLASS.getSimpleName, PLAYER_SYNC_CLASS.getPackage.getName)
-
+  private val Adder = """add([A-Z][a-zA-z0-9]*)""".r
+  private val Remover = """remove([A-Z][a-zA-z0-9]*)""".r
   private val PLAYER_SYNC_INIT = SMethodStatement("buildClass()")
-
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/ToStringMethods.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/ToStringMethods.scala
new file mode 100644
index 0000000000000000000000000000000000000000..39d0ed6c7cf1e8297c341232a68239d17360d12c
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/ToStringMethods.scala
@@ -0,0 +1,39 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model.SMethod
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.rosi_project.model_sync.generator.acr_model.SMethodStatement
+import org.rosi_project.model_sync.generator.acr_model.SClass
+
+object ToStringMethods {
+  
+  def normalToStringMethod(cls: SClass): SMethod = {
+    new SMethod(
+        name = "toString",
+        result = PredefTypes.String,
+        params = Seq.empty,
+        implementation = Seq(SMethodStatement((List(s"""  "${cls.getName}:" """) ++ cls.getOnlyDeepAttributes.map(attr => s""" " ${attr.getName}=" + ${attr.getName} """)).mkString(" + "))),
+        overrides = true
+      )
+  } 
+  
+  def joinToStringMethod(s: String): SMethod = {
+    new SMethod(
+        name = "toString",
+        result = PredefTypes.String,
+        params = Seq.empty,
+        implementation = Seq(SMethodStatement(s"""  "JOIN ${s}: " + baseObj + " " + otherObj """)),
+        overrides = true
+      )
+  }
+  
+  def onlyStringToStringMethod(s: String): SMethod = {
+    new SMethod(
+        name = "toString",
+        result = PredefTypes.String,
+        params = Seq.empty,
+        implementation = Seq(SMethodStatement(s"""  "${s}" """)),
+        overrides = true
+      )
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/ViewGeneratingVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/ViewGeneratingVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..c290a7add0719d5ce0ddc2e3bda469c1ac06747e
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/ViewGeneratingVisitor.scala
@@ -0,0 +1,138 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.acr_model.types._
+import org.rosi_project.model_sync.generator.PackageNames
+
+class ViewGeneratingVisitor extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    
+    val viewCompartment = new SViewClass(sModel.getName.capitalize + PackageNames.viewPostName, PackageNames.viewPkgName)
+    var newInternalRoles: Seq[SInnerViewNaturalClass] = Seq.empty
+    var newInternalRelationalRoles: Seq[SInnerViewRelationalClass] = Seq.empty
+    viewCompartment.addParent(PredefRsumTypes.IVIEW_COMPARTMENT_STYPE)
+    
+    //Iterate over all Model classes and create natural internal role classes
+    sModel.getModelClasses.foreach(cls => {
+      val internalClass = new SInnerViewNaturalClass(cls.getName + PackageNames.viewRolePostName,
+          _sClassType = cls.sClassType,
+          _externalClass = viewCompartment, 
+          sumSource = cls)
+      //sets the attributes from the source class
+      var newAtts: Set[SAttribute] = Set.empty
+      cls.getAttributes.foreach(attr => {
+        var newAtt = SAttribute(attr.getName, attr.getTypeElement, attr.unique)
+        newAtt.setVisibility(MethodVisibility.protectedVis)
+        newAtt.isFinal = true
+        newAtts += newAtt
+      })
+      internalClass.setAttributes(newAtts.toSeq)  
+      newInternalRoles = newInternalRoles :+ internalClass
+      viewCompartment.addInternalClass(internalClass)
+    })
+    
+    //Now add the parents to all natural internal roles first
+    newInternalRoles.foreach(inner => {
+      val cls = inner.sumSource
+      //set inheritance to abstract view role
+      if (cls.isRootClass) {
+        inner.addParent(PredefRsumTypes.AVIEW_ROLE_STYPE)
+      }
+      //add parents
+      cls.getAllParents().foreach(p => {
+        val existing: Option[STypedElement] = newInternalRoles.find(existing => existing.getName == p.getName + PackageNames.viewRolePostName)
+        if (!existing.isEmpty) {
+          inner.addParent(existing.get)
+        }
+      })
+    })
+    
+    //add now the messages because they can depend on the parents
+    newInternalRoles.foreach(inner => {
+      //add initialize method if necessary
+      if (!inner.isAbstract && !inner.isInterface) {
+        inner.addMethod(ViewMethods.getIsRelationalMethod(false))
+        inner.addMethod(ViewMethods.getCreationObjectMethod(inner))
+      }    
+      //add delete method
+      inner.addMethod(ToStringMethods.onlyStringToStringMethod("VNR: " + inner.getName))
+      inner.addMethod(ViewMethods.getDeleteElementNaturalMethod(inner))
+      //add getter and setter for attributes in the inner class
+      inner.getAttributes.foreach(attr => {
+        inner.addMethod(ViewMethods.getViewAttributeGetter(attr))
+        inner.addMethod(ViewMethods.getViewAttributeSetter(attr))
+      })      
+    })
+    
+    //Iterate over all Relational compartments and create relational internal role classes
+    sModel.getRelationalCompartments.foreach(r => {
+      var sourceAtt: SAttribute = null
+      var targetAtt: SAttribute = null
+      //set as attributes the other classes
+      var sourceRole: SInnerViewNaturalClass = null
+      var targetRole: SInnerViewNaturalClass = null
+      r.getAttributes.foreach(attr => {
+        newInternalRoles.foreach(inte => {
+          if (inte.getName == attr.getTypeElement.getName + PackageNames.viewRolePostName) {
+            if (attr.getName == "sInstance") {
+              sourceRole = inte
+              sourceAtt = new SAttribute("source", inte)
+              sourceAtt.isFinal = true
+              sourceAtt.setVisibility(MethodVisibility.privateVis)
+            } else {
+              targetRole = inte
+              targetAtt = new SAttribute("target", inte)
+              targetAtt.isFinal = true
+              targetAtt.setVisibility(MethodVisibility.privateVis)
+            }
+          }
+        })
+      })
+      val internalClass = new SInnerViewRelationalClass(r.getName + PackageNames.viewRolePostName, _externalClass = viewCompartment, 
+          sumSource = r.asInstanceOf[SRelationalCompartmentClass], viewSource = sourceRole, viewTarget = targetRole)      
+      internalClass.setAttributes(sourceAtt ++ targetAtt)
+      internalClass.addMethod(ViewMethods.getIsRelationalMethod(true))
+      internalClass.addMethod(ViewMethods.getCreationObjectMethod(internalClass, true, true))      
+      internalClass.addMethod(ViewMethods.getDeleteElementRelationMethod(internalClass, true, true))
+      internalClass.addMethod(ToStringMethods.onlyStringToStringMethod("VRR: " + internalClass.getName))
+      ViewMethods.getSourceAndTargetGetter(internalClass).foreach(internalClass.addMethod(_))
+      internalClass.addParent(PredefRsumTypes.AVIEW_ROLE_STYPE)
+      ViewMethods.createAllReferenceLinks(internalClass, true, true)
+      newInternalRelationalRoles = newInternalRelationalRoles :+ internalClass
+      viewCompartment.addInternalClass(internalClass)
+    })
+    
+    //add methods that must be override from the view trait
+    viewCompartment.addMethod(ViewMethods.getIsViewableMethod((sModel.getRelationalCompartments ++ sModel.getModelClasses).toSet))
+    viewCompartment.addMethod(ViewMethods.getViewNameMethod(viewCompartment))
+    viewCompartment.addMethod(ViewMethods.getGetNaturalRoleMethod(newInternalRoles.toSet))
+    viewCompartment.addMethod(ViewMethods.getGetRelationalRoleMethod(newInternalRelationalRoles.toSet))
+    viewCompartment.addMethod(ToStringMethods.onlyStringToStringMethod("VC: " + viewCompartment.getName))
+    //Create methods to create elements from the view
+    ViewMethods.getCreateNaturalRoleMethods(newInternalRoles.toSet).foreach(viewCompartment.addMethod(_))
+    
+    //add the view to the list for generating views
+    sModel.addViewCompartment(viewCompartment)
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+  
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/ViewMethods.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/ViewMethods.scala
new file mode 100644
index 0000000000000000000000000000000000000000..ed616df0b225be8ec05e1b0b879399d424494c9e
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/ViewMethods.scala
@@ -0,0 +1,317 @@
+package org.rosi_project.model_sync.generator.sync
+
+import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
+import org.rosi_project.model_sync.generator.acr_model._
+import org.rosi_project.model_sync.generator.acr_model.types.SSet
+
+object ViewMethods {
+  
+  def getDeleteElementRelationMethod(ref: SInnerViewRelationalClass, createNormal: Boolean, createOpposite: Boolean): SMethod = {
+    val method = new SMethod(
+      name = "deleteElement",
+      result = PredefTypes.Unit,
+      params = Seq.empty,
+      implementation = Seq.empty, 
+      true)
+    var impl: Seq[SMethodStatement] = Seq.empty
+    if (createNormal) {
+      impl = impl :+ SMethodStatement(content = s"source.remove${ref.sumSource.connectedRef.getName.capitalize}Intern(this)")
+    }
+    if (createOpposite && ref.sumSource.connectedRef.hasOpposite) {
+      impl = impl :+ SMethodStatement(content = s"target.remove${ref.sumSource.connectedRef.oppositeRef.getName.capitalize}Intern(this)")
+    }
+    impl = impl :+ SMethodStatement(content = "super.deleteElement()")
+    method.implementation = impl
+    method
+  }
+  
+  def getDeleteElementNaturalMethod(ref: SInnerViewNaturalClass): SMethod = {
+    val method = new SMethod(
+      name = "deleteElement",
+      result = PredefTypes.Unit,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement(content = "super.deleteElement()")), 
+      true)
+    method
+  }
+    
+  def getSourceAndTargetGetter(ref: SInnerViewRelationalClass): Seq[SMethod] = {
+    (new SMethod(
+      name = "getSource",
+      result = ref.viewSource,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement("source"))) ++
+    new SMethod(
+      name = "getTarget",
+      result = ref.viewTarget,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement("target"))))
+  }
+  
+  def getCreateNaturalRoleMethods(naturalRoles: Set[SInnerViewNaturalClass]): Seq[SMethod] = {
+    var methods: Seq[SMethod] = Seq.empty
+    naturalRoles.foreach(nr => {
+      if (!nr.isAbstract && !nr.isInterface) {
+        val method = new SMethod(
+            name = s"create${nr.sumSource.getName}",
+            result = nr,
+            params = nr.getAllConstructorParameters,
+            implementation = Seq(SMethodStatement(content = s"return new ${nr.getName}(${nr.getAllConstructorParameters.map(m => m.getName).mkString(", ")})")))
+        methods = methods :+ method
+      }
+    })
+    methods
+  }
+  
+  def getIsRelationalMethod(relational: Boolean): SMethod = {
+    val method = new SMethod(
+      name = "isRelational",
+      result = PredefTypes.Boolean,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement(content = s"return ${relational}")), 
+      true)    
+    method.setVisibility(MethodVisibility.protectedVis)
+    method
+  }
+  
+  def getCreationObjectMethod(nat: SInnerViewNaturalClass): SMethod = {
+    val method = new SMethod(
+      name = "getCreationObject",
+      result = PredefTypes.Object,
+      params = Seq.empty,
+      implementation = Seq.empty,
+      true) 
+    if (nat.sumSource.isInstanceOf[SJoinClass]) {
+      val jcls = nat.sumSource.asInstanceOf[SJoinClass]      
+      method.implementation = Seq(SMethodStatement(content = s"return new ${jcls.getName}(new ${jcls.base.getName}(" + 
+          s"${jcls.base.getAllConstructorParameters.map(HelperFunctions.initialAttributeDoing(_, nat.getDeepStructuralFeatures)).mkString(", ")}), new ${jcls.other.getName}(" +
+          s"${jcls.other.getAllConstructorParameters.map(HelperFunctions.initialAttributeDoing(_, nat.getDeepStructuralFeatures)).mkString(", ")}))", usedTypes = Set(jcls.other, jcls.base)))
+    } else {  
+      method.implementation = Seq(SMethodStatement(content = s"return new ${nat.sumSource.getName}(" + 
+          s"${nat.sumSource.getAllConstructorParameters.map(HelperFunctions.initialAttributeDoing(_, nat.getDeepStructuralFeatures)).mkString(", ")})"))
+    }
+    method.setVisibility(MethodVisibility.protectedVis)
+    method
+  }
+    
+  def getCreationObjectMethod(ref: SInnerViewRelationalClass, createNormal: Boolean, createOpposite: Boolean): SMethod = {
+    val method = new SMethod(
+      name = "getCreationObject",
+      result = PredefTypes.Object,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement(content = "return")), 
+      true)
+    var statements: Seq[SMethodStatement] = Seq.empty
+    if (ref.sumSource.connectedRef.hasOpposite && createOpposite) {
+      statements = Seq(SMethodStatement(content = s"target.set${ref.sumSource.connectedRef.oppositeRef.getName.capitalize}Intern(this)"))
+    }
+    if (createNormal) {
+      statements = statements ++ SMethodStatement(content = s"source.set${ref.sumSource.connectedRef.getName.capitalize}Intern(this)")
+    }
+    statements = statements ++ Seq(SMethodStatement(content = s"""val sp: ${ref.sumSource.sClass.getName} = getPlayerOfType(source, "${ref.sumSource.sClass.getName}").asInstanceOf[${ref.sumSource.sClass.getName}]""",
+            usedTypes = Set(ref.viewSource.sumSource)),
+        SMethodStatement(content = s"""val tp: ${ref.sumSource.tClass.getName} = getPlayerOfType(target, "${ref.sumSource.tClass.getName}").asInstanceOf[${ref.sumSource.tClass.getName}]""",
+            usedTypes = Set(ref.viewTarget.sumSource)),
+        SMethodStatement(content = s"val v: ${ref.sumSource.getName} = new ${ref.sumSource.getName}(sp, tp)",
+            usedTypes = Set(ref.sumSource)),
+        SMethodStatement(content = s"return v"))    
+    method.implementation = statements
+    method.setVisibility(MethodVisibility.protectedVis)
+    method
+  }
+  
+  def getGetNaturalRoleMethod(types: Set[SInnerViewNaturalClass]): SMethod = {
+    val method = new SMethod(
+      name = "getNaturalRole",
+      result = PredefRsumTypes.AVIEW_ROLE_STYPE,
+      params = Seq(SMethodParameter("className", PredefTypes.Object)),
+      implementation = Seq.empty)
+    var statements: Seq[SMethodStatement] = Seq.empty 
+    types.foreach(t => {
+      if (!t.isAbstract && !t.isInterface) {        
+        var statement = s"if (className.isInstanceOf[${t.sumSource.getName}]) return new " +
+          s"${t.getName}(${t.getAllConstructorParameters.map(HelperFunctions.classEmptyConstructorParameterCreation(_)).mkString(", ")})"
+        statements = statements :+ SMethodStatement(content = statement, usedTypes = Set(t))
+      }
+    })
+    statements = statements :+ SMethodStatement(content = "return null")
+    method.implementation = statements
+    method.setVisibility(MethodVisibility.protectedVis)
+    method
+  }
+  
+  def getGetRelationalRoleMethod(types: Set[SInnerViewRelationalClass]): SMethod = {
+    val method = new SMethod(
+      name = "getRelationalRole",
+      result = PredefRsumTypes.AVIEW_ROLE_STYPE,
+      params = Seq(SMethodParameter("className", PredefTypes.Object), SMethodParameter("sourceRole", PredefRsumTypes.AVIEW_ROLE_STYPE), SMethodParameter("targetRole", PredefRsumTypes.AVIEW_ROLE_STYPE)),
+      implementation = Seq.empty)
+    
+    var statements: Seq[SMethodStatement] = Seq.empty 
+    types.foreach(t => {
+      var statement = s"if (className.isInstanceOf[${t.sumSource.getName}]) return new " +
+        s"${t.getName}(sourceRole.asInstanceOf[${t.viewSource.getName}], targetRole.asInstanceOf[${t.viewTarget.getName}])"
+      statements = statements :+ SMethodStatement(content = statement, usedTypes = Set(t))
+    })
+    statements = statements :+ SMethodStatement(content = "return null")
+    method.implementation = statements    
+    method.setVisibility(MethodVisibility.protectedVis)
+    method
+  }
+    
+  def getIsViewableMethod(types: Set[SClass]): SMethod = {
+    val method = new SMethod(
+      name = "isViewable",
+      result = PredefTypes.Boolean,
+      params = Seq(SMethodParameter("className", PredefTypes.Object)),
+      implementation = Seq.empty)
+    var newTypes: Set[STypedElement] = Set.empty
+    types.filter(_.isInstanceOf[SJoinClass]).foreach(cls => {
+      newTypes = newTypes + cls.asInstanceOf[SJoinClass].base + cls.asInstanceOf[SJoinClass].other
+    })
+    if (types.isEmpty) {
+      method.implementation = Seq(SMethodStatement(content = "return false", usedTypes = newTypes))
+    } else {
+      val statement = s"if (${types.filter(t => !t.isAbstract && !t.isInterface).map(HelperFunctions.classNameCreation(_)).mkString(" || ")}) return true"
+      method.implementation = Seq(SMethodStatement(content = statement, usedTypes = types.asInstanceOf[Set[STypedElement]]),
+          SMethodStatement(content = "return false", usedTypes = newTypes))
+    }
+    method.setVisibility(MethodVisibility.protectedVis)
+    method
+  }  
+      
+  def getViewNameMethod(viewCompartment: SClass): SMethod = {
+    new SMethod(
+      name = "getViewName",
+      result = PredefTypes.String,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement(content = s"${viewCompartment.getName}.getViewName()", usedTypes = Set(PredefTypes.String))),
+      overrides = true)
+  }
+  
+  def getViewAttributeGetter(struc: SStructuralFeature): SMethod = {
+    new SMethod(
+      name = s"get${struc.getName.firstLetterToUpperCase}View",
+      result = struc.getTypeElement,
+      params = Seq.empty,
+      implementation = Seq(SMethodStatement(content = s"+this get${struc.getName.firstLetterToUpperCase}()", usedTypes = Set(struc.getTypeElement))))
+  }
+  
+  def getViewAttributeSetter(struc: SStructuralFeature): SMethod = {
+    new SMethod(
+      name = s"set${struc.getName.firstLetterToUpperCase}View",
+      result = PredefTypes.Unit,
+      params = Seq(SMethodParameter(struc.getName.toLowerCase(), struc.getTypeElement)),
+      implementation = Seq(SMethodStatement(content = s"+this set${struc.getName.firstLetterToUpperCase}(${struc.getName.toLowerCase()})", usedTypes = Set(struc.getTypeElement)), 
+          SMethodStatement(content = s"+this changeSomething()")))
+  }
+  
+  def createAllReferenceLinks(refClass: SInnerViewRelationalClass, createNormal: Boolean, createOpposite: Boolean): Unit = {
+    val targetClass: SInnerViewNaturalClass = refClass.viewTarget
+    val sourceClass: SInnerViewNaturalClass = refClass.viewSource
+    val realRef: SReference = refClass.sumSource.connectedRef
+    val oppoRef: SReference = refClass.sumSource.connectedRef.oppositeRef
+    if (createNormal) {
+      createReferenceLinks(refClass, realRef, sourceClass, targetClass, true)
+    }
+    if (createOpposite) {
+      if (oppoRef != null) {
+        createReferenceLinks(refClass, oppoRef, targetClass, sourceClass, false)
+      }
+    }
+  }
+
+  private def createReferenceLinks(refClass: SInnerViewRelationalClass, realRef: SReference, sourceClass: SInnerViewNaturalClass, targetClass: SInnerViewNaturalClass, isReal: Boolean): Unit = {
+    val getStatement: String = if (isReal) "getTarget" else "getSource"
+    val thisStatement: String = if (isReal) "(this, v)" else "(v, this)"
+    if (realRef.upperBound == 1) {
+      //upper Bound = 1
+      //variable settings
+      sourceClass.augmentConstructor(SMethodStatement(s"private var ${realRef.getName}: ${refClass.getDeepName} = null"))
+      //internal variables
+      val removeMethodInternal = new SMethod(
+        name = s"remove${realRef.getName.capitalize}Intern",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("v", refClass)), //TODO: remove this then each remove internal method has different input parameters
+        implementation = Seq(SMethodStatement(content = s"${realRef.getName} = null")))
+      removeMethodInternal.setVisibility(MethodVisibility.privateExternalClass)
+      sourceClass.addMethod(removeMethodInternal)
+      val setMethodInternal = new SMethod(
+        name = s"set${realRef.getName.capitalize}Intern",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("v", refClass)),
+        implementation = Seq(SMethodStatement(content = s"${realRef.getName} = v")))
+      setMethodInternal.setVisibility(MethodVisibility.privateExternalClass)
+      sourceClass.addMethod(setMethodInternal)
+      //external variables
+      sourceClass.addMethod(new SMethod(
+        name = s"get${realRef.getName.capitalize}",
+        result = targetClass,
+        params = Seq.empty,
+        implementation = Seq(SMethodStatement(content = s"return ${realRef.getName}.${getStatement}()"))))
+      sourceClass.addMethod(new SMethod(
+        name = s"set${realRef.getName.capitalize}",
+        result = PredefTypes.Boolean,
+        params = Seq(SMethodParameter("v", targetClass)),
+        implementation = Seq(SMethodStatement(content = "if (v == null) return false"),
+          SMethodStatement(content = "if (!containsRole(v.asInstanceOf[AViewRole])) return false"),
+          SMethodStatement(content = s"if (${realRef.getName} != null) {"),
+          SMethodStatement(content = s"if (${realRef.getName}.${getStatement}() == v) return false"),
+          SMethodStatement(content = s"${realRef.getName}.deleteElement()"),
+          SMethodStatement(content = "}"),
+          SMethodStatement(content = s"new ${refClass.getName}${thisStatement}"),
+          SMethodStatement(content = "return true"))))
+    } else {
+      //upper Bound = endless
+      //variable settings
+      sourceClass.augmentConstructor(SMethodStatement(s"private var ${realRef.getName}: Set[${refClass.getDeepName}] = Set.empty"))
+      //internal variables
+      val removeMethodInternal = new SMethod(
+        name = s"remove${realRef.getName.capitalize}Intern",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("v", refClass)),
+        implementation = Seq(SMethodStatement(content = s"${realRef.getName} -= v")))
+      removeMethodInternal.setVisibility(MethodVisibility.privateExternalClass)
+      sourceClass.addMethod(removeMethodInternal)
+      val setMethodInternal = new SMethod(
+        name = s"set${realRef.getName.capitalize}Intern",
+        result = PredefTypes.Unit,
+        params = Seq(SMethodParameter("v", refClass)),
+        implementation = Seq(SMethodStatement(content = s"${realRef.getName} += v")))
+      setMethodInternal.setVisibility(MethodVisibility.privateExternalClass)
+      sourceClass.addMethod(setMethodInternal)
+      //external variables
+      sourceClass.addMethod(new SMethod(
+        name = s"get${realRef.getName.capitalize}",
+        result = SSet(targetClass),
+        params = Seq.empty,
+        implementation = Seq(SMethodStatement(content = s"var vs: Set[${targetClass.getDeepName}] = Set.empty"),
+          SMethodStatement(content = s"${realRef.getName}.foreach{ v => vs += v.${getStatement}()}"),
+          SMethodStatement(content = "return vs"))))
+      sourceClass.addMethod(new SMethod(
+        name = s"has${realRef.getName.capitalize}",
+        result = PredefTypes.Boolean,
+        params = Seq(SMethodParameter("v", targetClass)),
+        implementation = Seq(SMethodStatement(content = s"return get${realRef.getName.capitalize}.contains(v)"))))
+      sourceClass.addMethod(new SMethod(
+        name = s"add${realRef.getName.capitalize}",
+        result = PredefTypes.Boolean,
+        params = Seq(SMethodParameter("v", targetClass)),
+        implementation = Seq(SMethodStatement(content = s"if (has${realRef.getName.capitalize}(v) || !containsRole(v.asInstanceOf[AViewRole])) return false"),
+          SMethodStatement(content = s"new ${refClass.getName}${thisStatement}"),
+          SMethodStatement(content = "return true"))))
+      sourceClass.addMethod(new SMethod(
+        name = s"remove${realRef.getName.capitalize}",
+        result = PredefTypes.Boolean,
+        params = Seq(SMethodParameter("v", targetClass)),
+        implementation = Seq(SMethodStatement(content = s"if (!has${realRef.getName.capitalize}(v)) return false"),
+          SMethodStatement(content = s"${realRef.getName}.foreach{ h =>"),
+          SMethodStatement(content = s"if (h.${getStatement}() == v) {"),
+          SMethodStatement(content = "h.deleteElement()"),
+          SMethodStatement(content = "return true"),
+          SMethodStatement(content = "}}"),
+          SMethodStatement(content = "return true"))))
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/package.scala b/src/main/scala/org/rosi_project/model_sync/generator/sync/package.scala
index 4e0a694ebd741b85202f40dac9ad9ecf4b9298e4..e5139c2a06546e5f5490d2791069edc64621c806 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/sync/package.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/sync/package.scala
@@ -8,8 +8,6 @@ import org.rosi_project.model_sync.generator.acr_model.{SMethodStatement, SModel
   */
 package object sync {
 
-  val RES_PATH = "res/"
-
   implicit def t2SeqT[T](t: T): Seq[T] = Seq(t)
 
   implicit def string2SeqMethodImpl(impl: String): Seq[SMethodStatement] = Seq(SMethodStatement(impl))
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/test/ApplicationTest.scala b/src/main/scala/org/rosi_project/model_sync/generator/test/ApplicationTest.scala
new file mode 100644
index 0000000000000000000000000000000000000000..10c6275f5b2321b1c3d5229e7c224d385dfe40cc
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/test/ApplicationTest.scala
@@ -0,0 +1,128 @@
+package org.rosi_project.model_sync.generator.test
+
+import org.rosi_project.model_sync.generator.GeneratorConfig
+import org.rosi_project.model_sync.generator.Generator
+import java.io.File
+import org.rosi_project.model_sync.generator.Creation
+
+object ApplicationTest extends App {
+  
+  runLibraries()
+      
+  //runTestLibrary(Creation.rolesum)
+  //runCombinedTest(Creation.rolecomb)
+  //runShrinkingModel(Creation.rolesum)
+  //runTestAML(Creation.rolesum)
+  
+  //TTC Case examples
+  //runTestEmfLibrary(Creation.rolecomb)
+  //runTTC2019(Creation.rolecomb)
+  //runTTC2019(Creation.rolesync)  
+  //runTTCLive2019(Creation.rolesync)
+
+  //Run all tests
+  //runAllTests(Creation.rsum)
+  //runAllTests(Creation.rsync)
+  
+  def runLibraries(): Unit = {
+    println("SUMM #####################################################################################")
+    runCombinedTest(Creation.rolesum)
+    runTestLibrary(Creation.rolesum)
+    
+    println("SYNC #####################################################################################")
+    runCombinedTest(Creation.rolesync)
+    runTestLibrary(Creation.rolesync)
+    
+    println("COMB #####################################################################################")
+    runCombinedTest(Creation.rolecomb)
+    runTestLibrary(Creation.rolecomb)
+  }
+  
+  def runAllTests(cre: Creation.Value): Unit = {
+    println("#####################################################################################")
+    runTestFamily(cre)
+    println("#####################################################################################")
+    runTestSimplePerson(cre)
+    println("#####################################################################################")
+    runTestPerson(cre)
+    println("#####################################################################################")
+    runTestLibrary(cre)
+    println("#####################################################################################")
+    runTestShrinkingModel(cre)
+    println("#####################################################################################")
+    runTestAML(cre)
+    println("#####################################################################################")
+    runTestIMDB(cre)
+    println("#####################################################################################")
+    runTestModelJoinLib(cre)
+    println("#####################################################################################")
+    runCombinedTest(cre)
+    println("#####################################################################################")
+  }
+  
+  def runTTCLive2019(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/BibTeX.ecore", "assets/models/DocBook.ecore", "assets/models/NMetaChanges.ecore"), false, new File("assets/models"), create = cre);
+    new Generator(config).run()
+  }
+  
+  def runTTC2019(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/BDD.ecore", "assets/models/BDDv2.ecore", "assets/models/TT.ecore"), false, new File("assets/models"), create = cre);
+    new Generator(config).run()
+  }
+  
+  def runShrinkingModel(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/ShrinkingModel.ecore"), false, new File("assets/models"), modelJoin = "assets/model_join/shrinking.modeljoin", create = cre);
+    new Generator(config).run()
+  }
+  
+  def runCombinedTest(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/IMDBDatabase.ecore", "assets/models/ModelJoinLibrary.ecore"), false, new File("assets/models"), modelJoin = "assets/model_join/simple.modeljoin", create = cre);
+    new Generator(config).run()
+  }
+  
+  def runTestFamily(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/Family.ecore"), false, new File("assets/models"), create = cre);
+    new Generator(config).run()
+  }
+  
+  def runTestSimplePerson(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/SimplePerson.ecore"), false, new File("assets/models"), create = cre);
+    new Generator(config).run()
+  }
+  
+  def runTestPerson(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/Person.ecore"), false, new File("assets/models"), create = cre);
+    new Generator(config).run()
+  }
+  
+  def runTestLibrary(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/Library.ecore"), false, new File("assets/models"), modelJoin = "assets/model_join/manager.modeljoin", create = cre);
+    new Generator(config).run()
+  }
+  
+  def runTestEmfLibrary(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/EMFLibrary.ecore"), false, new File("assets/models"), create = cre);
+    new Generator(config).run()
+  }
+  
+  def runTestShrinkingModel(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/ShrinkingModel.ecore"), false, new File("assets/models"), create = cre);
+    new Generator(config).run()
+  }
+  
+  def runTestAML(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/AML.ecore"), false, new File("assets/models"), create = cre);
+    new Generator(config).run()
+  }
+  
+  def runTestIMDB(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/IMDBDatabase.ecore"), false, new File("assets/models"), create = cre);
+    new Generator(config).run()
+  }
+  
+  def runTestModelJoinLib(cre: Creation.Value): Unit = {
+    var config: GeneratorConfig = GeneratorConfig(Seq("assets/models/ModelJoinLibrary.ecore"), false, new File("assets/models"), create = cre);
+    new Generator(config).run()
+  }
+    
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriterTest.scala b/src/main/scala/org/rosi_project/model_sync/generator/test/SClassWriterTest.scala
similarity index 67%
rename from src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriterTest.scala
rename to src/main/scala/org/rosi_project/model_sync/generator/test/SClassWriterTest.scala
index 528232225f239873446d478ce402be9a6a76a604..b1b1d6761a8515bb00253410a90ea4e4ebb2f5c0 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/io/SClassWriterTest.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/test/SClassWriterTest.scala
@@ -1,7 +1,9 @@
-package org.rosi_project.model_sync.generator.io
+package org.rosi_project.model_sync.generator.test
 
 import org.rosi_project.model_sync.generator.acr_model._
 import org.rosi_project.model_sync.generator.sync.{GetterSetterGeneratingVisitor, SyncEnhancingVisitor}
+import org.rosi_project.model_sync.generator.io.SClassWriter
+import scala.collection.Seq
 
 /**
   * @author Rico Bergmann
@@ -11,12 +13,14 @@ object SClassWriterTest/* extends App */{
   val stringType = SType("String")
   val attrs = Seq(SAttribute("name", stringType))
   val sayHelloMethod = new SMethod("sayHello", stringType, Seq.empty, Seq(SMethodStatement("s\"Hello $name\"")))
-  val modelClass = new SClass("Person", attributes = attrs, methods = Seq(sayHelloMethod))
+  val modelClass = new SClass("Person", "foo")
+  modelClass.setAttributes(attrs)
+  modelClass.addMethod(sayHelloMethod)
 
   val getterSetterVisitor = new GetterSetterGeneratingVisitor
   modelClass.accept(getterSetterVisitor)
-
-  val syncNotificationVisitor = new SyncEnhancingVisitor(null)
+  
+  val syncNotificationVisitor = new SyncEnhancingVisitor
   modelClass.accept(syncNotificationVisitor)
 
   val writer = new SClassWriter(modelClass)
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriterTest.scala b/src/main/scala/org/rosi_project/model_sync/generator/test/SModelFSWriterTest.scala
similarity index 68%
rename from src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriterTest.scala
rename to src/main/scala/org/rosi_project/model_sync/generator/test/SModelFSWriterTest.scala
index 266077240831ebcfb08efbc09ea975e656a2c3b4..b7f00b87273be3a934316afc6f13327d65fd795a 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/io/SModelFSWriterTest.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/test/SModelFSWriterTest.scala
@@ -1,24 +1,25 @@
-package org.rosi_project.model_sync.generator.io
+package org.rosi_project.model_sync.generator.test
 
 import org.rosi_project.model_sync.generator.acr_model.{SimpleSModel, _}
 import org.rosi_project.model_sync.generator.sync.{GetterSetterGeneratingVisitor, SyncEnhancingVisitor}
-
-import scala.reflect.io.File
+import scala.collection.Seq
 
 /** @author Rico Bergmann
   */
 object SModelFSWriterTest/* extends App */{
 
-  val model = new SimpleSModel
+  val model = new SimpleSModel("Foo", "source", "http.//test.test")
 
   val stringType = SType("String")
 
   val personAttrs = Seq(SAttribute("name", stringType))
   val personSayHelloMethod = new SMethod("sayHello", stringType, Seq.empty, Seq(SMethodStatement("s\"Hello $name\"")))
-  val personClass = new SClass("Person", sPackage = "foo", attributes = personAttrs, methods = Seq(personSayHelloMethod))
+  val personClass = new SClass("Person", "foo")
+  personClass.setAttributes(personAttrs)
+  personClass.addMethod(personSayHelloMethod)
 
   val getterSetterVisitor = new GetterSetterGeneratingVisitor
-  val syncNotificationVisitor = new SyncEnhancingVisitor(null)
+  val syncNotificationVisitor = new SyncEnhancingVisitor
 
   model.addModelClass(personClass)
 
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/test/SModelGeneratorTest.scala b/src/main/scala/org/rosi_project/model_sync/generator/test/SModelGeneratorTest.scala
new file mode 100644
index 0000000000000000000000000000000000000000..038ef0c7979c4d1ce7983e0bb79f83dfe36cd97c
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/test/SModelGeneratorTest.scala
@@ -0,0 +1,26 @@
+package org.rosi_project.model_sync.generator.test
+
+import org.eclipse.emf.common.util.URI
+import org.eclipse.emf.ecore.{EObject, EPackage}
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
+import org.rosi_project.model_sync.generator.conversion.SModelGenerator
+
+/**
+  * @author Rico Bergmann
+  */
+object SModelGeneratorTest/* extends App */{
+  
+  val path: String = "assets/ttc17.ecore"
+  
+  val resourceSet = new ResourceSetImpl()
+  val _ = resourceSet.getResourceFactoryRegistry.getExtensionToFactoryMap.put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl())
+  val res = resourceSet.getResource(URI.createFileURI(path), true)
+  
+  require(null != res)
+  require(!res.getContents.isEmpty)
+  println(s"We done: $res")
+
+  res.getContents.toArray(new Array[EObject](0)).toList.find(_.isInstanceOf[EPackage]).foreach(e => (new SModelGenerator).convert(e.asInstanceOf[EPackage], "source"))
+}
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/ConstructorTemplate.scala b/src/main/scala/org/rosi_project/model_sync/generator/ui/ConstructorTemplate.scala
similarity index 56%
rename from src/main/scala/org/rosi_project/model_sync/generator/sync/ConstructorTemplate.scala
rename to src/main/scala/org/rosi_project/model_sync/generator/ui/ConstructorTemplate.scala
index c1dfbbec7dee61f50deceb0b3ad7a26c2c215ce8..b732523defa64a09e5f6d08f4493c816ebe5b8e9 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/sync/ConstructorTemplate.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/ui/ConstructorTemplate.scala
@@ -1,18 +1,19 @@
-package org.rosi_project.model_sync.generator.sync
+package org.rosi_project.model_sync.generator.ui
 
-import org.rosi_project.model_sync.instances.ModelInstanceConstructor
 import org.rosi_project.model_sync.generator.acr_model.{SClass, SImport, SMethod, SMethodParameter, SMethodStatement, SType, types => acr}
+import org.rosi_project.model_sync.generator.sync.string2SeqMethodImpl
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
 
 /** Creates implementations of [[ModelInstanceConstructor]] for model classes.
   *
   * @param modelClass the class for which the constructor should be wrapped
   * @author Rico Bergmann
   */
-class ConstructorTemplate(modelClass: SClass) extends SClass(name = s"${modelClass.name}Constructor") {
+class ConstructorTemplate(modelClass: SClass) extends SClass(_name = s"${modelClass.getName}Constructor", _sPackage = s"${modelClass.sPackage}.visualize") {
 
-  parent = PredefTypes.ModelInstanceConstructor
+  addParent(PredefUiTypes.MODEL_INSTANCE_CONSTRUCTOR_STYPE)
 
-  private val constructorParams = modelClass.attributes.map(attr => s"classOf[${attr.attrType.getName}]").mkString(", ")
+  private val constructorParams: String = generateConstructorParams
 
   constructorStatements = constructorStatements :+ SMethodStatement(s"private val ${ConstructorTemplate.ConstructorAttr} = classOf[${modelClass.getName}].getConstructor($constructorParams)")
 
@@ -26,22 +27,29 @@ class ConstructorTemplate(modelClass: SClass) extends SClass(name = s"${modelCla
     ),
     new SMethod(
       name = "invoke",
-      result = SType.AnyRef,
+      result = PredefTypes.AnyRef,
       params = Seq(SMethodParameter("args", acr.SSeq(acr.PredefTypes.Object))),
       implementation = s"${ConstructorTemplate.ConstructorAttr}.newInstance(args: _*)",
       overrides = true
     ),
     new SMethod(
       name = "toString",
-      result = SType.String,
+      result = PredefTypes.String,
       params = Seq.empty,
       implementation = s""" "${modelClass.getName} Constructor" """,
       overrides = true
     )
   )
 
-  override def getNecessaryImports: Set[SImport] = modelClass.getUsedTypes.filter(_.getPackage != "").map(elem => SImport(elem.getPackage, elem.getName)) ++ super.getNecessaryImports + SImport(modelClass.getPackage, modelClass.getName)
+  override def getNecessaryImports: Set[SImport] = {
+    (modelClass.getUsedTypes.filter(_.getPackage != "").map(elem => SImport(elem.getPackage, elem.getName)) 
+      ++ super.getNecessaryImports 
+      + SImport(modelClass.getPackage, modelClass.getName))      
+  }
 
+  private def generateConstructorParams: String = {
+    modelClass.getDeepStructuralFeatures.map(attr => s"classOf[${attr.getTypeElement.getName}]").mkString(", ")
+  }
 }
 
 object ConstructorTemplate {
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/InitialModelTemplate.scala b/src/main/scala/org/rosi_project/model_sync/generator/ui/InitialModelTemplate.scala
similarity index 53%
rename from src/main/scala/org/rosi_project/model_sync/generator/sync/InitialModelTemplate.scala
rename to src/main/scala/org/rosi_project/model_sync/generator/ui/InitialModelTemplate.scala
index 018824aa198f879de82decbd01bf37b5fbf06ac6..e45e03b87f47ee2fee63517f74d71787eebcf41b 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/sync/InitialModelTemplate.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/ui/InitialModelTemplate.scala
@@ -1,22 +1,21 @@
-package org.rosi_project.model_sync.generator.sync
+package org.rosi_project.model_sync.generator.ui
 
 import java.io.File
-
 import org.rosi_project.model_sync.generator.{Model, ModelDataException}
 import org.rosi_project.model_sync.generator.acr_model._
 import org.rosi_project.model_sync.generator.acr_model.{types => acr}
 import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
-import org.rosi_project.model_sync.provider.DisplayableModelForInitialization
-
+import org.rosi_project.model_sync.generator.sync.string2SeqMethodImpl
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
 
 /** Creates implementations of [[DisplayableModelForInitialization]] for models.
   *
   * @param model the model which should be initialized
   * @author Rico Bergmann
   */
-class InitialModelTemplate(model: Model) extends SClass(name = s"Initialized${Model.parseClass(model.primaryClass)._2.firstLetterToUpperCase}") {
+class InitialModelTemplate(model: Model) extends SClass(_name = s"Initialized${Model.parseClass(model.primaryClass)._2.firstLetterToUpperCase}", _sPackage = s"${Model.parseClass(model.primaryClass)._1}.visualize") {
 
-  parent = SType("DisplayableModelForInitialization", sPackage = "org.rosi_project.model_sync.provider")
+  addParent(SType("DisplayableModelForInitialization", "org.rosi_project.model_sync.provider"))
 
   private val primaryClassComps = Model.parseClass(model.primaryClass)
   private val primaryClass: SClass = STypeRegistry.query(primaryClassComps._2, primaryClassComps._1).getOrElse(throw new ModelDataException).asInstanceOf[SClass]
@@ -26,55 +25,76 @@ class InitialModelTemplate(model: Model) extends SClass(name = s"Initialized${Mo
   private var modelImagePath = "None"
   model.image.foreach(image => {
     val imageFile = new File(image)
-    modelImagePath = s"""Some(new File("${RES_PATH + imageFile.getName}"))"""
+    modelImagePath = s"""Some(new File("${PredefUiTypes.RES_PATH + imageFile.getName}"))"""
   })
 
 
   methods = Seq(
     new SMethod (
       name = "getName",
-      result = SType.String,
+      result = PredefTypes.String,
       params = Seq.empty,
-      implementation = s""" "${model.name}" """
+      implementation = s""" "${model.name}" """,
+      true
     ),
     new SMethod (
       name = "getInstanceClass",
       result = SType("Class[_ <: AnyRef]"),
       params = Seq.empty,
-      implementation = s"classOf[${primaryClass.getName}]"
+      implementation = Seq(SMethodStatement(s"classOf[${primaryClass.getName}]", Set(primaryClass))),
+      true
     ),
     new SMethod (
       name = "getModelDiagram",
       result = acr.PredefTypes.option(acr.PredefTypes.File),
       params = Seq.empty,
-      implementation = modelImagePath
+      implementation = modelImagePath,
+      true
     ),
 
     new SMethod (
       name = "getConstructors",
-      result = acr.SSeq(PredefTypes.ModelInstanceConstructor),
+      result = acr.SSeq(PredefUiTypes.MODEL_INSTANCE_CONSTRUCTOR_STYPE),
       params = Seq.empty,
-      implementation = s"Seq(${allModelClasses.map(cls => s"new ${cls.getName}Constructor").mkString(", ")})"
+      implementation = s"Seq(${allModelClasses
+        .filter(!_.isAbstract)
+        .map(cls => 
+          s"new ${cls.getName}Constructor").mkString(", ")})",
+      true
     ),
     new SMethod (
       name = "getUpdateMethods",
-      result = acr.SSeq(PredefTypes.ModelInstanceModifier),
+      result = acr.SSeq(PredefUiTypes.MODEL_INSTANCE_MODIFIER_STYPE),
       params = Seq.empty,
-      implementation = s"Seq(${allModelClasses.map(cls => cls.attributes.map(attr => s"new ${cls.name}${attr.name.firstLetterToUpperCase}Modifier").mkString(", ")).mkString(", ")})"
+      implementation = s"Seq(${allModelClasses
+          .filter(_.getStructuralFeatures.nonEmpty)
+          .map(cls => {
+            cls.getStructuralFeatures.map(attr => s"new ${cls.getName}${attr.getName.firstLetterToUpperCase}Modifier").mkString(", ")             
+              })
+          .mkString(", ")})",
+      true
     ),
-    new SMethod (
+    new SMethod(
+      name = "toString",
+      result = PredefTypes.String,
+      params = Seq.empty,
+      implementation = s""" "${getName}" """,
+      overrides = true
+    )
+    /*new SMethod (
       name = "getInstances",
       result = acr.SSeq(SType.AnyRef),
       params = Seq.empty,
-      implementation = "Seq.empty" // TODO
-    )
+      implementation = "Seq.empty", // TODO
+      true
+    )*/
   )
 
   if (model.nested.nonEmpty) {
 
     methods = methods :+ new SMethod(
       name = "getNestedModels",
-      result = acr.SSeq(PredefTypes.DisplayableModel),
+      result = acr.SSeq(PredefUiTypes.DISPLAYABLE_MODEL_STYPE),
       params = Seq.empty,
       implementation = s"Seq( ${model.nested.getOrElse(List()).map(nested => "new Initialized"  + Model.parseClass(nested.primaryClass)._2.firstLetterToUpperCase).mkString(", ")} )",
       overrides = true
@@ -82,16 +102,16 @@ class InitialModelTemplate(model: Model) extends SClass(name = s"Initialized${Mo
 
   }
 
-  constructorStatements = Statements.ModelRegistration +: constructorStatements
-
-  override def getNecessaryImports: Set[SImport] = {
-    val base = super.getNecessaryImports + Imports.ModelRegistry
+  augmentConstructor(Statements.ModelRegistration)
 
+  /*override def getNecessaryImports: Set[SImport] = {
+    val base = super.getNecessaryImports
+    
     if (primaryClass.isDefaultPackage) {
       base
     } else {
       base + SImport(primaryClass.getPackage, primaryClass.getName)
     }
-  }
+  }*/
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/ModelProviderTemplate.scala b/src/main/scala/org/rosi_project/model_sync/generator/ui/ModelProviderTemplate.scala
similarity index 59%
rename from src/main/scala/org/rosi_project/model_sync/generator/sync/ModelProviderTemplate.scala
rename to src/main/scala/org/rosi_project/model_sync/generator/ui/ModelProviderTemplate.scala
index 9b912f66a65b930ceeb400206f4c89d5f195f283..99b2a17cb713b0cc9b36461f88e65660165ea917 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/sync/ModelProviderTemplate.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/ui/ModelProviderTemplate.scala
@@ -1,29 +1,30 @@
-package org.rosi_project.model_sync.generator.sync
+package org.rosi_project.model_sync.generator.ui
 
 import org.rosi_project.model_sync.generator.Model
 import org.rosi_project.model_sync.generator.acr_model.{SClass, SMethod, types => acr}
 import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
-import org.rosi_project.model_sync.provider.ModelSyncProvider
+import org.rosi_project.model_sync.generator.sync.string2SeqMethodImpl
+import scala.collection.Seq
 
 /** Creates implementations of [[ModelSyncProvider]] for models.
   *
   * @param model the model which should be initialized
   * @author Rico Bergmann
   */
-class ModelProviderTemplate(model: Model) extends SClass(name = "ModelProvider") {
+class ModelProviderTemplate(model: Model) extends SClass(_name = "ModelProvider", _sPackage = s"${Model.parseClass(model.primaryClass)._1}.visualize") {
 
-  parent = PredefTypes.ModelProvider
+  addParent(PredefUiTypes.MODEL_SYNC_PROVIDER_STYPE)
 
   methods = Seq(
     new SMethod (
       name = "getInitialDisplayableModel",
-      result = PredefTypes.DisplayableModelForInitialization,
+      result = PredefUiTypes.DISPLAYABLE_MODEL_FOR_INITIALIZATION_STYPE,
       params = Seq.empty,
       implementation = s"new Initialized${Model.parseClass(model.primaryClass)._2.firstLetterToUpperCase}"
     ),
     new SMethod (
       name = "getDisplayableModelsForIntegration",
-      result = acr.SSeq(PredefTypes.DisplayableModelForIntegration),
+      result = acr.SSeq(PredefUiTypes.DISPLAYABLE_MODEL_FOR_INTEGRATION_STYPE),
       params = Seq.empty,
       implementation = "Seq.empty"
     )
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/ModifierTemplate.scala b/src/main/scala/org/rosi_project/model_sync/generator/ui/ModifierTemplate.scala
similarity index 56%
rename from src/main/scala/org/rosi_project/model_sync/generator/sync/ModifierTemplate.scala
rename to src/main/scala/org/rosi_project/model_sync/generator/ui/ModifierTemplate.scala
index 065a04ca7a11ca0813534c284d4384eb951db4d0..02135e66bfbfb7f273c2c6f110193051f656e135 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/sync/ModifierTemplate.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/ui/ModifierTemplate.scala
@@ -1,8 +1,10 @@
-package org.rosi_project.model_sync.generator.sync
+package org.rosi_project.model_sync.generator.ui
 
-import org.rosi_project.model_sync.generator.acr_model.{GenericSType, SAttribute, SClass, SImport, SMethod, SMethodParameter, SMethodStatement, SType, STypedElement, types => acr}
+import org.rosi_project.model_sync.generator.acr_model.{GenericSType, SStructuralFeature, SClass, SImport, SMethod, SMethodParameter, SMethodStatement, SType, STypedElement, types => acr}
 import org.rosi_project.model_sync.generator.support.ExtendedString.stringToExtended
-import org.rosi_project.model_sync.instances.ModelInstanceModifier
+import org.rosi_project.model_sync.generator.sync.string2SeqMethodImpl
+import scala.collection.Seq
+import org.rosi_project.model_sync.generator.acr_model.types.PredefTypes
 
 /** Creates implementations of [[ModelInstanceModifier]] for attributes of model classes.
   *
@@ -10,12 +12,12 @@ import org.rosi_project.model_sync.instances.ModelInstanceModifier
   * @param attribute the attribute for which the modifier should be created
   * @author Rico Bergmann
   */
-class ModifierTemplate(modelClass: SClass, attribute: SAttribute) extends SClass(name = s"${modelClass.name}${attribute.name.firstLetterToUpperCase}Modifier") {
+class ModifierTemplate(modelClass: SClass, attribute: SStructuralFeature) extends SClass(_name = s"${modelClass.getName}${attribute.getName.firstLetterToUpperCase}Modifier", _sPackage = s"${modelClass.sPackage}.visualize") {
 
-  parent = PredefTypes.ModelInstanceModifier
+  addParent(PredefUiTypes.MODEL_INSTANCE_MODIFIER_STYPE)
 
   constructorStatements = constructorStatements :+
-    SMethodStatement(s"""private val ${ModifierTemplate.MethodAttr} = classOf[${modelClass.getName}].getMethod("set${attribute.name.firstLetterToUpperCase}", classOf[${attribute.getType}])""")
+    SMethodStatement(s"""private val ${ModifierTemplate.MethodAttr} = classOf[${modelClass.getName}].getMethod("set${attribute.getName.firstLetterToUpperCase}", classOf[${attribute.getTypeElement.getName}])""")
 
   methods = Seq(
     new SMethod (
@@ -27,22 +29,22 @@ class ModifierTemplate(modelClass: SClass, attribute: SAttribute) extends SClass
     ),
     new SMethod (
       name = "invoke",
-      result = SType.Unit,
-      params = Seq(SMethodParameter("instance", SType.AnyRef), SMethodParameter("args", acr.SSeq(SType.AnyRef))),
+      result = PredefTypes.Unit,
+      params = Seq(SMethodParameter("instance", PredefTypes.AnyRef), SMethodParameter("args", acr.SSeq(PredefTypes.AnyRef))),
       implementation = s"${ModifierTemplate.MethodAttr}.invoke(instance, args: _*)",
       overrides = true
     ),
     new SMethod(
       name = "toString",
-      result = SType.String,
+      result = PredefTypes.String,
       params = Seq.empty,
-      implementation = s""" "Change ${attribute.name}" """,
+      implementation = s""" "Change ${attribute.getName}" """,
       overrides = true
     )
   )
 
   override def getNecessaryImports: Set[SImport] = {
-    val attrImports = attribute.attrType match {
+    val attrImports = attribute.getTypeElement match {
       case gt : GenericSType => SImport.generateImports(gt, gt.typeParam)
       case t : STypedElement => SImport.generateImports(t)
     }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/ui/PredefUiTypes.scala b/src/main/scala/org/rosi_project/model_sync/generator/ui/PredefUiTypes.scala
new file mode 100644
index 0000000000000000000000000000000000000000..3dcd4cf803316af14cdd59a61dd57a9aaa2e2bfc
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/ui/PredefUiTypes.scala
@@ -0,0 +1,31 @@
+package org.rosi_project.model_sync.generator.ui
+
+import org.rosi_project.model_sync.generator.acr_model.SType
+import org.rosi_project.model_sync.provider._
+import org.rosi_project.model_sync.instances._
+
+object PredefUiTypes {
+  
+  val RES_PATH = "res/"
+  
+  private val DISPLAYABLE_MODEL_CLASS = classOf[DisplayableModel]
+  val         DISPLAYABLE_MODEL_STYPE = SType(DISPLAYABLE_MODEL_CLASS.getSimpleName, DISPLAYABLE_MODEL_CLASS.getPackage.getName)
+  
+  private val DISPLAYABLE_MODEL_FOR_INITIALIZATION_CLASS = classOf[DisplayableModelForInitialization]
+  val         DISPLAYABLE_MODEL_FOR_INITIALIZATION_STYPE = SType(DISPLAYABLE_MODEL_FOR_INITIALIZATION_CLASS.getSimpleName, DISPLAYABLE_MODEL_FOR_INITIALIZATION_CLASS.getPackage.getName)
+
+  private val DISPLAYABLE_MODEL_FOR_INTEGRATION_CLASS = classOf[DisplayableModelForIntegration]
+  val         DISPLAYABLE_MODEL_FOR_INTEGRATION_STYPE = SType(DISPLAYABLE_MODEL_FOR_INTEGRATION_CLASS.getSimpleName, DISPLAYABLE_MODEL_FOR_INTEGRATION_CLASS.getPackage.getName)
+  
+  private val MODEL_SYNC_PROVIDER_CLASS = classOf[ModelSyncProvider]
+  val         MODEL_SYNC_PROVIDER_STYPE = SType(MODEL_SYNC_PROVIDER_CLASS.getSimpleName, MODEL_SYNC_PROVIDER_CLASS.getPackage.getName)
+  
+  private val MODEL_REGISTRY_CLASS = ModelRegistry.getClass
+  val         MODEL_REGISTRY_STYPE = SType(MODEL_REGISTRY_CLASS.getSimpleName.replace("$", ""), MODEL_REGISTRY_CLASS.getPackage.getName)
+  
+  private val MODEL_INSTANCE_CONSTRUCTOR_CLASS = classOf[ModelInstanceConstructor]
+  val         MODEL_INSTANCE_CONSTRUCTOR_STYPE = SType(MODEL_INSTANCE_CONSTRUCTOR_CLASS.getSimpleName, MODEL_INSTANCE_CONSTRUCTOR_CLASS.getPackage.getName)
+  
+  private val MODEL_INSTANCE_MODIFIER_CLASS = classOf[ModelInstanceModifier]
+  val         MODEL_INSTANCE_MODIFIER_STYPE = SType(MODEL_INSTANCE_MODIFIER_CLASS.getSimpleName, MODEL_INSTANCE_MODIFIER_CLASS.getPackage.getName)
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/sync/Statements.scala b/src/main/scala/org/rosi_project/model_sync/generator/ui/Statements.scala
similarity index 56%
rename from src/main/scala/org/rosi_project/model_sync/generator/sync/Statements.scala
rename to src/main/scala/org/rosi_project/model_sync/generator/ui/Statements.scala
index 59fa88d7d81fe94ed4dcccfbc1ae5a9b1eedf680..729cf98a3956933b685a9699d2aa0e6f1c99e92e 100644
--- a/src/main/scala/org/rosi_project/model_sync/generator/sync/Statements.scala
+++ b/src/main/scala/org/rosi_project/model_sync/generator/ui/Statements.scala
@@ -1,4 +1,4 @@
-package org.rosi_project.model_sync.generator.sync
+package org.rosi_project.model_sync.generator.ui
 
 import org.rosi_project.model_sync.generator.acr_model.SMethodStatement
 
@@ -10,6 +10,6 @@ import org.rosi_project.model_sync.generator.acr_model.SMethodStatement
   */
 object Statements {
 
-  val ModelRegistration = SMethodStatement("ModelRegistry.registerNewModel(this)", Set(PredefTypes.ModelRegistry))
+  val ModelRegistration = SMethodStatement("val registered = ModelRegistry.registerNewModel(this)", Set(PredefUiTypes.MODEL_REGISTRY_STYPE))
 
 }
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/ui/SyncUiVisitor.scala b/src/main/scala/org/rosi_project/model_sync/generator/ui/SyncUiVisitor.scala
new file mode 100644
index 0000000000000000000000000000000000000000..26cc53a33d9d89ebe6de59e7c361c0d5c228dedb
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/ui/SyncUiVisitor.scala
@@ -0,0 +1,49 @@
+package org.rosi_project.model_sync.generator.ui
+
+import org.rosi_project.model_sync.generator.ModelConfig
+import org.rosi_project.model_sync.generator.acr_model._
+
+/**
+ * Add the UI Provider classes for the visualisation in the user interface.
+ */
+class SyncUiVisitor(val modelCfg: ModelConfig) extends SModelVisitor {
+
+  override def visit(sModel: SModel): Unit = {
+    var additionalSyncClasses: Seq[SClass] = Seq.empty
+    sModel.getModelClasses.foreach(cls => {
+      if (!cls.isAbstract && !cls.isInterface) {
+        additionalSyncClasses = additionalSyncClasses :+ new ConstructorTemplate(cls)
+      }
+      cls.getStructuralFeatures.foreach(struc => {
+        additionalSyncClasses = additionalSyncClasses :+ new ModifierTemplate(cls, struc)
+      })
+    })
+
+    additionalSyncClasses.foreach(sModel.addProviderClass)
+
+    modelCfg.init.nested.foreach(_.foreach(model => sModel.addProviderClass(new InitialModelTemplate(model))))
+    sModel.addProviderClass(new InitialModelTemplate(modelCfg.init))
+    sModel.addProviderClass(new ModelProviderTemplate(modelCfg.init))
+
+  }
+
+  override def visit(sClass: SClass): Unit = {
+    // pass
+  }
+
+  override def visit(sAttr: SAttribute): Unit = {
+    // pass
+  }
+
+  override def visit(sRef: SReference): Unit = {
+    // pass
+  }
+
+  override def visit(sMethod: SMethod): Unit = {
+    // pass
+  }
+
+  override def visit(sType: SType): Unit = {
+    // pass
+  }
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/util/ClassAndInstance.scala b/src/main/scala/org/rosi_project/model_sync/generator/util/ClassAndInstance.scala
new file mode 100644
index 0000000000000000000000000000000000000000..1ef23113d87b0a6c8065b430121112d4e6fb6803
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/util/ClassAndInstance.scala
@@ -0,0 +1,8 @@
+package org.rosi_project.model_sync.generator.util
+
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.EPackage
+
+class ClassAndInstance(val pkg: EPackage, val obj: EObject) {
+  
+}
\ No newline at end of file
diff --git a/src/main/scala/org/rosi_project/model_sync/generator/util/InstanceLine.scala b/src/main/scala/org/rosi_project/model_sync/generator/util/InstanceLine.scala
new file mode 100644
index 0000000000000000000000000000000000000000..56bd013cd7ce0d1d44472f5a3b08c6c2169581e5
--- /dev/null
+++ b/src/main/scala/org/rosi_project/model_sync/generator/util/InstanceLine.scala
@@ -0,0 +1,38 @@
+package org.rosi_project.model_sync.generator.util
+
+import scala.collection.JavaConverters._
+import org.eclipse.emf.ecore.EObject
+import org.rosi_project.model_sync.generator.acr_model.STypedElement
+import org.eclipse.emf.ecore.EClass
+import org.rosi_project.model_sync.generator.sync.HelperFunctions
+import org.rosi_project.model_sync.generator.acr_model.SMethodParameter
+import org.rosi_project.model_sync.generator.acr_model.STypeRegistry
+import org.eclipse.emf.ecore.EStructuralFeature
+
+class InstanceLine(val counter: Int, val obj: EObject, val usedType: STypedElement, val lineString: String = "") {
+  
+  def getLine(): String = {
+    if (obj != null) {
+      return s"val i${counter} = new ${usedType.getName} (${usedType.getAllConstructorParameters.map(classEmptyConstructorParameterCreation(_)).mkString(", ")})"
+    }
+    return lineString
+  }
+  
+  def getName(): String = "i" + counter
+  
+  def classEmptyConstructorParameterCreation(t: SMethodParameter): String = {
+    if (STypeRegistry.isDefaultType(t.getType.getName)) {
+      var structs: Seq[EStructuralFeature] = obj.eClass().getEAllStructuralFeatures.asScala
+      structs.foreach(att => {
+        if (att.getName == t.getName) {
+          if (t.getType.getName == "String" && obj.eGet(att) != null) {
+            return s""" "${obj.eGet(att)}" """
+          } else {
+            return obj.eGet(att) + ""
+          }
+        }    
+      })
+    }
+    return HelperFunctions.classEmptyType(t.getTypeName)
+  }
+}
\ No newline at end of file