diff --git a/entity/AnyContact_entity/entityfields/contacttype/valueProcess.js b/entity/AnyContact_entity/entityfields/contacttype/valueProcess.js
index 32bb8ca1976dad71cedfc90616c378fce1d9ccde..1974bb4d5a7c88145de2d44d53a22c00ece7aab3 100644
--- a/entity/AnyContact_entity/entityfields/contacttype/valueProcess.js
+++ b/entity/AnyContact_entity/entityfields/contacttype/valueProcess.js
@@ -2,4 +2,4 @@ import("system.result");
 import("system.vars");
 import("Contact_lib")
 
-result.object(ContactUtils.getRelationType(vars.get("$field.CONTACTID"), vars.get("$field.PERSON_ID"), vars.get("$field.ORGANISATION_ID")));
\ No newline at end of file
+result.object(ContactUtils.getContactType(vars.get("$field.CONTACTID"), vars.get("$field.PERSON_ID"), vars.get("$field.ORGANISATION_ID")));
\ No newline at end of file
diff --git a/entity/AnyContact_entity/recordcontainers/db/fromClauseProcess.js b/entity/AnyContact_entity/recordcontainers/db/fromClauseProcess.js
index c2008fc0d19dfe96ca7074d6f2ceddf2c5941f78..7dc4c1aa3f7ef16b0515795e0db3bfd3aabff75a 100644
--- a/entity/AnyContact_entity/recordcontainers/db/fromClauseProcess.js
+++ b/entity/AnyContact_entity/recordcontainers/db/fromClauseProcess.js
@@ -1,4 +1,4 @@
 import("system.result");
 import("Contact_lib")
 
-result.string(ContactUtils.getFullRelationString());
\ No newline at end of file
+result.string(ContactUtils.getFullContactString());
\ No newline at end of file
diff --git a/entity/Contract_entity/entityfields/contact_id/linkedContextProcess.js b/entity/Contract_entity/entityfields/contact_id/linkedContextProcess.js
index e678b842c5b6cf510473693a355fa7833dcf28e8..2e504d63e3b5a3f71b54b072798b3ad09c50984b 100644
--- a/entity/Contract_entity/entityfields/contact_id/linkedContextProcess.js
+++ b/entity/Contract_entity/entityfields/contact_id/linkedContextProcess.js
@@ -2,4 +2,4 @@ import("system.vars");
 import("system.result");
 import("Contact_lib");
 
-result.string(ContactUtils.getContextByRelationId(vars.getString("$field.CONTACT_ID")));
\ No newline at end of file
+result.string(ContactUtils.getContextByContactId(vars.getString("$field.CONTACT_ID")));
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/activities/children/presetlinks_param/valueProcess.js b/entity/Offer_entity/entityfields/activities/children/presetlinks_param/valueProcess.js
index db35a547ac2cbf60774b6ddb9be4781b81196a68..e4c6c134df6be187331e47d8c2c4d5a9871b7c2b 100644
--- a/entity/Offer_entity/entityfields/activities/children/presetlinks_param/valueProcess.js
+++ b/entity/Offer_entity/entityfields/activities/children/presetlinks_param/valueProcess.js
@@ -7,7 +7,7 @@ var links = [];
 
 if (contactId)
 {
-    links.push([ContactUtils.getContextByRelationId(contactId), contactId]);
+    links.push([ContactUtils.getContextByContactId(contactId), contactId]);
 }
 
 if (vars.get("$field.SALESPROJECT_ID"))
diff --git a/entity/Offer_entity/entityfields/contact_id/linkedContextProcess.js b/entity/Offer_entity/entityfields/contact_id/linkedContextProcess.js
index e678b842c5b6cf510473693a355fa7833dcf28e8..2e504d63e3b5a3f71b54b072798b3ad09c50984b 100644
--- a/entity/Offer_entity/entityfields/contact_id/linkedContextProcess.js
+++ b/entity/Offer_entity/entityfields/contact_id/linkedContextProcess.js
@@ -2,4 +2,4 @@ import("system.vars");
 import("system.result");
 import("Contact_lib");
 
-result.string(ContactUtils.getContextByRelationId(vars.getString("$field.CONTACT_ID")));
\ No newline at end of file
+result.string(ContactUtils.getContextByContactId(vars.getString("$field.CONTACT_ID")));
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/newactivity/onActionProcess.js b/entity/Offer_entity/entityfields/newactivity/onActionProcess.js
index d0e6ebcf2bdd9a61c92ebde5728203de9d3f0c99..4be677edd52ad21e51db57a867790397f1fe35bc 100644
--- a/entity/Offer_entity/entityfields/newactivity/onActionProcess.js
+++ b/entity/Offer_entity/entityfields/newactivity/onActionProcess.js
@@ -7,7 +7,7 @@ var links = [];
 
 if (contactId)
 {
-    links.push([ContactUtils.getContextByRelationId(contactId), contactId]);
+    links.push([ContactUtils.getContextByContactId(contactId), contactId]);
 }
 
 if (vars.get("$field.SALESPROJECT_ID"))
diff --git a/entity/Offer_entity/entityfields/newtask/onActionProcess.js b/entity/Offer_entity/entityfields/newtask/onActionProcess.js
index b77c8343aa0def1afccab6e7c4a4dc5558da7e9b..f0165851eda69a6c3a0187d29f05c133b4118ed3 100644
--- a/entity/Offer_entity/entityfields/newtask/onActionProcess.js
+++ b/entity/Offer_entity/entityfields/newtask/onActionProcess.js
@@ -7,7 +7,7 @@ var links = [];
 
 if (contactId)
 {
-    links.push([ContactUtils.getContextByRelationId(contactId), contactId]);
+    links.push([ContactUtils.getContextByContactId(contactId), contactId]);
 }
 
 if (vars.get("$field.SALESPROJECT_ID"))
