diff --git a/aliasDefinition/Data_alias/indexsearchgroups/org/affectedIds.js b/aliasDefinition/Data_alias/indexsearchgroups/org/affectedIds.js
index ae199b2018a9652efde2cbe29362e0e1f0e0b58c..59126ad58df30299bc21dcb629b3fef2b781a50e 100644
--- a/aliasDefinition/Data_alias/indexsearchgroups/org/affectedIds.js
+++ b/aliasDefinition/Data_alias/indexsearchgroups/org/affectedIds.js
@@ -2,12 +2,13 @@ import("system.db");
 import("system.result");
 import("system.vars");
 import("IndexSearch_lib");
-var indexHelper, infoContainer, onUpdFn, tableName, res;
+import("Sql_lib");
+
+var infoContainer, onUpdFn, tableName, res;
 
-indexHelper = new IndexsearchUtils();
 tableName = vars.get("$local.table");
 idValue = vars.get("$local.idvalue");
-infoContainer =  indexHelper.createAffectedInfoContainer(idValue, null, vars.get("$local.action")
+infoContainer =  IndexsearchUtils.createAffectedInfoContainer(idValue, null, vars.get("$local.action")
     ,function (){return vars.get("$local.columns")}
     ,function (){return vars.get("$local.oldvalues")}
     ,function (){return vars.get("$local.values")});
@@ -21,16 +22,16 @@ switch (tableName)
         res = db.array(db.COLUMN, "select RELATION.RELATIONID from RELATION where RELATION.PERS_ID is null and RELATION.ORG_ID = '" + idValue + "'");
         break;
     case "ADDRESS":
-        res = indexHelper.getAffectedIdValues("RELATION_ID", infoContainer, function (id){
+        res = IndexsearchUtils.getAffectedIdValues("RELATION_ID", infoContainer, function (id){
             return db.array(db.COLUMN, ["select ADDRESS.RELATION_ID from ADDRESS where ADDRESS.ADDRESSID = ?", [
-                    [id, db.getColumnTypes("ADDRESS", ["ADDRESSID"])[0]]
+                    [id, SqlUtils.getSingleColumnType("ADDRESS", ["ADDRESSID"])]
             ]]);
         });
         break;
     case "COMM":
-        res = indexHelper.getAffectedIdValues("RELATION_ID", infoContainer, function (id){
+        res = IndexsearchUtils.getAffectedIdValues("RELATION_ID", infoContainer, function (id){
             return db.array(db.COLUMN, ["select ADDRESS.RELATION_ID from COMM where COMMID = ?", [
-                    [id, db.getColumnTypes("COMM", ["COMMID"])[0]]
+                    [id, SqlUtils.getSingleColumnType("COMM", ["COMMID"])]
             ]]);
         });
         break;
diff --git a/aliasDefinition/Data_alias/indexsearchgroups/pers/affectedIds.js b/aliasDefinition/Data_alias/indexsearchgroups/pers/affectedIds.js
index a87cc105b4964eab1b273f808b2586b93b041a24..80d3d35764628599b1812c367844a7433711b413 100644
--- a/aliasDefinition/Data_alias/indexsearchgroups/pers/affectedIds.js
+++ b/aliasDefinition/Data_alias/indexsearchgroups/pers/affectedIds.js
@@ -2,12 +2,13 @@ import("system.db");
 import("system.result");
 import("system.vars");
 import("IndexSearch_lib");
-var indexHelper, infoContainer, onUpdFn, tableName, res;
+import("Sql_lib");
+
+var infoContainer, onUpdFn, tableName, res;
 
-indexHelper = new IndexsearchUtils();
 tableName = vars.get("$local.table");
 idValue = vars.get("$local.idvalue");
-infoContainer =  indexHelper.createAffectedInfoContainer(idValue, null, vars.get("$local.action")
+infoContainer =  IndexsearchUtils.createAffectedInfoContainer(idValue, null, vars.get("$local.action")
     ,function (){return vars.get("$local.columns")}
     ,function (){return vars.get("$local.oldvalues")}
     ,function (){return vars.get("$local.values")});
@@ -24,16 +25,16 @@ switch (tableName)
         res = db.array(db.COLUMN, "select RELATION.RELATIONID from RELATION where RELATION.PERS_ID is not null and RELATION.ORG_ID = '" + idValue + "'");
         break;
     case "ADDRESS":
-        res = indexHelper.getAffectedIdValues("RELATION_ID", infoContainer, function (id){
+        res = IndexsearchUtils.getAffectedIdValues("RELATION_ID", infoContainer, function (id){
             return db.array(db.COLUMN, ["select ADDRESS.RELATION_ID from ADDRESS where ADDRESS.ADDRESSID = ?", [
-                    [id, db.getColumnTypes("ADDRESS", ["ADDRESSID"])[0]]
+                    [id, SqlUtils.getSingleColumnType("ADDRESS", ["ADDRESSID"])]
             ]]);
         });
         break;
     case "COMM":
-        res = indexHelper.getAffectedIdValues("RELATION_ID", infoContainer, function (id){
+        res = IndexsearchUtils.getAffectedIdValues("RELATION_ID", infoContainer, function (id){
             return db.array(db.COLUMN, ["select ADDRESS.RELATION_ID from COMM where COMMID = ?", [
-                    [id, db.getColumnTypes("COMM", ["COMMID"])[0]]
+                    [id, SqlUtils.getSingleColumnType("COMM", ["COMMID"])]
             ]]);
         });
         break;
diff --git a/entity/Comm_entity/entityfields/addr/onValidation.js b/entity/Comm_entity/entityfields/addr/onValidation.js
index 97fccc1a01aeaa1794aae039d5bf8f8d00ddca22..f7e031675a3de8e05eb86384e2ee943f5ab9de88 100644
--- a/entity/Comm_entity/entityfields/addr/onValidation.js
+++ b/entity/Comm_entity/entityfields/addr/onValidation.js
@@ -7,6 +7,7 @@ import("system.mail");
 import("Keyword_lib");
 import("Comm_lib");
 import("Util_lib");
+import("Entity_lib");
 
 var kwdUtil = new KeywordUtils();
 var kwd = kwdUtil.createKeyword("COMM.MEDIUM");
@@ -15,7 +16,7 @@ var commCategory = kwd.getPropForKey(commMedium, "contentType", true);//TODO: ma
 
 var fn = CommValidationUtil.makeValidationFn(commCategory);
 if (fn != null){
-    var commAddr = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.ADDR"));
+    var commAddr = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.ADDR"));
     var additional = CommValidationUtil.getExtensionsBlueprint();
     additional.countryCode = vars.get("$param.RelationsMainCountry_param");//TODO: try to use users language first and then the companies
     var res = fn.call(null, commAddr, additional);
diff --git a/entity/Contract_entity/entityfields/contractcode/onValidation.js b/entity/Contract_entity/entityfields/contractcode/onValidation.js
index e357339a3f7c17483b1c7188c54a1c547174f19a..8d2de85d894a32c92d53fd9e16cffb2b1fd153fb 100644
--- a/entity/Contract_entity/entityfields/contractcode/onValidation.js
+++ b/entity/Contract_entity/entityfields/contractcode/onValidation.js
@@ -3,8 +3,12 @@ import("system.result");
 import("system.vars");
 import("system.db");
 import("Util_lib");
+import("Entity_lib");
 
-var codeCount = db.cell("select count(CONTRACTCODE) from CONTRACT where CONTRACTCODE = '" + ProcessHandlingUtil.getOnValidationValue(vars.get("$field.CONTRACTCODE")) + "'"
+var contractCode, codeCount;
+
+contractCode = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.CONTRACTCODE"));
+codeCount = db.cell("select count(CONTRACTCODE) from CONTRACT where CONTRACTCODE = '" + contractCode + "'"
                        + " and CONTRACTID <> '" + vars.get("$field.CONTRACTID") + "'");
 if(codeCount > 0)
 {
diff --git a/entity/Contract_entity/entityfields/contractdue/onValidation.js b/entity/Contract_entity/entityfields/contractdue/onValidation.js
index d269674beab0906856f8e8bc83afe6ffe48c73f9..eec165e723c8199c6314723ff0e928d2f734a3ec 100644
--- a/entity/Contract_entity/entityfields/contractdue/onValidation.js
+++ b/entity/Contract_entity/entityfields/contractdue/onValidation.js
@@ -3,10 +3,10 @@ import("system.translate");
 import("system.vars");
 import("Date_lib");
 import("Util_lib");
+import("Entity_lib");
 
-var dateUtils = new DateUtils();
-var cDue = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.CONTRACTDUE"));
+var cDue = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.CONTRACTDUE"));
 
-if (dateUtils.validateBeginnBeforeEnd(vars.get("$field.CONTRACTSTART"), cDue) === false || dateUtils.validateBeginnBeforeEnd(cDue, vars.get("$field.CONTRACTEND")) === false) {
+if (DateUtils.validateBeginnBeforeEnd(vars.get("$field.CONTRACTSTART"), cDue) === false || DateUtils.validateBeginnBeforeEnd(cDue, vars.get("$field.CONTRACTEND")) === false) {
     result.string(translate.text("The next due date must be after the start of the contract and before the expiry of the contract!"));
 }
diff --git a/entity/Contract_entity/entityfields/contractend/onValidation.js b/entity/Contract_entity/entityfields/contractend/onValidation.js
index 8bb7dc15d6b77c65124e37372351a6c158d526e6..c2b570b75775ae1f669ba1a8e7ad9b716e17f2eb 100644
--- a/entity/Contract_entity/entityfields/contractend/onValidation.js
+++ b/entity/Contract_entity/entityfields/contractend/onValidation.js
@@ -2,10 +2,10 @@ import("system.result");
 import("system.vars");
 import("Date_lib");
 import("Util_lib");
+import("Entity_lib");
 
-var dateUtils = new DateUtils();
-var cEnd = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.CONTRACTEND"));
+var cEnd = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.CONTRACTEND"));
 var cDue = vars.get("$field.CONTRACTDUE");
 
-if (dateUtils.validateBeginnBeforeEnd(vars.get("$field.CONTRACTSTART"), cEnd) === false)
-    result.string(dateUtils.getValidationFailString());
\ No newline at end of file
+if (DateUtils.validateBeginnBeforeEnd(vars.get("$field.CONTRACTSTART"), cEnd) === false)
+    result.string(DateUtils.getValidationFailString());
\ No newline at end of file
diff --git a/entity/Contract_entity/entityfields/contractend/onValueChange.js b/entity/Contract_entity/entityfields/contractend/onValueChange.js
index ae1ba0c5ca77f89b745d574da6d9f0c44d7013e1..b411c425e4e4a1a21d063b31fec6d81c61e9c913 100644
--- a/entity/Contract_entity/entityfields/contractend/onValueChange.js
+++ b/entity/Contract_entity/entityfields/contractend/onValueChange.js
@@ -1,7 +1,8 @@
 import("system.vars");
 import("Util_lib");
+import("Entity_lib");
 
-var cEnd = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.CONTRACTEND"));
+var cEnd = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.CONTRACTEND"));
 var cDue = vars.get("$field.CONTRACTDUE");
 
 if (cDue > cEnd && cDue != "")
diff --git a/entity/Contract_entity/entityfields/contractstart/onValidation.js b/entity/Contract_entity/entityfields/contractstart/onValidation.js
index 4ebb606eceef9c7f65fe763bb1ac5f1c62430f39..f7e82b3fd8a66a24591a7fb75a849799a3755ad4 100644
--- a/entity/Contract_entity/entityfields/contractstart/onValidation.js
+++ b/entity/Contract_entity/entityfields/contractstart/onValidation.js
@@ -3,10 +3,10 @@ import("system.result");
 import("system.vars");
 import("Date_lib");
 import("Util_lib");
+import("Entity_lib");
 
-var dateUtils = new DateUtils();
-var cStart = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.CONTRACTSTART"));
+var cStart = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.CONTRACTSTART"));
 var cDue = vars.get("$field.CONTRACTDUE");
 
-if (dateUtils.validateBeginnBeforeEnd(cStart, vars.get("$field.CONTRACTEND")) === false)
-    result.string(dateUtils.getValidationFailString());
\ No newline at end of file
+if (DateUtils.validateBeginnBeforeEnd(cStart, vars.get("$field.CONTRACTEND")) === false)
+    result.string(DateUtils.getValidationFailString());
\ No newline at end of file
diff --git a/entity/Contract_entity/entityfields/contractstart/onValueChange.js b/entity/Contract_entity/entityfields/contractstart/onValueChange.js
index 2e58cfbebf5c3583bb3f18ffcc1a3d9e80b542e5..f2e29fdda8f9227616cd3dc7f3879867b2bfbaa8 100644
--- a/entity/Contract_entity/entityfields/contractstart/onValueChange.js
+++ b/entity/Contract_entity/entityfields/contractstart/onValueChange.js
@@ -1,7 +1,8 @@
 import("system.vars");
 import("Util_lib");
+import("Entity_lib");
 
-var cStart = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.CONTRACTSTART"));
+var cStart = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.CONTRACTSTART"));
 var cDue = vars.get("$field.CONTRACTDUE");
 
 if (cDue < cStart && cDue != "")
diff --git a/entity/Offer_entity/Offer_entity.aod b/entity/Offer_entity/Offer_entity.aod
index d159a36c18531a46cfa2bbf9f4ae93895ea75c3a..fb017884871b067886006739a58eb23b9aed8941 100644
--- a/entity/Offer_entity/Offer_entity.aod
+++ b/entity/Offer_entity/Offer_entity.aod
@@ -3,6 +3,7 @@
   <name>Offer_entity</name>
   <title>Offer</title>
   <majorModelMode>DISTRIBUTED</majorModelMode>
+  <documentation>%aditoprj%/entity/Offer_entity/documentation.adoc</documentation>
   <grantUpdateProcess>%aditoprj%/entity/Offer_entity/grantUpdateProcess.js</grantUpdateProcess>
   <grantDeleteProcess>%aditoprj%/entity/Offer_entity/grantDeleteProcess.js</grantDeleteProcess>
   <recordContainerType>DB</recordContainerType>
@@ -37,6 +38,7 @@
     </entityField>
     <entityField>
       <name>OFFERCODE</name>
+      <documentation>%aditoprj%/entity/Offer_entity/entityfields/offercode/documentation.adoc</documentation>
       <title>Offer number</title>
       <tableName>OFFER</tableName>
       <columnName>OFFERCODE</columnName>
@@ -69,6 +71,7 @@
     </entityField>
     <entityField>
       <name>RELATION_ID</name>
+      <documentation>%aditoprj%/entity/Offer_entity/entityfields/relation_id/documentation.adoc</documentation>
       <title>Contact / Company</title>
       <tableName>OFFER</tableName>
       <columnName>RELATION_ID</columnName>
@@ -182,6 +185,7 @@
     </entityField>
     <entityField>
       <name>TotalGross</name>
+      <documentation>%aditoprj%/entity/Offer_entity/entityfields/totalgross/documentation.adoc</documentation>
       <title>Total gross</title>
       <state>READONLY</state>
       <valueProcess>%aditoprj%/entity/Offer_entity/entityfields/totalgross/valueProcess.js</valueProcess>
@@ -222,6 +226,7 @@
     </entityActionField>
     <entityField>
       <name>VERSNR</name>
+      <documentation>%aditoprj%/entity/Offer_entity/entityfields/versnr/documentation.adoc</documentation>
       <title>Vers. no.</title>
       <tableName>OFFER</tableName>
       <columnName>VERSNR</columnName>
@@ -230,6 +235,7 @@
     </entityField>
     <entityField>
       <name>OFFER_ID</name>
+      <documentation>%aditoprj%/entity/Offer_entity/entityfields/offer_id/documentation.adoc</documentation>
     </entityField>
     <entityFieldGroup>
       <name>OfferCode_VersNr</name>
diff --git a/entity/Offer_entity/documentation.adoc b/entity/Offer_entity/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..c11de6b80022e744fb25f0e547aa69c66eeb3d00
--- /dev/null
+++ b/entity/Offer_entity/documentation.adoc
@@ -0,0 +1,15 @@
+= OFFER
+
+:hardbreaks:
+
+Entity contains meta data of the Offer module.
+It provides data from database table _OFFER_.
+
+== Actions
+
+* _Copy offer_: All values, offeritems included, are copyed and inserted in a new offer (new offer code, versnr. _1_).
+* _New offer version_: All values, offeritems included, are copyed and inserted in a **new offer version** (versnr. + _1_).
+
+== Submodules
+
+* Offeritem
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/newoffer/onActionProcess.js b/entity/Offer_entity/entityfields/newoffer/onActionProcess.js
index 8d44f51deacd1ece4560b02cdb57803cb104cdfa..46d81aed97b3bd2e86b855020476b9a11e0618b1 100644
--- a/entity/Offer_entity/entityfields/newoffer/onActionProcess.js
+++ b/entity/Offer_entity/entityfields/newoffer/onActionProcess.js
@@ -2,9 +2,9 @@ import("system.logging");
 import("system.vars");
 import("system.neon");
 import("Util_lib");
+import("Neon_lib");
 import("OfferOrder_lib");
 
-var CMUtils = new CopyModuleUtils();
 var offUtils = new OfferUtils();
 
 var InputMapping = {
@@ -24,6 +24,6 @@ var InputMapping = {
     }
 }
 
-var ModulesMapping = CMUtils.copyModule(InputMapping);
+var ModulesMapping = CopyModuleUtils.copyModule(InputMapping);
 
-CMUtils.openNewModules("Offer_context", ModulesMapping);
\ No newline at end of file
+CopyModuleUtils.openNewModules("Offer_context", ModulesMapping);
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/newofferversion/onActionProcess.js b/entity/Offer_entity/entityfields/newofferversion/onActionProcess.js
index 60eaab09684e3967b9b0c72763695ccb5a88464c..7482f38129f497c9040811e120752578a9498a44 100644
--- a/entity/Offer_entity/entityfields/newofferversion/onActionProcess.js
+++ b/entity/Offer_entity/entityfields/newofferversion/onActionProcess.js
@@ -2,9 +2,9 @@ import("system.logging");
 import("system.vars");
 import("system.neon");
 import("Util_lib");
+import("Neon_lib");
 import("OfferOrder_lib");
 
-var CMUtils = new CopyModuleUtils();
 var offUtils = new OfferUtils();
 
 var InputMapping = {
@@ -24,6 +24,6 @@ var InputMapping = {
     }
 }
 
-var ModulesMapping = CMUtils.copyModule(InputMapping);
+var ModulesMapping = CopyModuleUtils.copyModule(InputMapping);
 
-CMUtils.openNewModules("Offer_context", ModulesMapping);
\ No newline at end of file
+CopyModuleUtils.openNewModules("Offer_context", ModulesMapping);
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/offer_id/documentation.adoc b/entity/Offer_entity/entityfields/offer_id/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..45c579ffee22ce5cfa74223c23851653a2bb8750
--- /dev/null
+++ b/entity/Offer_entity/entityfields/offer_id/documentation.adoc
@@ -0,0 +1,4 @@
+= OFFER_ID
+:hardbreaks:
+
+This field contains link information to previous offer version.
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/offercode/documentation.adoc b/entity/Offer_entity/entityfields/offercode/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..019d2f6339229de4bf8ba5b485bcba702cb0c6cb
--- /dev/null
+++ b/entity/Offer_entity/entityfields/offercode/documentation.adoc
@@ -0,0 +1,5 @@
+= OFFERCODE
+:hardbreaks:
+
+Unique identification number of the offer.
+It's automatically generated from the starting number _1000_.
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/offercode/onValidation.js b/entity/Offer_entity/entityfields/offercode/onValidation.js
index c2f733568d6821237b66fdd31a38a894370a3d18..63c353b420b443050d33dc23602eda47a08da9c8 100644
--- a/entity/Offer_entity/entityfields/offercode/onValidation.js
+++ b/entity/Offer_entity/entityfields/offercode/onValidation.js
@@ -3,11 +3,12 @@ import("system.result");
 import("system.neon");
 import("OfferOrder_lib");
 import("Util_lib");
+import("Entity_lib");
 
 var OfferUtils = new OfferUtils();
 
 if( vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW
-    && !OfferUtils.validateOfferNumber(ProcessHandlingUtil.getOnValidationValue(vars.get("$field.OFFERCODE"))) )
+    && !OfferUtils.validateOfferNumber(ProcessHandlingUtils.getOnValidationValue(vars.get("$field.OFFERCODE"))) )
 {
     vars.set( "$field.OFFERCODE", SalesprojectUtils.getNextOfferNumber().toString() );
 }
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/offerdate/valueProcess.js b/entity/Offer_entity/entityfields/offerdate/valueProcess.js
index af2c1f09cc605dfe6664dd0c9829026fc6785993..aeddd594f71497dedb45c4c73862b6c4dd78d440 100644
--- a/entity/Offer_entity/entityfields/offerdate/valueProcess.js
+++ b/entity/Offer_entity/entityfields/offerdate/valueProcess.js
@@ -5,7 +5,6 @@ import("Date_lib");
 
 if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW && vars.get("$this.value") == "")
 {
-    var DateUtils = new DateUtils();
     result.string(DateUtils.getTodayUTC());
 }
 else
diff --git a/entity/Offer_entity/entityfields/relation_id/documentation.adoc b/entity/Offer_entity/entityfields/relation_id/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..e978c88ef79f2554ac4731f7d4c3eb17aa50ea8b
--- /dev/null
+++ b/entity/Offer_entity/entityfields/relation_id/documentation.adoc
@@ -0,0 +1,10 @@
+= RELATION_ID
+:hardbreaks:
+
+Over this field the company or contact person of customer is linked.
+
+== onValueChange
+
+If set in the selected company or contact person, the following field value are taken over:
+
+* LANGUAGE
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/relation_id/onValueChange.js b/entity/Offer_entity/entityfields/relation_id/onValueChange.js
index 4c3220606c52acb4eb2ee09d69427060bbd987e8..9e8a557d9112443d5bb050c2df798542b21dbbd4 100644
--- a/entity/Offer_entity/entityfields/relation_id/onValueChange.js
+++ b/entity/Offer_entity/entityfields/relation_id/onValueChange.js
@@ -1,8 +1,9 @@
 import("system.vars");
 import("system.db");
 import("Util_lib");
+import("Entity_lib");
 
-var relid = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.RELATION_ID"));
+var relid = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.RELATION_ID"));
 if(relid != "")
 {
     var relData = db.array(db.ROW, "select LANGUAGE from RELATION where RELATIONID = '" + relid + "'");
diff --git a/entity/Offer_entity/entityfields/totalgross/documentation.adoc b/entity/Offer_entity/entityfields/totalgross/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..c727abed66886d38bd46c6df6e1045b82666eb30
--- /dev/null
+++ b/entity/Offer_entity/entityfields/totalgross/documentation.adoc
@@ -0,0 +1,6 @@
+= TotalGross
+:hardbreaks:
+
+Contains the total gross of the offer (net).
+This is calculated as follows: _NET_ + _VAT_.
+Both are calculated in *_Offeritem_entity_* at _onDBInsert_, _onDBUpdate_ and _onDBDelete_.
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/versnr/documentation.adoc b/entity/Offer_entity/entityfields/versnr/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..0d9cdfe8dd6e5f417025786617c8df67e43d9520
--- /dev/null
+++ b/entity/Offer_entity/entityfields/versnr/documentation.adoc
@@ -0,0 +1,8 @@
+= VERSNR
+:hardbreaks:
+
+Additional to the offercode there's a version number.
+By default it contains the value _1_.
+
+A new offer version can be created over the action _newOfferVersion_.
+Then the new value is the old one incremented by _1_.
\ No newline at end of file
diff --git a/entity/Offeritem_entity/Offeritem_entity.aod b/entity/Offeritem_entity/Offeritem_entity.aod
index f9636b1e8709caf576c908bcba3680a4458bf93e..dfa1a79e76789c678181e5b94f12d8387578636b 100644
--- a/entity/Offeritem_entity/Offeritem_entity.aod
+++ b/entity/Offeritem_entity/Offeritem_entity.aod
@@ -3,6 +3,7 @@
   <name>Offeritem_entity</name>
   <title>Offeritem</title>
   <majorModelMode>DISTRIBUTED</majorModelMode>
+  <documentation>%aditoprj%/entity/Offeritem_entity/documentation.adoc</documentation>
   <grantCreateProcess>%aditoprj%/entity/Offeritem_entity/grantCreateProcess.js</grantCreateProcess>
   <grantUpdateProcess>%aditoprj%/entity/Offeritem_entity/grantUpdateProcess.js</grantUpdateProcess>
   <grantDeleteProcess>%aditoprj%/entity/Offeritem_entity/grantDeleteProcess.js</grantDeleteProcess>
@@ -117,15 +118,16 @@
     </entityField>
     <entityField>
       <name>PRODUCT_ID</name>
+      <documentation>%aditoprj%/entity/Offeritem_entity/entityfields/product_id/documentation.adoc</documentation>
       <title>Article</title>
       <tableName>OFFERITEM</tableName>
       <columnName>PRODUCT_ID</columnName>
       <possibleItemsProcess>%aditoprj%/entity/Offeritem_entity/entityfields/product_id/possibleItemsProcess.js</possibleItemsProcess>
-      <onValidation>%aditoprj%/entity/Offeritem_entity/entityfields/product_id/onValidation.js</onValidation>
       <onValueChange>%aditoprj%/entity/Offeritem_entity/entityfields/product_id/onValueChange.js</onValueChange>
     </entityField>
     <entityField>
       <name>QUANTITY</name>
+      <documentation>%aditoprj%/entity/Offeritem_entity/entityfields/quantity/documentation.adoc</documentation>
       <title>Quantity</title>
       <tableName>OFFERITEM</tableName>
       <columnName>QUANTITY</columnName>
@@ -180,6 +182,7 @@
     </entityParameter>
     <entityField>
       <name>TotalPrice</name>
+      <documentation>%aditoprj%/entity/Offeritem_entity/entityfields/totalprice/documentation.adoc</documentation>
       <title>Sum</title>
       <contentType>NUMBER</contentType>
       <outputFormat>#,##0.00</outputFormat>
diff --git a/entity/Offeritem_entity/documentation.adoc b/entity/Offeritem_entity/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..a5283456a0759e860a058690aeb402321c2779ec
--- /dev/null
+++ b/entity/Offeritem_entity/documentation.adoc
@@ -0,0 +1,21 @@
+= OFFERITEM
+:hardbreaks:
+
+Entity contains products that belong to the linked offer.
+It provides data from database table _OFFERITEM_ by a JDito record container.
+
+== onDBInsert
+
+If a new offer item is to be added, the parts list of the corresponding product 
+is inserted at the same time. A new item is created for each product.
+The net sum in the linked offer is updated.
+
+== onDBUpdate
+
+The net sum in the linked offer is updated.
+
+
+== onDBDelete
+
+Before deletion of an item, its subordinated items are also deleted.
+The net sum in the linked offer is updated.
\ No newline at end of file
diff --git a/entity/Offeritem_entity/entityfields/product_id/documentation.adoc b/entity/Offeritem_entity/entityfields/product_id/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..5d6ffbd8dd98f0a218cec7b0d8a0228b1e65b94e
--- /dev/null
+++ b/entity/Offeritem_entity/entityfields/product_id/documentation.adoc
@@ -0,0 +1,14 @@
+= PRODUCT_ID
+:hardbreaks:
+
+Contains link to selected product for this item.
+
+== onValueChange
+
+The following field are set with the values from the selected product:
+
+* GROUPCODEID
+* UNIT
+* ITEMNAME
+* PRICE & VAT: Values from the current valid price list defined to this product. 
+  For futher informations see the comments in method __getPriceListToUse_ in _Product_lib_.
\ No newline at end of file
diff --git a/entity/Offeritem_entity/entityfields/product_id/onValidation.js b/entity/Offeritem_entity/entityfields/product_id/onValidation.js
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/entity/Offeritem_entity/entityfields/product_id/onValueChange.js b/entity/Offeritem_entity/entityfields/product_id/onValueChange.js
index 196b4ab169ea3cbfdb3f6e1feb6d341ce6a008ae..252419a862f0599a975424643fd12bd2a60f1958 100644
--- a/entity/Offeritem_entity/entityfields/product_id/onValueChange.js
+++ b/entity/Offeritem_entity/entityfields/product_id/onValueChange.js
@@ -3,8 +3,9 @@ import("system.vars");
 import("system.neon");
 import("Product_lib");
 import("Util_lib");
+import("Entity_lib");
 
-var pid = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.PRODUCT_ID"));
+var pid = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.PRODUCT_ID"));
 if(pid != "")
 {
     var curr = vars.exists("$param.Currency_param") ? vars.get("$param.Currency_param") : "";
diff --git a/entity/Offeritem_entity/entityfields/quantity/documentation.adoc b/entity/Offeritem_entity/entityfields/quantity/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..5f7419c93c2913f83e1e1ab76f14dd1f03e49d2c
--- /dev/null
+++ b/entity/Offeritem_entity/entityfields/quantity/documentation.adoc
@@ -0,0 +1,9 @@
+= QUANTITY
+:hardbreaks:
+
+Quantity of selected product in this item.
+
+== onValueChange
+
+The fields PRICE & VAT are set by changing quantity when a product has already been selected.
+The reason for this is that you can define a quantity as of which price lists are valid.
\ No newline at end of file
diff --git a/entity/Offeritem_entity/entityfields/quantity/onValueChange.js b/entity/Offeritem_entity/entityfields/quantity/onValueChange.js
index d605b64c6f8ad78ba76189a0333d426011f7e337..aedc968cc70beb0c78061c5d2848f9fcc89caed3 100644
--- a/entity/Offeritem_entity/entityfields/quantity/onValueChange.js
+++ b/entity/Offeritem_entity/entityfields/quantity/onValueChange.js
@@ -3,9 +3,10 @@ import("system.vars");
 import("system.neon");
 import("Product_lib");
 import("Util_lib");
+import("Entity_lib");
 
 var pid = vars.get("$field.PRODUCT_ID");
-var newQuantity = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.QUANTITY"));
+var newQuantity = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.QUANTITY"));
 if(pid != "" && newQuantity != "")
 {
     var curr = vars.exists("$param.Currency_param") ? vars.get("$param.Currency_param") : "";
diff --git a/entity/Offeritem_entity/entityfields/totalprice/documentation.adoc b/entity/Offeritem_entity/entityfields/totalprice/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..481fb639fb88ae3d95aa88fa8cf0cee9160dc2e5
--- /dev/null
+++ b/entity/Offeritem_entity/entityfields/totalprice/documentation.adoc
@@ -0,0 +1,5 @@
+= TotalPrice
+:hardbreaks:
+
+Contains the total price of the item.
+This is calculated as follows: _QUANTITY_ * _PRICE_ * (100 - _DISCOUNT_) / 100
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/Prod2prod_entity.aod b/entity/Prod2prod_entity/Prod2prod_entity.aod
index 5966912c271c770f8c6f9f04cb4b9bfc3f8e9a5b..ce05f40bd6b8211c3c09efc9b048a706a6fbf6c1 100644
--- a/entity/Prod2prod_entity/Prod2prod_entity.aod
+++ b/entity/Prod2prod_entity/Prod2prod_entity.aod
@@ -2,6 +2,7 @@
 <entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.5" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.0.5">
   <name>Prod2prod_entity</name>
   <majorModelMode>DISTRIBUTED</majorModelMode>
+  <documentation>%aditoprj%/entity/Prod2prod_entity/documentation.adoc</documentation>
   <externalOpenAction>%aditoprj%/entity/Prod2prod_entity/externalOpenAction.js</externalOpenAction>
   <recordContainerType>JDITO</recordContainerType>
   <alias>Data_alias</alias>
@@ -49,6 +50,7 @@
     </entityField>
     <entityField>
       <name>DEST_ID</name>
+      <documentation>%aditoprj%/entity/Prod2prod_entity/entityfields/dest_id/documentation.adoc</documentation>
       <tableName></tableName>
       <columnName></columnName>
       <fieldName>DEST_ID</fieldName>
@@ -81,6 +83,7 @@
     </entityField>
     <entityField>
       <name>SOURCE_ID</name>
+      <documentation>%aditoprj%/entity/Prod2prod_entity/entityfields/source_id/documentation.adoc</documentation>
       <title>Product</title>
       <tableName></tableName>
       <columnName></columnName>
@@ -90,6 +93,7 @@
     </entityField>
     <entityField>
       <name>TAKEPRICE</name>
+      <documentation>%aditoprj%/entity/Prod2prod_entity/entityfields/takeprice/documentation.adoc</documentation>
       <title>Price</title>
       <tableName></tableName>
       <columnName></columnName>
diff --git a/entity/Prod2prod_entity/documentation.adoc b/entity/Prod2prod_entity/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..59bbbae97ad3a477420b71e111fac26c5dada832
--- /dev/null
+++ b/entity/Prod2prod_entity/documentation.adoc
@@ -0,0 +1,34 @@
+= Prod2prod_entity
+:hardbreaks:
+
+Entity contains links between products.
+It provides data from database table _PROD2PROD_.
+
+The record container loads the parts list of the passed product.
+This means which sub-products this product consists of.
+
+A possible **definiton** for a parts list is:
+
+[quote, McGraw-Hill Dictionary of Scientific & Technical Terms, 6E. S.v. "parts list." Retrieved November 26 2018 from https://encyclopedia2.thefreedictionary.com/parts+list]
+____
+One or more printed sheets showing a manufacturer's parts or assemblies of an end item by illustration or a numerical listing of part numbers and names; it does not outline any assembly, maintenance, or operating instructions, and it may or may not have a price list cover sheet.
+____
+
+Database table _PROD2PROD_ contains the two foreign key columns _DEST_ID_ and _SOURCE_ID_.
+Both contain a _PRODUCTID_. The following visualization clarifies the structure of a parts list.
+
+++++
+<img src="data:image/png;base64,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" style="cursor:pointer;max-width:100%;" onclick="(function(img){if(img.wnd!=null&&!img.wnd.closed){img.wnd.focus();}else{var r=function(evt){if(evt.data=='ready'&&evt.source==img.wnd){img.wnd.postMessage(decodeURIComponent(img.getAttribute('src')),'*');window.removeEventListener('message',r);}};window.addEventListener('message',r);img.wnd=window.open('https://www.draw.io/?client=1&lightbox=1&edit=_blank');}})(this);"/>
+++++
+
+////
+How to edit this diagram:
+1. copy complete <img> tag from above
+2. paste it into text editor and save it as a html file
+3. open html file with browser
+4. click on the diagram
+5. at the bottom of the page you can start edit mode
+6. edit diagram on draw.io
+7. get <img> tag of the diagram with File -> Embed -> Image
+8. replace tag above
+////
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/dest_id/documentation.adoc b/entity/Prod2prod_entity/entityfields/dest_id/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..34ed7bcc2d426001e59818f56d45016fdb521c6e
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/dest_id/documentation.adoc
@@ -0,0 +1,7 @@
+= DEST_ID
+:hardbreaks:
+
+This column contains link information (foreign key) to the product to which it is a part of (parent).
+
+== Preset New
+The system defaults to the passed value of the parameter _ProductId_param_.
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/optional/documentation.adoc b/entity/Prod2prod_entity/entityfields/optional/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..3ca64e8047d84398535b3cfa2d20919c5ecd4e25
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/optional/documentation.adoc
@@ -0,0 +1,4 @@
+= OPTIONAL
+:hardbreaks:
+
+Flag for offer / order. The value is taken over in offer / order.
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/source_id/documentation.adoc b/entity/Prod2prod_entity/entityfields/source_id/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..59dcd2e0f4c01785c34f531b3f43bd54235841f6
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/source_id/documentation.adoc
@@ -0,0 +1,8 @@
+= SOURCE_ID
+:hardbreaks:
+
+This column contains link information (foreign key) to the partial product. (child)
+ 
+== value list
+Listed are all products which are **not already part of** parts list.
+This means each product recursively appears in _DEST_ID_ or _SOURCE_ID_ of the current product passed by parameter _ProductId_param_ **is excluded**.
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/takeprice/documentation.adoc b/entity/Prod2prod_entity/entityfields/takeprice/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..eb617876677f893ff5d953b92f7cd5cff145f60e
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/takeprice/documentation.adoc
@@ -0,0 +1,4 @@
+= TAKEPRICE
+:hardbreaks:
+
+Flag for offer / order. If set the current valid price list to this product is taken over in offer / order.
\ No newline at end of file
diff --git a/entity/Product_entity/Product_entity.aod b/entity/Product_entity/Product_entity.aod
index 439bbabafd0959b155035cc79d979774c422fcfe..c0010e3e41a6303993fb2d67197ca7e828b0ff60 100644
--- a/entity/Product_entity/Product_entity.aod
+++ b/entity/Product_entity/Product_entity.aod
@@ -3,6 +3,7 @@
   <name>Product_entity</name>
   <title>Product</title>
   <majorModelMode>DISTRIBUTED</majorModelMode>
+  <documentation>%aditoprj%/entity/Product_entity/documentation.adoc</documentation>
   <recordContainerType>DB</recordContainerType>
   <iconId>VAADIN:HAMMER</iconId>
   <alias>Data_alias</alias>
@@ -60,6 +61,7 @@
     </entityField>
     <entityField>
       <name>PRODUCTCODE</name>
+      <documentation>%aditoprj%/entity/Product_entity/entityfields/productcode/documentation.adoc</documentation>
       <title>Product number</title>
       <tableName>PRODUCT</tableName>
       <columnName>PRODUCTCODE</columnName>
diff --git a/entity/Product_entity/documentation.adoc b/entity/Product_entity/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..ccd3865898d44c3d0ebd4b3bd46633d4f84b8bf1
--- /dev/null
+++ b/entity/Product_entity/documentation.adoc
@@ -0,0 +1,12 @@
+= PRODUCT
+
+:hardbreaks:
+
+Entity contains meta data of the Product module.
+It provides data from database table _PRODUCT_.
+
+== Submodules
+
+* Parts list (Prod2Prod)
+* Product price
+* Stock
\ No newline at end of file
diff --git a/entity/Product_entity/entityfields/productcode/documentation.adoc b/entity/Product_entity/entityfields/productcode/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..e3dd7742201c099ba3c7af84b92d80b5c9444479
--- /dev/null
+++ b/entity/Product_entity/entityfields/productcode/documentation.adoc
@@ -0,0 +1,4 @@
+= PRODUCTCODE
+:hardbreaks:
+
+Unique identification number of the product. (max. 30 characters, not automatically generated)
\ No newline at end of file
diff --git a/entity/Product_entity/entityfields/productcode/onValidation.js b/entity/Product_entity/entityfields/productcode/onValidation.js
index b72108499db871aa2345dd05649f4cf0178edbc5..1dc5b4f996393023dd1f9e0f4070aad491cf515b 100644
--- a/entity/Product_entity/entityfields/productcode/onValidation.js
+++ b/entity/Product_entity/entityfields/productcode/onValidation.js
@@ -3,8 +3,12 @@ import("system.result");
 import("system.vars");
 import("system.db");
 import("Util_lib");
+import("Entity_lib");
 
-var codeCount = db.cell("select count(PRODUCTCODE) from PRODUCT where PRODUCTCODE = '" + ProcessHandlingUtil.getOnValidationValue(vars.get("$field.PRODUCTCODE")) + "'"
+var codeCount, productCode;
+
+productCode = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.PRODUCTCODE"));
+codeCount = db.cell("select count(PRODUCTCODE) from PRODUCT where PRODUCTCODE = '" + productCode + "'"
                        + " and PRODUCTID <> '" + vars.get("$field.PRODUCTID") + "'");
 if(codeCount > 0)
 {
diff --git a/entity/Productprice_entity/Productprice_entity.aod b/entity/Productprice_entity/Productprice_entity.aod
index 0897e500a76be11b22381413ef3a4c312199ea08..039922c708f81775e5285feb0d1fd9cc8af6af88 100644
--- a/entity/Productprice_entity/Productprice_entity.aod
+++ b/entity/Productprice_entity/Productprice_entity.aod
@@ -135,9 +135,11 @@
     </entityField>
     <entityField>
       <name>PRICELIST</name>
+      <documentation>%aditoprj%/entity/Productprice_entity/entityfields/pricelist/documentation.adoc</documentation>
       <title>Price list</title>
       <tableName>PRODUCTPRICE</tableName>
       <columnName>PRICELIST</columnName>
+      <mandatoryProcess>%aditoprj%/entity/Productprice_entity/entityfields/pricelist/mandatoryProcess.js</mandatoryProcess>
       <possibleItemsProcess>%aditoprj%/entity/Productprice_entity/entityfields/pricelist/possibleItemsProcess.js</possibleItemsProcess>
       <state>AUTO</state>
       <stateProcess>%aditoprj%/entity/Productprice_entity/entityfields/pricelist/stateProcess.js</stateProcess>
diff --git a/entity/Productprice_entity/documentation.adoc b/entity/Productprice_entity/documentation.adoc
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cb6558ccb5adeee75778e6e5e83b152b94f590c7 100644
--- a/entity/Productprice_entity/documentation.adoc
+++ b/entity/Productprice_entity/documentation.adoc
@@ -0,0 +1,15 @@
+= PRODUCTPRICE
+
+:hardbreaks:
+
+Entity contains price lists for the linked product.
+It provides data from database table _PRODUCTPRICE_.
+
+== New price list via product
+
+By creation via product you have to select a price list type using the field _PRICELIST_.
+
+== New price list via organisation (custom price list)
+
+By creation via an organisation you don't have do select a price list type because
+it's a custom price list \-> field _RELATION_ID_ is filled automatically by parameter _Relation_Id_param_.
\ No newline at end of file
diff --git a/entity/Productprice_entity/entityfields/pricelist/documentation.adoc b/entity/Productprice_entity/entityfields/pricelist/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..777173dda73190f975c75f5475f8f7a31b4d7bfb
--- /dev/null
+++ b/entity/Productprice_entity/entityfields/pricelist/documentation.adoc
@@ -0,0 +1,18 @@
+= PRICELIST
+
+:hardbreaks:
+
+Field indicates the type of the price list.
+
+== onValidation
+
+There's a **verficiation** for current pricelist whether an **identical price list already exists** for product.
+The following criteria will be checked in function _ProductUtils.checkForIndenticalPriceLists()_:
+
+* Identical price list type
+* Identical from quantity
+* Identical currency
+* Identical purchase price/sales price
+* Idcentical Valid from and valid to OR 
+
+If all criteria are fulfilled, price list can not be saved.
\ No newline at end of file
diff --git a/entity/Productprice_entity/entityfields/pricelist/mandatoryProcess.js b/entity/Productprice_entity/entityfields/pricelist/mandatoryProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..6db2c72b17a7335446e477540a3117ae5704fa35
--- /dev/null
+++ b/entity/Productprice_entity/entityfields/pricelist/mandatoryProcess.js
@@ -0,0 +1,7 @@
+import("system.vars");
+import("system.result");
+
+if(vars.get("$field.RELATION_ID") != "")
+    result.string("false");
+else
+    result.string("true");
\ No newline at end of file
diff --git a/entity/Productprice_entity/entityfields/pricelist/onValidation.js b/entity/Productprice_entity/entityfields/pricelist/onValidation.js
index 4927c81bd892cc93dbb387a3f8a1407982471e41..280ee4e3e23eed2cd040d924b6db4a9d482935a0 100644
--- a/entity/Productprice_entity/entityfields/pricelist/onValidation.js
+++ b/entity/Productprice_entity/entityfields/pricelist/onValidation.js
@@ -3,10 +3,11 @@ import("system.result");
 import("system.vars");
 import("Product_lib");
 import("Util_lib");
+import("Entity_lib");
 
 var pUtils = new ProductUtils();
 var priceList = {
-                priceList: ProcessHandlingUtil.getOnValidationValue(vars.get("$field.PRICELIST"))
+                priceList: ProcessHandlingUtils.getOnValidationValue(vars.get("$field.PRICELIST"))
                 , fromQuantity: vars.get("$field.FROMQUANTITY")
                 , buySell: vars.get("$field.BUYSELL")
                 , currency: vars.get("$field.CURRENCY")
diff --git a/entity/Productprice_entity/entityfields/valid_from/onValidation.js b/entity/Productprice_entity/entityfields/valid_from/onValidation.js
index 74fa861f9bb6db8bcef42cc1ee335bd281fadac6..5ebbf1a7dccee4b0a58c46b478596bf326697184 100644
--- a/entity/Productprice_entity/entityfields/valid_from/onValidation.js
+++ b/entity/Productprice_entity/entityfields/valid_from/onValidation.js
@@ -2,9 +2,9 @@ import("system.result");
 import("system.vars");
 import("Date_lib");
 import("Util_lib");
+import("Entity_lib");
 
-var dateUtils = new DateUtils();
-var cStart = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.VALID_FROM"));
+var cStart = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.VALID_FROM"));
 
-if (dateUtils.validateBeginnBeforeEnd(cStart, vars.get("$field.VALID_TO")) === false)
-    result.string(dateUtils.getValidationFailString());
\ No newline at end of file
+if (DateUtils.validateBeginnBeforeEnd(cStart, vars.get("$field.VALID_TO")) === false)
+    result.string(DateUtils.getValidationFailString());
\ No newline at end of file
diff --git a/entity/Productprice_entity/entityfields/valid_to/onValidation.js b/entity/Productprice_entity/entityfields/valid_to/onValidation.js
index de9f15393fcf97ff4efb4edd960f4aea2a268d72..3ada2dd1e76e6dceb2b4c1dbf169bf91e0125579 100644
--- a/entity/Productprice_entity/entityfields/valid_to/onValidation.js
+++ b/entity/Productprice_entity/entityfields/valid_to/onValidation.js
@@ -2,9 +2,9 @@ import("system.result");
 import("system.vars");
 import("Date_lib");
 import("Util_lib");
+import("Entity_lib");
 
-var dateUtils = new DateUtils();
-var cEnd = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.VALID_TO"));
+var cEnd = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.VALID_TO"));
 
-if (dateUtils.validateBeginnBeforeEnd(vars.get("$field.VALID_FROM"), cEnd) === false)
-    result.string(dateUtils.getValidationFailString());
\ No newline at end of file
+if (DateUtils.validateBeginnBeforeEnd(vars.get("$field.VALID_FROM"), cEnd) === false)
+    result.string(DateUtils.getValidationFailString());
\ No newline at end of file
diff --git a/entity/SalesprojectCompetition_entity/entityfields/reason/onValidation.js b/entity/SalesprojectCompetition_entity/entityfields/reason/onValidation.js
index 6a13d6a1ca6838c022617f2face7ebe539efab78..dde86e982a4f580311473d37bdb9ee9c61c8dd77 100644
--- a/entity/SalesprojectCompetition_entity/entityfields/reason/onValidation.js
+++ b/entity/SalesprojectCompetition_entity/entityfields/reason/onValidation.js
@@ -2,8 +2,9 @@ import("system.result");
 import("system.vars");
 import("system.translate");
 import("Util_lib");
+import("Entity_lib");
 
-var reason = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.REASON"));
+var reason = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.REASON"));
 
 if (!vars.getString("$field.DATE_CANCELLED") && reason) {
     result.string(translate.text("A reason is only possible if a date is given."))
diff --git a/entity/Salesproject_entity/entityfields/enddate/valueProcess.js b/entity/Salesproject_entity/entityfields/enddate/valueProcess.js
index b27871853b658ad34b7de4e3e674d0a627c1617b..857933a9839949add7347dcccb862b6b40601dec 100644
--- a/entity/Salesproject_entity/entityfields/enddate/valueProcess.js
+++ b/entity/Salesproject_entity/entityfields/enddate/valueProcess.js
@@ -5,7 +5,6 @@ import("Date_lib");
 
 if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW && vars.get("$this.value") == "")
 {
-    var DateUtils = new DateUtils();
     result.string(DateUtils.getDateIncrementedByYears(DateUtils.getTodayUTC(), 1));
 }
 else
diff --git a/entity/Salesproject_entity/entityfields/projectcode/onValidation.js b/entity/Salesproject_entity/entityfields/projectcode/onValidation.js
index d98945cc17aabeb18d7213d3ebb8e6c408d0e6ac..1f7657c4feda5d0e61dd89fe7dccffa1043efb85 100644
--- a/entity/Salesproject_entity/entityfields/projectcode/onValidation.js
+++ b/entity/Salesproject_entity/entityfields/projectcode/onValidation.js
@@ -3,9 +3,10 @@ import("system.result");
 import("system.neon");
 import("Salesproject_lib");
 import("Util_lib");
+import("Entity_lib");
 
 if( vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW
-    && !Salesproject.validateProjectNumber(ProcessHandlingUtil.getOnValidationValue(vars.get("$field.PROJECTCODE"))) )
+    && !Salesproject.validateProjectNumber(ProcessHandlingUtils.getOnValidationValue(vars.get("$field.PROJECTCODE"))) )
 {
     vars.set( "$field.PROJECTCODE", Salesproject.getNextProjectNumber().toString("1 = 1") );
 }
\ No newline at end of file
diff --git a/entity/Salesproject_entity/entityfields/startdate/valueProcess.js b/entity/Salesproject_entity/entityfields/startdate/valueProcess.js
index af2c1f09cc605dfe6664dd0c9829026fc6785993..aeddd594f71497dedb45c4c73862b6c4dd78d440 100644
--- a/entity/Salesproject_entity/entityfields/startdate/valueProcess.js
+++ b/entity/Salesproject_entity/entityfields/startdate/valueProcess.js
@@ -5,7 +5,6 @@ import("Date_lib");
 
 if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW && vars.get("$this.value") == "")
 {
-    var DateUtils = new DateUtils();
     result.string(DateUtils.getTodayUTC());
 }
 else
diff --git a/entity/Stock_entity/Stock_entity.aod b/entity/Stock_entity/Stock_entity.aod
index 918140f62110b5d809333a1b3a4c7f677f4ee9d3..dfae4c28d432d6336ce785d7b4d71155351ba1a1 100644
--- a/entity/Stock_entity/Stock_entity.aod
+++ b/entity/Stock_entity/Stock_entity.aod
@@ -3,6 +3,7 @@
   <name>Stock_entity</name>
   <title>Stock</title>
   <majorModelMode>DISTRIBUTED</majorModelMode>
+  <documentation>%aditoprj%/entity/Stock_entity/documentation.adoc</documentation>
   <recordContainerType>DB</recordContainerType>
   <alias>Data_alias</alias>
   <conditionProcess>%aditoprj%/entity/Stock_entity/conditionProcess.js</conditionProcess>
diff --git a/entity/Stock_entity/documentation.adoc b/entity/Stock_entity/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..988a6942455abacabdd88bb4170f27b36ed446e5
--- /dev/null
+++ b/entity/Stock_entity/documentation.adoc
@@ -0,0 +1,6 @@
+= STOCK
+
+:hardbreaks:
+
+Entity contains stock for the linked product.
+It provides data from database table _STOCK_.
\ No newline at end of file
diff --git a/entity/Stock_entity/entityfields/stockcount/valueProcess.js b/entity/Stock_entity/entityfields/stockcount/valueProcess.js
index d5de29c8e34a1b58595736e30155324f168ff5b5..4c32e2524eda69478457c1979858e40229135cba 100644
--- a/entity/Stock_entity/entityfields/stockcount/valueProcess.js
+++ b/entity/Stock_entity/entityfields/stockcount/valueProcess.js
@@ -5,7 +5,7 @@ import("Product_lib");
 
 if(vars.exists("$param.ProductId_param") && vars.get("$param.ProductId_param") != "")
 {
-    var ProductUtils = new ProductUtils();
+    var pUtils = new ProductUtils();
 
-    result.string( ProductUtils.getStockCount(vars.get("$param.ProductId_param")) );
+    result.string( pUtils.getStockCount(vars.get("$param.ProductId_param")) );
 }
\ No newline at end of file
diff --git a/others/guide/how to write JDito code.adoc b/others/guide/how to write JDito code.adoc
index 7e71a092f62e6fdd0ee34c4c77d5e6be4ee5c6eb..79d6a489bccec838c897e390e6607cdb895c69b3 100644
--- a/others/guide/how to write JDito code.adoc	
+++ b/others/guide/how to write JDito code.adoc	
@@ -1,5 +1,5 @@
 How to write JDito code
-============================
+=======================
 :toc2: left
 :numbered:
 
@@ -26,11 +26,27 @@ data = vars.get.......
 Example:
 [source,javascript]
 ----
-for (i = 0, i < dataLen; i++){
+for (i = 0, i < dataLen; i++) {
     //code here
 }
 ----
 
+=== loops ===
+nested loops should be defined with replicated indexer variables (or with a good and describing name)
+
+Therefore it's easy to see in which level of the counter you are.
+
+Example:
+[source,javascript]
+----
+for (i = 0, i < dataLen; i++) {
+    for (ii = 0, ii < dataLen[i].length; ii++) {
+        //code...
+    }
+}
+----
+
+
 == defining different types of functions n libraries ==
 
 === by using static methods ===
diff --git a/others/guide/how to write a library.adoc b/others/guide/how to write a library.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..a3175cc3f706693f1bcf5664c997e095dd5362f4
--- /dev/null
+++ b/others/guide/how to write a library.adoc	
@@ -0,0 +1,110 @@
+How to write a JDito library
+============================
+:toc2: left
+:numbered:
+
+
+== defining different types of functions ==
+
+=== by using static methods ===
+This will be mostly utility functions and so on, where there is no need to instanciate an object. You'll need this probably the most time.
+
+
+Definition:
+[source,javascript]
+----
+/**
+ * provides static methods for validation of communication data
+ * do not create an instance of this
+ * @static
+ * @class
+ */
+function CommValidationUtil(){<1>
+}
+
+/**
+ * returns a blueprint for validation extensions; these extensions are needed for validating comm data and can be passed to other functions
+ * @return {object} a object with properties that have a specific default value; normally you want to overwrite that value
+ */
+CommValidationUtil.getExtensionsBlueprint = function(){<2>
+    return {
+        countryCode: null
+    };
+}
+----
+<1> the function-object that keeps everything together - this function should never be actually called (no direct call, no indirect call)
+<2> an actual function that can be called
+
+And how to use it:
+[source,javascript]
+----
+import("Comm_lib");
+
+var additionals = CommValidationUtil.getExtensionsBlueprint();
+----
+
+=== by creating an object with functions ===
+
+You may want to hold data and create objects where methods share that data. 
+
+Definition:
+[source,javascript]
+----
+/**
+ * object for easier handling of conditions; <1>
+ * With this object you do not have to check if the string is empty or not;
+ * you don't need to append a "1=1" condition or similar;
+ * this objects gains most benefit if you have a lot of conditions that are added (or not) depending on tons of JDito-conditions
+ * @class 
+ * @param {String} [alias=the current alias] the database alias where the condition shall be executed later (important for column types of preparedStatements) <2>
+ * @example //TODO: add missing example <3>
+ */
+function SqlCondition(alias){<4>
+   //setting null is only needed to provide autocomplete for the ADITO-designer
+    this.preparedValues = null;
+    this._init();//the properties are initalized in an extra function because init is nearly the same as resetting (clearing) the SqlConditions
+    this.alias = alias;
+}
+/**
+ * append with SQL-and; no paranthesize of existing conditions is done
+ * @param {String} cond the condition string which shall be appended
+ * @return {Object} current SqlCondition-object
+ */
+SqlCondition.prototype.and = function(cond){<5>
+    if (!cond)
+        return this;
+    if (this._sqlStorage)
+        this._sqlStorage += " and ";
+    this._sqlStorage += cond;
+    return this;
+}
+----
+
+<1> JS-Doc comment: http://usejsdoc.org/
+<2> use the correct form for optional/required parameters: http://usejsdoc.org/tags-param.html
+<3> examples are usefull on more complex functions
+<4> constructor function; init propiertes (do not set functions ("methods") here!)
+<5> add functions ("methods") to the prototype, they are available through the prototype chain
+
+And how to use it (normally you'd want to use preparedStatements but for the sake of an easy example it's a bit shorter here)
+[source,javascript]
+----
+import("system.vars");
+import("system.result");
+import("Sql_lib");
+import("Comm_lib");
+
+var cond, mediumIds, idVal;
+
+cond = new SqlCondition();
+
+mediumIds = CommExtensions.getContextualMediumIds();
+if (mediumIds.length > 0)
+    cond.and("COMM.MEDIUM_ID in (" + mediumIds.join(", ") + ")");
+
+idVal = vars.get("$local.idvalue");
+if (uids.length > 0)
+    cond.and("COMM.COMMID = '" + idVal + "' ");
+
+result.string(cond.toString("COMM.OPTIONAL = 't'"));
+----
\ No newline at end of file
diff --git a/process/Date_lib/process.js b/process/Date_lib/process.js
index 18a8c5d75a362aa1c4c552ee1cb394267be39062..b91e9b129d54a95f3e9c00c637daf7797da40f48 100644
--- a/process/Date_lib/process.js
+++ b/process/Date_lib/process.js
@@ -5,45 +5,44 @@ import("system.datetime");
  * provides methods for interactions with dates
  */
 function DateUtils(){
-    
-    var that = this;
-    /**
-     * Validates two date inputs (beginning should always be before the end!)
-     * 
-     * @param pStart {Number}
-     * @param pEnd {Number}
-     * 
-     * @result {Boolean|null} Boolean if it was able to check smth or null if the input values were not valid
-     */
-    this.validateBeginnBeforeEnd = function(pStart, pEnd) {
-        if (pStart == "" || pStart == null || pEnd == "" || pEnd == null) return null;
-        return pStart <= pEnd;
-    }
-    
-    this.getValidationFailString = function(){
-        return translate.text("The expiry date must be after the start date!");
-    }
-    
-    /**
-     * Delivers the current date at midnight in UTC
-     * 
-     * @result {Number} 
-     */
-    this.getTodayUTC = function(){
-        return datetime.today("UTC");
-    }
-    
-    /**
-     * Delivers the passed date incremented by passed years
-     * 
-     * @param pDate {Number}
-     * @param pYears {Number}
-     * 
-     * @result {Number} date incremented by years
-     */
-    this.getDateIncrementedByYears = function(pDate, pYears){
-        var dateObj = new Date(pDate);
-        
-        return dateObj.setFullYear(dateObj.getFullYear() + pYears);
-    }
+}
+
+/**
+ * Validates two date inputs (beginning should always be before the end!)
+ * 
+ * @param pStart {Number}
+ * @param pEnd {Number}
+ * 
+ * @result {Boolean|null} Boolean if it was able to check smth or null if the input values were not valid
+ */
+DateUtils.validateBeginnBeforeEnd = function(pStart, pEnd) {
+    if (pStart == "" || pStart == null || pEnd == "" || pEnd == null) return null;
+    return pStart <= pEnd;
+}
+
+DateUtils.getValidationFailString = function(){
+    return translate.text("The expiry date must be after the start date!");
+}
+
+/**
+ * Delivers the current date at midnight in UTC
+ * 
+ * @result {Number} 
+ */
+DateUtils.getTodayUTC = function(){
+    return datetime.today("UTC");
+}
+
+/**
+ * Delivers the passed date incremented by passed years
+ * 
+ * @param pDate {Number}
+ * @param pYears {Number}
+ * 
+ * @result {Number} date incremented by years
+ */
+DateUtils.getDateIncrementedByYears = function(pDate, pYears){
+    var dateObj = new Date(pDate);
+
+    return dateObj.setFullYear(dateObj.getFullYear() + pYears);
 }
\ No newline at end of file
diff --git a/process/Entity_lib/Entity_lib.aod b/process/Entity_lib/Entity_lib.aod
new file mode 100644
index 0000000000000000000000000000000000000000..d8eaf5d930b5b52d7ffac81d99591fbecf8dc56c
--- /dev/null
+++ b/process/Entity_lib/Entity_lib.aod
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.7" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.1.7">
+  <name>Entity_lib</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <process>%aditoprj%/process/Entity_lib/process.js</process>
+</process>
diff --git a/process/Entity_lib/process.js b/process/Entity_lib/process.js
new file mode 100644
index 0000000000000000000000000000000000000000..4c0e41ed076844b898fe86edc950773ceb3d1d15
--- /dev/null
+++ b/process/Entity_lib/process.js
@@ -0,0 +1,23 @@
+/**
+* provides static methods for special handling of entities in JDito-Processes
+* do not create an instance of this
+* @class
+* @static
+*/
+function ProcessHandlingUtils(){
+}
+
+/**
+* In onValidation-Process a local variable called "$local.value" is made available from kernel.
+* It contains the entered value - the field contains the value only after successfull validation (vars.get("$field.Fieldname")).
+* The onValidation-Process is running again before saving the entity, at this point there's "$local.value" varialbe no longer available,
+* but the entered value now is the present one because the field has already been validated before.
+* Otherwise a "variable not found" error would occur.
+*
+* @param {String} fieldValue value of the field onValidation-Process is executed ( e.g. vars.get("$field.Fieldname") )
+*
+* @return {String} Field value for onValidation-Process
+*/
+ProcessHandlingUtils.getOnValidationValue = function(fieldValue) {
+    return vars.exists("$local.value") ? vars.get("$local.value") : fieldValue;
+}
diff --git a/process/IndexSearch_lib/process.js b/process/IndexSearch_lib/process.js
index 355f73d542a6f979ef23dcc47be2b0f101f271da..87a8adbe541d58ccabc57c4e81b5238569e62327 100644
--- a/process/IndexSearch_lib/process.js
+++ b/process/IndexSearch_lib/process.js
@@ -1,61 +1,70 @@
-function IndexsearchUtils(){
-    this.getAffectedIdValues = function(fieldname, affectedInfoContainer, updateFn){
-        var affectedIds;
-        switch (affectedInfoContainer.action){
-            case "I":  
-                affectedIds = [affectedInfoContainer.newValues[affectedInfoContainer.columns.indexOf(fieldname)]];
-                break;
-            case "U":
-                affectedIds = updateFn.call(null, affectedInfoContainer.id);
-                break;
-            case "D":
-                affectedIds = [affectedInfoContainer.oldValues[affectedInfoContainer.columns.indexOf(fieldname)]];
-                break;
-        }
-        return affectedIds || [];
-    }
-    
-    this.createAffectedInfoContainer = function(changedIdValue, changedTable, action, columnsFn, oldValueFn, newValueFn){
-        var res, internalStorage;
-        internalStorage = {};
-        res = {
-             id: changedIdValue
-            ,table: changedTable
-            ,action: action
-            ,columns: null //null for autocomplete in the ADITO-designer
-            ,oldValues: null 
-            ,newValues: null
-        };
-        Object.defineProperty(res, "columns", {
-            get: function(){
-                if (internalStorage["columns"] == undefined)
-                    internalStorage["columns"] = columnsFn.call(null);
-                return internalStorage["columns"];
-            }
-            ,set: function (v){
-                internalStorage["columns"] = v;
-            }
-        });
-        Object.defineProperty(res, "oldValues", {
-            get: function(){
-                if (internalStorage["oldValues"] == undefined)
-                    internalStorage["oldValues"] = oldValueFn.call(null);
-                return internalStorage["oldValues"];
-            }
-            ,set: function (v){
-                internalStorage["oldValues"] = v;
-            }
-        });
-        Object.defineProperty(res, "newValues", {
-            get: function(){
-                if (internalStorage["newValues"] == undefined)
-                    internalStorage["newValues"] = newValueFn.call(null);
-                return internalStorage["newValues"];
-            }
-            ,set: function (v){
-                internalStorage["newValues"] = v;
-            }
-        });
-        return res;
-    }
+/**
+* provides static methods for special handling of entities in JDito-Processes
+* do not create an instance of this
+* @class
+* @static
+*/
+function IndexsearchUtils(){
+}
+
+//todo: comment
+IndexsearchUtils.getAffectedIdValues = function(fieldname, affectedInfoContainer, updateFn) {
+    var affectedIds;
+    switch (affectedInfoContainer.action){
+        case "I":  
+            affectedIds = [affectedInfoContainer.newValues[affectedInfoContainer.columns.indexOf(fieldname)]];
+            break;
+        case "U":
+            affectedIds = updateFn.call(null, affectedInfoContainer.id);
+            break;
+        case "D":
+            affectedIds = [affectedInfoContainer.oldValues[affectedInfoContainer.columns.indexOf(fieldname)]];
+            break;
+    }
+    return affectedIds || [];
+}
+
+//todo: comment
+IndexsearchUtils.createAffectedInfoContainer = function(changedIdValue, changedTable, action, columnsFn, oldValueFn, newValueFn) {
+    var res, internalStorage;
+    internalStorage = {};
+    res = {
+         id: changedIdValue
+        ,table: changedTable
+        ,action: action
+        ,columns: null //null for autocomplete in the ADITO-designer
+        ,oldValues: null 
+        ,newValues: null
+    };
+    Object.defineProperty(res, "columns", {
+        get: function(){
+            if (internalStorage["columns"] == undefined)
+                internalStorage["columns"] = columnsFn.call(null);
+            return internalStorage["columns"];
+        }
+        ,set: function (v){
+            internalStorage["columns"] = v;
+        }
+    });
+    Object.defineProperty(res, "oldValues", {
+        get: function(){
+            if (internalStorage["oldValues"] == undefined)
+                internalStorage["oldValues"] = oldValueFn.call(null);
+            return internalStorage["oldValues"];
+        }
+        ,set: function (v){
+            internalStorage["oldValues"] = v;
+        }
+    });
+    Object.defineProperty(res, "newValues", {
+        get: function(){
+            if (internalStorage["newValues"] == undefined)
+                internalStorage["newValues"] = newValueFn.call(null);
+            return internalStorage["newValues"];
+        }
+        ,set: function (v){
+            internalStorage["newValues"] = v;
+        }
+    });
+    return res;
 }
\ No newline at end of file
diff --git a/process/Neon_lib/Neon_lib.aod b/process/Neon_lib/Neon_lib.aod
new file mode 100644
index 0000000000000000000000000000000000000000..7cf15ed468aacf84f69010e2b03c1ad3ccf64e56
--- /dev/null
+++ b/process/Neon_lib/Neon_lib.aod
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.7" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.1.7">
+  <name>Neon_lib</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <process>%aditoprj%/process/Neon_lib/process.js</process>
+</process>
diff --git a/process/Neon_lib/process.js b/process/Neon_lib/process.js
new file mode 100644
index 0000000000000000000000000000000000000000..441ffa8b7d4332333fd4d9af6dffad713d563e17
--- /dev/null
+++ b/process/Neon_lib/process.js
@@ -0,0 +1,384 @@
+/**
+ * Class containing utility functions for copying modules
+ * @class
+ */
+function CopyModuleUtils() {
+}
+
+/**
+ * opens the new created modules in neonClient
+ * 
+ * @param {String} pNeonContext req Name of the neon context that should be opened
+ * @param {Object} pModulesMapping req ModulesMapping object created by method copyModule
+ * 
+ * @example var ModulesMapping = CMUtils.copyModule(InputMapping);
+ *
+ *   CMUtils.openNewModules("Offer_context", ModulesMapping);
+ */
+CopyModuleUtils.openNewModules = function(pNeonContext, pModulesMapping)
+{
+    if(pModulesMapping != undefined)
+    {
+        var rootModule = Object.keys(pModulesMapping)[0];
+        if(pModulesMapping[rootModule].DataRows != undefined)
+        {
+            var newids = [];
+
+            for(var row in pModulesMapping[rootModule].DataRows)
+            {
+                newids.push(pModulesMapping[rootModule].DataRows[row].newPrimaryKey);
+            }
+
+            if(newids.length > 0)
+                neon.openContext(pNeonContext, newids, neon.OPERATINGSTATE_VIEW, null);
+        }
+    }
+}
+
+/**
+*   Creates a copy of a specified module together with specified subordinated modules. <br>
+*   The structure of the input mapping object is the following:  <br>
+*  pInputMapping {
+*   (only one rootModule allowed)
+*    $rootModule$: { 
+*        condition: "sqlWhereCondition"
+*        , ValueMapping: {$colName$: "value"}
+*        , destinationModuleName: "destinationModuleName"
+*        , DestinationColumnMapping: { $sourceColName$ : "destinationColName" }  
+*        , SubModules: {
+*            $Module$:{ 
+*                condition: "sqlWhereCondition"
+*                , ValueMapping: {$colName$: "value"}
+*                , destinationModuleName: "destinationModuleName"
+*                , DestinationColumnMapping: { $sourceColName$ : "destinationColName" }  
+*                , SubModules: {...}
+*            }
+*        }
+*    }
+* }
+* 
+* @param {Object} pInputMapping
+*
+* @example var CMUtils = new CopyModuleUtils();
+*
+*    var InputMapping = {
+*
+*        "OFFER": {
+*                condition: "OFFERID = '" + vars.get("$field.OFFERID") + "'"
+*                ,SubModules:{
+*                    "OFFERITEM": {
+*                        condition: "OFFER_ID = '" + vars.get("$field.OFFERID") + "' order by ITEMSORT" 
+*                }
+*            }
+*        }
+*    }
+*
+*    CMUtils.copyModule(InputMapping);
+*/
+CopyModuleUtils.copyModule = function(pInputMapping)
+{
+    var AliasDefinitionStructure = project.getAliasDefinitionStructure("Data_alias", null);
+    var ModulesMapping = {};
+    var statements = [];
+
+    buildMapping( pInputMapping );
+    buildStatements( ModulesMapping );
+
+    if(statements.length > 0)
+        db.inserts( statements ); 
+
+    return ModulesMapping;
+
+    /**
+     * Builds a mapping Object for the copyModule Method.  <br>
+     * The structure of the Object is the following:  <br>
+     * ModulesMapping = {  
+     * 
+     *   $rootModule$: { ($$ marks an object property) 
+     *   
+     *        (ModuleMapping) 
+     *        name: "moduleName"  
+     *        , destinationModuleName: "destinationModuleName" 
+     *        , DestinationColumnMapping: { $sourceColName$ : "destinationColName" } 
+     *        , ValueMapping: {$colName$: "value"} 
+     *        , dataRows:{ 
+     *            (ModuleRowMapping) 
+     *            $rowid$: {  
+     *                name: "moduleName" 
+     *                , oldPrimaryKey: "oldPrimaryKeyValue" 
+     *                , newPrimaryKey: "newPrimaryKeyValue" 
+     *                , ColumnMapping: { $colName$: { newValue: "newValue", oldValue: "oldValue", destinationColumn: "destinationColumn" } } 
+     *                , ModuleMapping: object reference to ModuleMapping object that contains ModuleRowMapping objects 
+     *                , ParentModuleMapping: object reference to supervised ModuleMapping object (at this point "null" because there is no supervised object) 
+     *            } 
+     *        }   
+     *        , SubModules: { 
+     *                  (ModuleMapping) 
+     *                  $moduleName$: { 
+     *                       name: "moduleName" 
+     *                      , destinationModuleName: "destinationModuleName" 
+     *                      , DestinationColumnMapping: { $sourceColName$ : "destinationColName" } 
+     *                      , ValueMapping: {$colName$: "value"} 
+     *                      , dataRows:{ 
+     *                          (ModuleRowMapping) 
+     *                           $rowid$: {  
+     *                              name: "moduleName" 
+     *                              , oldPrimaryKey: "oldPrimaryKeyValue" 
+     *                              , newPrimaryKey: "newPrimaryKeyValue" 
+     *                              , ColumnMapping: { $colName$: { newValue: "newValue", oldValue: "oldValue", destinationColumn: "destinationColumn" } } 
+     *                              , ModuleMapping:  
+     *                              , ParentModuleMapping: object reference to supervised ModuleMapping object (at this point "null" because there is no supervised object) 
+     *                           } 
+     *                      } 
+     *                      , SubModules: {...} 
+     *                  } 
+     *        }  
+     *
+     *   } 
+     *
+     *} 
+     *
+     * @param {Object} pInputMapping InputMapping
+     */
+    function buildMapping(pInputMapping)
+    {
+        //root mapping
+        var rootModule = Object.keys(pInputMapping)[0];
+        var ModuleMapping = _ModuleMapping(rootModule, pInputMapping[rootModule]);
+        var ModuleData = _getModuleData(rootModule, pInputMapping[rootModule].condition);
+
+        for(var row in ModuleData)
+        {
+            var ModuleRowMapping = _ModuleRowMapping(ModuleMapping, null, ModuleData[row]);
+
+            ModuleMapping.DataRows[ModuleRowMapping.oldPrimaryKey] = ModuleRowMapping;
+        }
+
+        ModulesMapping[rootModule] = ModuleMapping;
+
+        //recursive subordinated modules mapping
+        _buildSubordinatedMapping(pInputMapping, ModuleMapping);
+
+
+        //delivers stored data for module in Database with condition
+        function _getModuleData(pModule, pCondition)
+        {
+            if(pModule == undefined)    return {};
+
+            var ModuleColumnsStructure = AliasDefinitionStructure.tables[pModule].columns;
+            var cols = Object.keys(ModuleColumnsStructure);
+
+            var condition = "1=1";
+            if(pCondition != undefined)
+                condition = pCondition;
+
+            var dbData = db.table("select " + cols.join(", ") + " from " + pModule + " where " + condition);
+
+            //map 2d-Array to Object { $rowNumber$: { $columnName$: { value: "valueInDB" } } }
+            var DataObj = {};
+            for(var row = 0; row < dbData.length; row++)
+            {
+                DataObj[row] = {};
+                for(var col = 0; col < dbData[row].length; col++)
+                {
+                    DataObj[row][cols[col]] = {
+                        value: dbData[row][col]
+                    };
+                }
+            }
+
+            return DataObj;
+        }
+
+
+        //recursive: ModuleMapping and ModuleRowMapping for subordinated modules
+        function _buildSubordinatedMapping(pInputMapping, pParentModuleMapping)
+        {
+            var SubModules = pInputMapping[pParentModuleMapping.name].SubModules;
+            if(SubModules == undefined)
+                return;
+
+            for(var subModuleName in SubModules)
+            {
+                var ModuleMapping = _ModuleMapping(subModuleName, SubModules[subModuleName]);
+                ModuleData = _getModuleData(subModuleName, SubModules[subModuleName].condition);
+                for(var row in ModuleData)
+                {
+                    ModuleRowMapping = _ModuleRowMapping(ModuleMapping, pParentModuleMapping, ModuleData[row]);
+                    ModuleMapping.DataRows[ModuleRowMapping.oldPrimaryKey] = ModuleRowMapping;
+                }
+
+                ModulesMapping[pParentModuleMapping.name].SubModules[subModuleName] = ModuleMapping;
+
+                _buildSubordinatedMapping(SubModules, ModuleMapping);
+            }
+        }
+
+        function _ModuleMapping( pModuleName, pInputModuleMapping )
+        {
+            return {
+                name: pModuleName,
+                destinationModuleName: pInputModuleMapping.destinationModuleName == undefined ? pModuleName : pInputModuleMapping.destinationModuleName,
+                DestinationColumnMapping: pInputModuleMapping.DestinationColumnMapping == undefined ? {} : pInputModuleMapping.DestinationColumnMapping,
+                ValueMapping: pInputModuleMapping.ValueMapping == undefined ? {} : pInputModuleMapping.ValueMapping,
+                DataRows:{}, 
+                SubModules: {}
+            };
+        }
+
+        function _ModuleRowMapping(pModuleMapping, pParentModuleMapping, pDataRow)
+        {
+            var ModuleRowMapping = {
+                name: pModuleMapping.name,
+                oldPrimaryKey: null,
+                newPrimaryKey: null,
+                ColumnMapping: {},
+                ModuleMapping: pModuleMapping,
+                ParentModuleMapping: pParentModuleMapping
+            };
+
+            var ModuleColumnsStructure = AliasDefinitionStructure.tables[ModuleRowMapping.name].columns;
+
+            //build ColumnMapping
+            for(var col in ModuleColumnsStructure)
+            {
+                //set defined columns from InputMapping -> if not defined, use the same column
+                var destinationColumn = ModuleRowMapping.ModuleMapping.DestinationColumnMapping[col];
+                if(destinationColumn == undefined)
+                    destinationColumn = col; 
+
+                //set defined values from InputMapping -> if not defined, use the value from DB
+                var oldValue = pDataRow[col].value;
+                var newValue = newValue = ModuleRowMapping.ModuleMapping.ValueMapping[col];
+                if(newValue == undefined)
+                    newValue = oldValue;
+
+                //set new primary key
+                if(ModuleColumnsStructure[col].primaryKey)  
+                {
+                    ModuleRowMapping.oldPrimaryKey = ModuleRowMapping.ColumnMapping[col] = oldValue;
+                    newValue = util.getNewUUID();
+                    ModuleRowMapping.newPrimaryKey = newValue;
+                }
+
+                ModuleRowMapping.ColumnMapping[col] = _columnMapping(newValue, oldValue, destinationColumn);
+            }
+
+            switch(ModuleRowMapping.name)
+            {
+                case "OFFER":
+                {
+                    //andere Values setzen
+                    ModuleRowMapping.ColumnMapping["OFFERDATE"].newValue = DateUtils.getTodayUTC();
+                }
+                break;
+                case "OFFERITEM":
+                {
+                    //OFFER_ID mappen
+                    if(ModuleRowMapping.ParentModuleMapping.name == "OFFER")
+                    {
+                        ModuleRowMapping.ColumnMapping["OFFER_ID"].newValue = ModulesMapping[ModuleRowMapping.ParentModuleMapping.name].DataRows[ModuleRowMapping.ColumnMapping["OFFER_ID"].oldValue].newPrimaryKey;
+                    }
+                    //ASSIGNEDTO mappen
+                    if(ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].oldValue != "")
+                    {
+                        if(ModuleRowMapping.ParentModuleMapping == null)
+                        {
+                            ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].newValue = ModulesMapping["OFFERITEM"].DataRows[ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].oldValue].newPrimaryKey;
+                        }
+                        else
+                        {
+                            ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].newValue = ModuleRowMapping.ModuleMapping.DataRows[ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].oldValue].newPrimaryKey;
+                        }
+                    }
+                }
+                break;
+                case "OFFERLINK":
+                {
+
+                    }
+                default:
+                {
+
+                    }
+
+
+            }
+
+            //Spezialbehandlung USER_NEW DATENEW....
+            if(ModuleRowMapping.ColumnMapping["DATE_NEW"] != undefined)        ModuleRowMapping.ColumnMapping["DATE_NEW"].newValue = datetime.date();
+            if(ModuleRowMapping.ColumnMapping["USER_NEW"] != undefined)        ModuleRowMapping.ColumnMapping["USER_NEW"].newValue = vars.get("$sys.user");
+            if(ModuleRowMapping.ColumnMapping["DATE_EDIT"] != undefined)        ModuleRowMapping.ColumnMapping["DATE_EDIT"].newValue = "";
+            if(ModuleRowMapping.ColumnMapping["USER_EDIT"] != undefined)        ModuleRowMapping.ColumnMapping["USER_EDIT"].newValue = "";
+
+            return ModuleRowMapping;
+        }
+
+
+
+
+        function _columnMapping(pNewValue, pOldValue, pDestinationColumn)
+        {
+            return {
+                newValue: pNewValue,
+                oldValue: pOldValue,
+                destinationColumn: pDestinationColumn
+            };
+        }
+
+    }
+
+    /**
+     * Builds the insert statements for passed ModulesMapping
+     * 
+     * @param {Object} pModulesMapping ModulesMapping from buildMapping()
+     */
+    function buildStatements(pModulesMapping)
+    {   
+        var rootModule = Object.keys(pModulesMapping)[0];
+
+        for(var row in pModulesMapping[rootModule].DataRows)
+        {
+            //buildInsertStatement
+            statements.push(_statement(pModulesMapping[rootModule].DataRows[row]));
+        }
+
+        _subordinatedStatements(pModulesMapping[rootModule]);
+
+        function _subordinatedStatements(pMapping)
+        {
+            if(pMapping.SubModules == undefined)
+                return;
+
+            for(var subModule in pMapping.SubModules)
+            {
+
+                for(var row in pMapping.SubModules[subModule].DataRows)
+                {
+                    statements.push(_statement(pMapping.SubModules[subModule].DataRows[row]));
+                }
+
+                _subordinatedStatements(pMapping.SubModules[subModule]);
+            }
+
+        }
+
+        function _statement(pRowMapping)
+        {
+            var cols = [];
+            var vals = [];
+            var destTable = pRowMapping.ModuleMapping.destinationModuleName;
+            var colMapping = pRowMapping.ColumnMapping;
+
+            for(var col in colMapping)
+            {
+                cols.push(colMapping[col].destinationColumn);
+                vals.push(colMapping[col].newValue.toString());
+            }
+
+            var colTypes = db.getColumnTypes(destTable, cols)
+
+            return [destTable, cols, colTypes, vals];
+        }
+    }
+}
diff --git a/process/OfferOrder_lib/process.js b/process/OfferOrder_lib/process.js
index 3e32be2ad1ab81fd1382f913485c231788c09444..7ace6bd3b1719873563408cbf29b80f968d9ac61 100644
--- a/process/OfferOrder_lib/process.js
+++ b/process/OfferOrder_lib/process.js
@@ -15,8 +15,7 @@ function OfferUtils()
      */
     this.getNextOfferNumber = function()
     {
-        var JdUtils = new JDitoUtils();
-        return JdUtils.getNextUniqueNumber("OFFERCODE", "OFFER");
+        return NumberSequencingUtils.getNextUniqueNumber("OFFERCODE", "OFFER");
     }
     
     /**
@@ -26,8 +25,7 @@ function OfferUtils()
      */
     this.getNextOfferVersionNumber = function(pOfferCode)
     {
-        var JdUtils = new JDitoUtils();
-        return JdUtils.getNextUniqueNumber("VERSNR", "OFFER", 1, "OFFERCODE = " + pOfferCode);
+        return NumberSequencingUtils.getNextUniqueNumber("VERSNR", "OFFER", 1, "OFFERCODE = " + pOfferCode);
     }
     
     /**
@@ -39,8 +37,7 @@ function OfferUtils()
      */
     this.validateOfferNumber = function(pOfferNumber)
     {
-        var JdUtils = new JDitoUtils();
-        return JdUtils.validateUniqueNumber(pOfferNumber, "OFFERCODE", "OFFER");
+        return NumberSequencingUtils.validateUniqueNumber(pOfferNumber, "OFFERCODE", "OFFER");
     }
     
     this.getOfferNumberValidationFailString = function()
diff --git a/process/Product_lib/process.js b/process/Product_lib/process.js
index 161c665d32d38340cba27e1bb437dd318b2b30b8..94451a5e126ea8427c36a2cdf0a633d5633e6bd8 100644
--- a/process/Product_lib/process.js
+++ b/process/Product_lib/process.js
@@ -82,7 +82,7 @@ function ProductUtils()
      * @param pPriceListFilter {Object} opt { currency: "currencyValue", quantity: "quantityValue", relationId: "relationIdValue (for custom price lists)" }
      * 
      * @example //Product_entity, Field: PRODUCT_ID, Process: onValueChange
-     *          var pid = ProcessHandlingUtil.getOnValidationValue(vars.get("$field.PRODUCT_ID"));
+     *          var pid = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.PRODUCT_ID"));
      *          var curr = vars.exists("$param.Currency_param") ? vars.get("$param.Currency_param") : "";
      *          var relid = vars.exists("$param.RelationId_param") ? vars.get("$param.RelationId_param") : "";
      *          var pUtils = new ProductUtils();
@@ -280,7 +280,7 @@ function ProductUtils()
      * @example //Productprice_entity, Field: PRICELIST, Process: onValidation
      *          var pUtils = new ProductUtils();
      *          var priceList = {
-     *                          priceList: ProcessHandlingUtil.getOnValidationValue(vars.get("$field.PRICELIST"))
+     *                          priceList: ProcessHandlingUtils.getOnValidationValue(vars.get("$field.PRICELIST"))
      *                          , fromQuantity: vars.get("$field.FROMQUANTITY")
      *                          , buySell: vars.get("$field.BUYSELL")
      *                          , currency: vars.get("$field.CURRENCY")
diff --git a/process/Salesproject_lib/process.js b/process/Salesproject_lib/process.js
index e3f10b6a49e5053b051b02a90dadc40c94dcf995..231a2538d20894fff9b6f9774568d282a3721d1c 100644
--- a/process/Salesproject_lib/process.js
+++ b/process/Salesproject_lib/process.js
@@ -24,8 +24,7 @@ Salesproject = {
      * @result {String} next valid project number
      */
     getNextProjectNumber: function() {
-        var JdUtils = new JDitoUtils();
-        return JdUtils.getNextUniqueNumber("PROJECTCODE", "SALESPROJECT");
+        return NumberSequencingUtils().getNextUniqueNumber("PROJECTCODE", "SALESPROJECT");
     },
     
     /**
@@ -36,8 +35,7 @@ Salesproject = {
      * @result {boolean} passed number is valid
      */
     validateProjectNumber: function(projectNumber) {
-        var JdUtils = new JDitoUtils();
-        return JdUtils.validateUniqueNumber(projectNumber, "PROJECTCODE", "SALESPROJECT");
+        return NumberSequencingUtils.validateUniqueNumber(projectNumber, "PROJECTCODE", "SALESPROJECT");
     },
     
     /**
diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js
index 61a7c941e309be1fc8a8673b61865554c633b333..15ba49d93fcc1bca95135476814c1f5798f85b0e 100644
--- a/process/Sql_lib/process.js
+++ b/process/Sql_lib/process.js
@@ -657,6 +657,7 @@ SqlUtils.getSingleColumnType = function(fieldOrTableName, columnName, alias) {
 /**
  *Class containing utilities for SQL
  *@deprecated use SqlMaskingUtils
+ *@todo: shift to newer objects or remove
  *@class
  */
 function LegacySqlUtils()
@@ -1169,55 +1170,7 @@ function LegacySqlUtils()
 
         return res;
     }
-    /**
-    * Setzt eine Condition zusammen und liefert sie zurück
-    * builds a conditions and returns it
-    *
-    * @param {Object} pValue req Filtervalue
-    * @param {String} pCondition req variable in which the condition should be written
-    * @param {String} pWhere req additional condition
-    * @param {Integer} pSQLType opt SQLTYPES type of pValue
-    * @param {Array} pPreparedValues opt Value for the condition, if it's a prepared statement
-    *
-    * @return {String}
-    */
-    this.makeCondition = function( pValue, pCondition, pWhere, pSQLType, pPreparedValues)
-    {
-        if ( pValue != "" )
-        {
-            if ( pCondition != "" ) 
-                pCondition += " and ";
-
-            pCondition += pWhere;
 
-            if(pPreparedValues != undefined)
-            {
-                pPreparedValues.push([pValue, pSQLType]);
-            }
-        }
-        return pCondition;
-    }
-    /**
-     * returns a type of column in the database
-     *
-     * @param {String} pTableName req name of a table (e.g. "EVENT") OR if pColumnName is not passed table.column (e.g. "EVENT.STATUS")
-     * @param {String} pColumnName opt name of column (e.g. "STATUS") if in pTableName only tablename is passed
-     * @param {String} pAlias opt Alias to the database where the type should be loaded; default is current alias
-     *
-     * @return {String} type of column such as SQLTYPES.xyz
-     */
-    this.getSingleColumnType = function(pTableName, pColumnName, pAlias)
-    {
-        if (pColumnName == undefined)
-        {
-            pColumnName = pTableName.substring(pTableName.indexOf(".") + 1);
-            pTableName = pTableName.substring(0, pTableName.indexOf("."));
-        }
-        if (pAlias == undefined)
-            pAlias = db.getCurrentAlias();
-
-        return db.getColumnTypes(pTableName, [pColumnName], pAlias)[0];
-    }
     /**
     * calls a given function for N blocks of sql-data as long as records are available or the paging-process is manually canceled
     *
diff --git a/process/Util_lib/process.js b/process/Util_lib/process.js
index 969fe5b2f57169f259666d6e1a2e6f9059d1b40a..ace960b642dbf072b869738f86de3d5a4f9a4bc1 100644
--- a/process/Util_lib/process.js
+++ b/process/Util_lib/process.js
@@ -15,819 +15,407 @@ import("OfferOrder_lib");
 import("Date_lib");
 
 /**
- * Class containing utility functions for images
- * 
+ * Class containing static utility functions for use with arrays
  * @class
- *
+ * @static
  */
-function ImageUtils()
-{
-    var that = this;
-    /**
-    * reads a picture depending on description and icon_type from ASYS_ICONS
-    * @param {String} pIconType requ ICON_TYPE of ASYS_ICONS
-    * @param {String} pDescription requ DESCRIPTION of ASYS_ICONS
-    * @param {Boolean} pBase64 opt true/undefined: BINDATA (Tables, trees) or false: ID (Icons, XMPP picture)
-    * 
-    * @return {String} BINDATA of ASYS_ICONS
-    * 
-    * 
-    */
-    this.getIcon = function(pIconType, pDescription, pBase64)
-    {
-        var field = pBase64 || pBase64 == undefined ? "BINDATA" : "ID";
-        return db.cell("select " + field + " from ASYS_ICONS where DESCRIPTION = '" + pDescription + "' and ICON_TYPE = '" + pIconType + "'",
-            "_____SYSTEMALIAS");
-    }
-
-    /**
-    * reads frequently used combination of description and bindata/id from ASYS_ICONS
-    * @param {String} pIconType ICON_TYPE of ASYS_ICONS
-    * @param {Boolean} pBase64 opt true: BINDATA or false/undefined: ID
-    *
-    * @return {String[][]} Key: Description, Value: ID
-    * 
-    */
-    this.getImageObject = function (pIconType, pBase64)
-    {
-        var field = pBase64 ? "BINDATA" : "ID";
-
-        var icons = {};//kein Array sondern Object, da es sich um ein assoziatives Array handelt
-        var data = db.table("select " + field + ", DESCRIPTION from ASYS_ICONS where ICON_TYPE = '" + pIconType + "'",
-            "_____SYSTEMALIAS");
-        for (var i = 0; i < data.length; i++ )
-            icons[data[i][1]] = data[i][0];
-
-        return icons;
-    }
+function ArrayUtils(){
 }
-/**
- * class containing utils for URLs
- * @class
- */
-function UrlUtils()
-{
-    var that = this;
-    /** 
-    * Extracts a query param from an URL
-    *
-    * @param {String} pURL the text from which the parameter should be read
-    * @param {String} pParameter Name of the parameter
-    *  (Messaging mit Default Trenner:
-    *  - im.internal: "id=", "title_ack=", "title_dcl=", "text_ack=", "text_dcl=", "desc=", "name=", "result=", "decidable=", "icon=", "icon_ack=", "icon_dcl="
-    *  - im.file: "id=", "size=", "result=", "requestor=")
-    * @param {String} pSplit opt der String, which marks the end of the param value, standard is '&'
-    *
-    * @return {String} the extracted value or null if param not existent
-    * 
-    * 
-    */
-    this.extractBlock = function(pURL, pParameter, pSplit)
-    {
-        var idLeft = pURL.indexOf(pParameter, 0);
-        if(idLeft <= -1)
-            return null; // Kein Block vorhanden
-        if(pSplit != undefined) var idRight = pURL.indexOf(pSplit, idLeft);
-        if(pSplit == undefined || idRight <= -1) idRight = pURL.indexOf("&", idLeft);
-        if(idRight <= -1)
-            idRight = pURL.length;
-
-        return pURL.substring(idLeft + pParameter.length, idRight);
-    }
-
-    /**
-    * opens the browser
-    *
-    * @param {String} pUrl req
-    * @param {String} pBrowserType opt Browser type 1 = Native (Internet Explorer Rendering Engine)
-    *                              ,2 = JavaFX (WebKit Rendering Engine), 3 = Native, if possible.
-    *                              default is 2;
-    *
-    * @return {void}
-    * 
-    *
-    */
-    this.openUrl = function(pUrl, pBrowserType)
-    {
-        if ( pUrl != "" )
-        {
-            if (pUrl.substr(0, 4) != "http"
-                && pUrl.substr(0, 4) != "ftp:"
-                && pUrl.substr(0, 5) != "file:")
-                {
-                pUrl = "http://" + pUrl;
-            }
 
-            var browserType = pBrowserType || 2;
-            swing.openBrowser(true, false, encodeURI(pUrl), swing.WINDOW_CURRENT, [], browserType);
-        }
-    }
-}
 /**
- * Class containing String utility functions
- * @class
+ * sorts a two dimensional array by the given index
+ *
+ * @param {Array} targetArray the Array to be sorted
+ * @param {String} index the index of the field to sort by
+ * @param {Boolean} [sortAsc=false] TRUE sorts ascending, FALSE sorts decending
+ * @param {Boolean} [isNumber=false] TRUE sorts numerical, FALSE or undefined sorts alphanumerical
+ *
+ * @return targetArray
+ *
+ * @throws {RangeError} if index is outside pArray.length
+ * 
  * 
  */
-function StringUtils()
-{
-    var that = this;
-    /**
-    * validates if a string is a UUID according to versions 1 through 5 of RFC4122
-    * @param {String} pUUID String to be validated
-    * @param {bool} pIgnoreCase true if case sensitivty isn't needed
-    *
-    * @return {Boolean} ob es sich um eine UUID handelt
-    * 
-    * 
-    */
-    this.isValidUUID = function(pUUID, pIgnoreCase)
-    {
-        if (pIgnoreCase)
-        {
-            pUUID = pUUID.toLowerCase();
+ArrayUtils.sort2d = function(targetArray, index, sortAsc, isNumber){
+    if (targetArray.length == 0)
+        return targetArray;
+    if (targetArray[0].length == 0)
+        return targetArray;
+    if (index >= targetArray[0].length)
+        throw new RangeError("Index Out Of Bounds: " + index + " >= " + targetArray[0].length);
+
+    var sortFn = function (x, y){
+        if ( isNumber ) {
+            xx = Number(x[index]);
+            yy = Number(y[index]);
         }
-
-        return new RegExp(/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/).test(pUUID);
-    }
-    /**
-    * Returns wether a string starts with given string or not.
-    * @param pString String, which is being searched in
-    * @param pStringToSearch String, which is being searched
-    * 
-    * @return {Boolean}
-    * 
-    * 
-    */
-    this.stringStatrsWith = function(pString, pStringToSearch)
-    {
-        return pString.indexOf(pStringToSearch) === 0;
-    }
-    /**
-    * Splits street and buildingnumber
-    *
-    * @param {String} pAddress req Address
-    *
-    * @return {Array}  [ Street, BuildingNr ]
-    * 
-    * 
-    */
-    this.splitAddress = function(pAddress)
-    {
-        var ret = ["",""];
-        if(pAddress != "")
-        {
-            var arr = pAddress.match( /^[^0-9]+|[0-9]+.*$/g);
-            ret[0] = arr[0].trim();
-            if(arr[1]) 
-                ret[1] = arr[1].trim();
+        else {
+            xx = x[index];
+            yy = y[index];
+
+            xx = xx.toLowerCase();
+            xx = xx.replace(/ä/g,"ae");
+            xx = xx.replace(/ö/g,"oe");
+            xx = xx.replace(/ü/g,"ue");
+            xx = xx.replace(/ß/g,"ss");
+
+            yy = yy.toLowerCase();
+            yy = yy.replace(/ä/g,"ae");
+            yy = yy.replace(/ö/g,"oe");
+            yy = yy.replace(/ü/g,"ue");
+            yy = yy.replace(/ß/g,"ss");
         }
-        return ret;
+        if (xx == yy)
+            return 0;
+        if (xx < yy)
+            return (sortAsc ? -1 : 1);
+        return (sortAsc ? 1 : -1);
     }
 
-    /**
-    * Generates the string which shows, who created the dataset and who edited it
-    *
-    * @param {String} pDateNew req Date of creation
-    * @param {String} pUserNew req name of the user, who created the dataset 
-    * @param {String} pDateEdit req date of the last change
-    * @param {String} pUserEdit req name of last editor
-    *
-    * @return {String}
-    * 
-    * 
-    */
-    this.label_new_edit = function(pDateNew, pUserNew, pDateEdit, pUserEdit)
-    {
-        var retst = translate.withArguments("created on %0 by %1", [ datetime.toDate(pDateNew, translate.text("yyyy-MM-dd")), pUserNew]);
-        if (pDateEdit != undefined && pDateEdit != "")  retst += " | " + translate.withArguments("changed on %0 by %1", [ datetime.toDate(pDateEdit, translate.text("yyyy-MM-dd")), pUserEdit]);
-        return(retst)
-    }
-    
-    /**
-    * uses the right translate method, depending on the parameters
-    *
-    * @param {String} pText string to be translated
-    * @param {String} pLocale locale for translating
-    *
-    * @return {String}
-    *
-    * 
-    */
-    this.translateStr = function( pText, pLocale )
-    {
-        if ( pLocale == undefined )   
-            return translate.text(pText);
-        else 
-            return translate.text(pText, pLocale)
-    }
-    
-
+    targetArray.sort(sortFn);
+    return targetArray
 }
-/**
- * Class containing utility functions for use with arrays
- * @class
- */
-function DataUtils()
-{
-    var that = this;
-    /**
-    * sorts a two dim array by the given index
-    *
-    * @param {Array} pArray req the Array to be sorted
-    * @param {String} pIndex req the index of the field to sort by
-    * @param {Boolean} pUp req TRUE sorts ascending, FALSE sorts decending
-    * @param {Boolean} isNumber TRUE sorts numerical, FALSE or undefined sorts alphanumerical
-    *
-    * @return void
-    *
-    * @throws {Error} if index is outside pArray.length
-    * 
-    * 
-    */
-    this.array_mDimSort = function(pArray, pIndex, pUp, isNumber)
-    {
-        if (pArray.length == 0)
-            return;
-
-        if (pArray[0].length == 0)
-            return;
 
-        if (pIndex >= pArray[0].length)
-            throw new Error("Index Out Of Bounds: " + pIndex + " >= " + pArray[0].length);
-
-        /*
-        * the sort function
-        *
-        * @param {String} x req value 1
-        * @param {String} y req value 2
-        *
-        * @return {Integer}
-        * 
-        * @memberof array_mDimSort
-        */
-        function array_mDimSorter(x, y)
-        {
-            if ( isNumber )
-            {
-                xx = Number(x[pIndex]);
-                yy = Number(y[pIndex]);
-            }
-            else
-            {
-                xx = x[pIndex];
-                yy = y[pIndex];
-
-                //Umlaute austauschen
-                xx = xx.toLowerCase();
-                xx = xx.replace(/ä/g,"ae");
-                xx = xx.replace(/ö/g,"oe");
-                xx = xx.replace(/ü/g,"ue");
-                xx = xx.replace(/ß/g,"ss");
-
-                yy = yy.toLowerCase();
-                yy = yy.replace(/ä/g,"ae");
-                yy = yy.replace(/ö/g,"oe");
-                yy = yy.replace(/ü/g,"ue");
-                yy = yy.replace(/ß/g,"ss");
-            }
-            if (xx == yy)
-                return 0;
-
-            if (xx < yy)
-                return (pUp ? -1 : 1);
-
-            return (pUp ? 1 : -1);
+/**
+* sorts an array up to 6 columns with sortorder
+*
+* @param {Array} targetArray req the array with data
+* @param {Integer} us req  the Sortorder for Column 1 = Param u (1=asc, -1=desc)
+* @param {Integer} u req the 1 Column
+* @param {Integer} vs opt  the Sortorder for Column 2 = Param v (1=asc, -1=desc)
+* @param {Integer} v opt the 2 Column
+* @param {Integer} ws opt  the Sortorder for Column 3 = Param w (1=asc, -1=desc)
+* @param {Integer} w opt the 3 Column
+* @param {Integer} xs opt  the Sortorder for Column 4 = Param x (1=asc, -1=desc)
+* @param {Integer} x opt the 4 Column
+* @param {Integer} ys opt  the Sortorder for Column 5 = Param y (1=asc, -1=desc)
+* @param {Integer} y opt the 5 Column
+* @param {Integer} zs opt  the Sortorder for Column 6 = Param z (1=asc, -1=desc)
+* @param {Integer} z opt the 6 Column
+*
+* @return {void}
+*/
+ArrayUtils.sortMulti = function(targetArray, us, u, vs, v, ws, w, xs, x, ys, y, zs, z) {
+    /*
+     * sort of a two dim array, up to 6 columns
+     *
+     * @param {String} a req value 1, first compared element
+     * @param {String} b req value 2, sencond compared element
+     *
+     * @return {Integer} -1 - set a below b, 0 - equal, 1 - set b below a 
+     */
+    var sortFn = function(a, b) {
+        var stringComparison = function(a, b) {
+            a = a.toLowerCase();
+            a = a.replace(/ä/g,"ae");
+            a = a.replace(/ö/g,"oe");
+            a = a.replace(/ü/g,"ue");
+            a = a.replace(/ß/g,"ss");
+
+            b = b.toLowerCase();
+            b = b.replace(/ä/g,"ae");
+            b = b.replace(/ö/g,"oe");
+            b = b.replace(/ü/g,"ue");
+            b = b.replace(/ß/g,"ss");
+
+            return( a == b ) ? 0 : ( a > b ) ? 1 : -1;
         }
 
-        pArray.sort(array_mDimSorter);
-    }
-
-    /**
-    * sorts an array up to 6 columns with sortorder
-    *
-    * @param {Array} pArray req the array with data
-    * @param {Integer} us req  the Sortorder for Column 1 = Param u (1=asc, -1=desc)
-    * @param {Integer} u req the 1 Column
-    * @param {Integer} vs opt  the Sortorder for Column 2 = Param v (1=asc, -1=desc)
-    * @param {Integer} v opt the 2 Column
-    * @param {Integer} ws opt  the Sortorder for Column 3 = Param w (1=asc, -1=desc)
-    * @param {Integer} w opt the 3 Column
-    * @param {Integer} xs opt  the Sortorder for Column 4 = Param x (1=asc, -1=desc)
-    * @param {Integer} x opt the 4 Column
-    * @param {Integer} ys opt  the Sortorder for Column 5 = Param y (1=asc, -1=desc)
-    * @param {Integer} y opt the 5 Column
-    * @param {Integer} zs opt  the Sortorder for Column 6 = Param z (1=asc, -1=desc)
-    * @param {Integer} z opt the 6 Column
-    *
-    * @return {void}
-    * 
-    * 
-    */
-    this.sortArray = function(pArray, us, u, vs, v, ws, w, xs, x, ys, y, zs, z)
-    {
-        pArray.sort(_sortmulti);
-        /*
-        * sort of a two dim array, up to 6 columns
-        *
-        * @param {String} a req value 1, first compared element
-        * @param {String} b req value 2, sencond compared element
-        *
-        * @return {Integer} -1 - set a below b, 0 - equal, 1 - set b below a 
-        */
-        function _sortmulti(a, b)
-        {
-            var stringComparison = function(a, b)	
-            {
-                a = a.toLowerCase();
-                a = a.replace(/ä/g,"ae");
-                a = a.replace(/ö/g,"oe");
-                a = a.replace(/ü/g,"ue");
-                a = a.replace(/ß/g,"ss");
-
-                b = b.toLowerCase();
-                b = b.replace(/ä/g,"ae");
-                b = b.replace(/ö/g,"oe");
-                b = b.replace(/ü/g,"ue");
-                b = b.replace(/ß/g,"ss");
 
-                return( a == b ) ? 0 : ( a > b ) ? 1 : -1;
-            }
-            
-            
-            var swap=0;
+        var swap=0;
 
-            if (isNaN(a[u] - b[u])) // if there is a string in the first compared element
-                if( isNaN(a[u]) && isNaN(b[u]) ) // if both are strings,
-                    swap = stringComparison(a[u], b[u]); // then: true - false = 1; false - true = -1
-                else
-                    swap = (isNaN(a[u]) ? 1 : -1);
+        if (isNaN(a[u] - b[u])) // if there is a string in the first compared element
+            if( isNaN(a[u]) && isNaN(b[u]) ) // if both are strings,
+                swap = stringComparison(a[u], b[u]); // then: true - false = 1; false - true = -1
             else
-                swap = (a[u] - b[u]);
+                swap = (isNaN(a[u]) ? 1 : -1);
+        else
+            swap = (a[u] - b[u]);
 
-            if ((v == undefined) || (swap != 0))
-                return swap * us;
-            else
-            if (isNaN(a[v] - b[v]))
-                if ((isNaN(a[v])) && (isNaN(b[v])))
-                    swap =  stringComparison(a[v], b[v]);
-                else
-                    swap = (isNaN(a[v]) ? 1 : -1);
+        if ((v == undefined) || (swap != 0))
+            return swap * us;
+        else
+        if (isNaN(a[v] - b[v]))
+            if ((isNaN(a[v])) && (isNaN(b[v])))
+                swap =  stringComparison(a[v], b[v]);
             else
-                swap = (a[v] - b[v]);
+                swap = (isNaN(a[v]) ? 1 : -1);
+        else
+            swap = (a[v] - b[v]);
 
-            if ((w == undefined) || (swap != 0))
-                return swap * vs;
-            else
-            if (isNaN(a[w] - b[w]))
-                if ((isNaN(a[w])) && (isNaN(b[w])))
-                    swap =  stringComparison(a[w], b[w]);
-                else
-                    swap = (isNaN(a[w]) ? 1 : -1);
+        if ((w == undefined) || (swap != 0))
+            return swap * vs;
+        else
+        if (isNaN(a[w] - b[w]))
+            if ((isNaN(a[w])) && (isNaN(b[w])))
+                swap =  stringComparison(a[w], b[w]);
             else
-                swap = (a[w] - b[w]);
+                swap = (isNaN(a[w]) ? 1 : -1);
+        else
+            swap = (a[w] - b[w]);
 
-            if ((x == undefined) || (swap != 0))
-                return swap * ws;
-            else
-            if (isNaN(a[x] - b[x]))
-                if ((isNaN(a[x])) && (isNaN(b[x])))
-                    swap =  stringComparison(a[x], b[x]);
-                else
-                    swap = (isNaN(a[x]) ? 1 : -1);
+        if ((x == undefined) || (swap != 0))
+            return swap * ws;
+        else
+        if (isNaN(a[x] - b[x]))
+            if ((isNaN(a[x])) && (isNaN(b[x])))
+                swap =  stringComparison(a[x], b[x]);
             else
-                swap = (a[x] - b[x]);
+                swap = (isNaN(a[x]) ? 1 : -1);
+        else
+            swap = (a[x] - b[x]);
 
-            if ((y == undefined) || (swap != 0))
-                return swap * xs;
-            else
-            if (isNaN(a[y] - b[y]))
-                if ((isNaN(a[y])) && (isNaN(b[y])))
-                    swap =  stringComparison(a[y], b[y]);
-                else
-                    swap = (isNaN(a[y]) ? 1 : -1);
+        if ((y == undefined) || (swap != 0))
+            return swap * xs;
+        else
+        if (isNaN(a[y] - b[y]))
+            if ((isNaN(a[y])) && (isNaN(b[y])))
+                swap =  stringComparison(a[y], b[y]);
             else
-                swap = (a[y] - b[y]);
+                swap = (isNaN(a[y]) ? 1 : -1);
+        else
+            swap = (a[y] - b[y]);
 
-            if ((z == undefined) || (swap != 0))
-                return swap * ys;
-            else
-            if(isNaN(a[z] - b[z]))
-                if((isNaN(a[z])) && (isNaN(b[z])))
-                    swap =  stringComparison(a[z], b[z]);
-                else
-                    swap = (isNaN(a[z]) ? 1 : -1);
+        if ((z == undefined) || (swap != 0))
+            return swap * ys;
+        else
+        if(isNaN(a[z] - b[z]))
+            if((isNaN(a[z])) && (isNaN(b[z])))
+                swap =  stringComparison(a[z], b[z]);
             else
-                swap = (a[z] - b[z]);
-
-            return swap * zs;
-        }
-
-    }
-
-    /**
-    * removes an element from an array
-    *
-    * @param {Array} pArray req Array from which the element should be removed
-    * @param {String} pElement req index of the element which should be removed
-    *
-    * @return {Array} array without the removed element
-    * 
-    * 
-    */
-    this.removeElement = function(pArray, pElement)
-    {
-        return pArray.splice(pElement, 1);
-    }
-    
-    /**
-    * returns all elemtens not in pSource
-    *
-    * @param {Array} pSource req this elements are being searched
-    * @param {Array} pReference req in this array the search is done
-    * @param {Boolean} pIgnoreCase opt
-    *
-    * @return {Array[]} resultIn
-    * 
-    * 
-    */
-    this.notIn = function(pSource, pReference, pIgnoreCase)
-    {
-        var resultIn = new Array();
-        for (var i = 0; i < pSource.length; i++)
-        {
-            if (!that.hasElement(pReference, pSource[i], pIgnoreCase))
-                resultIn.push(pSource[i]);
-        }
-
-        return resultIn;
-    }    
-
-    /**
-    * returns if an element is in an array.
-    *
-    * @param {Array} pArray req array which should be searched in 
-    * @param {String} pElement req Element which should looked for
-    * @param {Boolean} pIgnoreCase opt
-    *
-    * @return {Boolean} true if it has the element
-    * 
-    * 
-    */
-    this.hasElement = function(pArray, pElement, pIgnoreCase)
-    {
-        for (var i = 0; i < pArray.length; i++)
-        {
-            if ( pIgnoreCase != undefined && pIgnoreCase )
-            {
-                if (pArray[i].toLowerCase() == pElement.toLowerCase())	
-                    return true;
-            }
-            else	
-                if (pArray[i] == pElement)	
-                    return true;
-        }
+                swap = (isNaN(a[z]) ? 1 : -1);
+        else
+            swap = (a[z] - b[z]);
 
-        return false;
+        return swap * zs;
     }
-    
-    /**
-     * concats arrays column by column
-     * see example for more details
-     * logging.show(JSON.stringify(concatArrayColumns(a, b)));
-     * //[["a","A"],["b","B"],["c","C"]]
-     *
-     * logging.show(JSON.stringify(a.concat(b)));
-     * //["a","b","c","A","B","C"]
-     * @param {Array} pArray1 req you have to pass at least 2 Arrays that shall be concated but you can pass as many as you want
-     * @param {Array} pArrayN req you have to pass at least 2 Arrays that shall be concated but you can pass as many as you want
-     *
-     *
-     *
-     * @return {Array} Beschreibung
-     * 
-     * 
-     */
-    this.concatArrayColumns = function(pArray1, pArrayN)
-    {
-        var res = [];
 
-        for (var i = 0, l = arguments.length; i < l; i++)//this function can handle an "unlimited" amount of functionparams
-        {
-            var inpArr = arguments[i];
-            for (var ii = 0, ll = inpArr.length; ii < ll; ii++)
-            {
-                if (res[ii] == undefined)
-                    res[ii] = [];
-
-                    res[ii] = res[ii].concat(inpArr[ii]);
-            }
-        }
-        return res;
-    }
-    
-    /**
-    *  function to determine, if an object is truly an Array
-    *  @param {Object} pArray
-    *  @return {Boolean} returns wether an Object is an Array (true) or not (false)
-    *  
-    *  
-    */
-    this.isArray = function(pArray)
-    {
-        return (pArray && typeof pArray === "object" && typeof pArray.length === "number" && !(pArray.propertyIsEnumerable('length')))          
-    }
+    targetArray.sort(sortFn);
+    return targetArray;
 }
-/**
- * Class containing utility functions for table components
- * @class
- */
-function TableUtils()
-{
-    var that = this;
-    /**
-    * Moving Tablerows Sort field up or down a step
-    *
-    * @param {String} pTable req Table
-    * @param {String} pTableComp req name of the table comp
-    * @param {String} pCountField req sort field name z.B. 'SORT'
-    * @param {String} pDirection req 'up' oder 'down'
-    * @param {String} pCondition opt
-    *
-    * @return {void}
-    * 
-    * 
-    */
-    this.moveRow = function(pTable, pTableComp, pCountField, pDirection, pCondition)
-    {
-        that.sortRow(pTable, pCountField, pCondition);
-        
-        if (pCondition == undefined || pCondition == "") 
-            pCondition = "";
-        else 
-            pCondition = " and " + pCondition;
-        
-        var id = text.decodeFirst(vars.getString(pTableComp));
-        var col = [pCountField];
-        var nextval;
-        var typ = db.getColumnTypes( pTable, col);
-        var oldval = db.cell("select " + pCountField + " from " + pTable + " where " + pTable + "ID = '" + id + "'");
-        
-        if (pDirection == "up")
-        {
-            nextval = db.cell("select max(" + pCountField + ") from " + pTable
-                + " where " + pCountField + " < " + oldval + pCondition);
-        }
-        else
-        {
-            nextval = db.cell("select min(" + pCountField + ") from " + pTable
-                + " where " + pCountField + " > " + oldval + pCondition);
-        }
-        if ( nextval == "" )  
-            nextval = 0;
-        var nextID = db.cell("select " + pTable + "ID from " + pTable + " where " + pCountField + " = " + nextval + pCondition);
-        db.updateData(pTable, col, typ, [oldval], pTable + "ID = '" + nextID + "'")
-        db.updateData(pTable, col, typ, [nextval], pTable + "ID = '" + id + "'")
-    }
 
-    /**
-    * activates Up/Down buttons
-    *
-    * @param {String} pTable req Table
-    * @param {String} pTableComp req name of the table comp
-    * @param {String} pSortfield req sort field name z.B. 'SORT'
-    * @param {String} pDirection req 'up' or 'down'
-    * @param {String} pCondition opt
-    *
-    * @return {Boolean} true if active
-    * 
-    * 
-    */
-    this.moveActive = function(pTable, pTableComp, pSortfield, pDirection, pCondition)
-    {
-        var oldval = "min";
-        var minmax = "min";
-        var id = text.decodeFirst(vars.getString(pTableComp));
-
-        if (pCondition == undefined || pCondition == "") 
-            pCondition = "";
-        else 
-            pCondition = " where " + pCondition;
-        
-        if (id != "" && swing.getTableDataByAttribute(pTableComp, swing.INSERTED ).length == 0 && vars.getString("$sys.workingmode") == swing.FRAMEMODE_EDIT )
-        {
-            oldval = db.cell("select " + pSortfield + " from " + pTable + " where " + pTable + "ID = '" + id + "'");
-            
-            if(pDirection == "down")	
-                minmax = "max";
-            
-            minmax = db.cell("select " + minmax + "(" + pSortfield + ") from " + pTable + pCondition);
-        }
-        return (oldval != minmax || oldval == "" || minmax == "" )
-    }
+/**
+* removes an specific element from an array
+*
+* @param {Array} targetArray Array from which the element should be removed
+* @param {String} elementPos  index of the element which should be removed
+*
+* @return {Array} array containing the deleted element
+*/
+ArrayUtils.removeElement = function(targetArray, elementPos) {
+    return targetArray.splice(elementPos, 1);
 }
+    
 /**
- * Class containing utility functions for use with base64 and binaries
- * @class
+ * concats arrays column by column;
+ * see example for more details
+ *
+ * @param {Array} array1 you have to pass at least 2 Arrays that shall be concated but you can pass as many as you want
+ * @param {Array} arrayN you have to pass at least 2 Arrays that shall be concated but you can pass as many as you want
+ *
+ * @return {Array} concatenated array
+ * 
+ * @example
+ * var a = ["a", "b", "c"];
+ * var b = ["A", "B", "C"];
+ * logging.show(JSON.stringify(concatArrayColumns(a, b)));
+ * //[["a","A"],["b","B"],["c","C"]]
+ *
+ * logging.show(JSON.stringify(a.concat(b)));
+ * //["a","b","c","A","B","C"]
  */
-function BinaryUtils()
-{
-    var that = this;
-    /**
-    * decodes 64Based String
-    *
-    * @param {String} input req the string
-    *
-    * @return {String} decoded String
-    * 
-    * 
-    */
-    this.decode64 = function(input)
-    {
-        var charset = new Configuration().getOption("Base64Charset");
+ArrayUtils.concatColumns = function(array1, arrayN) {
+    var res, i, ii, l, ll, inpArr;
+    res = [];
 
-        if ( charset == "" )
-            charset = "ISO-8859-15";
-        return util.decodeBase64String(input, charset);
-    }
-    /**
-    * returns the original size of a B64 coded String in bytes
-    *
-    * @param {String} pBase64str req base64 encoded string
-    *
-    * @return {Number} size of the string in bytes
-    * 
-    * 
-    */
-    this.getBase64lengthBytes = function(pBase64str)
-    {
-        var res = pBase64str.length;
-        res = eMath.divDec(res, 4);
-        res = Math.ceil(res);
-        res = eMath.mulInt(3, res);
-
-        return +res;//cast und return
-    }
-    
-    /**
-     *  sanitizes the filelist gotten from Drag&Drop and returns it.
-     *  
-     *  @param {String[]} pFilelist req Die Filelist als Stringarray.
-     *  
-     *  
-     */
-    this.sanitizeFilelist = function(pFilelist)
-    {
-        var sanitized = [];
-        
-        if(pFilelist != undefined && pFilelist.length > 0)
-        {
-            for(let i = 0; i < pFilelist.length; i++)
-            {
-                if(swing.doClientIntermediate(swing.CLIENTCMD_FILEIO_ISDIRECTORY, [pFilelist[i]]) == "false")
-                    sanitized.push(pFilelist[i]);
-            }
+    for (i = 0, l = arguments.length; i < l; i++) {//this function can handle an "unlimited" amount of functionparams
+        inpArr = arguments[i];
+        for (ii = 0, ll = inpArr.length; ii < ll; ii++) {
+            if (res[ii] == undefined)
+                res[ii] = [];
+
+            res[ii] = res[ii].concat(inpArr[ii]);
         }
-        
-        return sanitized;
     }
-    /**
-     *  reads the folders in a filelist and returns their contained files
-     *
-     *  @param {String[]} pFilelist req Die Filelist als Stringarray.
-     *  
-     *  
-     */
-    this.resolveSubfolders = function(pFilelist)
-    {
-        //read systemconfig for D&D
-        var cfg = new Configuration();
-        var filesize   = (cfg.getOption("dnd.maxFileSize") *1000 *1000 );
-        var fileamount = 30;
-        var files = [];
-        var folders = [];
+    return res;
+}
 
-        if(pFilelist != undefined && pFilelist.length > 0)
-        {
-            //separate files and folders
-            for (let i = 0; i < pFilelist.length; i++)
-            {
-                if(swing.doClientIntermediate(swing.CLIENTCMD_FILEIO_ISDIRECTORY, [pFilelist[i]]) == "false")
-                    files.push(pFilelist[i]);
-                else
-                    folders.push(pFilelist[i]);
-            }
 
-            //resovle Files in Folders
-            if(folders.length > 0)
-            {
-                for (let j = 0; j < folders.length; j++)
-                {
-                    var resolvedFiles = swing.doClientIntermediate(swing.CLIENTCMD_FILEIO_LISTFILES, [folders[j]]);
-                    if(resolvedFiles.length > 0)
-                    {
-                        for (let k = 0; k < resolvedFiles.length; k++) resolvedFiles[k] = folders[j] + "\\" + resolvedFiles[k];
-                        files = files.concat(resolvedFiles);
-                    }
+/**
+ * returns if an element is in an array; 
+ * this is needed because there is currently no support for Array.prototype.includes() and we cannot easily use a polyfill and extend the Array.prototype
+ *
+ * @param {Array} targetArray array where the element should be searched in 
+ * @param {any primitive type} element the element which should be looked for
+ * @param {Boolean} [ignoreStringCase=false] if you've got a string array y
+ *
+ * @return {Boolean} true if it has the element
+ */
+ArrayUtils.hasElement = function(targetArray, element, ignoreStringCase) {
+    var i, l;
+    if (ignoreStringCase)//do only once to save ressources and not for every array element
+        element = element.toString().toLowerCase();
+    for (i = 0, l = targetArray.length; i < l; i++) {
+        if (ignoreStringCase) {
+            if (targetArray[i].toString().toLowerCase() == element)	
+                return true;
+        }
+        else {
+            if (targetArray[i] == element)
+                return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Class containing utility functions for use with JSON
+ * @class
+ * @static
+ */
+function JSONUtils() {
+}
+
+/**
+ * A custom JSON.stringify() to
+ * - keep the functions as string
+ * - stringify JavaArrays
+ * - stringify undefined as undefined and not as null
+ *
+ * @param {Object} obj the object to stringify
+ *
+ * @return {String} the stringified object as string representation
+ */
+JSONUtils.customStringify = function(obj) {
+    //stringify part from JSON polyfill: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON
+    var toString = Object.prototype.toString;
+    var escMap = {
+        '"': '\\"', 
+        '\\': '\\\\', 
+        '\b': '\\b', 
+        '\f': '\\f', 
+        '\n': '\\n', 
+        '\r': '\\r', 
+        '\t': '\\t'
+    };
+    var escFunc = function (m) {
+        return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1);
+    };
+    var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g;
+
+    var stringify = function (value){
+        //because: "undefined == null" is true
+        if (value === undefined) {
+            return 'undefined';
+        } else if (value == null) {
+            return 'null';
+        } else if (typeof value === 'number') {
+            return isFinite(value) ? value.toString() : 'null';
+        } else if (typeof value === 'boolean') {
+            return value.toString();
+        } else if (typeof value === 'object')
+{
+            //check with "hasOwnProperty" because in JavaArrays using value.toJSON would cause an exception
+            if (toString.call(value) != '[object Map]' && value.hasOwnProperty("toJSON") && typeof value.toJSON === 'function') {
+                return value.toString();
+            } else if (toString.call(value) === '[object Array]') {
+                var res = '[';
+                for (var i = 0; i < value.length; i++)
+                    res += (i ? ', ' : '') + stringify(value[i]);
+                return res + ']';
+            } else if (toString.call(value) === '[object Object]' || toString.call(value) === '[object Map]') {
+                var tmp = [];
+                for (var k in value) {
+                    if (hasOwnProperty.call(value, k))
+                        tmp.push(stringify(k) + ': ' + stringify(value[k]));
                 }
+                return '{' + tmp.join(', ') + '}';
+            //custom addition to stringify Rhino JavaArrays
+            } else if (toString.call(value) === '[object JavaArray]') {
+                return value.toSource().toString();
             }
-
-            //recursive call, cause more subfolders may be present
-            if( that.hasSubfolders(files) )
-                files = that.resolveSubfolders(files);
         }
-
-        //filter out files, that exceed the size limit
-        var retfiles = [];
-        for (let m = 0; m < files.length; m++)
+        //custom addition for function transform
+        //JSON.stringify returns null on functions (default)
+        //instead return source code of funciton for callback-functions
+        else if (typeof value === 'function')
         {
-            if(retfiles.length == fileamount)
-                break;
-
-            if(swing.doClientIntermediate(swing.CLIENTCMD_FILEIO_GETLENGTH, [files[m]]) <= filesize)
-                retfiles.push(files[m]);
+            return value.toString();
         }
 
-        logging.log(retfiles)
-        return retfiles;
+        return '"' + value.toString().replace(escRE, escFunc) + '"';
     }
-    /**
-     *  Checks if subfolders are present in a filelist
-     *
-     *  @param {String[]} pFilelist req the file list as string array
-     *  
-     *  
-     */
-    this.hasSubfolder = function(pFilelist)
-    {
-        var ret = false;
-        if(pFilelist != undefined && pFilelist.length > 0)
-        {
-            for (let i = pFilelist.length; i >= 0; i--)
-            {
-                if(swing.doClientIntermediate(swing.CLIENTCMD_FILEIO_ISDIRECTORY, [pFilelist[i]]) == "true")
-                {
-                    ret = true;
-                    break;
-                }
 
-            }
-        }
-        return ret;
+    return stringify(obj);
+}
+
+/**
+ * Class containing functions for sequential numbers
+ * @class
+ * @static
+ */
+function NumberSequencingUtils(){
+}
+    
+/**
+ * Delivers the next unique number
+ *
+ * @param {String} pColumn database column that contains unique numbers
+ * @param {String} pTable database table
+ * @param {Number} [pStartNumber=1000] number to start numeration
+ * @param {String} [pCondition=no condition] SQL Where Conditon
+ * 
+ * @result {String} next valid number
+ */
+NumberSequencingUtils.getNextUniqueNumber = function(pColumn, pTable, pStartNumber, pCondition) {
+    var maxNum = NumberSequencingUtils.getMaxUniqueNumber(pColumn, pTable, pCondition);
+    if(maxNum == "0") {
+        if(pStartNumber == undefined)   pStartNumber = 1000;
+        return pStartNumber;
     }
+    return eMath.addInt(maxNum, "1");//increment currently highest number
+}
     
+/**
+ * Checks if the passed number is valid (has to be unique)
+ * 
+ * @param {String} pNumber number to check
+ * @param {String} pColumn req database column that contains unique numbers
+ * @param {String} pTable req database table
+ * @param {String} pCondition opt SQL Where Conditon
+ * 
+ * @result {boolean} passed number is valid
+ */
+NumberSequencingUtils.validateUniqueNumber = function(pNumber, pColumn, pTable, pCondition) {
+    var maxNum = NumberSequencingUtils.getMaxUniqueNumber(pColumn, pTable, pCondition);
+    return Number(pNumber) > Number(maxNum);
+}
+    
+/**
+ * Delivers the hightest number currently stored in database
+ * 
+ * @param {String} pColumn req database column that contains unique numbers
+ * @param {String} pTable req database table
+ * @param {String} pCondition opt SQL Where Conditon
+ * 
+ * @result {String} hightest number
+ */
+NumberSequencingUtils.getMaxUniqueNumber = function(pColumn, pTable, pCondition) {
+    var condition = "";
+    if(pCondition != undefined)
+        condition += " where " + pCondition;
+    var maxNum = db.cell("select max(" + pColumn + ") from " + pTable + condition);
+    return maxNum == "" ? "0" : maxNum;
 }
+
 /**
  * Class containing miscellaneous utiltiy function extending JDito
  * @class
+ * @deprecated
+ * @todo: remove
  */
 function JDitoUtils()
 {
-    var that = this;
-    /**
-     * A wrapper for process.executeScript
-     *
-     * @param {String} pIdentifier req The identifier for the script (for better error logging)
-     * @param {String} pScript req The script to execute
-     * @param {Object} pLocalVariables opt The local variables which can be accessed within the script
-     * @param {Array} pImports opt To add additional imports  which will be prepended to the script
-     * @param {Boolean} pWrapIntoResult opt To wrap pScript into 'result.string("***")'
-     * @param {String} pAlias opt The alias to use within the script
-     *
-     * @return {Object} The result of the script
-     *
-     */
-    this.evalScript = function(pIdentifier, pScript, pLocalVariables, pImports, pWrapIntoResult, pAlias)
-    {
-        var defaultImports = ["system.result", "system.vars"];
-        var importsToPrepend = [];
-
-        // add pImports to to defaultImports
-        if (pImports != undefined) defaultImports = defaultImports.concat(pImports);
-
-        // go trough all defaultImports an check if they already exists
-        for (var i = 0; i < defaultImports.length; i++ )
-        {
-            var cImport = "import(\"" + defaultImports[i] + "\");";
-
-            if (pScript.indexOf(cImport) == -1)
-            {
-                // If the current default import was not found within the script it will be prepended
-                importsToPrepend.push(cImport);
-            }
-        }
-
-        // join the imports to prepend and place them in front of a new variable
-        var script2Execute = importsToPrepend.join("\r\n") + (importsToPrepend.length > 0 ? "\r\n" : "");
-
-        // Check if the script needs to be wrapped into result.string() (e.g. (function(){return "result";})())
-        if (pWrapIntoResult)
-            script2Execute += "\r\nresult.string(" + pScript + ");\r\n"; // Wrap into 'result.string("***")'
-        else
-            script2Execute += pScript; // Just add the script after the prepended imports
-
-        return process.executeScript("[evalScript]" + pIdentifier, script2Execute, (pLocalVariables != undefined && pLocalVariables != null ? pLocalVariables : {}), (pAlias != undefined && pAlias != null ? pAlias : null));
-    }
-
     /**
      * Returns a list of aliasNames with a given type
      * ignores errors when an alias is not confgiured (empty)
@@ -863,617 +451,36 @@ function JDitoUtils()
 
         return dbAliases;
     }
-
-    /**
-    * returns a sorted and translated list of countries ;
-    * DE, AT and CH are at the beginning of the list, if pData is undefined
-    *
-    * @param {String} pLanguage opt Sprache
-    * @param {String[][]} pData opt if the data should not be gathered automatically
-    *                               it can be given to this parameter.
-    *                               with this, the function can be used to translate country names
-    *
-    * @return {String[][]} consisting of ISO2 and Name
-    *
-    * 
-    */
-    this.getCountries = function(pLanguage, pData)
-    {
-        var data, temp;
-        if(pData == undefined)
-        {
-            data = [ ["DE", "Deutschland"], ["AT", "Österreich"], ["CH", "Schweiz"] ];
-            temp = db.table("select COUNTRYINFO.ISO2, COUNTRYINFO.NAME_DE "
-                + "from COUNTRYINFO "
-                + "where COUNTRYINFO.ISO2 not in ('DE', 'AT', 'CH')");
-        }
-        else
-        {
-            data = [];
-            temp = pData;
-        }
-
-        for(var i = 0; i < data.length; i++)    
-            data[i][1] = translateStr(data[i][1], pLanguage);
-        for(let i = 0; i < temp.length; i++)    
-            temp[i][1] = translateStr(temp[i][1], pLanguage).trim();
-
-        //Sortierung nach der Ãœbersetzung
-        array_mDimSort(temp, 1, true, false);
-
-        return data.concat(temp);
-    }
-    
-    /**
-     * Delivers the next unique number
-     *
-     * @param {String} pColumn req database column that contains unique numbers
-     * @param {String} pTable req database table
-     * @param {Number} pStartNumber opt number to start numeration
-     * @param {String} pCondition opt SQL Where Conditon
-     * 
-     * @result {String} next valid number
-     */
-    this.getNextUniqueNumber = function(pColumn, pTable, pStartNumber, pCondition){
-        var maxNum = that.getMaxUniqueNumber(pColumn, pTable, pCondition);
-        
-        if(maxNum == "0")    
-        {
-            if(pStartNumber == undefined)   pStartNumber = 1000;
-            return pStartNumber;
-        }
-        
-        return eMath.addInt(maxNum, "1");//increment currently highest number
-    }
-    
-    /**
-     * Checks if the passed number is valid (has to be unique)
-     * 
-     * @param {String} pNumber number to check
-     * @param {String} pColumn req database column that contains unique numbers
-     * @param {String} pTable req database table
-     * @param {String} pCondition opt SQL Where Conditon
-     * 
-     * @result {boolean} passed number is valid
-     */
-    this.validateUniqueNumber = function(pNumber, pColumn, pTable, pCondition){
-        var maxNum = that.getMaxUniqueNumber(pColumn, pTable, pCondition);
-        
-        return Number(pNumber) > Number(maxNum);
-    }
-    
-    /**
-     * Delivers the hightest number currently stored in database
-     * 
-     * @param {String} pColumn req database column that contains unique numbers
-     * @param {String} pTable req database table
-     * @param {String} pCondition opt SQL Where Conditon
-     * 
-     * @result {String} hightest number
-     */
-    this.getMaxUniqueNumber = function(pColumn, pTable, pCondition){
-        
-        var condition = "";
-        if(pCondition != undefined)
-            condition += " where " + pCondition;
-        
-        var maxNum = db.cell("select max(" + pColumn + ") from " + pTable + condition);
-        
-        return maxNum == "" ? "0" : maxNum;
-    }
 }
-/**
- * Class containing utility functions for use with JSON
- * @class
- */
-function JSONUtils()
-{
-    /**
-     * A custom JSON.stringify() to
-     * - keep the functions as string
-     * - stringify JavaArrays
-     * - stringify undefined as undefined and not as null
-     *
-     * @param {Object} pObj req The object to stringify
-     *
-     * @return {String} The stringified string
-     * 
-     * 
-     */
-    this.stringifyJSON = function(pObj)
-    {
-        //stringify part from JSON polyfill: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON
-        var toString = Object.prototype.toString;
-        var escMap = {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'};
-        var escFunc = function (m) { return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); };
-        var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g;
-
-        var stringify = function (value){
-          //because: "undefined == null" is true
-          if (value === undefined) {
-            return 'undefined';
-          } else if (value == null) {
-            return 'null';
-          } else if (typeof value === 'number') {
-            return isFinite(value) ? value.toString() : 'null';
-          } else if (typeof value === 'boolean') {
-            return value.toString();
-          } else if (typeof value === 'object')
-          {
-              //check with "hasOwnProperty" because in JavaArrays using value.toJSON would cause an exception
-             if (toString.call(value) != '[object Map]' && value.hasOwnProperty("toJSON") && typeof value.toJSON === 'function') {
-              return value.toString();
-            } else if (toString.call(value) === '[object Array]') {
-              var res = '[';
-              for (var i = 0; i < value.length; i++)
-                res += (i ? ', ' : '') + stringify(value[i]);
-              return res + ']';
-            } else if (toString.call(value) === '[object Object]' || toString.call(value) === '[object Map]') {
-              var tmp = [];
-              for (var k in value) {
-                if (hasOwnProperty.call(value, k))
-                  tmp.push(stringify(k) + ': ' + stringify(value[k]));
-              }
-              return '{' + tmp.join(', ') + '}';
-            //custom addition to stringify Rhino JavaArrays
-            } else if (toString.call(value) === '[object JavaArray]') {
-                return value.toSource().toString();
-            }
-          }
-          //custom addition for function transform
-          //JSON.stringify returns null on functions (default)
-          //instead return source code of funciton for callback-functions
-          else if (typeof value === 'function')
-          {
-              return value.toString();
-          }
-
-          return '"' + value.toString().replace(escRE, escFunc) + '"';
-        }
-
-        return stringify(pObj);
-    }
-    /**
-     * checks if pStr is JSON
-     *
-     * @param {pStr}
-     *
-     * @return false or parsed JSON
-     * 
-     * 
-     */
-    this.isJSON = function(pStr)
-    {
-        if (typeof(pStr) != "string")
-            return false;
-
-        if (pStr[0] != "{")
-            return false;
-
-        if (pStr[pStr.length-1] != "}")
-            return false;
-
-        try
-        {
-            var parse = JSON.parse(pStr);
-            return parse;
-        }
-        catch (ex)
-        {
-            return false;
-        }
 
-        return parse;
-    }    
-}
 
 /**
- * Class containing utility functions for copying modules
+ * Class containing String utility functions
  * @class
+ * @deprecated
+ * @todo: remove this funciton
  */
-function CopyModuleUtils()
+function StringUtils(){}
 {
-    var that = this;
     
     /**
-     * opens the new created modules in neonClient
-     * 
-     * @param {String} pNeonContext req Name of the neon context that should be opened
-     * @param {Object} pModulesMapping req ModulesMapping object created by method copyModule
-     * 
-     * @example var ModulesMapping = CMUtils.copyModule(InputMapping);
-     *
-     *   CMUtils.openNewModules("Offer_context", ModulesMapping);
-     */
-    this.openNewModules = function(pNeonContext, pModulesMapping)
-    {
-        if(pModulesMapping != undefined)
-        {
-            var rootModule = Object.keys(pModulesMapping)[0];
-            if(pModulesMapping[rootModule].DataRows != undefined)
-            {
-                var newids = [];
-
-                for(var row in pModulesMapping[rootModule].DataRows)
-                {
-                    newids.push(pModulesMapping[rootModule].DataRows[row].newPrimaryKey);
-                }
-
-                if(newids.length > 0)
-                    neon.openContext(pNeonContext, newids, neon.OPERATINGSTATE_VIEW, null);
-            }
-        }
-    }
-    
-   /**
-    *   Creates a copy of a specified module together with specified subordinated modules. <br>
-    *   The structure of the input mapping object is the following:  <br>
-    *  pInputMapping {
-    *   (only one rootModule allowed)
-    *    $rootModule$: { 
-    *        condition: "sqlWhereCondition"
-    *        , ValueMapping: {$colName$: "value"}
-    *        , destinationModuleName: "destinationModuleName"
-    *        , DestinationColumnMapping: { $sourceColName$ : "destinationColName" }  
-    *        , SubModules: {
-    *            $Module$:{ 
-    *                condition: "sqlWhereCondition"
-    *                , ValueMapping: {$colName$: "value"}
-    *                , destinationModuleName: "destinationModuleName"
-    *                , DestinationColumnMapping: { $sourceColName$ : "destinationColName" }  
-    *                , SubModules: {...}
-    *            }
-    *        }
-    *    }
-    * }
-    * 
-    * @param {Object} pInputMapping
-    *
-    * @example var CMUtils = new CopyModuleUtils();
+    * uses the right translate method, depending on the parameters
     *
-    *    var InputMapping = {
+    * @param {String} pText string to be translated
+    * @param {String} pLocale locale for translating
     *
-    *        "OFFER": {
-    *                condition: "OFFERID = '" + vars.get("$field.OFFERID") + "'"
-    *                ,SubModules:{
-    *                    "OFFERITEM": {
-    *                        condition: "OFFER_ID = '" + vars.get("$field.OFFERID") + "' order by ITEMSORT" 
-    *                }
-    *            }
-    *        }
-    *    }
+    * @return {String}
     *
-    *    CMUtils.copyModule(InputMapping);
+    * 
     */
-    this.copyModule = function(pInputMapping)
+    this.translateStr = function( pText, pLocale )
     {
-        var AliasDefinitionStructure = project.getAliasDefinitionStructure("Data_alias", null);
-        var ModulesMapping = {};
-        var statements = [];
-
-        buildMapping( pInputMapping );
-        buildStatements( ModulesMapping );
-        
-        if(statements.length > 0)
-            db.inserts( statements ); 
-        
-        return ModulesMapping;
-        
-        /**
-         * Builds a mapping Object for the copyModule Method.  <br>
-         * The structure of the Object is the following:  <br>
-         * ModulesMapping = {  
-         * 
-         *   $rootModule$: { ($$ marks an object property) 
-         *   
-         *        (ModuleMapping) 
-         *        name: "moduleName"  
-         *        , destinationModuleName: "destinationModuleName" 
-         *        , DestinationColumnMapping: { $sourceColName$ : "destinationColName" } 
-         *        , ValueMapping: {$colName$: "value"} 
-         *        , dataRows:{ 
-         *            (ModuleRowMapping) 
-         *            $rowid$: {  
-         *                name: "moduleName" 
-         *                , oldPrimaryKey: "oldPrimaryKeyValue" 
-         *                , newPrimaryKey: "newPrimaryKeyValue" 
-         *                , ColumnMapping: { $colName$: { newValue: "newValue", oldValue: "oldValue", destinationColumn: "destinationColumn" } } 
-         *                , ModuleMapping: object reference to ModuleMapping object that contains ModuleRowMapping objects 
-         *                , ParentModuleMapping: object reference to supervised ModuleMapping object (at this point "null" because there is no supervised object) 
-         *            } 
-         *        }   
-         *        , SubModules: { 
-         *                  (ModuleMapping) 
-         *                  $moduleName$: { 
-         *                       name: "moduleName" 
-         *                      , destinationModuleName: "destinationModuleName" 
-         *                      , DestinationColumnMapping: { $sourceColName$ : "destinationColName" } 
-         *                      , ValueMapping: {$colName$: "value"} 
-         *                      , dataRows:{ 
-         *                          (ModuleRowMapping) 
-         *                           $rowid$: {  
-         *                              name: "moduleName" 
-         *                              , oldPrimaryKey: "oldPrimaryKeyValue" 
-         *                              , newPrimaryKey: "newPrimaryKeyValue" 
-         *                              , ColumnMapping: { $colName$: { newValue: "newValue", oldValue: "oldValue", destinationColumn: "destinationColumn" } } 
-         *                              , ModuleMapping:  
-         *                              , ParentModuleMapping: object reference to supervised ModuleMapping object (at this point "null" because there is no supervised object) 
-         *                           } 
-         *                      } 
-         *                      , SubModules: {...} 
-         *                  } 
-         *        }  
-         *
-         *   } 
-         *
-         *} 
-         *
-         * @param {Object} pInputMapping InputMapping
-         */
-        function buildMapping(pInputMapping)
-        {
-            //root mapping
-            var rootModule = Object.keys(pInputMapping)[0];
-            var ModuleMapping = _ModuleMapping(rootModule, pInputMapping[rootModule]);
-            var ModuleData = _getModuleData(rootModule, pInputMapping[rootModule].condition);
-            
-            for(var row in ModuleData)
-            {
-                var ModuleRowMapping = _ModuleRowMapping(ModuleMapping, null, ModuleData[row]);
-
-                ModuleMapping.DataRows[ModuleRowMapping.oldPrimaryKey] = ModuleRowMapping;
-            }
-            
-            ModulesMapping[rootModule] = ModuleMapping;
-            
-            //recursive subordinated modules mapping
-            _buildSubordinatedMapping(pInputMapping, ModuleMapping);
-            
-            
-            //delivers stored data for module in Database with condition
-            function _getModuleData(pModule, pCondition)
-            {
-                if(pModule == undefined)    return {};
-                
-                var ModuleColumnsStructure = AliasDefinitionStructure.tables[pModule].columns;
-                var cols = Object.keys(ModuleColumnsStructure);
-                
-                var condition = "1=1";
-                if(pCondition != undefined)
-                    condition = pCondition;
-
-                var dbData = db.table("select " + cols.join(", ") + " from " + pModule + " where " + condition);
-                
-                //map 2d-Array to Object { $rowNumber$: { $columnName$: { value: "valueInDB" } } }
-                var DataObj = {};
-                for(var row = 0; row < dbData.length; row++)
-                {
-                    DataObj[row] = {};
-                    for(var col = 0; col < dbData[row].length; col++)
-                    {
-                        DataObj[row][cols[col]] = {
-                            value: dbData[row][col]
-                        };
-                    }
-                }
-
-                return DataObj;
-            }
-            
-            
-            //recursive: ModuleMapping and ModuleRowMapping for subordinated modules
-            function _buildSubordinatedMapping(pInputMapping, pParentModuleMapping)
-            {
-                var SubModules = pInputMapping[pParentModuleMapping.name].SubModules;
-                if(SubModules == undefined)
-                    return;
-
-                for(var subModuleName in SubModules)
-                {
-                    var ModuleMapping = _ModuleMapping(subModuleName, SubModules[subModuleName]);
-                    ModuleData = _getModuleData(subModuleName, SubModules[subModuleName].condition);
-                    for(var row in ModuleData)
-                    {
-                        ModuleRowMapping = _ModuleRowMapping(ModuleMapping, pParentModuleMapping, ModuleData[row]);
-                        ModuleMapping.DataRows[ModuleRowMapping.oldPrimaryKey] = ModuleRowMapping;
-                    }
-
-                    ModulesMapping[pParentModuleMapping.name].SubModules[subModuleName] = ModuleMapping;
-
-                    _buildSubordinatedMapping(SubModules, ModuleMapping);
-                }
-            }
-            
-            function _ModuleMapping( pModuleName, pInputModuleMapping )
-            {
-                return {
-                    name: pModuleName,
-                    destinationModuleName: pInputModuleMapping.destinationModuleName == undefined ? pModuleName : pInputModuleMapping.destinationModuleName,
-                    DestinationColumnMapping: pInputModuleMapping.DestinationColumnMapping == undefined ? {} : pInputModuleMapping.DestinationColumnMapping,
-                    ValueMapping: pInputModuleMapping.ValueMapping == undefined ? {} : pInputModuleMapping.ValueMapping,
-                    DataRows:{}, 
-                    SubModules: {}
-                };
-            }
-
-            function _ModuleRowMapping(pModuleMapping, pParentModuleMapping, pDataRow)
-            {
-                var ModuleRowMapping = {
-                    name: pModuleMapping.name,
-                    oldPrimaryKey: null,
-                    newPrimaryKey: null,
-                    ColumnMapping: {},
-                    ModuleMapping: pModuleMapping,
-                    ParentModuleMapping: pParentModuleMapping
-                };
-
-                var ModuleColumnsStructure = AliasDefinitionStructure.tables[ModuleRowMapping.name].columns;
-
-               //build ColumnMapping
-                for(var col in ModuleColumnsStructure)
-                {
-                    //set defined columns from InputMapping -> if not defined, use the same column
-                    var destinationColumn = ModuleRowMapping.ModuleMapping.DestinationColumnMapping[col];
-                    if(destinationColumn == undefined)
-                        destinationColumn = col; 
-                    
-                    //set defined values from InputMapping -> if not defined, use the value from DB
-                    var oldValue = pDataRow[col].value;
-                    var newValue = newValue = ModuleRowMapping.ModuleMapping.ValueMapping[col];
-                    if(newValue == undefined)
-                        newValue = oldValue;
-                    
-                    //set new primary key
-                    if(ModuleColumnsStructure[col].primaryKey)  
-                    {
-                        ModuleRowMapping.oldPrimaryKey = ModuleRowMapping.ColumnMapping[col] = oldValue;
-                        newValue = util.getNewUUID();
-                        ModuleRowMapping.newPrimaryKey = newValue;
-                    }
-                    
-                    ModuleRowMapping.ColumnMapping[col] = _columnMapping(newValue, oldValue, destinationColumn);
-                }
-
-                switch(ModuleRowMapping.name)
-                {
-                    case "OFFER":
-                    {
-                        //andere Values setzen
-                        var dtUtils = new DateUtils();
-                        ModuleRowMapping.ColumnMapping["OFFERDATE"].newValue = dtUtils.getTodayUTC();
-                    }
-                    break;
-                    case "OFFERITEM":
-                    {
-                        //OFFER_ID mappen
-                        if(ModuleRowMapping.ParentModuleMapping.name == "OFFER")
-                        {
-                            ModuleRowMapping.ColumnMapping["OFFER_ID"].newValue = ModulesMapping[ModuleRowMapping.ParentModuleMapping.name].DataRows[ModuleRowMapping.ColumnMapping["OFFER_ID"].oldValue].newPrimaryKey;
-                        }
-                        //ASSIGNEDTO mappen
-                        if(ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].oldValue != "")
-                        {
-                            if(ModuleRowMapping.ParentModuleMapping == null)
-                            {
-                                ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].newValue = ModulesMapping["OFFERITEM"].DataRows[ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].oldValue].newPrimaryKey;
-                            }
-                            else
-                            {
-                                ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].newValue = ModuleRowMapping.ModuleMapping.DataRows[ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].oldValue].newPrimaryKey;
-                            }
-                        }
-                    }
-                    break;
-                    case "OFFERLINK":
-                    {
-
-                    }
-                    default:
-                    {
-
-                    }
-
-
-                }
-
-                //Spezialbehandlung USER_NEW DATENEW....
-                if(ModuleRowMapping.ColumnMapping["DATE_NEW"] != undefined)        ModuleRowMapping.ColumnMapping["DATE_NEW"].newValue = datetime.date();
-                if(ModuleRowMapping.ColumnMapping["USER_NEW"] != undefined)        ModuleRowMapping.ColumnMapping["USER_NEW"].newValue = vars.get("$sys.user");
-                if(ModuleRowMapping.ColumnMapping["DATE_EDIT"] != undefined)        ModuleRowMapping.ColumnMapping["DATE_EDIT"].newValue = "";
-                if(ModuleRowMapping.ColumnMapping["USER_EDIT"] != undefined)        ModuleRowMapping.ColumnMapping["USER_EDIT"].newValue = "";
-
-                return ModuleRowMapping;
-            }
-            
-            
-            
-            
-            function _columnMapping(pNewValue, pOldValue, pDestinationColumn)
-            {
-                return {
-                    newValue: pNewValue,
-                    oldValue: pOldValue,
-                    destinationColumn: pDestinationColumn
-                };
-            }
-
-        }
-        
-        /**
-         * Builds the insert statements for passed ModulesMapping
-         * 
-         * @param {Object} pModulesMapping ModulesMapping from buildMapping()
-         */
-        function buildStatements(pModulesMapping)
-        {   
-            var rootModule = Object.keys(pModulesMapping)[0];
-
-            for(var row in pModulesMapping[rootModule].DataRows)
-            {
-                //buildInsertStatement
-                statements.push(_statement(pModulesMapping[rootModule].DataRows[row]));
-            }
-
-            _subordinatedStatements(pModulesMapping[rootModule]);
-
-            function _subordinatedStatements(pMapping)
-            {
-                if(pMapping.SubModules == undefined)
-                    return;
-
-                for(var subModule in pMapping.SubModules)
-                {
-
-                    for(var row in pMapping.SubModules[subModule].DataRows)
-                    {
-                        statements.push(_statement(pMapping.SubModules[subModule].DataRows[row]));
-                    }
-
-                    _subordinatedStatements(pMapping.SubModules[subModule]);
-                }
-
-            }
-
-            function _statement(pRowMapping)
-            {
-                var cols = [];
-                var vals = [];
-                var destTable = pRowMapping.ModuleMapping.destinationModuleName;
-                var colMapping = pRowMapping.ColumnMapping;
-
-                for(var col in colMapping)
-                {
-                    cols.push(colMapping[col].destinationColumn);
-                    vals.push(colMapping[col].newValue.toString());
-                }
-
-                var colTypes = db.getColumnTypes(destTable, cols)
-
-                return [destTable, cols, colTypes, vals];
-            }
-        }
+        if ( pLocale == undefined )   
+            return translate.text(pText);
+        else 
+            return translate.text(pText, pLocale)
     }
-}
-
-/**
-* provides somehow static methods for special handling in JDito-Processes
-* do not create an instance of this
-* @class
-*/
-ProcessHandlingUtil = {
     
-    /**
-    * In onValidation-Process a local variable called "$local.value" is made available from kernel.
-    * It contains the entered value - the field contains the value only after successfull validation (vars.get("$field.Fieldname")).
-    * The onValidation-Process is running again before saving the entity, at this point there's "$local.value" varialbe no longer available,
-    * but the entered value now is the present one because the field has already been validated before.
-    * Otherwise a "variable not found" error would occur.
-    *
-    * @param {String} pFieldValue req value of the field onValidation-Process is executed ( e.g. vars.get("$field.Fieldname") )
-    * @return {String} Field value for onValidation-Process
-    */
-    getOnValidationValue: function(pFieldValue)
-    {
-        return vars.exists("$local.value") ? vars.get("$local.value") : pFieldValue;
-    }
+
 }
+