diff --git a/entity/Offer_entity/entityfields/salesproject_id/mandatoryProcess.js b/entity/Offer_entity/entityfields/salesproject_id/mandatoryProcess.js
index 05b1f9bd5c0c54e2c707e0ac6f2fce2ea12850e0..3bd7da35b29fe62a814c8f4562736441d1b99708 100644
--- a/entity/Offer_entity/entityfields/salesproject_id/mandatoryProcess.js
+++ b/entity/Offer_entity/entityfields/salesproject_id/mandatoryProcess.js
@@ -2,7 +2,7 @@ import("system.vars");
 import("system.result");
 import("Contact_lib");
 
-var type = ContactUtils.getRelationType(vars.get("$field.CONTACT_ID"), vars.get("$field.CONTACT_PERSON_ID"), vars.get("$field.CONTACT_ORG_ID"));
+var type = ContactUtils.getContactType(vars.get("$field.CONTACT_ID"), vars.get("$field.CONTACT_PERSON_ID"), vars.get("$field.CONTACT_ORG_ID"));
 
 result.string(type != 2);
 
diff --git a/entity/Offer_entity/entityfields/tasks/children/presetlinks_param/valueProcess.js b/entity/Offer_entity/entityfields/tasks/children/presetlinks_param/valueProcess.js
index db35a547ac2cbf60774b6ddb9be4781b81196a68..e4c6c134df6be187331e47d8c2c4d5a9871b7c2b 100644
--- a/entity/Offer_entity/entityfields/tasks/children/presetlinks_param/valueProcess.js
+++ b/entity/Offer_entity/entityfields/tasks/children/presetlinks_param/valueProcess.js
@@ -7,7 +7,7 @@ var links = [];
 
 if (contactId)
 {
-    links.push([ContactUtils.getContextByRelationId(contactId), contactId]);
+    links.push([ContactUtils.getContextByContactId(contactId), contactId]);
 }
 
 if (vars.get("$field.SALESPROJECT_ID"))
diff --git a/entity/Offeritem_entity/entityfields/quantity/onValidation.js b/entity/Offeritem_entity/entityfields/quantity/onValidation.js
index b6b200a8090a588e8b3dc92419ce03155b2898e4..7797e12bfd656b1ca61bd99adbf43b5c7d4db5e9 100644
--- a/entity/Offeritem_entity/entityfields/quantity/onValidation.js
+++ b/entity/Offeritem_entity/entityfields/quantity/onValidation.js
@@ -1,10 +1,8 @@
 import("system.translate");
-import("system.logging");
 import("system.result");
 import("system.vars");
 
-logging.log("validate")
 if (parseInt(vars.get("$field.QUANTITY")) <= 0)
 {
     result.string(translate.text("${QUANTITY_LOWER_THAN_1}"));
-}
\ No newline at end of file
+}
diff --git a/entity/Order_entity/entityfields/activities/children/presetlinks_param/valueProcess.js b/entity/Order_entity/entityfields/activities/children/presetlinks_param/valueProcess.js
index db35a547ac2cbf60774b6ddb9be4781b81196a68..e4c6c134df6be187331e47d8c2c4d5a9871b7c2b 100644
--- a/entity/Order_entity/entityfields/activities/children/presetlinks_param/valueProcess.js
+++ b/entity/Order_entity/entityfields/activities/children/presetlinks_param/valueProcess.js
@@ -7,7 +7,7 @@ var links = [];
 
 if (contactId)
 {
-    links.push([ContactUtils.getContextByRelationId(contactId), contactId]);
+    links.push([ContactUtils.getContextByContactId(contactId), contactId]);
 }
 
 if (vars.get("$field.SALESPROJECT_ID"))
diff --git a/entity/Order_entity/entityfields/contact_id/linkedContextProcess.js b/entity/Order_entity/entityfields/contact_id/linkedContextProcess.js
index e678b842c5b6cf510473693a355fa7833dcf28e8..2e504d63e3b5a3f71b54b072798b3ad09c50984b 100644
--- a/entity/Order_entity/entityfields/contact_id/linkedContextProcess.js
+++ b/entity/Order_entity/entityfields/contact_id/linkedContextProcess.js
@@ -2,4 +2,4 @@ import("system.vars");
 import("system.result");
 import("Contact_lib");
 
-result.string(ContactUtils.getContextByRelationId(vars.getString("$field.CONTACT_ID")));
\ No newline at end of file
+result.string(ContactUtils.getContextByContactId(vars.getString("$field.CONTACT_ID")));
\ No newline at end of file
diff --git a/entity/Order_entity/entityfields/newactivity/onActionProcess.js b/entity/Order_entity/entityfields/newactivity/onActionProcess.js
index 52c2254f6fb64e4784e400dfe61d00e2f2013197..1a27d3d454d20447d05ec6064c1852a7d9e49d01 100644
--- a/entity/Order_entity/entityfields/newactivity/onActionProcess.js
+++ b/entity/Order_entity/entityfields/newactivity/onActionProcess.js
@@ -7,7 +7,7 @@ var links = [];
 
 if (contactId)
 {
-    links.push([ContactUtils.getContextByRelationId(contactId), contactId]);
+    links.push([ContactUtils.getContextByContactId(contactId), contactId]);
 }
 
 if (vars.get("$field.SALESPROJECT_ID"))
diff --git a/entity/Order_entity/entityfields/newtask/onActionProcess.js b/entity/Order_entity/entityfields/newtask/onActionProcess.js
index a2fb8e983a3a08d7bda6b2a66f520f4fdc2ba719..3d0aeaf0beab976054701f3a58a709df8e67de92 100644
--- a/entity/Order_entity/entityfields/newtask/onActionProcess.js
+++ b/entity/Order_entity/entityfields/newtask/onActionProcess.js
@@ -7,7 +7,7 @@ var links = [];
 
 if (contactId)
 {
-    links.push([ContactUtils.getContextByRelationId(contactId), contactId]);
+    links.push([ContactUtils.getContextByContactId(contactId), contactId]);
 }
 
 if (vars.get("$field.SALESPROJECT_ID"))
diff --git a/entity/Order_entity/entityfields/tasks/children/presetlinks_param/valueProcess.js b/entity/Order_entity/entityfields/tasks/children/presetlinks_param/valueProcess.js
index db35a547ac2cbf60774b6ddb9be4781b81196a68..e4c6c134df6be187331e47d8c2c4d5a9871b7c2b 100644
--- a/entity/Order_entity/entityfields/tasks/children/presetlinks_param/valueProcess.js
+++ b/entity/Order_entity/entityfields/tasks/children/presetlinks_param/valueProcess.js
@@ -7,7 +7,7 @@ var links = [];
 
 if (contactId)
 {
-    links.push([ContactUtils.getContextByRelationId(contactId), contactId]);
+    links.push([ContactUtils.getContextByContactId(contactId), contactId]);
 }
 
 if (vars.get("$field.SALESPROJECT_ID"))
diff --git a/entity/Organisation_entity/Organisation_entity.aod b/entity/Organisation_entity/Organisation_entity.aod
index 1c9253f9ce066a6edf0d3b8fa50a36f517d8f4c7..ea7df11cc5e14ae0284e09a69f3f0f3d96648c43 100644
--- a/entity/Organisation_entity/Organisation_entity.aod
+++ b/entity/Organisation_entity/Organisation_entity.aod
@@ -187,6 +187,7 @@
       <consumer>Addresses</consumer>
       <searchable v="false" />
       <state>AUTO</state>
+      <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/address_id/valueProcess.js</valueProcess>
       <displayValueProcess>%aditoprj%/entity/Organisation_entity/entityfields/address_id/displayValueProcess.js</displayValueProcess>
     </entityField>
     <entityConsumer>
@@ -639,6 +640,7 @@
       <alias>Data_alias</alias>
       <fromClauseProcess>%aditoprj%/entity/Organisation_entity/recordcontainers/db/fromClauseProcess.js</fromClauseProcess>
       <conditionProcess>%aditoprj%/entity/Organisation_entity/recordcontainers/db/conditionProcess.js</conditionProcess>
+      <onDBInsert>%aditoprj%/entity/Organisation_entity/recordcontainers/db/onDBInsert.js</onDBInsert>
       <onDBUpdate>%aditoprj%/entity/Organisation_entity/recordcontainers/db/onDBUpdate.js</onDBUpdate>
       <linkInformation>
         <linkInformation>
diff --git a/entity/Organisation_entity/recordcontainers/db/onDBInsert.js b/entity/Organisation_entity/recordcontainers/db/onDBInsert.js
new file mode 100644
index 0000000000000000000000000000000000000000..ba0e67422c062558e49b062c65e43e35fa5e2b95
--- /dev/null
+++ b/entity/Organisation_entity/recordcontainers/db/onDBInsert.js
@@ -0,0 +1,3 @@
+import("system.logging");
+import("system.vars");
+
diff --git a/entity/Prod2prod_entity/Prod2prod_entity.aod b/entity/Prod2prod_entity/Prod2prod_entity.aod
index a6c4e305ff501ff5c3a5ddafed8e664845a48475..ff0f7aa649bb92f6cb269c95d11a47769de19e08 100644
--- a/entity/Prod2prod_entity/Prod2prod_entity.aod
+++ b/entity/Prod2prod_entity/Prod2prod_entity.aod
@@ -139,15 +139,11 @@
       <onDelete>%aditoprj%/entity/Prod2prod_entity/recordcontainers/jdito/onDelete.js</onDelete>
       <recordFields>
         <element>UID.value</element>
-        <element>PARENTID.value</element>
-        <element>PROD2PRODID.value</element>
+        <element>SOURCE_ID.value</element>
+        <element>DEST_ID.value</element>
         <element>QUANTITY.value</element>
-        <element>OPTIONAL.value</element>
-        <element>TAKEPRICE.value</element>
         <element>PRODUCTCODE.value</element>
         <element>PRODUCTID.value</element>
-        <element>SOURCE_ID.value</element>
-        <element>DEST_ID.displayValue</element>
       </recordFields>
     </jDitoRecordContainer>
   </recordContainers>
diff --git a/entity/Prod2prod_entity/recordcontainers/jdito/contentProcess.js b/entity/Prod2prod_entity/recordcontainers/jdito/contentProcess.js
index 1eca5fb315ce03cf0f9cd20ce70f3b869cddd834..2e71e4c9dd769dfb2ac8d258de4574683599ad0d 100644
--- a/entity/Prod2prod_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/Prod2prod_entity/recordcontainers/jdito/contentProcess.js
@@ -1,3 +1,4 @@
+import("system.logging");
 import("system.neon");
 import("system.result");
 import("system.vars");
@@ -5,17 +6,138 @@ import("system.db");
 import("system.util");
 import("Product_lib");
 
+/**
+ * Calculate the root elements for this tree.
+ * 
+ * @param productRootID string
+ * @param rows TreeData[]
+ * @return string[]
+ */
+function calculateRootElements (productRootID, rows) {
+   return rows.filter(function (row) {
+       // Filter predicate if the DIST_ID matches.
+      return row[2] === productRootID;
+   }).map(function (row) {
+       // Map to PROD2PROD_ID.
+       return row[0];
+   });
+}
+
+/**
+* Calculates a mapping object which has the PROD2PROD_ID as
+* key and the full TreeData array as value.
+* 
+* @param rows TreeData[]
+* @return {[key: TreeData]}
+*/
+function buildProd2ProdIDMapping (rows) {
+    var mapping = {}
+    
+    rows.forEach(function(row) {
+        // Create new property which PROD2PROD_ID as key and data
+        // as value.
+       mapping[row[0]] = row;
+    });
+    
+    return mapping;
+}
+
+/**
+ * Calcualtes the children mapping structure which has the DIST_ID
+ * as key and an array of PROD2PROD_IDs as value.
+ *
+ * @param rows TreeData[]
+ * @return {[key: string[]]}
+ */
+function buildChildrenMapping(rows) {
+    var parrentMapping = {}
+    
+    rows.forEach(function (row) {
+        // Create empty array if not created previously.
+        if (parrentMapping[row[2]] === undefined)
+          parrentMapping[row[2]] = []
+      
+      // Push with DIST_ID as key and PROD2PROD_ID as value.
+      parrentMapping[row[2]].push(row[0]);
+    })
+    
+    return parrentMapping
+}
+
+/**
+ * Calculates the graph starting from the given elementID.
+ */
+function buildGraph (elementID, parentElementID, mappingStructure, prod2prodIdMapping) {
+    var elements = []
+ 
+    // Get the PROD2PROD data array and copy it.
+    // Copying is requried due to mutability of arrays.
+    var elementData = prod2prodIdMapping[elementID].slice(0);
+    
+    // Just as an error prevention.
+    if (elementData === undefined)
+        return elements;
+    
+    // Generate new PROD2PROD_ID to create a uniqueness between the PROD2PROD objects.
+    var virtualProd2ProdId = util.getNewUUID();
+    
+    // Override actual PROD2PROD_ID with new ID.
+    elementData[0] = virtualProd2ProdId;
+ 
+    // Override parent id to match overriden prod2prodId of parent
+    if (parentElementID === null || parentElementID === undefined)
+        // Describes an root element
+        elementData[2] = null;
+    else
+        elementData[2] = parentElementID;
+ 
+    // Push element data to elements array of this graph.
+    elements.push(elementData);
+
+    // Search for children
+    var childrens = mappingStructure[elementData[1]];
+
+    if (childrens !== undefined && childrens.length > 0) {
+        // Build graph for each children
+
+        childrens.forEach(function(children) {
+            // Recursive function call (!)
+            
+            var graphResult = buildGraph(children, elementData[0], mappingStructure, prod2prodIdMapping);
+            
+            graphResult.forEach(function(res) {elements.push(res)})
+        });
+    }
+
+    return elements;
+}
+
 if (vars.get("$sys.recordstate") != neon.OPERATINGSTATE_NEW)
 {
     var prodid = vars.exists("$param.ProductId_param") 
                  && vars.get("$param.ProductId_param") != null ? vars.get("$param.ProductId_param") : "";
     if(prodid != "")
     {
-        var p2pUtils = new Prod2ProdUtils(prodid);
-        result.object(p2pUtils.getPartsListForRecordContainer());
+        // First 3 columns are crucial, the rest is optional.
+        var data = db.table("select PROD2PRODID, SOURCE_ID, DEST_ID, QUANTITY, PRODUCTCODE, PRODUCTID "
+                    + "from PROD2PROD join PRODUCT on PROD2PROD.SOURCE_ID = PRODUCTID "
+                    + "order by PRODUCTCODE");
+                
+        var prod2prodIdMapping = buildProd2ProdIDMapping(data);
+        var childrenMapping = buildChildrenMapping(data);
+        var rootElements = calculateRootElements(prodid, data);
+        
+        var allData = []
+        
+        rootElements.forEach(function(rg) {
+            var graphData = buildGraph(rg, null, childrenMapping, prod2prodIdMapping)
+            graphData.forEach(function (gd) { allData.push(gd); })
+        })
+                
+        result.object(allData);
     }
 }
 else
 {
     result.object([]);
-}
\ No newline at end of file
+}
diff --git a/neonContext/Prod2prod/Prod2prod.aod b/neonContext/Prod2prod/Prod2prod.aod
index 3599d2911411108281f6660aa074a9d6087a9979..5f3312e66db92e967ab68ffbf4668b4fafcbf9bb 100644
--- a/neonContext/Prod2prod/Prod2prod.aod
+++ b/neonContext/Prod2prod/Prod2prod.aod
@@ -16,5 +16,9 @@
       <name>428b22a1-427f-4547-a478-964442078bc1</name>
       <view>Prod2ProdEdit_view</view>
     </neonViewReference>
+    <neonViewReference>
+      <name>257aa20f-d6b4-4a64-8f61-bb62b6ef49c8</name>
+      <view>Prod2prodTable_view</view>
+    </neonViewReference>
   </references>
 </neonContext>
diff --git a/neonView/Prod2prodFilter_view/Prod2prodFilter_view.aod b/neonView/Prod2prodFilter_view/Prod2prodFilter_view.aod
index b22717b6dc3e85d0af6f3d8b88d740f7f67ceb3c..eeaf321c7d4fb8abf36121ada2ec9a394a9c7aa2 100644
--- a/neonView/Prod2prodFilter_view/Prod2prodFilter_view.aod
+++ b/neonView/Prod2prodFilter_view/Prod2prodFilter_view.aod
@@ -11,7 +11,7 @@
   <children>
     <treetableViewTemplate>
       <name>Partlist</name>
-      <parentField>PARENTID</parentField>
+      <parentField>DEST_ID</parentField>
       <favoriteActionGroup1>alter</favoriteActionGroup1>
       <titleField>PRODUCTCODE</titleField>
       <descriptionField>QUANTITY</descriptionField>
diff --git a/neonView/Prod2prodTable_view/Prod2prodTable_view.aod b/neonView/Prod2prodTable_view/Prod2prodTable_view.aod
new file mode 100644
index 0000000000000000000000000000000000000000..7b14b322f32eb0d867d8fbea6f83da35863a9503
--- /dev/null
+++ b/neonView/Prod2prodTable_view/Prod2prodTable_view.aod
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.0">
+  <name>Prod2prodTable_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <tableViewTemplate>
+      <name>data</name>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonTableColumn>
+          <name>1a1880db-4a23-4c0f-9a87-7da546461cca</name>
+          <entityField>PARENTID</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>40710edc-b8ef-43fa-8f8c-99add3946c47</name>
+          <entityField>SOURCE_ID</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>673daab5-c779-49db-aaf4-851f2d0a2c95</name>
+          <entityField>QUANTITY</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>0c99aadc-0798-45eb-b015-8cdef16bf0f1</name>
+          <entityField>OPTIONAL</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>da0abba6-9ea0-4503-9b51-8d232f345aa8</name>
+          <entityField>TAKEPRICE</entityField>
+        </neonTableColumn>
+      </columns>
+    </tableViewTemplate>
+  </children>
+</neonView>
diff --git a/neonView/ProductMain_view/ProductMain_view.aod b/neonView/ProductMain_view/ProductMain_view.aod
index 7ac4a87c4db385d9c6be171334d2084be0cbe6e9..ed9d388e2641f2c4c61afc9c7c36c7144c580d4c 100644
--- a/neonView/ProductMain_view/ProductMain_view.aod
+++ b/neonView/ProductMain_view/ProductMain_view.aod
@@ -29,6 +29,11 @@
       <entityField>#ENTITY</entityField>
       <view>ProductDescription_view</view>
     </neonViewReference>
+    <neonViewReference>
+      <name>cbcf23d7-1d80-41c5-8041-8e768fa91487</name>
+      <entityField>ProductLinks</entityField>
+      <view>Prod2prodTable_view</view>
+    </neonViewReference>
     <neonViewReference>
       <name>7f416115-ff89-45ca-be10-ed568cac266c</name>
       <entityField>ProductLinks</entityField>
diff --git a/process/Contact_lib/process.js b/process/Contact_lib/process.js
index b3e659f848a3d5c46b8376121477ea329ebbffac..4dc852d62ea958c7327fa1c1a5e8b459fe1589b1 100644
--- a/process/Contact_lib/process.js
+++ b/process/Contact_lib/process.js
@@ -50,7 +50,7 @@ function ContactUtils() {}
  * This saves an extra select from CONTACT. <br>
  *  <br>
  *  <br>
- * @param {String} pRelationId
+ * @param {String} pContactId
  * @param {String} pPersId selected from the CONTACT table
  * @param {String} pOrgId selected from the CONTACT table
  *  <br>
@@ -59,34 +59,34 @@ function ContactUtils() {}
  *                      2 if privat person <br>
  *                      3 if person of an organisation <br>
  */
-ContactUtils.getRelationType = function(pRelationId, pPersId, pOrgId)
+ContactUtils.getContactType = function(pContactId, pPersId, pOrgId)
 {
     if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW || vars.get("$sys.recordstate") == neon.OPERATINGSTATE_EDIT)
     {
-        return ContactUtils.getRelationTypeByRelation(pRelationId);
+        return ContactUtils.getContactTypeByContactId(pContactId);
     }
     else
     {
-        return ContactUtils.getRelationTypeByPersOrg(pPersId, pOrgId);
+        return ContactUtils.getContactTypeByPersOrg(pPersId, pOrgId);
     }
 }
 
 /**
  * get the type of contact for a relationId <br>
- * If you already have persId and orgId from the CONTACT table, use getRelationTypeByPersOrg() <br>
- * @param {String} pRelationId
+ * If you already have persId and orgId from the CONTACT table, use getContactTypeByPersOrg() <br>
+ * @param {String} pContactId
  * <br>
  * @return {Integer} 0 if relationId not found <br>
  *                  1 if organisation <br>
  *                  2 if privat person <br>
  *                  3 if person of an organisation <br>
  */
-ContactUtils.getRelationTypeByRelation = function(pRelationId)
+ContactUtils.getContactTypeByContactId = function(pContactId)
 {
-    var relationData = ContactUtils.getPersOrgIds(pRelationId);
+    var relationData = ContactUtils.getPersOrgIds(pContactId);
     if (relationData[0]) 
     {
-        return this.getRelationTypeByPersOrg(relationData[1], relationData[2]);
+        return this.getContactTypeByPersOrg(relationData[1], relationData[2]);
     }
     else
     {
@@ -102,7 +102,7 @@ ContactUtils.getRelationTypeByRelation = function(pRelationId)
  * !!It does not check if the person / org ids really exist!! <br>
  * !!And it does not check if really any contact with this person / org ids exist!! <br>
  *  <br>
- * This function is more performant than getRelationTypeByRelation, <br>
+ * This function is more performant than getContactTypeByContactId, <br>
  * because it doesn't load something from the db. <br>
  *  <br>
  * It is meant to be used by entitys, where you can load person and org with the DataRecord. <br>
@@ -116,7 +116,7 @@ ContactUtils.getRelationTypeByRelation = function(pRelationId)
  *                      2 if privat person <br>
  *                      3 if person of an organisation <br>
  */
-ContactUtils.getRelationTypeByPersOrg = function(pPersId, pOrgId)
+ContactUtils.getContactTypeByPersOrg = function(pPersId, pOrgId)
 {
     if (!pPersId)
     {
@@ -147,7 +147,7 @@ ContactUtils.getRelationTypeByPersOrg = function(pPersId, pOrgId)
  * !!It does not check if the person / org ids really exist!! <br>
  * !!And it does not check if really any contact with this person / org ids exist!! <br>
  *  <br>
- * This function is more performant than getContextByRelationId, <br>
+ * This function is more performant than getContextByContactId, <br>
  * because it doesn't load something from the db. <br>
  *  <br>
  * It is meant to be used by entitys, where you can load person and org with the DataRecord. <br>
@@ -161,7 +161,7 @@ ContactUtils.getRelationTypeByPersOrg = function(pPersId, pOrgId)
  */
 ContactUtils.getContextByPersOrg = function(pPersId, pOrgId)
 {
-    switch (ContactUtils.getRelationTypeByPersOrg(pPersId, pOrgId))
+    switch (ContactUtils.getContactTypeByPersOrg(pPersId, pOrgId))
     {
         case 1: // Org
             return ContextUtils.getContextName("Organisation");
@@ -177,27 +177,27 @@ ContactUtils.getContextByPersOrg = function(pPersId, pOrgId)
  * return the corresponding context of the contact <br>
  * If you already have persId and orgId from the CONTACT table, use getContextByPersOrg() <br>
  * 
- * @param {String} pRelationId
+ * @param {String} pContactId
  * @return {String} contextname or "" if contact not found
  */
-ContactUtils.getContextByRelationId = function(pRelationId)
+ContactUtils.getContextByContactId = function(pContactId)
 {
-    var relationData = ContactUtils.getPersOrgIds(pRelationId);
+    var relationData = ContactUtils.getPersOrgIds(pContactId);
     return ContactUtils.getContextByPersOrg(relationData[1], relationData[2])
 }
 
 /**
  * get the person- and org-id from a contact as array
  * 
- * @param {String} pRelationId
+ * @param {String} pContactId
  * @return {String[]} result as [persid, orgid] if one of them is null in the db, "" will be returned as the id.
  */
-ContactUtils.getPersOrgIds = function(pRelationId)
+ContactUtils.getPersOrgIds = function(pContactId)
 {
-    if (pRelationId) {
+    if (pContactId) {
         return db.array(db.ROW, 
             SqlCondition.begin()
-                        .andPrepare("CONTACT.CONTACTID", pRelationId)
+                        .andPrepare("CONTACT.CONTACTID", pContactId)
                         .buildSql("select CONTACTID, PERSON_ID, ORGANISATION_ID from CONTACT", "1=0"));
     }
     
@@ -264,14 +264,13 @@ ContactUtils.getTitleByPersonId = function(pPersonId)
  *
  * @return {String}
  */
-ContactUtils.getFullRelationString = function()
+ContactUtils.getFullContactString = function()
 {
     return " CONTACT join ORGANISATION on ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID"
     + " left join PERSON on PERSON.PERSONID = CONTACT.PERSON_ID"
     + " left join ADDRESS on ADDRESS.ADDRESSID = CONTACT.ADDRESS_ID";
 }
 
-
 /**
  * object for handling of a single contact
  * provides static- and instance-functions
diff --git a/process/OfferOrder_lib/process.js b/process/OfferOrder_lib/process.js
index 1b286d5154d3bec99a17fff08da8f70ef755b303..bb660ba440d2f9ebebe90fa4883372927b681d18 100644
--- a/process/OfferOrder_lib/process.js
+++ b/process/OfferOrder_lib/process.js
@@ -272,10 +272,9 @@ ItemUtils.prototype.insertPartsList = function(columns, productId, assignedTo, c
         columns = columns.concat(additionalProductInfo.map(function(item) {return item[0]}));
         var colTypes = db.getColumnTypes(table, columns);
         
-        // partsList[rootProdId] = root node
-        if (partsList[rootProdId] != undefined) // if product has a parts list
+        if (partsList.root != undefined) // if product has a parts list
         {
-            __itemInsertStatement(partsList[rootProdId], assignedTo, currency, contactId);
+            __itemInsertStatement(partsList.root, assignedTo, currency, contactId);
         }
 
         if (statements.length > 0)
diff --git a/process/PostalAddress_lib/process.js b/process/PostalAddress_lib/process.js
index 40445e11ecbd90447ef35c2df80f330ee39473fc..f3f2b67f1bd8e6dd44e583a7c2a9052d2e6ee5d7 100644
--- a/process/PostalAddress_lib/process.js
+++ b/process/PostalAddress_lib/process.js
@@ -63,8 +63,8 @@ AddressUtils.getFormattedOnlineAddressById = function(pAddressId)
  * 
  * @return {String}
  */
-AddressUtils.getAddress = function(pRelationId) {
-    var address = db.array(db.ROW, SqlCondition.begin().andPrepare("CONTACT.CONTACTID", pRelationId).buildSql('select CONTACTID, ADDRESS, BUILDINGNO, ZIP, CITY, "NAME", FIRSTNAME, LASTNAME, TITLE from' + ContactUtils.getFullRelationString(), "1=0"));
+AddressUtils.getAddress = function(pContactId) {
+    var address = db.array(db.ROW, SqlCondition.begin().andPrepare("CONTACT.CONTACTID", pContactId).buildSql('select CONTACTID, ADDRESS, BUILDINGNO, ZIP, CITY, "NAME", FIRSTNAME, LASTNAME, TITLE from' + ContactUtils.getFullContactString(), "1=0"));
     
     // TODO: currently there are some relations without standard address. Use Hardcoded one.
     if (!address[1]) {
@@ -75,7 +75,7 @@ AddressUtils.getAddress = function(pRelationId) {
         address[4] = dummyAddress[3];
         
     }
-    var type = ContactUtils.getRelationTypeByRelation(pRelationId);
+    var type = ContactUtils.getContactTypeByContactId(pContactId);
     
     return AddressUtils.formatAddress(type, address[1], address[2], address[3], address[4], address[5], address[6], address[7], address[8]);
 }
@@ -103,7 +103,7 @@ AddressUtils.getAddressById = function(pAddressId) {
         address[4] = dummyAddress[4];
         
     }
-    var type = ContactUtils.getRelationTypeByRelation(address[0]);   
+    var type = ContactUtils.getContactTypeByContactId(address[0]);   
 
     var names = db.array(db.ROW, SqlCondition.begin()
                                              .andPrepare("CONTACT.CONTACTID", address[0])
diff --git a/process/Product_lib/process.js b/process/Product_lib/process.js
index 6ee4f51c5dd21b8a37604f9d4e22269358babdee..7f1383f16f3f237b640367c13bc3da8bd2d5bf39 100644
--- a/process/Product_lib/process.js
+++ b/process/Product_lib/process.js
@@ -393,14 +393,15 @@ ProductUtils.removeImage = function(pProductId)
  * @class
  *
  */
-function Prod2ProdUtils(productId) {    
+function Prod2ProdUtils(productId) 
+{    
     this.productId = productId;
     this.data = undefined;
 }
 
 /**
- * Delivers an Object containing parts list structure for passed product "productId" (Constructor parameter)
- * 
+ * Delivers an Object containing parts list structure for passed product "pProductId" (Constructor parameter)
+ *  
  * @return {Object} { $prod2prodid$ { <br>
  *                       ids: [ Array containing child Prod2ProdIds for passed product "pProductId" (Constructor parameter) ] <br>
  *                       , rowdata: [ "PROD2PRODID", "DEST_ID", "SOURCE_ID", "QUANTITY", "OPTIONAL", "TAKEPRICE" ] from DB-Table PROD2PROD <br>
@@ -409,10 +410,13 @@ function Prod2ProdUtils(productId) {
  *                       , quantity: "Quantity" <br>
  *                       , optional: "0" = not optional, "1" = optional <br>
  *                       , takeprice: "0" = no price, "1" = price <br>
+ *                       , productcode: "Productcode" <br>
+ *                       , productid: "Productid" <br>
  *                  } }
  */
-Prod2ProdUtils.prototype.getPartsListObject = function() {
-    return this._relateChilds().getTreeObject();
+Prod2ProdUtils.prototype.getPartsListObject = function() 
+{
+    return this._relateChilds();
 }
 
 /**
@@ -434,9 +438,27 @@ Prod2ProdUtils.prototype.getPartsListObject = function() {
  *                    , "PRODUCTCODE"
  *                    , "PRODUCTID"] ]
  */
-Prod2ProdUtils.prototype.getPartsListForRecordContainer = function() {
-    var tree = this._relateChilds();
-    return tree.toArray(7);
+Prod2ProdUtils.prototype.getPartsListForRecordContainer = function() 
+{
+    var ret = [];
+    var childs = this._relateChilds();
+
+    __push(childs.root);
+
+    function __push(pObj)
+    {
+        for(var i = 0; i < pObj.ids.length; i++)
+        {
+            var rowdata = childs[pObj.ids[i]].rowdata;
+            var UID = util.getNewUUID();
+            var PARENTID = childs[pObj.ids[i]].destid;
+
+            rowdata = [UID, PARENTID].concat(rowdata);
+            ret.push(rowdata);
+            __push( childs[pObj.ids[i]] );
+        }
+    }
+    return ret;
 }
 
 /**
@@ -446,18 +468,21 @@ Prod2ProdUtils.prototype.getPartsListForRecordContainer = function() {
 * 
 * @return {String[]} [ "SOURCE_ID" ]
 */
-Prod2ProdUtils.prototype.getPartsListProdIds = function() {
+Prod2ProdUtils.prototype.getPartsListProdIds = function() 
+{
     var ret = [];
-    var childs = this._relateChilds().getTreeObject();
+    var childs = this._relateChilds();
 
     __push(childs.root);
 
     return ret;
 
-    function __push(pObj) {
-        for (var i = 0; i < pObj.ids.length; i++) {
+    function __push(pObj)
+    {
+        for(var i = 0; i < pObj.ids.length; i++)
+        {
             ret.push(childs[pObj.ids[i]].sourceid);
-            __push(childs[pObj.ids[i]]);
+            __push( childs[pObj.ids[i]] );
         }
     }
 }
@@ -469,7 +494,8 @@ Prod2ProdUtils.prototype.getPartsListProdIds = function() {
 * 
 * @return {String[]} [ "DEST_ID" ]
 */
-Prod2ProdUtils.prototype.getParentProdIds = function() {
+Prod2ProdUtils.prototype.getParentProdIds = function() 
+{
     var ret = [];
     var parents = this._relateParents();
 
@@ -477,10 +503,12 @@ Prod2ProdUtils.prototype.getParentProdIds = function() {
 
     return ret;
 
-    function __push(pObj) {
-        for (var i = 0; i < pObj.ids.length; i++) {
+    function __push(pObj)
+    {
+        for(var i = 0; i < pObj.ids.length; i++)
+        {
             ret.push(parents[pObj.ids[i]].destid);
-            __push(parents[pObj.ids[i]]);
+            __push( parents[pObj.ids[i]] );
         }
     }
 }
@@ -491,9 +519,10 @@ Prod2ProdUtils.prototype.getParentProdIds = function() {
 *
 * @ignore
 */
-Prod2ProdUtils.prototype._initProd2ProdData = function() {
+Prod2ProdUtils.prototype._initProd2ProdData = function()
+{
     if (this.data == undefined) {
-        this.data = db.table("select SOURCE_ID, DEST_ID, PROD2PRODID, QUANTITY, OPTIONAL, TAKEPRICE, PRODUCTCODE, PRODUCTID, SOURCE_ID, DEST_ID "
+        this.data = db.table("select PROD2PRODID, DEST_ID, SOURCE_ID, QUANTITY, OPTIONAL, TAKEPRICE, PRODUCTCODE, PRODUCTID "
                     + "from PROD2PROD join PRODUCT on PROD2PROD.SOURCE_ID = PRODUCTID "
                     + "order by PRODUCTCODE ");
     }
@@ -502,78 +531,77 @@ Prod2ProdUtils.prototype._initProd2ProdData = function() {
 /**
  * object tree to relate products by DEST_ID / SOURCE_ID.
  **/
-Prod2ProdUtils.prototype._buildTree = function(supervised) {
+Prod2ProdUtils.prototype._buildTree = function(pSupervised)
+{
     this._initProd2ProdData();
-    var productId = this.productId;
+
+        var tree = { root: {ids: [], sourceid: this.productId } };
         
-    var tree = DataTree.begin(this.productId).addArray(this.data,
-        function(pUid, pNode)
+        if(pSupervised)
+            tree = { root: {ids: [], destid: this.productId } };
+
+        for (var i = 0; i < this.data.length; i++)
         {
-            if (pUid == productId)
+            var prod2prodid = this.data[i][0];
+            if ( tree[prod2prodid] == undefined )   
             {
-                pNode["sourceid"] = productId;
-                if (supervised) 
-                {
-                    pNode["destid"] = productId;
-                }
-            } 
-            else
-            {
-                pNode["destid"] = pNode.parent;
-                pNode["sourceid"] = pUid;
-                
-                if (pNode.data != undefined) {
-                    pNode["quantity"] = pNode.data[1];
-                    pNode["optional"] = pNode.data[2];
-                    pNode["takeprice"] = pNode.data[3];
-                    pNode["productcode"] = pNode.data[4];
-                    pNode["productid"] = pNode.data[5];
-                }
+                tree[prod2prodid] = {
+                    ids: [] 
+                    , rowdata: this.data[i].slice(0)//copy to get NativeArray for concatenation
+                    , destid: this.data[i][1]
+                    , sourceid: this.data[i][2] 
+                    , quantity: this.data[i][3]
+                    , optional: this.data[i][4]
+                    , takeprice: this.data[i][5]
+                    , productcode: this.data[i][6]
+                    , productid: this.data[i][7]
+                };
             }
         }
-    );
+        
+        return tree;
 
-    return tree;
 }
 
-Prod2ProdUtils.prototype._relateChilds = function() {
+Prod2ProdUtils.prototype._relateChilds = function()
+{
     var tree = this._buildTree(false);
-    __relate(this.productId);
+
+    __relate("root");
 
     return tree;
 
-    function __relate(id) {
-        var treeObject = tree.getTreeObject();
-        if (treeObject[id] != undefined)
+    function __relate(pID)
+    {
+        for ( var id in tree )
         {
-            for (var treeId in treeObject) {
-                if (treeObject[treeId].destid == treeObject[id].sourceid && treeObject[id].ids.indexOf(treeId) == -1) { 
-                    treeObject[id].ids.push(treeId);
-                    __relate(treeId);
-                }    
-            }
+            if ( tree[id].destid == tree[pID].sourceid && tree[pID].ids.indexOf(id) == -1 )
+            {   
+                tree[pID].ids.push(id);
+                __relate(id);
+            }    
         }
     }
 }
 
-Prod2ProdUtils.prototype._relateParents = function() {
+Prod2ProdUtils.prototype._relateParents = function() 
+{
     var tree = this._buildTree(true);
 
-    __relate(this.productId);
+    __relate("root");
 
     return tree;
 
 
-    function __relate(id) {
-        var treeObject = tree.getTreeObject();
-        if (treeObject[id] != undefined)
+    function __relate(pID)
+    {
+        for ( var id in tree )
         {
-            for (var treeId in treeObject) {
-                if (treeObject[treeId].sourceid == treeObject[id].destid && treeObject[id].ids.indexOf(treeId) == -1) {   
-                    treeObject[id].ids.push(treeId);
-                    __relate(treeId);
-                }    
-            }
+            if ( tree[id].sourceid == tree[pID].destid && tree[pID].ids.indexOf(id) == -1 )
+            {   
+                tree[pID].ids.push(id);
+                __relate(id);
+            }    
         }
     }
 }
\ No newline at end of file