From 0d8d9e161501fb0a4eda9a4b9706ba8e0a9e3459 Mon Sep 17 00:00:00 2001
From: "j.goderbauer" <j.goderbauer@adito.de>
Date: Fri, 5 Oct 2018 13:52:38 +0200
Subject: [PATCH] [Projekt: Entwicklung - Neon][TicketNr.: 1023713][COMM -
 Standard setzten (Aktion, Button, Darstellung)]

---
 .../is_standard/possibleItemsProcess.js       |   12 +-
 entity/Comm_entity/Comm_entity.aod            |   32 +-
 entity/Comm_entity/conditionProcess.js        |   35 +-
 .../entityfields/commid/valueProcess.js       |    2 +
 .../entityfields/is_standard/valueProcess.js  |    8 +-
 .../medium_id/possibleItemsProcess.js         |   28 +-
 .../medium_id/valueMappingProcess.js          |    8 +
 entity/Pers_entity/Pers_entity.aod            |   60 +
 .../mediumcategoriesfilter_param/code.js      |    4 +
 .../children/relid_param/code.js              |    4 +
 .../mediumcategoriesfilter_param/code.js      |    4 +
 .../children/relid_param/code.js              |    4 +
 .../mediumcategoriesfilter_param/code.js      |    4 +
 .../children/relid_param/code.js              |    4 +
 .../_____LANGUAGE_EXTRA.aod                   |  616 ++---
 .../_____LANGUAGE_de/_____LANGUAGE_de.aod     |  764 +++---
 .../_____LANGUAGE_en/_____LANGUAGE_en.aod     |  608 ++---
 .../PersPreview_view/PersPreview_view.aod     |  134 +-
 process/Keyword_lib/process.js                |  479 ++--
 process/Sql_lib/process.js                    | 2070 +++++++++--------
 20 files changed, 2572 insertions(+), 2308 deletions(-)
 create mode 100644 entity/Comm_entity/entityfields/commid/valueProcess.js
 create mode 100644 entity/Comm_entity/entityfields/medium_id/valueMappingProcess.js
 create mode 100644 entity/Pers_entity/entityfields/perscommemail_dfo/children/mediumcategoriesfilter_param/code.js
 create mode 100644 entity/Pers_entity/entityfields/perscommemail_dfo/children/relid_param/code.js
 create mode 100644 entity/Pers_entity/entityfields/perscommothers_dfo/children/mediumcategoriesfilter_param/code.js
 create mode 100644 entity/Pers_entity/entityfields/perscommothers_dfo/children/relid_param/code.js
 create mode 100644 entity/Pers_entity/entityfields/perscommphone_dfo/children/mediumcategoriesfilter_param/code.js
 create mode 100644 entity/Pers_entity/entityfields/perscommphone_dfo/children/relid_param/code.js

diff --git a/entity/Address_entity/entityfields/is_standard/possibleItemsProcess.js b/entity/Address_entity/entityfields/is_standard/possibleItemsProcess.js
index b429686afd5..11676c10f99 100644
--- a/entity/Address_entity/entityfields/is_standard/possibleItemsProcess.js
+++ b/entity/Address_entity/entityfields/is_standard/possibleItemsProcess.js
@@ -1,7 +1,7 @@
-import("system.translate");
-import("system.result");
-
-result.object([
-     ["true", translate.text("Standardadresse")]
-    ,["false", ""]
+import("system.translate");
+import("system.result");
+
+result.object([
+     ["true", translate.text("standard address")]
+    ,["false", ""]
 ]);
\ No newline at end of file
diff --git a/entity/Comm_entity/Comm_entity.aod b/entity/Comm_entity/Comm_entity.aod
index 6cee6425031..3841980aa55 100644
--- a/entity/Comm_entity/Comm_entity.aod
+++ b/entity/Comm_entity/Comm_entity.aod
@@ -15,11 +15,13 @@
       <columnName>ADDR</columnName>
       <caption>${COMM_ADDRESS}</caption>
       <contentTypeProcess>%aditoprj%/entity/Comm_entity/entityfields/addr/contentTypeProcess.js</contentTypeProcess>
+      <valueProcess>%aditoprj%/entity/Comm_entity/entityfields/addr/valueProcess.js</valueProcess>
     </entityField>
     <entityField>
       <name>COMMID</name>
       <tableName>COMM</tableName>
       <columnName>COMMID</columnName>
+      <valueProcess>%aditoprj%/entity/Comm_entity/entityfields/commid/valueProcess.js</valueProcess>
     </entityField>
     <entityField>
       <name>DATE_EDIT</name>
@@ -39,6 +41,7 @@
       <columnName>MEDIUM_ID</columnName>
       <caption>Medium</caption>
       <possibleItemsProcess>%aditoprj%/entity/Comm_entity/entityfields/medium_id/possibleItemsProcess.js</possibleItemsProcess>
+      <valueMappingProcess>%aditoprj%/entity/Comm_entity/entityfields/medium_id/valueMappingProcess.js</valueMappingProcess>
     </entityField>
     <entityField>
       <name>RELATION_ID</name>
@@ -66,7 +69,8 @@
     <entityParameter>
       <name>RelId_param</name>
       <expose v="true" />
-      <description>PARAMETER</description>
+      <description>This parameter is used for specifing a related &amp;quot;RELATIONID&amp;quot; to a COMM-entry. 
+Usually this is used for filtering COMM-entires by a specified contact or creating a new entry that is related to a contact.</description>
     </entityParameter>
     <entityIncomingField>
       <name>PersComm_dfi</name>
@@ -78,6 +82,24 @@
           <fieldName>PersComm_dfo</fieldName>
           <isOutgoing v="false" />
         </entityDependency>
+        <entityDependency>
+          <name>6bee4be4-34bd-47fc-a909-8e8bbf2f45f2</name>
+          <entityName>Pers_entity</entityName>
+          <fieldName>PersCommPhone_dfo</fieldName>
+          <isOutgoing v="false" />
+        </entityDependency>
+        <entityDependency>
+          <name>89ff88fa-029f-4b0d-a358-b7b310a6e72c</name>
+          <entityName>Pers_entity</entityName>
+          <fieldName>PersCommOthers_dfo</fieldName>
+          <isOutgoing v="false" />
+        </entityDependency>
+        <entityDependency>
+          <name>90c0436e-3a46-40ec-ae73-b4aaded95bbc</name>
+          <entityName>Pers_entity</entityName>
+          <fieldName>PersCommEmail_dfo</fieldName>
+          <isOutgoing v="false" />
+        </entityDependency>
       </dependencies>
     </entityIncomingField>
     <entityIncomingField>
@@ -97,6 +119,14 @@
       <contentType>BOOLEAN</contentType>
       <valueProcess>%aditoprj%/entity/Comm_entity/entityfields/is_standard/valueProcess.js</valueProcess>
     </entityField>
+    <entityParameter>
+      <name>MediumCategoriesFilter_param</name>
+      <expose v="true" />
+      <mandatory v="false" />
+      <description>This param is used for filtering the categories of MEDIUM_IDs. For example share mobile-phone and in-house-telephone the same category (it&amp;apos;s a telephone-number).
+So, for only showing telephone-types you&amp;apos;ve to specify this parameter with it&amp;apos;s phone-number-category.
+</description>
+    </entityParameter>
   </entityFields>
   <linkInformation>
     <linkInformation>
diff --git a/entity/Comm_entity/conditionProcess.js b/entity/Comm_entity/conditionProcess.js
index 0d4b526962a..6693257607e 100644
--- a/entity/Comm_entity/conditionProcess.js
+++ b/entity/Comm_entity/conditionProcess.js
@@ -1,8 +1,27 @@
-import("system.logging");
-import("system.result");
-import("system.vars");
-
-if(vars.exists("$param.RelId_param") && vars.get("$param.RelId_param") != null)
-    result.string("COMM.RELATION_ID = ('" + vars.getString("$param.RelId_param") + "')");  
-else
-    result.string("1 = 2");  
\ No newline at end of file
+import("system.text");
+import("system.result");
+import("system.vars");
+import("Sql_lib");
+import("Keyword_lib");
+
+var cond, relId, mediumCategories, keywordUtil;
+
+cond = "";
+if(vars.exists("$param.RelId_param") && (relId = vars.get("$param.RelId_param")) != null){
+    cond += " and COMM.RELATION_ID in ('" + relId + "')";//TODO: quoting/prevent sql-injection 
+}
+if (vars.exists("$param.MediumCategoriesFilter_param") && (mediumCategories = vars.get("$param.MediumCategoriesFilter_param")) != null){
+    mediumCategories = text.decodeMS(mediumCategories);
+    keywordUtil = new KeywordUtils();
+    var kwd = keywordUtil.createKeyword("COMM.MEDIUM");
+    kwd.filter(function(id, name, customs){
+        return mediumCategories.indexOf(customs.category) > -1;
+    });
+    mediumIds = kwd.toArray("id");
+    if (mediumIds.length == 0)
+        throw new Error();//TODO: add message
+        
+    cond += " and COMM.MEDIUM_ID in (" + mediumIds.join(", ") + ")";
+}
+
+result.string(cond ? "1 = 1 " + cond: "1 = 2");
\ No newline at end of file
diff --git a/entity/Comm_entity/entityfields/commid/valueProcess.js b/entity/Comm_entity/entityfields/commid/valueProcess.js
new file mode 100644
index 00000000000..7a874732d3c
--- /dev/null
+++ b/entity/Comm_entity/entityfields/commid/valueProcess.js
@@ -0,0 +1,2 @@
+import("system.vars");
+vars.get("$param.RelId_param")
\ No newline at end of file
diff --git a/entity/Comm_entity/entityfields/is_standard/valueProcess.js b/entity/Comm_entity/entityfields/is_standard/valueProcess.js
index 64cb76b496b..c973c9d87af 100644
--- a/entity/Comm_entity/entityfields/is_standard/valueProcess.js
+++ b/entity/Comm_entity/entityfields/is_standard/valueProcess.js
@@ -1,4 +1,6 @@
-import("system.vars");
-import("system.result");
-
+import("system.logging");
+import("system.vars");
+import("system.result");
+
+logging.log("STANDARD.valueProcess|changedVal:" + vars.get("$this.value") + ">for>" + vars.get("$field.COMMID") + ">" + vars.get("$field.ADDR"));
 result.string(vars.get("$field.STANDARD") == "1");
\ No newline at end of file
diff --git a/entity/Comm_entity/entityfields/medium_id/possibleItemsProcess.js b/entity/Comm_entity/entityfields/medium_id/possibleItemsProcess.js
index aa20876613e..f73dccbca86 100644
--- a/entity/Comm_entity/entityfields/medium_id/possibleItemsProcess.js
+++ b/entity/Comm_entity/entityfields/medium_id/possibleItemsProcess.js
@@ -1,8 +1,20 @@
-import("system.result");
-import("Keyword_lib");
-
-var kwdUtils, items;
-
-kwdUtils = new KeywordUtils();
-items = kwdUtils.getStandardArray("COMM.MEDIUM");
-result.object(items);
\ No newline at end of file
+import("system.text");
+import("system.vars");
+import("system.result");
+import("Keyword_lib");
+
+var mediumCategories, kwdUtils, kwd, items;
+
+kwdUtils = new KeywordUtils();
+if (vars.exists("$param.MediumCategoriesFilter_param") && (mediumCategories = vars.get("$param.MediumCategoriesFilter_param")) != null){
+    mediumCategories = text.decodeMS(mediumCategories);
+    kwd = kwdUtils.createKeyword("COMM.MEDIUM");
+    kwd.filter(function(id, name, customs){
+        return mediumCategories.indexOf(customs.category) > -1;
+    });
+    items = kwd.toArray();
+}
+else {
+    items = kwdUtils.getStandardArray("COMM.MEDIUM");
+}
+result.object(items);
diff --git a/entity/Comm_entity/entityfields/medium_id/valueMappingProcess.js b/entity/Comm_entity/entityfields/medium_id/valueMappingProcess.js
new file mode 100644
index 00000000000..aa610615b48
--- /dev/null
+++ b/entity/Comm_entity/entityfields/medium_id/valueMappingProcess.js
@@ -0,0 +1,8 @@
+import("system.result");
+import("Keyword_lib");
+
+var kwdUtils, items;
+
+kwdUtils = new KeywordUtils();
+items = kwdUtils.getStandardArray("COMM.MEDIUM");
+result.object(items);
\ No newline at end of file
diff --git a/entity/Pers_entity/Pers_entity.aod b/entity/Pers_entity/Pers_entity.aod
index 81aaf1e8d13..448e4826911 100644
--- a/entity/Pers_entity/Pers_entity.aod
+++ b/entity/Pers_entity/Pers_entity.aod
@@ -283,6 +283,66 @@
         <fieldName>Org_dfi</fieldName>
       </dependency>
     </entityOutgoingField>
+    <entityOutgoingField>
+      <name>PersCommPhone_dfo</name>
+      <fieldType>DEPENDENCY_OUT</fieldType>
+      <caption>Communication Phone</caption>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Comm_entity</entityName>
+        <fieldName>PersComm_dfi</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>RelId_param</name>
+          <code>%aditoprj%/entity/Pers_entity/entityfields/perscommphone_dfo/children/relid_param/code.js</code>
+        </entityParameter>
+        <entityParameter>
+          <name>MediumCategoriesFilter_param</name>
+          <code>%aditoprj%/entity/Pers_entity/entityfields/perscommphone_dfo/children/mediumcategoriesfilter_param/code.js</code>
+        </entityParameter>
+      </children>
+    </entityOutgoingField>
+    <entityOutgoingField>
+      <name>PersCommEmail_dfo</name>
+      <fieldType>DEPENDENCY_OUT</fieldType>
+      <caption>Communication E-Mail</caption>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Comm_entity</entityName>
+        <fieldName>PersComm_dfi</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>RelId_param</name>
+          <code>%aditoprj%/entity/Pers_entity/entityfields/perscommemail_dfo/children/relid_param/code.js</code>
+        </entityParameter>
+        <entityParameter>
+          <name>MediumCategoriesFilter_param</name>
+          <code>%aditoprj%/entity/Pers_entity/entityfields/perscommemail_dfo/children/mediumcategoriesfilter_param/code.js</code>
+        </entityParameter>
+      </children>
+    </entityOutgoingField>
+    <entityOutgoingField>
+      <name>PersCommOthers_dfo</name>
+      <fieldType>DEPENDENCY_OUT</fieldType>
+      <caption>Communication Other</caption>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Comm_entity</entityName>
+        <fieldName>PersComm_dfi</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>RelId_param</name>
+          <code>%aditoprj%/entity/Pers_entity/entityfields/perscommothers_dfo/children/relid_param/code.js</code>
+        </entityParameter>
+        <entityParameter>
+          <name>MediumCategoriesFilter_param</name>
+          <code>%aditoprj%/entity/Pers_entity/entityfields/perscommothers_dfo/children/mediumcategoriesfilter_param/code.js</code>
+        </entityParameter>
+      </children>
+    </entityOutgoingField>
   </entityFields>
   <linkInformation>
     <linkInformation>
diff --git a/entity/Pers_entity/entityfields/perscommemail_dfo/children/mediumcategoriesfilter_param/code.js b/entity/Pers_entity/entityfields/perscommemail_dfo/children/mediumcategoriesfilter_param/code.js
new file mode 100644
index 00000000000..aaff61e4c88
--- /dev/null
+++ b/entity/Pers_entity/entityfields/perscommemail_dfo/children/mediumcategoriesfilter_param/code.js
@@ -0,0 +1,4 @@
+import("system.text");
+import("system.result");
+
+result.string(text.encodeMS(["EMAIL"]));
diff --git a/entity/Pers_entity/entityfields/perscommemail_dfo/children/relid_param/code.js b/entity/Pers_entity/entityfields/perscommemail_dfo/children/relid_param/code.js
new file mode 100644
index 00000000000..c618e8d6e5c
--- /dev/null
+++ b/entity/Pers_entity/entityfields/perscommemail_dfo/children/relid_param/code.js
@@ -0,0 +1,4 @@
+import("system.result");
+import("system.vars");
+
+result.string(vars.get("$field.RELATIONID"));
\ No newline at end of file
diff --git a/entity/Pers_entity/entityfields/perscommothers_dfo/children/mediumcategoriesfilter_param/code.js b/entity/Pers_entity/entityfields/perscommothers_dfo/children/mediumcategoriesfilter_param/code.js
new file mode 100644
index 00000000000..4f54b7ffc8a
--- /dev/null
+++ b/entity/Pers_entity/entityfields/perscommothers_dfo/children/mediumcategoriesfilter_param/code.js
@@ -0,0 +1,4 @@
+import("system.text");
+import("system.result");
+
+result.string(text.encodeMS(["OTHER"]));
diff --git a/entity/Pers_entity/entityfields/perscommothers_dfo/children/relid_param/code.js b/entity/Pers_entity/entityfields/perscommothers_dfo/children/relid_param/code.js
new file mode 100644
index 00000000000..c618e8d6e5c
--- /dev/null
+++ b/entity/Pers_entity/entityfields/perscommothers_dfo/children/relid_param/code.js
@@ -0,0 +1,4 @@
+import("system.result");
+import("system.vars");
+
+result.string(vars.get("$field.RELATIONID"));
\ No newline at end of file
diff --git a/entity/Pers_entity/entityfields/perscommphone_dfo/children/mediumcategoriesfilter_param/code.js b/entity/Pers_entity/entityfields/perscommphone_dfo/children/mediumcategoriesfilter_param/code.js
new file mode 100644
index 00000000000..10d8f95a842
--- /dev/null
+++ b/entity/Pers_entity/entityfields/perscommphone_dfo/children/mediumcategoriesfilter_param/code.js
@@ -0,0 +1,4 @@
+import("system.text");
+import("system.result");
+
+result.string(text.encodeMS(["PHONE"]));
diff --git a/entity/Pers_entity/entityfields/perscommphone_dfo/children/relid_param/code.js b/entity/Pers_entity/entityfields/perscommphone_dfo/children/relid_param/code.js
new file mode 100644
index 00000000000..c618e8d6e5c
--- /dev/null
+++ b/entity/Pers_entity/entityfields/perscommphone_dfo/children/relid_param/code.js
@@ -0,0 +1,4 @@
+import("system.result");
+import("system.vars");
+
+result.string(vars.get("$field.RELATIONID"));
\ No newline at end of file
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index 92d2227e33e..c7ad60356ce 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -1,305 +1,311 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<language xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.3" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/language/1.1.3">
-  <name>_____LANGUAGE_EXTRA</name>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <keyValueMap>
-    <entry>
-      <key>Company</key>
-    </entry>
-    <entry>
-      <key>German (Austria)</key>
-    </entry>
-    <entry>
-      <key>E-Mail</key>
-    </entry>
-    <entry>
-      <key>Customer</key>
-    </entry>
-    <entry>
-      <key>Internal</key>
-    </entry>
-    <entry>
-      <key>Male</key>
-    </entry>
-    <entry>
-      <key>Outgoing</key>
-    </entry>
-    <entry>
-      <key>History</key>
-    </entry>
-    <entry>
-      <key>Name</key>
-    </entry>
-    <entry>
-      <key>Austria</key>
-    </entry>
-    <entry>
-      <key>Der Alias \&amp;quot;%0\&amp;quot; konnte nicht geladen werden. Eventuell wurde er nicht konfiguriert</key>
-    </entry>
-    <entry>
-      <key>Customercode</key>
-    </entry>
-    <entry>
-      <key>Norwegian</key>
-    </entry>
-    <entry>
-      <key>Status</key>
-    </entry>
-    <entry>
-      <key>German (Germany)</key>
-    </entry>
-    <entry>
-      <key>Incoming</key>
-    </entry>
-    <entry>
-      <key>Active</key>
-    </entry>
-    <entry>
-      <key>${GENDER_OTHER}</key>
-    </entry>
-    <entry>
-      <key>Medium</key>
-    </entry>
-    <entry>
-      <key>Internet</key>
-    </entry>
-    <entry>
-      <key>Germany</key>
-    </entry>
-    <entry>
-      <key>Online-Meeting</key>
-    </entry>
-    <entry>
-      <key>Social Media</key>
-    </entry>
-    <entry>
-      <key>Visit</key>
-    </entry>
-    <entry>
-      <key>In review</key>
-    </entry>
-    <entry>
-      <key>German</key>
-    </entry>
-    <entry>
-      <key>Information</key>
-    </entry>
-    <entry>
-      <key>Language</key>
-    </entry>
-    <entry>
-      <key>Phone</key>
-    </entry>
-    <entry>
-      <key>[%0]the given keyword \&amp;quot;%1\&amp;quot; has no match with the possible keywordlist</key>
-    </entry>
-    <entry>
-      <key>Histories</key>
-    </entry>
-    <entry>
-      <key>Female</key>
-    </entry>
-    <entry>
-      <key>Supplier</key>
-    </entry>
-    <entry>
-      <key>English (United Kingdom)</key>
-    </entry>
-    <entry>
-      <key>Social</key>
-    </entry>
-    <entry>
-      <key>Contactmanagement</key>
-    </entry>
-    <entry>
-      <key>United Kingdom</key>
-    </entry>
-    <entry>
-      <key>Mobile</key>
-    </entry>
-    <entry>
-      <key>Office address</key>
-    </entry>
-    <entry>
-      <key>Contact</key>
-    </entry>
-    <entry>
-      <key>English</key>
-    </entry>
-    <entry>
-      <key>Home address</key>
-    </entry>
-    <entry>
-      <key>Type</key>
-    </entry>
-    <entry>
-      <key>Contacts</key>
-    </entry>
-    <entry>
-      <key>Norway</key>
-    </entry>
-    <entry>
-      <key>Prospect</key>
-    </entry>
-    <entry>
-      <key>the param \&amp;quot;%0\&amp;quot; in \&amp;quot;%1\&amp;quot; is mandatory and has to be set</key>
-    </entry>
-    <entry>
-      <key>Other</key>
-    </entry>
-    <entry>
-      <key>yyyy-MM-dd</key>
-    </entry>
-    <entry>
-      <key>Address</key>
-    </entry>
-    <entry>
-      <key>Addresses</key>
-    </entry>
-    <entry>
-      <key>${COMM_ADDRESS}</key>
-    </entry>
-    <entry>
-      <key>Gender</key>
-    </entry>
-    <entry>
-      <key>Date of birth</key>
-    </entry>
-    <entry>
-      <key>Lastname</key>
-    </entry>
-    <entry>
-      <key>Salutation</key>
-    </entry>
-    <entry>
-      <key>Middlename</key>
-    </entry>
-    <entry>
-      <key>Title</key>
-    </entry>
-    <entry>
-      <key>Addresstype</key>
-    </entry>
-    <entry>
-      <key>Firstname</key>
-    </entry>
-    <entry>
-      <key>Description</key>
-    </entry>
-    <entry>
-      <key>Direction</key>
-    </entry>
-    <entry>
-      <key>Entrydate</key>
-    </entry>
-    <entry>
-      <key>Subject</key>
-    </entry>
-    <entry>
-      <key>changed on %0 by %1</key>
-    </entry>
-    <entry>
-      <key>Post office box</key>
-    </entry>
-    <entry>
-      <key>created on %0 by %1</key>
-    </entry>
-    <entry>
-      <key>Delivery address</key>
-    </entry>
-    <entry>
-      <key>House number</key>
-    </entry>
-    <entry>
-      <key>Country</key>
-    </entry>
-    <entry>
-      <key>Communication</key>
-    </entry>
-    <entry>
-      <key>postcode</key>
-    </entry>
-    <entry>
-      <key>City</key>
-    </entry>
-    <entry>
-      <key>State</key>
-    </entry>
-    <entry>
-      <key>Region</key>
-    </entry>
-    <entry>
-      <key>District</key>
-    </entry>
-    <entry>
-      <key>Switzerland</key>
-    </entry>
-    <entry>
-      <key>Inactive</key>
-    </entry>
-    <entry>
-      <key>Nein</key>
-    </entry>
-    <entry>
-      <key>Bestätigt</key>
-    </entry>
-    <entry>
-      <key>Benutzer</key>
-    </entry>
-    <entry>
-      <key>frei</key>
-    </entry>
-    <entry>
-      <key>Vorläufig</key>
-    </entry>
-    <entry>
-      <key>Ja</key>
-    </entry>
-    <entry>
-      <key>Monatliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
-    </entry>
-    <entry>
-      <key>Betreff</key>
-    </entry>
-    <entry>
-      <key>Internal (2)</key>
-    </entry>
-    <entry>
-      <key>Company Addresses</key>
-    </entry>
-    <entry>
-      <key>Jährliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
-    </entry>
-    <entry>
-      <key>Termin</key>
-    </entry>
-    <entry>
-      <key>Außer Haus</key>
-    </entry>
-    <entry>
-      <key>Abgesagt</key>
-    </entry>
-    <entry>
-      <key>Tägliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
-    </entry>
-    <entry>
-      <key>yyyyMMdd</key>
-    </entry>
-    <entry>
-      <key>Gebucht</key>
-    </entry>
-    <entry>
-      <key>Ein Gruppentermin kann nur durch den Organisator bearbeitet werden.</key>
-    </entry>
-  </keyValueMap>
-  <font name="Dialog" style="0" size="11" />
-  <sqlModels>
-    <languageSql>
-      <name>Data_alias</name>
-      <alias>Data_alias</alias>
-      <statements>
-        <element></element>
-      </statements>
-    </languageSql>
-  </sqlModels>
-</language>
+<?xml version="1.0" encoding="UTF-8"?>
+<language xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.3" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/language/1.1.3">
+  <name>_____LANGUAGE_EXTRA</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <keyValueMap>
+    <entry>
+      <key>Company</key>
+    </entry>
+    <entry>
+      <key>German (Austria)</key>
+    </entry>
+    <entry>
+      <key>E-Mail</key>
+    </entry>
+    <entry>
+      <key>Customer</key>
+    </entry>
+    <entry>
+      <key>Internal</key>
+    </entry>
+    <entry>
+      <key>Male</key>
+    </entry>
+    <entry>
+      <key>Outgoing</key>
+    </entry>
+    <entry>
+      <key>History</key>
+    </entry>
+    <entry>
+      <key>Name</key>
+    </entry>
+    <entry>
+      <key>Austria</key>
+    </entry>
+    <entry>
+      <key>Der Alias \&amp;quot;%0\&amp;quot; konnte nicht geladen werden. Eventuell wurde er nicht konfiguriert</key>
+    </entry>
+    <entry>
+      <key>Customercode</key>
+    </entry>
+    <entry>
+      <key>Norwegian</key>
+    </entry>
+    <entry>
+      <key>Status</key>
+    </entry>
+    <entry>
+      <key>German (Germany)</key>
+    </entry>
+    <entry>
+      <key>Incoming</key>
+    </entry>
+    <entry>
+      <key>Active</key>
+    </entry>
+    <entry>
+      <key>${GENDER_OTHER}</key>
+    </entry>
+    <entry>
+      <key>Medium</key>
+    </entry>
+    <entry>
+      <key>Internet</key>
+    </entry>
+    <entry>
+      <key>Germany</key>
+    </entry>
+    <entry>
+      <key>Online-Meeting</key>
+    </entry>
+    <entry>
+      <key>Social Media</key>
+    </entry>
+    <entry>
+      <key>Visit</key>
+    </entry>
+    <entry>
+      <key>In review</key>
+    </entry>
+    <entry>
+      <key>German</key>
+    </entry>
+    <entry>
+      <key>Information</key>
+    </entry>
+    <entry>
+      <key>Language</key>
+    </entry>
+    <entry>
+      <key>Phone</key>
+    </entry>
+    <entry>
+      <key>[%0]the given keyword \&amp;quot;%1\&amp;quot; has no match with the possible keywordlist</key>
+    </entry>
+    <entry>
+      <key>Histories</key>
+    </entry>
+    <entry>
+      <key>Female</key>
+    </entry>
+    <entry>
+      <key>Supplier</key>
+    </entry>
+    <entry>
+      <key>English (United Kingdom)</key>
+    </entry>
+    <entry>
+      <key>Social</key>
+    </entry>
+    <entry>
+      <key>Contactmanagement</key>
+    </entry>
+    <entry>
+      <key>United Kingdom</key>
+    </entry>
+    <entry>
+      <key>Mobile</key>
+    </entry>
+    <entry>
+      <key>Office address</key>
+    </entry>
+    <entry>
+      <key>Contact</key>
+    </entry>
+    <entry>
+      <key>English</key>
+    </entry>
+    <entry>
+      <key>Home address</key>
+    </entry>
+    <entry>
+      <key>Type</key>
+    </entry>
+    <entry>
+      <key>Contacts</key>
+    </entry>
+    <entry>
+      <key>Norway</key>
+    </entry>
+    <entry>
+      <key>Prospect</key>
+    </entry>
+    <entry>
+      <key>the param \&amp;quot;%0\&amp;quot; in \&amp;quot;%1\&amp;quot; is mandatory and has to be set</key>
+    </entry>
+    <entry>
+      <key>Other</key>
+    </entry>
+    <entry>
+      <key>yyyy-MM-dd</key>
+    </entry>
+    <entry>
+      <key>Address</key>
+    </entry>
+    <entry>
+      <key>Addresses</key>
+    </entry>
+    <entry>
+      <key>${COMM_ADDRESS}</key>
+    </entry>
+    <entry>
+      <key>Gender</key>
+    </entry>
+    <entry>
+      <key>Date of birth</key>
+    </entry>
+    <entry>
+      <key>Lastname</key>
+    </entry>
+    <entry>
+      <key>Salutation</key>
+    </entry>
+    <entry>
+      <key>Middlename</key>
+    </entry>
+    <entry>
+      <key>Title</key>
+    </entry>
+    <entry>
+      <key>Addresstype</key>
+    </entry>
+    <entry>
+      <key>Firstname</key>
+    </entry>
+    <entry>
+      <key>Description</key>
+    </entry>
+    <entry>
+      <key>Direction</key>
+    </entry>
+    <entry>
+      <key>Entrydate</key>
+    </entry>
+    <entry>
+      <key>Subject</key>
+    </entry>
+    <entry>
+      <key>changed on %0 by %1</key>
+    </entry>
+    <entry>
+      <key>Post office box</key>
+    </entry>
+    <entry>
+      <key>created on %0 by %1</key>
+    </entry>
+    <entry>
+      <key>Delivery address</key>
+    </entry>
+    <entry>
+      <key>House number</key>
+    </entry>
+    <entry>
+      <key>Country</key>
+    </entry>
+    <entry>
+      <key>Communication</key>
+    </entry>
+    <entry>
+      <key>postcode</key>
+    </entry>
+    <entry>
+      <key>City</key>
+    </entry>
+    <entry>
+      <key>State</key>
+    </entry>
+    <entry>
+      <key>Region</key>
+    </entry>
+    <entry>
+      <key>District</key>
+    </entry>
+    <entry>
+      <key>Switzerland</key>
+    </entry>
+    <entry>
+      <key>Inactive</key>
+    </entry>
+    <entry>
+      <key>Bestätigt</key>
+    </entry>
+    <entry>
+      <key>Benutzer</key>
+    </entry>
+    <entry>
+      <key>frei</key>
+    </entry>
+    <entry>
+      <key>Vorläufig</key>
+    </entry>
+    <entry>
+      <key>Monatliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
+    </entry>
+    <entry>
+      <key>Betreff</key>
+    </entry>
+    <entry>
+      <key>Internal (2)</key>
+    </entry>
+    <entry>
+      <key>Company Addresses</key>
+    </entry>
+    <entry>
+      <key>Jährliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
+    </entry>
+    <entry>
+      <key>Termin</key>
+    </entry>
+    <entry>
+      <key>Außer Haus</key>
+    </entry>
+    <entry>
+      <key>Abgesagt</key>
+    </entry>
+    <entry>
+      <key>Tägliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
+    </entry>
+    <entry>
+      <key>yyyyMMdd</key>
+    </entry>
+    <entry>
+      <key>Gebucht</key>
+    </entry>
+    <entry>
+      <key>Ein Gruppentermin kann nur durch den Organisator bearbeitet werden.</key>
+    </entry>
+    <entry>
+      <key>Communication Other</key>
+    </entry>
+    <entry>
+      <key>Communication Phone</key>
+    </entry>
+    <entry>
+      <key>Communication E-Mail</key>
+    </entry>
+    <entry>
+      <key>standard address</key>
+    </entry>
+  </keyValueMap>
+  <font name="Dialog" style="0" size="11" />
+  <sqlModels>
+    <languageSql>
+      <name>Data_alias</name>
+      <alias>Data_alias</alias>
+      <statements>
+        <element></element>
+      </statements>
+    </languageSql>
+  </sqlModels>
+</language>
diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
index 39203791eb0..b7dfaee3c09 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -1,377 +1,387 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<language xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.3" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/language/1.1.3">
-  <name>_____LANGUAGE_de</name>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <language>de</language>
-  <country></country>
-  <variant></variant>
-  <keyValueMap>
-    <entry>
-      <key>Company</key>
-      <value>Firma</value>
-    </entry>
-    <entry>
-      <key>German (Austria)</key>
-      <value>Deutsch (Österreich)</value>
-    </entry>
-    <entry>
-      <key>E-Mail</key>
-      <value>E-Mail</value>
-    </entry>
-    <entry>
-      <key>Customer</key>
-      <value>Kunde</value>
-    </entry>
-    <entry>
-      <key>Internal</key>
-      <value>Intern</value>
-    </entry>
-    <entry>
-      <key>Male</key>
-      <value>Männlich</value>
-    </entry>
-    <entry>
-      <key>Outgoing</key>
-      <value>Ausgehend</value>
-    </entry>
-    <entry>
-      <key>History</key>
-      <value>Historie</value>
-    </entry>
-    <entry>
-      <key>Name</key>
-      <value>Name</value>
-    </entry>
-    <entry>
-      <key>Austria</key>
-      <value>Österreich</value>
-    </entry>
-    <entry>
-      <key>Der Alias \&amp;quot;%0\&amp;quot; konnte nicht geladen werden. Eventuell wurde er nicht konfiguriert</key>
-    </entry>
-    <entry>
-      <key>Customercode</key>
-      <value>Kundennummer</value>
-    </entry>
-    <entry>
-      <key>Norwegian</key>
-      <value>Norwegisch</value>
-    </entry>
-    <entry>
-      <key>Status</key>
-      <value>Status</value>
-    </entry>
-    <entry>
-      <key>German (Germany)</key>
-      <value>Deutsch (Deutschland)</value>
-    </entry>
-    <entry>
-      <key>Incoming</key>
-      <value>Eingehend</value>
-    </entry>
-    <entry>
-      <key>Active</key>
-      <value>Aktiv</value>
-    </entry>
-    <entry>
-      <key>${GENDER_OTHER}</key>
-      <value>Sonstige</value>
-    </entry>
-    <entry>
-      <key>Medium</key>
-      <value>Medium</value>
-    </entry>
-    <entry>
-      <key>Internet</key>
-      <value>Internet</value>
-    </entry>
-    <entry>
-      <key>Germany</key>
-      <value>Deutschland</value>
-    </entry>
-    <entry>
-      <key>Online-Meeting</key>
-      <value>Online-Meeting</value>
-    </entry>
-    <entry>
-      <key>Social Media</key>
-      <value>Social Media</value>
-    </entry>
-    <entry>
-      <key>Visit</key>
-      <value>Besuch</value>
-    </entry>
-    <entry>
-      <key>In review</key>
-      <value>zur Prüfung</value>
-    </entry>
-    <entry>
-      <key>German</key>
-      <value>Deutsch</value>
-    </entry>
-    <entry>
-      <key>Information</key>
-      <value>Information</value>
-    </entry>
-    <entry>
-      <key>Language</key>
-      <value>Sprache</value>
-    </entry>
-    <entry>
-      <key>Phone</key>
-      <value>Telefon</value>
-    </entry>
-    <entry>
-      <key>[%0]the given keyword \&amp;quot;%1\&amp;quot; has no match with the possible keywordlist</key>
-    </entry>
-    <entry>
-      <key>Histories</key>
-      <value>Historien</value>
-    </entry>
-    <entry>
-      <key>Female</key>
-      <value>Weiblich</value>
-    </entry>
-    <entry>
-      <key>Supplier</key>
-      <value>Lieferant</value>
-    </entry>
-    <entry>
-      <key>English (United Kingdom)</key>
-      <value>Englisch (Vereinigtes Königreich)</value>
-    </entry>
-    <entry>
-      <key>Social</key>
-      <value></value>
-    </entry>
-    <entry>
-      <key>Contactmanagement</key>
-      <value>Kontaktmanagement</value>
-    </entry>
-    <entry>
-      <key>United Kingdom</key>
-      <value>Vereinigtes Königreich</value>
-    </entry>
-    <entry>
-      <key>Mobile</key>
-      <value>Mobil</value>
-    </entry>
-    <entry>
-      <key>Office address</key>
-      <value>Firmenadresse</value>
-    </entry>
-    <entry>
-      <key>Contact</key>
-      <value>Kontakt</value>
-    </entry>
-    <entry>
-      <key>English</key>
-      <value>Englisch</value>
-    </entry>
-    <entry>
-      <key>Home address</key>
-      <value>Privatadresse</value>
-    </entry>
-    <entry>
-      <key>Type</key>
-      <value>Typ</value>
-    </entry>
-    <entry>
-      <key>Contacts</key>
-      <value>Kontakte</value>
-    </entry>
-    <entry>
-      <key>Norway</key>
-      <value>Norwegen</value>
-    </entry>
-    <entry>
-      <key>Prospect</key>
-      <value>Interessent</value>
-    </entry>
-    <entry>
-      <key>the param \&amp;quot;%0\&amp;quot; in \&amp;quot;%1\&amp;quot; is mandatory and has to be set</key>
-      <value></value>
-    </entry>
-    <entry>
-      <key>Other</key>
-      <value>Sonstige</value>
-    </entry>
-    <entry>
-      <key>yyyy-MM-dd</key>
-      <value>dd.MM.yyyy
-</value>
-    </entry>
-    <entry>
-      <key>Address</key>
-      <value>Adresse</value>
-    </entry>
-    <entry>
-      <key>Addresses</key>
-      <value>Adressen</value>
-    </entry>
-    <entry>
-      <key>${COMM_ADDRESS}</key>
-      <value>Adresse</value>
-    </entry>
-    <entry>
-      <key>Gender</key>
-      <value>Geschlecht</value>
-    </entry>
-    <entry>
-      <key>Date of birth</key>
-      <value>Geburtsdatum</value>
-    </entry>
-    <entry>
-      <key>Lastname</key>
-      <value>Nachname</value>
-    </entry>
-    <entry>
-      <key>Salutation</key>
-      <value>Anrede</value>
-    </entry>
-    <entry>
-      <key>Middlename</key>
-      <value>Zwischenname</value>
-    </entry>
-    <entry>
-      <key>Title</key>
-      <value>Title</value>
-    </entry>
-    <entry>
-      <key>Addresstype</key>
-      <value>Adresstyp</value>
-    </entry>
-    <entry>
-      <key>Firstname</key>
-      <value>Vorname</value>
-    </entry>
-    <entry>
-      <key>Description</key>
-      <value>Beschreibung</value>
-    </entry>
-    <entry>
-      <key>Direction</key>
-      <value>Richtung</value>
-    </entry>
-    <entry>
-      <key>Entrydate</key>
-      <value>Eingangsdatum</value>
-    </entry>
-    <entry>
-      <key>Subject</key>
-      <value>Betreff</value>
-    </entry>
-    <entry>
-      <key>changed on %0 by %1</key>
-      <value>Geändert am %0 von %1</value>
-    </entry>
-    <entry>
-      <key>Post office box</key>
-      <value>Postfach</value>
-    </entry>
-    <entry>
-      <key>created on %0 by %1</key>
-      <value>Erstellt am %0 von %1</value>
-    </entry>
-    <entry>
-      <key>Delivery address</key>
-      <value>Lieferadresse</value>
-    </entry>
-    <entry>
-      <key>House number</key>
-      <value>Hausnummer</value>
-    </entry>
-    <entry>
-      <key>Country</key>
-      <value>Land</value>
-    </entry>
-    <entry>
-      <key>Communication</key>
-      <value>Kommunikation</value>
-    </entry>
-    <entry>
-      <key>postcode</key>
-      <value>Postleitzahl</value>
-    </entry>
-    <entry>
-      <key>City</key>
-      <value>Ort</value>
-    </entry>
-    <entry>
-      <key>State</key>
-      <value></value>
-    </entry>
-    <entry>
-      <key>Region</key>
-      <value>Region</value>
-    </entry>
-    <entry>
-      <key>District</key>
-      <value></value>
-    </entry>
-    <entry>
-      <key>Switzerland</key>
-      <value>Schweiz</value>
-    </entry>
-    <entry>
-      <key>Inactive</key>
-      <value>Inaktiv</value>
-    </entry>
-    <entry>
-      <key>Nein</key>
-    </entry>
-    <entry>
-      <key>Bestätigt</key>
-    </entry>
-    <entry>
-      <key>Benutzer</key>
-    </entry>
-    <entry>
-      <key>frei</key>
-    </entry>
-    <entry>
-      <key>Vorläufig</key>
-    </entry>
-    <entry>
-      <key>Ja</key>
-    </entry>
-    <entry>
-      <key>Monatliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
-    </entry>
-    <entry>
-      <key>Betreff</key>
-    </entry>
-    <entry>
-      <key>Internal (2)</key>
-    </entry>
-    <entry>
-      <key>Company Addresses</key>
-      <value>Firmenadressen</value>
-    </entry>
-    <entry>
-      <key>Jährliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
-    </entry>
-    <entry>
-      <key>Termin</key>
-    </entry>
-    <entry>
-      <key>Außer Haus</key>
-    </entry>
-    <entry>
-      <key>Abgesagt</key>
-    </entry>
-    <entry>
-      <key>Tägliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
-    </entry>
-    <entry>
-      <key>yyyyMMdd</key>
-    </entry>
-    <entry>
-      <key>Gebucht</key>
-    </entry>
-    <entry>
-      <key>Ein Gruppentermin kann nur durch den Organisator bearbeitet werden.</key>
-    </entry>
-  </keyValueMap>
-  <font name="Dialog" style="0" size="11" />
-</language>
+<?xml version="1.0" encoding="UTF-8"?>
+<language xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.3" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/language/1.1.3">
+  <name>_____LANGUAGE_de</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <language>de</language>
+  <country></country>
+  <variant></variant>
+  <keyValueMap>
+    <entry>
+      <key>Company</key>
+      <value>Firma</value>
+    </entry>
+    <entry>
+      <key>German (Austria)</key>
+      <value>Deutsch (Österreich)</value>
+    </entry>
+    <entry>
+      <key>E-Mail</key>
+      <value>E-Mail</value>
+    </entry>
+    <entry>
+      <key>Customer</key>
+      <value>Kunde</value>
+    </entry>
+    <entry>
+      <key>Internal</key>
+      <value>Intern</value>
+    </entry>
+    <entry>
+      <key>Male</key>
+      <value>Männlich</value>
+    </entry>
+    <entry>
+      <key>Outgoing</key>
+      <value>Ausgehend</value>
+    </entry>
+    <entry>
+      <key>History</key>
+      <value>Historie</value>
+    </entry>
+    <entry>
+      <key>Name</key>
+      <value>Name</value>
+    </entry>
+    <entry>
+      <key>Austria</key>
+      <value>Österreich</value>
+    </entry>
+    <entry>
+      <key>Der Alias \&amp;quot;%0\&amp;quot; konnte nicht geladen werden. Eventuell wurde er nicht konfiguriert</key>
+    </entry>
+    <entry>
+      <key>Customercode</key>
+      <value>Kundennummer</value>
+    </entry>
+    <entry>
+      <key>Norwegian</key>
+      <value>Norwegisch</value>
+    </entry>
+    <entry>
+      <key>Status</key>
+      <value>Status</value>
+    </entry>
+    <entry>
+      <key>German (Germany)</key>
+      <value>Deutsch (Deutschland)</value>
+    </entry>
+    <entry>
+      <key>Incoming</key>
+      <value>Eingehend</value>
+    </entry>
+    <entry>
+      <key>Active</key>
+      <value>Aktiv</value>
+    </entry>
+    <entry>
+      <key>${GENDER_OTHER}</key>
+      <value>Sonstige</value>
+    </entry>
+    <entry>
+      <key>Medium</key>
+      <value>Medium</value>
+    </entry>
+    <entry>
+      <key>Internet</key>
+      <value>Internet</value>
+    </entry>
+    <entry>
+      <key>Germany</key>
+      <value>Deutschland</value>
+    </entry>
+    <entry>
+      <key>Online-Meeting</key>
+      <value>Online-Meeting</value>
+    </entry>
+    <entry>
+      <key>Social Media</key>
+      <value>Social Media</value>
+    </entry>
+    <entry>
+      <key>Visit</key>
+      <value>Besuch</value>
+    </entry>
+    <entry>
+      <key>In review</key>
+      <value>zur Prüfung</value>
+    </entry>
+    <entry>
+      <key>German</key>
+      <value>Deutsch</value>
+    </entry>
+    <entry>
+      <key>Information</key>
+      <value>Information</value>
+    </entry>
+    <entry>
+      <key>Language</key>
+      <value>Sprache</value>
+    </entry>
+    <entry>
+      <key>Phone</key>
+      <value>Telefon</value>
+    </entry>
+    <entry>
+      <key>[%0]the given keyword \&amp;quot;%1\&amp;quot; has no match with the possible keywordlist</key>
+    </entry>
+    <entry>
+      <key>Histories</key>
+      <value>Historien</value>
+    </entry>
+    <entry>
+      <key>Female</key>
+      <value>Weiblich</value>
+    </entry>
+    <entry>
+      <key>Supplier</key>
+      <value>Lieferant</value>
+    </entry>
+    <entry>
+      <key>English (United Kingdom)</key>
+      <value>Englisch (Vereinigtes Königreich)</value>
+    </entry>
+    <entry>
+      <key>Social</key>
+      <value></value>
+    </entry>
+    <entry>
+      <key>Contactmanagement</key>
+      <value>Kontaktmanagement</value>
+    </entry>
+    <entry>
+      <key>United Kingdom</key>
+      <value>Vereinigtes Königreich</value>
+    </entry>
+    <entry>
+      <key>Mobile</key>
+      <value>Mobil</value>
+    </entry>
+    <entry>
+      <key>Office address</key>
+      <value>Firmenadresse</value>
+    </entry>
+    <entry>
+      <key>Contact</key>
+      <value>Kontakt</value>
+    </entry>
+    <entry>
+      <key>English</key>
+      <value>Englisch</value>
+    </entry>
+    <entry>
+      <key>Home address</key>
+      <value>Privatadresse</value>
+    </entry>
+    <entry>
+      <key>Type</key>
+      <value>Typ</value>
+    </entry>
+    <entry>
+      <key>Contacts</key>
+      <value>Kontakte</value>
+    </entry>
+    <entry>
+      <key>Norway</key>
+      <value>Norwegen</value>
+    </entry>
+    <entry>
+      <key>Prospect</key>
+      <value>Interessent</value>
+    </entry>
+    <entry>
+      <key>the param \&amp;quot;%0\&amp;quot; in \&amp;quot;%1\&amp;quot; is mandatory and has to be set</key>
+      <value></value>
+    </entry>
+    <entry>
+      <key>Other</key>
+      <value>Sonstige</value>
+    </entry>
+    <entry>
+      <key>yyyy-MM-dd</key>
+      <value>dd.MM.yyyy
+</value>
+    </entry>
+    <entry>
+      <key>Address</key>
+      <value>Adresse</value>
+    </entry>
+    <entry>
+      <key>Addresses</key>
+      <value>Adressen</value>
+    </entry>
+    <entry>
+      <key>${COMM_ADDRESS}</key>
+      <value>Adresse</value>
+    </entry>
+    <entry>
+      <key>Gender</key>
+      <value>Geschlecht</value>
+    </entry>
+    <entry>
+      <key>Date of birth</key>
+      <value>Geburtsdatum</value>
+    </entry>
+    <entry>
+      <key>Lastname</key>
+      <value>Nachname</value>
+    </entry>
+    <entry>
+      <key>Salutation</key>
+      <value>Anrede</value>
+    </entry>
+    <entry>
+      <key>Middlename</key>
+      <value>Zwischenname</value>
+    </entry>
+    <entry>
+      <key>Title</key>
+      <value>Title</value>
+    </entry>
+    <entry>
+      <key>Addresstype</key>
+      <value>Adresstyp</value>
+    </entry>
+    <entry>
+      <key>Firstname</key>
+      <value>Vorname</value>
+    </entry>
+    <entry>
+      <key>Description</key>
+      <value>Beschreibung</value>
+    </entry>
+    <entry>
+      <key>Direction</key>
+      <value>Richtung</value>
+    </entry>
+    <entry>
+      <key>Entrydate</key>
+      <value>Eingangsdatum</value>
+    </entry>
+    <entry>
+      <key>Subject</key>
+      <value>Betreff</value>
+    </entry>
+    <entry>
+      <key>changed on %0 by %1</key>
+      <value>Geändert am %0 von %1</value>
+    </entry>
+    <entry>
+      <key>Post office box</key>
+      <value>Postfach</value>
+    </entry>
+    <entry>
+      <key>created on %0 by %1</key>
+      <value>Erstellt am %0 von %1</value>
+    </entry>
+    <entry>
+      <key>Delivery address</key>
+      <value>Lieferadresse</value>
+    </entry>
+    <entry>
+      <key>House number</key>
+      <value>Hausnummer</value>
+    </entry>
+    <entry>
+      <key>Country</key>
+      <value>Land</value>
+    </entry>
+    <entry>
+      <key>Communication</key>
+      <value>Kommunikation</value>
+    </entry>
+    <entry>
+      <key>postcode</key>
+      <value>Postleitzahl</value>
+    </entry>
+    <entry>
+      <key>City</key>
+      <value>Ort</value>
+    </entry>
+    <entry>
+      <key>State</key>
+      <value></value>
+    </entry>
+    <entry>
+      <key>Region</key>
+      <value>Region</value>
+    </entry>
+    <entry>
+      <key>District</key>
+      <value></value>
+    </entry>
+    <entry>
+      <key>Switzerland</key>
+      <value>Schweiz</value>
+    </entry>
+    <entry>
+      <key>Inactive</key>
+      <value>Inaktiv</value>
+    </entry>
+    <entry>
+      <key>Bestätigt</key>
+    </entry>
+    <entry>
+      <key>Benutzer</key>
+    </entry>
+    <entry>
+      <key>frei</key>
+    </entry>
+    <entry>
+      <key>Vorläufig</key>
+    </entry>
+    <entry>
+      <key>Monatliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
+    </entry>
+    <entry>
+      <key>Betreff</key>
+    </entry>
+    <entry>
+      <key>Internal (2)</key>
+    </entry>
+    <entry>
+      <key>Company Addresses</key>
+      <value>Firmenadressen</value>
+    </entry>
+    <entry>
+      <key>Jährliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
+    </entry>
+    <entry>
+      <key>Termin</key>
+    </entry>
+    <entry>
+      <key>Außer Haus</key>
+    </entry>
+    <entry>
+      <key>Abgesagt</key>
+    </entry>
+    <entry>
+      <key>Tägliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
+    </entry>
+    <entry>
+      <key>yyyyMMdd</key>
+    </entry>
+    <entry>
+      <key>Gebucht</key>
+    </entry>
+    <entry>
+      <key>Ein Gruppentermin kann nur durch den Organisator bearbeitet werden.</key>
+    </entry>
+    <entry>
+      <key>Communication Other</key>
+      <value>Kommunikation Sonstige</value>
+    </entry>
+    <entry>
+      <key>Communication Phone</key>
+      <value>Kommunikation Telefon</value>
+    </entry>
+    <entry>
+      <key>Communication E-Mail</key>
+      <value>Kommunikation E-Mail</value>
+    </entry>
+    <entry>
+      <key>standard address</key>
+      <value>Standardadresse</value>
+    </entry>
+  </keyValueMap>
+  <font name="Dialog" style="0" size="11" />
+</language>
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index 6364678c597..399a5d44fbc 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -1,301 +1,307 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<language xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.3" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/language/1.1.3">
-  <name>_____LANGUAGE_en</name>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <language>en</language>
-  <country></country>
-  <variant></variant>
-  <keyValueMap>
-    <entry>
-      <key>Company</key>
-    </entry>
-    <entry>
-      <key>German (Austria)</key>
-    </entry>
-    <entry>
-      <key>E-Mail</key>
-    </entry>
-    <entry>
-      <key>Customer</key>
-    </entry>
-    <entry>
-      <key>Internal</key>
-    </entry>
-    <entry>
-      <key>Male</key>
-    </entry>
-    <entry>
-      <key>Outgoing</key>
-    </entry>
-    <entry>
-      <key>History</key>
-    </entry>
-    <entry>
-      <key>Name</key>
-    </entry>
-    <entry>
-      <key>Austria</key>
-    </entry>
-    <entry>
-      <key>Der Alias \&amp;quot;%0\&amp;quot; konnte nicht geladen werden. Eventuell wurde er nicht konfiguriert</key>
-    </entry>
-    <entry>
-      <key>Customercode</key>
-    </entry>
-    <entry>
-      <key>Norwegian</key>
-    </entry>
-    <entry>
-      <key>Status</key>
-    </entry>
-    <entry>
-      <key>German (Germany)</key>
-    </entry>
-    <entry>
-      <key>Incoming</key>
-    </entry>
-    <entry>
-      <key>Active</key>
-    </entry>
-    <entry>
-      <key>${GENDER_OTHER}</key>
-      <value>Other</value>
-    </entry>
-    <entry>
-      <key>Medium</key>
-    </entry>
-    <entry>
-      <key>Internet</key>
-    </entry>
-    <entry>
-      <key>Germany</key>
-    </entry>
-    <entry>
-      <key>Online-Meeting</key>
-    </entry>
-    <entry>
-      <key>Social Media</key>
-    </entry>
-    <entry>
-      <key>Visit</key>
-    </entry>
-    <entry>
-      <key>In review</key>
-    </entry>
-    <entry>
-      <key>German</key>
-    </entry>
-    <entry>
-      <key>Information</key>
-    </entry>
-    <entry>
-      <key>Language</key>
-    </entry>
-    <entry>
-      <key>Phone</key>
-    </entry>
-    <entry>
-      <key>[%0]the given keyword \&amp;quot;%1\&amp;quot; has no match with the possible keywordlist</key>
-    </entry>
-    <entry>
-      <key>Histories</key>
-    </entry>
-    <entry>
-      <key>Female</key>
-    </entry>
-    <entry>
-      <key>Supplier</key>
-    </entry>
-    <entry>
-      <key>English (United Kingdom)</key>
-    </entry>
-    <entry>
-      <key>Social</key>
-    </entry>
-    <entry>
-      <key>Contactmanagement</key>
-    </entry>
-    <entry>
-      <key>United Kingdom</key>
-    </entry>
-    <entry>
-      <key>Mobile</key>
-    </entry>
-    <entry>
-      <key>Office address</key>
-    </entry>
-    <entry>
-      <key>Contact</key>
-    </entry>
-    <entry>
-      <key>English</key>
-    </entry>
-    <entry>
-      <key>Home address</key>
-    </entry>
-    <entry>
-      <key>Type</key>
-    </entry>
-    <entry>
-      <key>Contacts</key>
-    </entry>
-    <entry>
-      <key>Norway</key>
-    </entry>
-    <entry>
-      <key>Prospect</key>
-    </entry>
-    <entry>
-      <key>the param \&amp;quot;%0\&amp;quot; in \&amp;quot;%1\&amp;quot; is mandatory and has to be set</key>
-    </entry>
-    <entry>
-      <key>Other</key>
-    </entry>
-    <entry>
-      <key>yyyy-MM-dd</key>
-    </entry>
-    <entry>
-      <key>Address</key>
-    </entry>
-    <entry>
-      <key>Addresses</key>
-    </entry>
-    <entry>
-      <key>${COMM_ADDRESS}</key>
-      <value>Address</value>
-    </entry>
-    <entry>
-      <key>Gender</key>
-    </entry>
-    <entry>
-      <key>Date of birth</key>
-    </entry>
-    <entry>
-      <key>Lastname</key>
-    </entry>
-    <entry>
-      <key>Salutation</key>
-    </entry>
-    <entry>
-      <key>Middlename</key>
-    </entry>
-    <entry>
-      <key>Title</key>
-    </entry>
-    <entry>
-      <key>Addresstype</key>
-    </entry>
-    <entry>
-      <key>Firstname</key>
-    </entry>
-    <entry>
-      <key>Description</key>
-    </entry>
-    <entry>
-      <key>Direction</key>
-    </entry>
-    <entry>
-      <key>Entrydate</key>
-    </entry>
-    <entry>
-      <key>Subject</key>
-    </entry>
-    <entry>
-      <key>changed on %0 by %1</key>
-    </entry>
-    <entry>
-      <key>Post office box</key>
-    </entry>
-    <entry>
-      <key>created on %0 by %1</key>
-    </entry>
-    <entry>
-      <key>Delivery address</key>
-    </entry>
-    <entry>
-      <key>House number</key>
-    </entry>
-    <entry>
-      <key>Country</key>
-    </entry>
-    <entry>
-      <key>Communication</key>
-    </entry>
-    <entry>
-      <key>postcode</key>
-    </entry>
-    <entry>
-      <key>City</key>
-    </entry>
-    <entry>
-      <key>State</key>
-    </entry>
-    <entry>
-      <key>Region</key>
-    </entry>
-    <entry>
-      <key>District</key>
-    </entry>
-    <entry>
-      <key>Switzerland</key>
-    </entry>
-    <entry>
-      <key>Inactive</key>
-    </entry>
-    <entry>
-      <key>Nein</key>
-    </entry>
-    <entry>
-      <key>Bestätigt</key>
-    </entry>
-    <entry>
-      <key>Benutzer</key>
-    </entry>
-    <entry>
-      <key>frei</key>
-    </entry>
-    <entry>
-      <key>Vorläufig</key>
-    </entry>
-    <entry>
-      <key>Ja</key>
-    </entry>
-    <entry>
-      <key>Monatliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
-    </entry>
-    <entry>
-      <key>Betreff</key>
-    </entry>
-    <entry>
-      <key>Internal (2)</key>
-    </entry>
-    <entry>
-      <key>Company Addresses</key>
-    </entry>
-    <entry>
-      <key>Jährliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
-    </entry>
-    <entry>
-      <key>Termin</key>
-    </entry>
-    <entry>
-      <key>Außer Haus</key>
-    </entry>
-    <entry>
-      <key>Abgesagt</key>
-    </entry>
-    <entry>
-      <key>Tägliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
-    </entry>
-    <entry>
-      <key>yyyyMMdd</key>
-    </entry>
-    <entry>
-      <key>Gebucht</key>
-    </entry>
-    <entry>
-      <key>Ein Gruppentermin kann nur durch den Organisator bearbeitet werden.</key>
-    </entry>
-  </keyValueMap>
-  <font name="Dialog" style="0" size="11" />
-</language>
+<?xml version="1.0" encoding="UTF-8"?>
+<language xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.3" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/language/1.1.3">
+  <name>_____LANGUAGE_en</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <language>en</language>
+  <country></country>
+  <variant></variant>
+  <keyValueMap>
+    <entry>
+      <key>Company</key>
+    </entry>
+    <entry>
+      <key>German (Austria)</key>
+    </entry>
+    <entry>
+      <key>E-Mail</key>
+    </entry>
+    <entry>
+      <key>Customer</key>
+    </entry>
+    <entry>
+      <key>Internal</key>
+    </entry>
+    <entry>
+      <key>Male</key>
+    </entry>
+    <entry>
+      <key>Outgoing</key>
+    </entry>
+    <entry>
+      <key>History</key>
+    </entry>
+    <entry>
+      <key>Name</key>
+    </entry>
+    <entry>
+      <key>Austria</key>
+    </entry>
+    <entry>
+      <key>Der Alias \&amp;quot;%0\&amp;quot; konnte nicht geladen werden. Eventuell wurde er nicht konfiguriert</key>
+    </entry>
+    <entry>
+      <key>Customercode</key>
+    </entry>
+    <entry>
+      <key>Norwegian</key>
+    </entry>
+    <entry>
+      <key>Status</key>
+    </entry>
+    <entry>
+      <key>German (Germany)</key>
+    </entry>
+    <entry>
+      <key>Incoming</key>
+    </entry>
+    <entry>
+      <key>Active</key>
+    </entry>
+    <entry>
+      <key>${GENDER_OTHER}</key>
+      <value>Other</value>
+    </entry>
+    <entry>
+      <key>Medium</key>
+    </entry>
+    <entry>
+      <key>Internet</key>
+    </entry>
+    <entry>
+      <key>Germany</key>
+    </entry>
+    <entry>
+      <key>Online-Meeting</key>
+    </entry>
+    <entry>
+      <key>Social Media</key>
+    </entry>
+    <entry>
+      <key>Visit</key>
+    </entry>
+    <entry>
+      <key>In review</key>
+    </entry>
+    <entry>
+      <key>German</key>
+    </entry>
+    <entry>
+      <key>Information</key>
+    </entry>
+    <entry>
+      <key>Language</key>
+    </entry>
+    <entry>
+      <key>Phone</key>
+    </entry>
+    <entry>
+      <key>[%0]the given keyword \&amp;quot;%1\&amp;quot; has no match with the possible keywordlist</key>
+    </entry>
+    <entry>
+      <key>Histories</key>
+    </entry>
+    <entry>
+      <key>Female</key>
+    </entry>
+    <entry>
+      <key>Supplier</key>
+    </entry>
+    <entry>
+      <key>English (United Kingdom)</key>
+    </entry>
+    <entry>
+      <key>Social</key>
+    </entry>
+    <entry>
+      <key>Contactmanagement</key>
+    </entry>
+    <entry>
+      <key>United Kingdom</key>
+    </entry>
+    <entry>
+      <key>Mobile</key>
+    </entry>
+    <entry>
+      <key>Office address</key>
+    </entry>
+    <entry>
+      <key>Contact</key>
+    </entry>
+    <entry>
+      <key>English</key>
+    </entry>
+    <entry>
+      <key>Home address</key>
+    </entry>
+    <entry>
+      <key>Type</key>
+    </entry>
+    <entry>
+      <key>Contacts</key>
+    </entry>
+    <entry>
+      <key>Norway</key>
+    </entry>
+    <entry>
+      <key>Prospect</key>
+    </entry>
+    <entry>
+      <key>the param \&amp;quot;%0\&amp;quot; in \&amp;quot;%1\&amp;quot; is mandatory and has to be set</key>
+    </entry>
+    <entry>
+      <key>Other</key>
+    </entry>
+    <entry>
+      <key>yyyy-MM-dd</key>
+    </entry>
+    <entry>
+      <key>Address</key>
+    </entry>
+    <entry>
+      <key>Addresses</key>
+    </entry>
+    <entry>
+      <key>${COMM_ADDRESS}</key>
+      <value>Address</value>
+    </entry>
+    <entry>
+      <key>Gender</key>
+    </entry>
+    <entry>
+      <key>Date of birth</key>
+    </entry>
+    <entry>
+      <key>Lastname</key>
+    </entry>
+    <entry>
+      <key>Salutation</key>
+    </entry>
+    <entry>
+      <key>Middlename</key>
+    </entry>
+    <entry>
+      <key>Title</key>
+    </entry>
+    <entry>
+      <key>Addresstype</key>
+    </entry>
+    <entry>
+      <key>Firstname</key>
+    </entry>
+    <entry>
+      <key>Description</key>
+    </entry>
+    <entry>
+      <key>Direction</key>
+    </entry>
+    <entry>
+      <key>Entrydate</key>
+    </entry>
+    <entry>
+      <key>Subject</key>
+    </entry>
+    <entry>
+      <key>changed on %0 by %1</key>
+    </entry>
+    <entry>
+      <key>Post office box</key>
+    </entry>
+    <entry>
+      <key>created on %0 by %1</key>
+    </entry>
+    <entry>
+      <key>Delivery address</key>
+    </entry>
+    <entry>
+      <key>House number</key>
+    </entry>
+    <entry>
+      <key>Country</key>
+    </entry>
+    <entry>
+      <key>Communication</key>
+    </entry>
+    <entry>
+      <key>postcode</key>
+    </entry>
+    <entry>
+      <key>City</key>
+    </entry>
+    <entry>
+      <key>State</key>
+    </entry>
+    <entry>
+      <key>Region</key>
+    </entry>
+    <entry>
+      <key>District</key>
+    </entry>
+    <entry>
+      <key>Switzerland</key>
+    </entry>
+    <entry>
+      <key>Inactive</key>
+    </entry>
+    <entry>
+      <key>Bestätigt</key>
+    </entry>
+    <entry>
+      <key>Benutzer</key>
+    </entry>
+    <entry>
+      <key>frei</key>
+    </entry>
+    <entry>
+      <key>Vorläufig</key>
+    </entry>
+    <entry>
+      <key>Monatliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
+    </entry>
+    <entry>
+      <key>Betreff</key>
+    </entry>
+    <entry>
+      <key>Internal (2)</key>
+    </entry>
+    <entry>
+      <key>Company Addresses</key>
+    </entry>
+    <entry>
+      <key>Jährliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
+    </entry>
+    <entry>
+      <key>Termin</key>
+    </entry>
+    <entry>
+      <key>Außer Haus</key>
+    </entry>
+    <entry>
+      <key>Abgesagt</key>
+    </entry>
+    <entry>
+      <key>Tägliche Serie nicht genauer spezifiziert. Ignoriere Serie.</key>
+    </entry>
+    <entry>
+      <key>yyyyMMdd</key>
+    </entry>
+    <entry>
+      <key>Gebucht</key>
+    </entry>
+    <entry>
+      <key>Ein Gruppentermin kann nur durch den Organisator bearbeitet werden.</key>
+    </entry>
+    <entry>
+      <key>Communication Other</key>
+    </entry>
+    <entry>
+      <key>Communication Phone</key>
+    </entry>
+    <entry>
+      <key>Communication E-Mail</key>
+    </entry>
+    <entry>
+      <key>standard address</key>
+    </entry>
+  </keyValueMap>
+  <font name="Dialog" style="0" size="11" />
+</language>
diff --git a/neonView/PersPreview_view/PersPreview_view.aod b/neonView/PersPreview_view/PersPreview_view.aod
index 44c36c38d2d..a3b9ca8a3a4 100644
--- a/neonView/PersPreview_view/PersPreview_view.aod
+++ b/neonView/PersPreview_view/PersPreview_view.aod
@@ -1,62 +1,72 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.0">
-  <name>PersPreview_view</name>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <layout>
-    <boxLayout>
-      <name>layout</name>
-    </boxLayout>
-  </layout>
-  <children>
-    <cardViewTemplate>
-      <name>PersHeader_template</name>
-      <iconField>IMAGE</iconField>
-      <titleField>NAME_fieldGroup</titleField>
-      <descriptionField>ORGNAME</descriptionField>
-      <entityField>#ENTITY</entityField>
-    </cardViewTemplate>
-    <neonViewReference>
-      <name>4c4b1e66-fdc2-469c-a553-244b6dbffbe0</name>
-      <entityField>PersAddress_dfo</entityField>
-      <view>AddressList_view</view>
-    </neonViewReference>
-    <neonViewReference>
-      <name>f4f9ba7d-b969-416b-a4c2-0be82ad1c744</name>
-      <entityField>OrgAddress_dfo</entityField>
-      <view>AddressList_view</view>
-    </neonViewReference>
-    <neonViewReference>
-      <name>41e3d75c-0456-4140-b651-eb45ffb53a35</name>
-      <entityField>PersComm_dfo</entityField>
-      <view>CommList_view</view>
-    </neonViewReference>
-    <genericViewTemplate>
-      <name>PersInfo_template</name>
-      <showDrawer v="true" />
-      <drawerCaption>weitere Informationen</drawerCaption>
-      <entityField>#ENTITY</entityField>
-      <fields>
-        <entityFieldLink>
-          <name>b1fae414-9818-48ff-8774-c310caf34d79</name>
-          <entityField>SALUTATION</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>c12f22ff-3536-45b6-b26f-1d8de6b5aea0</name>
-          <entityField>TITLE</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>a224aada-e6cf-4357-b563-d7ccf313d32d</name>
-          <entityField>MIDDLENAME</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>f9875d78-3d72-47d3-b729-9cf80d236f6e</name>
-          <entityField>GENDER</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>5d4e0828-b7fe-4f54-a47a-f9b5838fb1ae</name>
-          <entityField>DATEOFBIRTH</entityField>
-        </entityFieldLink>
-      </fields>
-    </genericViewTemplate>
-  </children>
-</neonView>
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.0">
+  <name>PersPreview_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <cardViewTemplate>
+      <name>PersHeader_template</name>
+      <iconField>IMAGE</iconField>
+      <titleField>NAME_fieldGroup</titleField>
+      <descriptionField>ORGNAME</descriptionField>
+      <entityField>#ENTITY</entityField>
+    </cardViewTemplate>
+    <neonViewReference>
+      <name>4c4b1e66-fdc2-469c-a553-244b6dbffbe0</name>
+      <entityField>PersAddress_dfo</entityField>
+      <view>AddressList_view</view>
+    </neonViewReference>
+    <neonViewReference>
+      <name>f4f9ba7d-b969-416b-a4c2-0be82ad1c744</name>
+      <entityField>OrgAddress_dfo</entityField>
+      <view>AddressList_view</view>
+    </neonViewReference>
+    <neonViewReference>
+      <name>45aae3a7-b04e-460f-a68d-8a40c6181528</name>
+      <entityField>PersCommEmail_dfo</entityField>
+      <view>CommList_view</view>
+    </neonViewReference>
+    <neonViewReference>
+      <name>83e51f10-a205-409b-9780-a7ee14104cc1</name>
+      <entityField>PersCommPhone_dfo</entityField>
+      <view>CommList_view</view>
+    </neonViewReference>
+    <neonViewReference>
+      <name>1dbf2020-a0e9-4f22-a1d7-aad60c9ec7d4</name>
+      <entityField>PersCommOthers_dfo</entityField>
+      <view>CommList_view</view>
+    </neonViewReference>
+    <genericViewTemplate>
+      <name>PersInfo_template</name>
+      <showDrawer v="true" />
+      <drawerCaption>weitere Informationen</drawerCaption>
+      <entityField>#ENTITY</entityField>
+      <fields>
+        <entityFieldLink>
+          <name>b1fae414-9818-48ff-8774-c310caf34d79</name>
+          <entityField>SALUTATION</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>c12f22ff-3536-45b6-b26f-1d8de6b5aea0</name>
+          <entityField>TITLE</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>a224aada-e6cf-4357-b563-d7ccf313d32d</name>
+          <entityField>MIDDLENAME</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>f9875d78-3d72-47d3-b729-9cf80d236f6e</name>
+          <entityField>GENDER</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>5d4e0828-b7fe-4f54-a47a-f9b5838fb1ae</name>
+          <entityField>DATEOFBIRTH</entityField>
+        </entityFieldLink>
+      </fields>
+    </genericViewTemplate>
+  </children>
+</neonView>
diff --git a/process/Keyword_lib/process.js b/process/Keyword_lib/process.js
index 85b57553f31..0a8b118c663 100644
--- a/process/Keyword_lib/process.js
+++ b/process/Keyword_lib/process.js
@@ -1,233 +1,248 @@
-import("system.translate");
-
-/**
- * provides methods for interactions with keywords
- */
-function KeywordUtils(){
-    /**
-     * returns the default case for keyword-arrays (id and translated name)
-     * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY"
-     * @return {Array} a 2D array in form of [["id1", "name1"], ["idN", "nameN"]]
-     * @example
-     * var kwdUtils, items;
-     * 
-     * kwdUtils = new KeywordUtils();
-     * items = kwdUtils.getStandardArray("ADDRESS.TYPE");
-     * result.object(items);
-     */
-    this.getStandardArray = function(keywordType){
-        return this.createKeyword(keywordType).toArray(["id", "name"]);
-    }
-    
-    /**
-     * returns a specific name (translated) - this is normally the view-value - of a given keyword;
-     * <br/>if the key could not be found an empty string "" is returned 
-     * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY"
-     * @param {String} key id value of the keyword where the view-value shall be searched
-     * @return {String} representation of the translated name of the keyword-key
-     * @example
-     * var kwdUtils, histMedium;
-     * histMedium = vars.get("$field.MEDIUM");
-     * if (histMedium){
-     *     kwdUtils = new KeywordUtils();
-     *     result.string(vars.get("$field.SUBJECT") + " (" + kwdUtils.getViewValue("HISTORY.MEDIUM", histMedium) + ")");
-     * }
-     */
-    this.getViewValue = function(keywordType, key){
-        var k = this.createKeyword(keywordType);
-        return k.getPropForKey(key, "name") || "";
-    }
-    
-    /**
-     * creates an object with methods for interacting with an specific keyword
-     * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY"
-     * @return {Object} object with the following methods:
-     * <br/>- toArray
-     * <br/>- getPropForKey
-     * <br/>- getPropsForKey
-     */
-    this.createKeyword = function(keywordType){
-        var valueContainer, _toArrayFn, _getPropForKeyFn, _getPropsForKeyFn;
-
-        switch (keywordType){
-            case "RELATION.STATUS":
-                valueContainer = createKeywordEntriesContainer([
-                     createKeywordEntry("0", translate.text("Inactive"))
-                    ,createKeywordEntry("1", translate.text("Active"))
-                    ,createKeywordEntry("2", translate.text("In review"))
-                ]);
-                break;
-            case "COUNTRY":
-                valueContainer = createKeywordEntriesContainer([
-                     createKeywordEntry("DE", translate.text("Germany"))
-                    ,createKeywordEntry("AT", translate.text("Austria"))
-                    ,createKeywordEntry("CH", translate.text("Switzerland"))
-                    ,createKeywordEntry("GB", translate.text("United Kingdom"))
-                    ,createKeywordEntry("NO", translate.text("Norway"))
-                ]);
-                break;
-            case "LANGUAGE":
-                valueContainer = createKeywordEntriesContainer([
-                     createKeywordEntry("de", translate.text("German"))
-                    ,createKeywordEntry("de-DE", translate.text("German (Germany)"))
-                    ,createKeywordEntry("de-AT", translate.text("German (Austria)"))
-                    ,createKeywordEntry("en", translate.text("English"))
-                    ,createKeywordEntry("en-GB", translate.text("English (United Kingdom)"))
-                    ,createKeywordEntry("no-NO", translate.text("Norwegian"))
-                ]);
-                break;
-            case "HISTORY.DIRECTION":
-                valueContainer = createKeywordEntriesContainer([
-                     createKeywordEntry("i", translate.text("Incoming"))
-                    ,createKeywordEntry("o", translate.text("Outgoing"))
-                ]);
-                break;
-            case "HISTORY.MEDIUM":
-                valueContainer = createKeywordEntriesContainer([
-                     createKeywordEntry("0", translate.text("Visit"))
-                    ,createKeywordEntry("1", translate.text("E-Mail"))
-                    ,createKeywordEntry("2", translate.text("Phone"))
-                    ,createKeywordEntry("3", translate.text("Internal"))
-                    ,createKeywordEntry("4", translate.text("Online-Meeting"))
-                ]);
-            case "COMM.MEDIUM":
-                valueContainer = createKeywordEntriesContainer([
-                     createKeywordEntry("0", translate.text("Mobile"), null, {category: "PHONE"})
-                    ,createKeywordEntry("1", translate.text("E-Mail"), null, {category: "EMAIL"})
-                    ,createKeywordEntry("2", translate.text("Phone"), null, {category: "PHONE"})
-                    ,createKeywordEntry("3", translate.text("Internet"), null, {category: "WEBSITE"})
-                ]);
-                break;
-            case "ADDRESS.TYPE":
-                valueContainer = createKeywordEntriesContainer([
-                     createKeywordEntry("1", translate.text("Office address"))
-                    ,createKeywordEntry("2", translate.text("Home address"))
-                    ,createKeywordEntry("3", translate.text("Delivery address"))
-                    ,createKeywordEntry("4", translate.text("Post office box"))
-                ]);
-                break;
-            case "ORG.TYPE":
-                valueContainer = createKeywordEntriesContainer([
-                     createKeywordEntry("0", translate.text("Customer"))
-                    ,createKeywordEntry("1", translate.text("Prospect"))
-                    ,createKeywordEntry("2", translate.text("Supplier"))
-                    ,createKeywordEntry("3", translate.text("Other"))
-                ]);
-                break;
-            case "PERS.GENDER":
-                valueContainer = createKeywordEntriesContainer([
-                     createKeywordEntry("f", translate.text("Female"))
-                    ,createKeywordEntry("m", translate.text("Male"))
-                    ,createKeywordEntry("o", translate.text("${GENDER_OTHER}"))
-                ]);
-                break;
-            default: 
-                throw new Error(translate.withArguments("[%0]the given keyword \"%1\" has no match with the possible keywordlist", [
-                    arguments.callee.name, keywordType
-                ]));
-                break;
-        }
-
-
-        _getPropForKeyFn = function(key, field, isCustom) {
-            var keyObject;
-            if (isCustom)
-                keyObject = valueContainer[key]["customProperties"];
-            else
-                keyObject = valueContainer[key];
-                
-            if (keyObject == undefined)
-                return undefined;
-            return keyObject[field];
-        };
-        
-        _getPropsForKeyFn = function(key, fields) {
-            var keyObject, i, l, currentRow, currentField;
-            
-            keyObject = valueContainer[key];
-            if (keyObject == undefined)
-                return [];//TODO: throw error instead?
-            l = fields.length;
-            currentRow = [];
-            for (i = 0; i < l; i++){
-                currentField = fields[i];
-                //check if the passed fieldnames match the existing fieldnames (<=> properties in the object)
-                //to prevent errors and unexpected behaviour
-                if (keyObject[currentField])
-                    currentRow.push(keyObject[currentField]);
-                else
-                    currentRow.push("");
-            }
-            return currentRow;
-        };
-        
-        _toArrayFn = function(fields){
-            var res, id, currentRow;
-
-            res = [];
-            if (!fields)
-                fields = ["id", "name"];
-            l = fields.length;
-            for (id in valueContainer){
-                currentRow = _getPropsForKeyFn(id, fields);
-                res.push(currentRow);
-            }
-            return res;
-        };
-
-        return {
-            /**
-             * toArray
-             */
-             toArray: _toArrayFn
-            ,getPropForKey: _getPropForKeyFn
-            ,getPropsForKey: _getPropsForKeyFn
-        };
-    };
-    
-    /**
-     * internal  function for creating an object that represents a keyword entry
-     * @param {String} id represents the key of an entry; a KeywordEntriesContainer can contain the same key only once
-     * @param {String} name represents the translated name of an entry; this is in most cases the view-value
-     * @param {String} [description=""] description text for describing the keyword
-     * @param {Object} [customProperties=null] an Object with additional properties; these can be virtually anything
-     * @return {Object} object that represents a single keyword entry; normally severel entries are cumulated in a "keywordEntriesContainer"
-     */
-    function createKeywordEntry(id, name, description, customProperties){
-        //TODO: verify if mandatory-checks are really that usefull or can at least be made easier
-        if (!id)
-            throw new Error(translate.withArguments("the param \"%0\" in \"%1\" is mandatory and has to be set", [
-                "id", arguments.callee.name
-            ]));
-        if (!name)
-            throw new Error(translate.withArguments("the param \"%0\" in \"%1\" is mandatory and has to be set", [
-                "name", arguments.callee.name
-            ]));
-
-        return {
-             id: id
-            ,name: name
-            ,description: description || ""
-            ,customProperties: customProperties
-        };
-    }
-
-    /**
-     * internal  function for creating an object that represents a container of several keywordEntries
-     * @param {Array} keywordEntries an Array of keywordEntry-objects (as they are created by "createKeywordEntry"
-     * @return {Object} object that contains several keywordEntries
-     */
-    function createKeywordEntriesContainer(keywordEntries){
-        var res, i, l, id;
-
-        res = {};
-        for (i = 0, l = keywordEntries.length; i < l; i++){
-            id = keywordEntries[i].id;
-            if (res[id] != undefined){
-                throw new Error("the given id is not unique since it already exists");
-            }
-            res[id] = keywordEntries[i];
-        }
-        return res;
-    }
+import("system.translate");
+
+/**
+ * provides methods for interactions with keywords
+ */
+function KeywordUtils(){
+    /**
+     * returns the default case for keyword-arrays (id and translated name)
+     * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY"
+     * @return {Array} a 2D array in form of [["id1", "name1"], ["idN", "nameN"]]
+     * @example
+     * var kwdUtils, items;
+     * 
+     * kwdUtils = new KeywordUtils();
+     * items = kwdUtils.getStandardArray("ADDRESS.TYPE");
+     * result.object(items);
+     */
+    this.getStandardArray = function(keywordType){
+        return this.createKeyword(keywordType).toArray(["id", "name"]);
+    }
+    
+    /**
+     * returns a specific name (translated) - this is normally the view-value - of a given keyword;
+     * <br/>if the key could not be found an empty string "" is returned 
+     * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY"
+     * @param {String} key id value of the keyword where the view-value shall be searched
+     * @return {String} representation of the translated name of the keyword-key
+     * @example
+     * var kwdUtils, histMedium;
+     * histMedium = vars.get("$field.MEDIUM");
+     * if (histMedium){
+     *     kwdUtils = new KeywordUtils();
+     *     result.string(vars.get("$field.SUBJECT") + " (" + kwdUtils.getViewValue("HISTORY.MEDIUM", histMedium) + ")");
+     * }
+     */
+    this.getViewValue = function(keywordType, key){
+        var k = this.createKeyword(keywordType);
+        return k.getPropForKey(key, "name") || "";
+    }
+    
+    /**
+     * creates an object with methods for interacting with an specific keyword
+     * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY"
+     * @return {Object} object with the following methods:
+     * <br/>- toArray
+     * <br/>- getPropForKey
+     * <br/>- getPropsForKey
+     */
+    this.createKeyword = function(keywordType){//TODO: rename ot createKeywordObj?
+        var valueContainer, _toArrayFn, _getPropForKeyFn, _getPropsForKeyFn;
+
+        switch (keywordType){
+            case "RELATION.STATUS":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("0", translate.text("Inactive"))
+                    ,createKeywordEntry("1", translate.text("Active"))
+                    ,createKeywordEntry("2", translate.text("In review"))
+                ]);
+                break;
+            case "COUNTRY":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("DE", translate.text("Germany"))
+                    ,createKeywordEntry("AT", translate.text("Austria"))
+                    ,createKeywordEntry("CH", translate.text("Switzerland"))
+                    ,createKeywordEntry("GB", translate.text("United Kingdom"))
+                    ,createKeywordEntry("NO", translate.text("Norway"))
+                ]);
+                break;
+            case "LANGUAGE":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("de", translate.text("German"))
+                    ,createKeywordEntry("de-DE", translate.text("German (Germany)"))
+                    ,createKeywordEntry("de-AT", translate.text("German (Austria)"))
+                    ,createKeywordEntry("en", translate.text("English"))
+                    ,createKeywordEntry("en-GB", translate.text("English (United Kingdom)"))
+                    ,createKeywordEntry("no-NO", translate.text("Norwegian"))
+                ]);
+                break;
+            case "HISTORY.DIRECTION":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("i", translate.text("Incoming"))
+                    ,createKeywordEntry("o", translate.text("Outgoing"))
+                ]);
+                break;
+            case "HISTORY.MEDIUM":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("0", translate.text("Visit"))
+                    ,createKeywordEntry("1", translate.text("E-Mail"))
+                    ,createKeywordEntry("2", translate.text("Phone"))
+                    ,createKeywordEntry("3", translate.text("Internal"))
+                    ,createKeywordEntry("4", translate.text("Online-Meeting"))
+                ]);
+            case "COMM.MEDIUM":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("0", translate.text("Mobile"), null, {category: "PHONE"})
+                    ,createKeywordEntry("1", translate.text("E-Mail"), null, {category: "EMAIL"})
+                    ,createKeywordEntry("2", translate.text("Phone"), null, {category: "PHONE"})
+                    ,createKeywordEntry("3", translate.text("Internet"), null, {category: "OTHER"})
+                ]);
+                break;
+            case "ADDRESS.TYPE":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("1", translate.text("Office address"))
+                    ,createKeywordEntry("2", translate.text("Home address"))
+                    ,createKeywordEntry("3", translate.text("Delivery address"))
+                    ,createKeywordEntry("4", translate.text("Post office box"))
+                ]);
+                break;
+            case "ORG.TYPE":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("0", translate.text("Customer"))
+                    ,createKeywordEntry("1", translate.text("Prospect"))
+                    ,createKeywordEntry("2", translate.text("Supplier"))
+                    ,createKeywordEntry("3", translate.text("Other"))
+                ]);
+                break;
+            case "PERS.GENDER":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("f", translate.text("Female"))
+                    ,createKeywordEntry("m", translate.text("Male"))
+                    ,createKeywordEntry("o", translate.text("${GENDER_OTHER}"))
+                ]);
+                break;
+            default: 
+                throw new Error(translate.withArguments("[%0]the given keyword \"%1\" has no match with the possible keywordlist", [
+                    arguments.callee.name, keywordType
+                ]));
+                break;
+        }
+
+
+        _getPropForKeyFn = function(key, field, isCustom) {
+            var keyObject;
+            if (isCustom)
+                keyObject = valueContainer[key]["customProperties"];
+            else
+                keyObject = valueContainer[key];
+                
+            if (keyObject == undefined)
+                return undefined;
+            return keyObject[field];
+        };
+        
+        _getPropsForKeyFn = function(key, fields) {
+            var keyObject, i, l, currentRow, currentField;
+            
+            keyObject = valueContainer[key];
+            if (keyObject == undefined)
+                return [];//TODO: throw error instead?
+            l = fields.length;
+            currentRow = [];
+            for (i = 0; i < l; i++){
+                currentField = fields[i];
+                //check if the passed fieldnames match the existing fieldnames (<=> properties in the object)
+                //to prevent errors and unexpected behaviour
+                if (keyObject[currentField])
+                    currentRow.push(keyObject[currentField]);
+                else
+                    currentRow.push("");
+            }
+            return currentRow;
+        };
+        
+        _toArrayFn = function(fields){
+            var res, id, currentRow;
+
+            res = [];
+            if (!fields)
+                fields = ["id", "name"];
+            else if (typeof(fields) == "string"){
+                for (id in valueContainer){
+                    res.push(_getPropForKeyFn(id, fields));
+                }
+                return res;
+            }
+            
+            for (id in valueContainer){
+                currentRow = _getPropsForKeyFn(id, fields);
+                res.push(currentRow);
+            }
+            return res;
+        };
+
+        return {
+            /**
+             * toArray
+             */
+             toArray: _toArrayFn
+            ,getPropForKey: _getPropForKeyFn
+            ,getPropsForKey: _getPropsForKeyFn
+            ,filter: function (callbackFn, thisArg){
+                for (id in valueContainer){
+                    if (false == callbackFn.call(thisArg, valueContainer[id].id, valueContainer[id].name, valueContainer[id].customProperties, 
+                            valueContainer[id], valueContainer)){
+                        delete valueContainer[id];
+                    }
+                }
+                return this;
+            }
+        };
+    };
+    
+    /**
+     * internal  function for creating an object that represents a keyword entry
+     * @param {String} id represents the key of an entry; a KeywordEntriesContainer can contain the same key only once
+     * @param {String} name represents the translated name of an entry; this is in most cases the view-value
+     * @param {String} [description=""] description text for describing the keyword
+     * @param {Object} [customProperties=null] an Object with additional properties; these can be virtually anything
+     * @return {Object} object that represents a single keyword entry; normally severel entries are cumulated in a "keywordEntriesContainer"
+     */
+    function createKeywordEntry(id, name, description, customProperties){
+        //TODO: verify if mandatory-checks are really that usefull or can at least be made easier
+        if (!id)
+            throw new Error(translate.withArguments("the param \"%0\" in \"%1\" is mandatory and has to be set", [
+                "id", arguments.callee.name
+            ]));
+        if (!name)
+            throw new Error(translate.withArguments("the param \"%0\" in \"%1\" is mandatory and has to be set", [
+                "name", arguments.callee.name
+            ]));
+
+        return {
+             id: id
+            ,name: name
+            ,description: description || ""
+            ,customProperties: customProperties
+        };
+    }
+
+    /**
+     * internal  function for creating an object that represents a container of several keywordEntries
+     * @param {Array} keywordEntries an Array of keywordEntry-objects (as they are created by "createKeywordEntry"
+     * @return {Object} object that contains several keywordEntries
+     */
+    function createKeywordEntriesContainer(keywordEntries){
+        var res, i, l, id;
+
+        res = {};
+        for (i = 0, l = keywordEntries.length; i < l; i++){
+            id = keywordEntries[i].id;
+            if (res[id] != undefined){
+                throw new Error("the given id is not unique since it already exists");
+            }
+            res[id] = keywordEntries[i];
+        }
+        return res;
+    }
 }
\ No newline at end of file
diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js
index 24a50f2516a..9187a8f49e5 100644
--- a/process/Sql_lib/process.js
+++ b/process/Sql_lib/process.js
@@ -1,1006 +1,1066 @@
-import("system.translate");
-import("system.vars");
-import("system.db");
-import("system.datetime");
-import("system.tools");
-import("system.SQLTYPES");
-import("Util_lib")
-
-function SqlMaskingUtils(){
-    //TODO: use callbacks for different handling?
-    /**
-    * masks the function cast of standard sql
-    *
-    * @param {String} field name of the database field that shall be castet
-    * @param {String} [targetDatatype] a SQLTYPES-value of the following: SQLTYPES.CHAR, SQLTYPES.VARCHAR, SQLTYPES.INTEGER, 
-    *                                   SQLTYPES.DECIMAL, SQLTYPES.DATE
-    * @param {int|int[]} targetLength specifies the length of the target data type;
-    *                                   <br/>- char/varchar: length
-    *                                   <br/>- decimal: [length, decimals]
-    * @param {String} [alias=the current alias] the alias where the statement shall be executed (this is needed to determine the database-type)
-    *
-    * @return {String} sql part to be included in sql-statements
-    */
-    this.cast = function (field, targetDatatype, targetLength, alias){
-        /* Some informations if you want to add supported databaseTypes or dataTypes:
-         * You should consider using the _mapDefaults function-expression (details in the functions doc)
-         * However you shouldn't use the function in a "default"-Block of a switch-case because of the following behaviour:
-         * If a datatype is not supported you just have to NOT specify "sqlDataType" (leave it "undefined") -> an error is then raised
-         * Therefore you should explicitly define which Data-type is supported and which is not
-        */
-        var dbType, functionName, sqlPart, sqlDataType, _mapDefaults;
-        if (alias == undefined) 
-            alias = vars.getString("$sys.dbalias");
-        dbType = db.getDatabaseType(alias);
-        functionName = "cast";//overwrite this in the "switch (dbType)" if needed with your DBMS
-
-        /**
-         * handles default-scenarios for mapping input-targetDatatype to a string for a sql-statement
-         * e.g. SQLTYPES.INTEGER --> int
-         * @param {Number} dataType input as a value of "SQLTYPES." that will be mapped to a string
-         * @return {String} the mapped dataType for using in a sql-statement
-         */
-        _mapDefaults = function (dataType){
-            var res;
-            switch(dataType)
-            {
-                case SQLTYPES.CHAR:
-                    res = "char";
-                    break;
-                case SQLTYPES.VARCHAR:
-                    res = "char";
-                    break;
-                case SQLTYPES.INTEGER:
-                    res = "int";
-                    break;
-                case SQLTYPES.DECIMAL:
-                    res = "decimal";
-                    break;
-                case SQLTYPES.DATE:
-                    res = "date";
-                    break;
-            }
-            return res;
-        }
-        switch (dbType) {
-            case db.DBTYPE_DERBY10:
-                switch(targetDatatype) {
-                    case SQLTYPES.VARCHAR:
-                        // Because of a Derby bug, you can't cast INTEGER into VARCHAR
-                        // Therefor first cast to char then to varchar
-                        // https://issues.apache.org/jira/browse/DERBY-2072
-                        field = "rtrim(" + cast(field, SQLTYPES.CHAR, targetLength, alias) + ")";
-                        sqlDataType = "varchar";
-                        break;
-                    case SQLTYPES.CHAR:
-                        //TODO: throw error if(targetLength > 254)? https://db.apache.org/derby/docs/10.14/ref/rrefsqlj13733.html
-                        sqlDataType = "char";
-                        break;
-                    case SQLTYPES.DECIMAL:
-                    case SQLTYPES.INTEGER:
-                    case SQLTYPES.DATE:
-                        sqlDataType = _mapDefaults(dataType);
-                        break;
-                }
-                break;
-            case db.DBTYPE_MARIADB10:
-            case db.DBTYPE_MYSQL4:
-                switch(targetDatatype) {
-                    case SQLTYPES.VARCHAR:
-                    case SQLTYPES.CHAR:
-                    case SQLTYPES.INTEGER:
-                    case SQLTYPES.DECIMAL:
-                    case SQLTYPES.DATE:
-                        sqlDataType = _mapDefaults(targetDatatype);
-                        break;
-                }
-                break;
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-                switch(pDatatype)
-                {
-                    case SQLTYPES.VARCHAR:
-                        datatype = "varchar2";
-                        break;
-                    case SQLTYPES.INTEGER:
-                        datatype = "number";
-                        targetLength = "10"
-                        break;
-                    case SQLTYPES.CHAR:
-                    case SQLTYPES.DECIMAL:
-                    case SQLTYPES.DATE:
-                        sqlDataType = _mapDefaults(targetDatatype);
-                        break;
-                }
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-                switch(pDatatype)
-                {
-                    case SQLTYPES.DATE:
-                    case SQLTYPES.DECIMAL:
-                    case SQLTYPES.INTEGER:
-                    case SQLTYPES.CHAR:
-                    case SQLTYPES.VARCHAR:
-                        sqlDataType = _mapDefaults(targetDatatype);
-                        break;
-                }
-                break;
-            case db.DBTYPE_SQLSERVER2000:
-                    case SQLTYPES.DATE:
-                    case SQLTYPES.DECIMAL:
-                    case SQLTYPES.INTEGER:
-                    case SQLTYPES.CHAR:
-                    case SQLTYPES.VARCHAR:
-                        sqlDataType = _mapDefaults(targetDatatype);
-                        break;
-            case db.DBTYPE_FIREBIRD250:
-                //TODO: firebird support?
-                break;
-        }
-        
-        if (sqlDataType == undefined) {
-            throw new Error("sqlDataType");//TODO: add usefull message
-        }
-        
-        if(targetLength == undefined)
-            targetLength = "";
-        else if(targetLength != "")
-        {
-            if(typeof(targetLength == "object") && (targetLength instanceof Array))
-                targetLength = "(" + targetLength.join(", ") + ")";
-            else
-                targetLength = "(" + targetLength + ")";
-        }
-        
-        sqlPart = functionName + "(" + field + " as " + sqlDataType + targetLength + ")";
-        return sqlPart;
-    }
-}
-
-/**
- *Class containing utilities for SQL
- *@deprecated use SqlMaskingUtils
- *@class
- */
-function LegacySqlUtils()
-{
-    var that = this;
-    /**
-    * masks the cast function for lob datatypes(clob, blob)
-    *
-    * @param {String} pField req the data field
-    * @param {Integer|Interger[]} pLength req the length of the data
-    *                                         decimal: [length, decimals]
-    * @param {String} pAlias req the database alias
-    *
-    * @return {String} (Teil einer SQL-Anweisung)
-    */
-    this.castLob = function(pField, pLength, pAlias)
-    {
-        if(pAlias == undefined) 
-            pAlias = vars.getString("$sys.dbalias");
-        
-        var dbtype = db.getDatabaseType(pAlias);
-
-        switch(Number(dbtype))
-        {
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-                return "DBMS_LOB.SUBSTR(" + pField + ", " + pLength + ", 1)";
-                break;
-            default:
-                return cast(pField, "varchar", pLength, pAlias);
-                break;
-        }
-    }
-    /**
-    * masks the function substring.
-    *
-    * @param {String }pExpression req
-    * @param {Integer} pStart req index of the beginning
-    * @param {String} pAlias req database alias
-    * @param {Integer} pLength req
-    *
-    * @return {String}
-    */
-    this.substring = function(pExpression, pStart, pLength, pAlias)
-    {
-        if(pLength == undefined) 
-            pLength = 100;
-        if(pAlias == undefined) 
-            pAlias = vars.getString("$sys.dbalias");
-        
-        var dbtype = db.getDatabaseType(pAlias);
-        var string = "";
-
-        switch(Number(dbtype))
-        {
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-                string = "substr";
-                break;
-            case db.DBTYPE_DERBY10:
-                string = "substr";
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-                string = "substr";
-                break;
-            case db.DBTYPE_SQLSERVER2000:
-                string = "substring";
-                break;
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                string = "substring";
-                break;
-        }
-
-        return string + "(" + pExpression + ", " + pStart + ", " + pLength + ")";
-    }
-    
-    /**
-    * masks the function concat.
-    *
-    * @param {Array} pFields req fields that should be concatenated
-    * @param {String} pSeparator opt field separator
-    * @param {String} pAlias opt database alias
-    *
-    * @return {String} part of SQL-querey
-    */
-    this.concat = function(pFields, pSeparator, pAlias)
-    {
-        var i;
-        if(pAlias == undefined || pAlias == "")  
-            pAlias =  vars.getString("$sys.dbalias");
-        
-        var dbtype = db.getDatabaseType(pAlias);
-        var concat_string = " || ";
-        var retstr = "";
-        var blank = "' '";
-        
-        //it must be checked for empty string and null
-        var isNotEmpty =  " != '' ";
-        var isNotNull = " is not null ";
-        if(pSeparator == undefined) 
-            pSeparator = " ";
-        
-        switch(Number(dbtype))
-        {
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                retstr = " concat_ws( '" + pSeparator + "'";
-                for(i=0; i<pFields.length; i++)
-                {
-                    retstr += ", " + pFields[i];
-                }
-                return retstr + ") ";
-                break;
-
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-                blank = "trim(' ')";
-                isNotEmpty = " is not null "; //needed for oracle
-                break;
-
-            case db.DBTYPE_SQLSERVER2000:
-                concat_string = " + ";
-                break;
-        }
-        pSeparator = concat_string + "'" + pSeparator + "'";
-        for(i = 0; i < pFields.length; i++)
-        {
-            if(retstr != "")  
-                retstr += concat_string;
-            if ( i < pFields.length - 1 ) //Check if another value follows, if not separator is not needed
-                retstr += " case when " + pFields[i] + isNotEmpty + " then case when " + this.trimSql(pFields[i+1], pAlias) + isNotEmpty + " and "
-                + this.trimSql(pFields[i+1], pAlias) + isNotNull + " then " + pFields[i] + pSeparator + " else " + pFields[i] + " end" + " else " + blank + " end ";
-            else
-                retstr += " case when " + pFields[i] + isNotEmpty + " then " + pFields[i] + " else " + blank + " end ";
-        }
-        return retstr;
-    }
-    /**
-    * builds a condition out of multiple conditions
-    *
-    * @param {Array} pArray req Array containing the conditions
-    * @param {String} pOperator req Operator that concatenates the conditions (AND/OR)
-    *
-    * @return {String} concatenated Condition
-    */
-    this.concatConditions = function(pArray, pOperator)
-    {
-        var resultCondition = "";
-
-        for(var i = 0; i < pArray.length; i++)
-        {
-            if(pArray[i] != null && pArray[i] != '')
-            {
-                if(resultCondition.length > 0)
-                    resultCondition += (" " + pOperator + " ");
-
-                resultCondition += pArray[i];
-            }
-        }
-
-        return resultCondition;
-    }
-    /**
-    * Checks if a new entry already exists
-    *
-    * @param {String} pTable req Databasetable(z.B. "comm")
-    * @param {Array} pColumns req colums, like sqlInsert
-    * @param {Array} pTypes req die datatypes, like sqlInsert
-    * @param {Array} pValues req values, like sqlInsert
-    * @param {Array} pExcludeFields opt columns, that should not be checked
-    * @param {String} pAlias opt Database alias
-    *
-    * @return {Integer}
-    */
-    this.isDuplicat = function(pTable, pColumns, pTypes, pValues, pExcludeFields, pAlias)
-    {
-        var col = new Array();
-        var typ = new Array();
-        var val = new Array();
-        var excludefields = ["DATE_NEW" ,"DATE_EDIT" ,"USER_NEW" ,"USER_EDIT", "KEYVALUE",  "KEYSORT", pTable.toUpperCase() + "ID"];
-        
-        if(pExcludeFields != undefined) 
-            excludefields = excludefields.concat(pExcludeFields);
-        if(pAlias == undefined)  
-            pAlias = vars.getString("$sys.dbalias");
-
-        for(var i = 0; i < pColumns.length; i++)
-        {
-            if(!hasElement(excludefields, pColumns[i], true) && pValues[i] != "" && pTypes[i] != SQLTYPES.LONGVARCHAR && pTypes[i] != SQLTYPES.CLOB)
-            {
-                col.push(pColumns[i]);
-                typ.push(pTypes[i]);
-                val.push(pValues[i]);
-            }
-        }
-        var count = db.getRowCount(pTable, col, typ, val, pAlias);
-        return count;
-    }
-    /**
-    *  returns the trim function depending on the database
-    *
-    * @param {String} pField field the should be trimmed
-    * @param {String} pAlias opt database alias
-    *
-    * @return {String}
-    */
-    this.trimSql = function(pField, pAlias)
-    {
-        if(pAlias == undefined || pAlias == "")  
-            pAlias =  vars.getString("$sys.dbalias");
-        
-        var dbtype = db.getDatabaseType(pAlias);
-        var string;
-
-        switch(Number(dbtype))
-        {
-            case db.DBTYPE_SQLSERVER2000:
-                string = "ltrim(rtrim(" + pField + "))";
-                break;
-            default:
-                string = "trim(" + pField + ")"
-                break;
-        }
-        return string;
-    }
-    /**
-    * returns the day of a date
-    *
-    * @param {Datetime} pDate req the date
-    * @param {String} pAlias req database alias
-    *
-    * @return {String}
-    */
-    this.dayFromDate = function(pDate, pAlias)
-    {
-        var usedAlias = pAlias;
-        
-        if(pAlias == undefined) 
-            usedAlias = vars.getString("$sys.dbalias");
-        
-        var dbAlias = db.getDatabaseType(usedAlias);
-        var string = "";
-
-        switch(Number(dbAlias))
-        {
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-                string = "to_char(" + pDate + ",'dd')";
-                break;
-            case db.DBTYPE_DERBY10:
-            case db.DBTYPE_SQLSERVER2000:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                string = "DAY(" + pDate + ")";
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-                string = "EXTRACT (DAY from " + pDate + ")";
-                break;
-        }
-        return string;
-    }
-    /**
-    * returns the month of a date
-    *
-    * @param {Datetime} pDate req the date
-    * @param {String} pAlias req database alias
-    *
-    * @return {String}
-    */
-    this.monthFromDate = function(pDate, pAlias)
-    {
-        var usedAlias = pAlias;
-        if(pAlias == undefined) 
-            usedAlias = vars.getString("$sys.dbalias");
-        
-        var dbAlias = db.getDatabaseType(usedAlias);
-        var string = "";
-
-        switch(Number(dbAlias))
-        {
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-                string = "to_char(" + pDate + ",'MM')";
-                break;
-            case db.DBTYPE_DERBY10:
-            case db.DBTYPE_SQLSERVER2000:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                string = "MONTH(" + pDate + ")";
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-                string = "EXTRACT (MONTH FROM " + pDate + ")";
-                break;
-        }
-        return string;
-    }
-    /**
-    * returns the year of a date
-    *
-    * @param {Datetime} pDate req the date
-    * @param {String} pAlias req database alias
-    *
-    * @return {String}
-    */
-    this.yearFromDate = function(pDate, pAlias)
-    {
-        var usedAlias = pAlias;
-        if(pAlias == undefined) 
-            usedAlias = vars.getString("$sys.dbalias");
-        
-        var dbAlias = db.getDatabaseType(usedAlias);
-        var string = "";
-
-        switch(Number(dbAlias))
-        {
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-                string = "to_char(" + pDate + ",'yyyy')";
-                break;
-            case db.DBTYPE_DERBY10:
-            case db.DBTYPE_SQLSERVER2000:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                string = "YEAR(" + pDate + ")";
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-                string = "EXTRACT (YEAR FROM " + pDate + ")";
-                break;
-        }
-        return string;
-    }
-    /**
-    * returns the function for current date depending on database
-    *
-    * @return {String} expression
-    */
-    this.currentDate = function()
-    {
-        var dbtype = db.getDatabaseType(vars.getString("$sys.dbalias"));
-        var expression = "";
-
-        switch (Number(dbtype))
-        {
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-            case db.DBTYPE_DERBY10:
-                expression = "CURRENT_DATE";
-                break;
-            case db.DBTYPE_SQLSERVER2000:
-                expression = "GETDATE()";
-                break;
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                expression = "NOW()";
-                break;
-        }
-        return expression;
-    }
-    /**
-    * returns the current search string incl placeholders
-    *
-    * @param {String} pfield req the search field
-    * @param {String} pfind req the search string
-    * @param {String} pIgnoreCase opt (true/false)
-    * @param {String} pPlaceHolder opt (Platzhalter config)
-    *
-    * @return {String}
-    */
-    this.getPlacerholderCondition = function( pfield, pfind, pIgnoreCase, pPlaceHolder )
-    {
-        var user = tools.getCurrentUser();
-        var IgCa;
-        var PlHo;
-
-        //wenn optoinal IgnoreCase und PlaceHolder vorhanden, dann diese verwenden
-        if(pIgnoreCase != undefined)
-            IgCa = pIgnoreCase;
-        else
-            IgCa = user[tools.PARAMS][tools.SELECTION_IGNORECASE];
-
-        if(pPlaceHolder != undefined)
-            PlHo = pPlaceHolder;
-        else
-            PlHo = user[tools.PARAMS][tools.SELECTION_PLACEHOLDER];
-
-        if ( pfind )
-        {
-            pfind = pfind.replace( new RegExp("\\'", "g"), "''");
-            pfind = pfind.replace( new RegExp("\\*", "g"), "%");
-            var ic = (IgCa == "true" ? "UPPER" : "");
-            var cond = "";
-            switch( PlHo )
-            {
-                case "1":
-                    cond = ic + "(" + pfield + ") like " + ic + "('" + pfind + "%')";
-                    break;
-                case "2":
-                    cond = ic + "(" + pfield + ") like " + ic + "('%" + pfind + "')";
-                    break;
-                case "3":
-                    cond = ic + "(" + pfield + ") like " + ic + "('%" + pfind + "%')";
-                    break;
-                case "4":
-                    cond = ic + "(" + pfield + ") like " + ic + "('" + pfind + "')";
-                    break;
-                default:
-                    cond = ic + "(" + pfield + ") = " + ic + "('" + pfind + "')";
-                    break;
-            }
-        }
-        return cond;
-    }
-    /**
-    * returns SQLSystax for a date.
-    *
-    * @param {String} pColumn req Column name
-    * @param {String} pAlias opt Database alias
-    * @param {Boolean} pWithTime opt if true, then add time hh:mm:ss
-    * @param {String} pFormat opt type of the format, e.g. yyyy-MM-dd; possible placeholers are: -dd -MM -yyyy
-    *
-    *@return {String} sqlstr, fully functional select for sql for different types of databases
-    */
-    this.getSqlFormattedDate = function(pColumn, pAlias, pWithTime, pFormat)
-    {
-        if(pAlias == undefined)  
-            pAlias = vars.getString("$sys.dbalias");
-        
-        var pDatabaseType = db.getDatabaseType(pAlias);
-        
-        if (pFormat == undefined)
-            pFormat = translate.text("yyyy-MM-dd");
-        
-        var str = "";
-        
-        switch(Number(pDatabaseType))
-        {
-            case db.DBTYPE_SQLSERVER2000:
-                day = "right('0' + cast(day(" + pColumn + ") as varchar(2)) , 2)";
-                month = "right('0' + cast(month(" + pColumn + ") as varchar(2)) , 2)";
-                year = "cast(year(" + pColumn + ") as char(4))";
-                time = pWithTime == true? that.concat(["' '","cast(cast(" + pColumn + " as time) as char(8))"], "", pAlias) : "";
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-                day = "extract(day from " + pColumn + ")";
-                month = "extract(month from " + pColumn + ")";
-                year = "extract(year from " + pColumn + ")";
-                time = pWithTime == true? that.concat(["' '","extract(time from" + pColumn + ")"], "", pAlias) : "";
-                break;
-            case db.DBTYPE_DERBY10:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                // concat will try to have a leading blank space if the number is => 10. This is why we had to use substr.
-                day = that.substring(that.concat(["case when day(" + pColumn + ") <= 9 then '00' else '0' end "
-                    , " trim(cast(day(" + pColumn + ") as char(2)))"], "", pAlias), 2, 2, pAlias);
-                month = that.substring(that.concat(["case when month(" + pColumn + ") <= 9 then '00' else '0' end "
-                    , "trim(cast(month(" + pColumn + ") as char(2)))"], "", pAlias), 2, 2, pAlias);
-                year = "trim(cast(year(" + pColumn + ") as char(4)))";
-                time = pWithTime == true? that.concat(["cast(' ' as char(1))", "trim(cast(time(" + pColumn + ") as char(8)))"], "", pAlias) : "";
-                break;
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_OCI:
-            case db.DBTYPE_ORACLE10_THIN:
-
-                day = "to_char(" + pColumn + ", 'dd') ";
-                month = "to_char(" + pColumn + ", 'MM') ";
-                year = "to_char(" + pColumn + ", 'yyyy') ";
-                time = pWithTime == true ? " to_char(" + pColumn + ", ' hh24:mi:ss')" : "";
-                break;
-            default:
-                str = "cast(" + pColumn + " as varchar (10))";
-                return str;
-                break;
-        }
-
-        var re = /(dd)|(MM)|(yyyy)/g        // Regex to check the date
-        var matchResult;
-        var endOfLastMatch = 0;
-        var res = [];
-        
-        while ((matchResult = re.exec(pFormat)) !== null) 
-        {
-            if( endOfLastMatch != matchResult.index)
-            {
-                res.push("'" + db.quote(pFormat.substring(endOfLastMatch, matchResult.index), pAlias) + "'");     // making sure we get the correct amount of quotations
-            }
-            switch(matchResult[0])
-            {
-                case "dd":
-                    res.push(day);
-                    break;
-                case "MM":
-                    res.push(month);
-                    break;
-                case "yyyy":
-                    res.push(year);
-                    break;
-            }
-            endOfLastMatch = re.lastIndex;
-        }
-        // making sure we get the correct amount of quotations
-        // allows us to add custom strings behind the format which will be shown in the output
-        // e.g. "yyyy-MM-dd 00:00", "date: MM/dd/yyyy"
-        res.push("'" + db.quote(pFormat.slice(endOfLastMatch), pAlias) + "'");
-        
-        if(time != "")
-            res.push(time);
-        
-        str = concat(res, "", pAlias);
-        
-        return str;
-    }
-    /**
-    * returns a SQL operator depending on an integer value, i.e. $local.operator
-    *
-    * @param {int} pVal
-    *
-    * @return {string}
-    */
-    this.getSQLOperator = function(pVal)
-    {
-        var retval = "";
-        switch(Number(pVal))
-        {
-            case 1:
-                retval = "=";
-                break; //equals
-            case 2:
-                retval = "<>";
-                break; //not equal
-            case 3:
-                retval = ">";
-                break; //greater
-            case 4:
-                retval = "<";
-                break; //lesser
-            case 5:
-                retval = "<=";
-                break; //lesser or equal
-            case 6:
-                retval = ">=";
-                break; //greater or equal
-            case 7:
-                retval = "like";
-                break; //contains
-            case 8:
-                retval = "not like";
-                break; //contains not
-            case 9:
-                retval = "";
-                break;
-            case 10:
-                retval = "";
-                break;
-            case 11:
-                retval = "is not null";
-                break;
-            case 12:
-                retval = "is null";
-                break;
-        }
-        return retval;
-    }
-    /**
-    *  returns the function which determines the length of binary data, depending on db type
-    *
-    * @param {String} pField name of the checked field
-    *
-    * @return {String}
-    */
-    this.binDataLength = function(pField)
-    {
-        var dbtype = db.getDatabaseType(vars.getString("$sys.dbalias"));
-        var length;
-
-        switch(Number(dbtype))
-        {
-            case db.DBTYPE_MARIADB10:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-            case db.DBTYPE_POSTGRESQL8:
-            case db.DBTYPE_DERBY10:
-                length = "LENGTH("+pField+")";
-                break;
-            case db.DBTYPE_SQLSERVER2000:
-                length = "DATALENGTH("+pField+")";
-                break;
-        }
-        return length;
-    }
-    /**
-     * returns the function for replacing a null value
-     *
-     * @param {String} pValue req
-     * @param {String} pReplaceWith
-     *
-     * @return {string}
-     */
-    this.isNull = function(pValue, pReplaceWith)
-    {
-        var pAlias = vars.getString("$sys.dbalias");
-        
-        if(pReplaceWith == undefined) 
-            pReplaceWith = 0;
-        
-        var pDatabaseType = db.getDatabaseType(pAlias);
-        
-        switch(Number(pDatabaseType))
-        {
-            case db.DBTYPE_SQLSERVER2000:
-                str = "isnull("+ pValue +", " + pReplaceWith+ ")";
-                break;
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_OCI:
-            case db.DBTYPE_ORACLE10_THIN :
-                str = "NVL("+ pValue +", "+ pReplaceWith+ ")";
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-            case db.DBTYPE_DERBY10:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-            default:
-                str = "COALESCE("+ pValue +", "+ pReplaceWith+ ")";
-                break;
-        }
-        return str;
-    }
-    /**
-    * returns the concat symbol depending on database type
-    *
-    * @param {String} pAlias opt database alias
-    *
-    * @return {String} Concat Symbol
-    */
-    this.getConcatSymbol = function(pAlias)
-    {
-        if(pAlias == undefined || pAlias == "")  
-            pAlias =  vars.getString("$sys.dbalias");
-        
-        var dbtype = db.getDatabaseType(pAlias);
-        var concatSymbol = " ";
-
-        switch(Number(dbtype))
-        {
-            case db.DBTYPE_SQLSERVER2000:
-                concatSymbol = " + ";
-                break;
-            case db.DBTYPE_MARIADB10:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-            case db.DBTYPE_POSTGRESQL8:
-            case db.DBTYPE_DERBY10:
-            default:
-                concatSymbol = " || ";
-                break;
-        }
-
-        return concatSymbol;
-    }
-    /**
-     * Builds a SQL IN condition, while accounting for the 1000 elements maximum
-     * Single conditions are concatenated with OR, which can be devastating for performance!
-     *
-     * @param {String} pFieldname req name of the field with table alias
-     *                                z.B ORGREL.RELATIONID
-     * @param {String[]|String[][]} pData req Data as ID Array
-     * @param {String} pQuoteSymbol opt symbol for quoting values,
-     *                                  Strings i.e.: ' default is no symbol
-     *
-     * @return {String} SQL condition: where VALS in (1,2,3)
-     */
-    this.getSqlInStatement = function(pFieldname, pData, pQuoteSymbol)
-    {
-        if (pData.length == 0)
-            return " 1 = 2 ";
-
-        var res = "";
-        var qs = pQuoteSymbol || "";
-
-        var MAX_COUNT = 1000;
-        //pData.length -1 um für den Fall, dass MAX_COUNT == pData.length ist trotzdem nur einen Aufruf
-        //zu machen
-        var count = ((pData.length -1) / MAX_COUNT) >> 0;//aus kommazahl eine ganzzahl machen
-        //<= verwenden, da bei einer Länge von "126" der Vorgang einmal ausgeführt werden soll
-        for (var i = 0; i <= count; i++)
-        {
-            if (i > 0)
-                res += "or ";
-
-            res += pFieldname + " in (" + qs + pData.slice(i * MAX_COUNT, i * MAX_COUNT + MAX_COUNT)
-            .join(qs + ", " + qs) + qs + ") ";
-        }
-
-        //wenn mehrere Zeilen mit "or" verknüpft wurden nochmal klammern
-        if (count > 0)
-            res = "(" + res + ")";
-
-        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
-    *
-    * @param {Object|String} pSql req sql statement that shall be executed
-    *                                 String: SQL-query in a simple text form
-    *                                 Object: prepared-sql-query: [sqlStr, [[value1, type1], [valueN, typeN]]]
-    * @param {Number} pBlockSize req Amount of records that shall be read per block. (you need to specify an ORDER BY in your SQL-query)
-    *                                "0" <=> all records
-    * @param {Object (function)} pCallback req a callback-function that is called for every block and has the following params:
-    *                                            myCallback(myDataBlockAs2Darray, myLoopCountThatStartsWith1)
-    *                                          If "false" is returned sqlPageData will abort the paging process and return false
-    * @param {String} pDbAlias opt Database-Aliasname, where the SQL-Statement shall be executed; default is the current dbalias
-    * @param {Number} pTimeout opt Timeout in milliseconds; When it's reached the SQL-Statement will abort; default is in PREFERENCES configured
-    * @param {Number} pStartOffset opt Position where to begin with  the data-reading-process; default is 0
-    *
-    *
-    * @return {bool} returns whether the function read all available data or not:
-    *                        false if the callback-function returned false, otherwise true
-    *
-    * @example
-    * var varValues = [];//you've got access to variables declared with 'var'
-    * let letValues = [];//you've got access to variables declared with 'let'
-    * var count = 0;//you cannot overwrite a variable of 'sqlPageData' by accident
-    *
-    * var sql = "select ORGNAME from ORG";
-    * var blockSize = 5 * 1000;
-    *
-    * var allRows = +db.cell("select count(*) from ORG");
-    *
-    * sqlPageData(sql, blockSize, function (pData, pRunNo){
-    *     var j = pData.length;//pData is the current block with data
-    *     logging.log(pRunNo.toString() + "#" + j);//pRunNo is the amount how often the func. has been already called
-    *     //you can calculate the progress easily by: progress = (blockSize* (pRunNo-1) + pData.length) / (allRows - startOffset)
-    *     //example in per cent:
-    *     var startOffset = 0;//we did not pass any startOffset to sqlPageData - this is equivalent to zero
-    *     var progress = (blockSize* (pRunNo-1) + pData.length) / (allRows - startOffset);
-    *     logging.log("progess: " + eMath.roundDec(progress * 100, 2, eMath.ROUND_CEILING) + "%");
-    *
-    *     for (var i = 0; i < j; i++)
-    *     {
-    *         varValues.push(pData[i][0]);
-    *         letValues.push(pData[i][0]);
-    *     }
-    *
-    *     count += pRunNo * 100;
-    *     logging.log("count:" + count);//you cannot overwrite a variable of 'sqlPageData' by accident
-    * });
-    *
-    * logging.show(letValues);//contains orgnames
-    * logging.show(varValues);//contains orgnames
-    */
-   this.sqlPageData = function(pSql, pBlockSize, pCallback, pDbAlias, pTimeout, pStartOffset)
-   {
-       if (pDbAlias == undefined)
-           pDbAlias = db.getCurrentAlias();
-
-       if (pStartOffset == undefined)
-           pStartOffset = 0;
-
-       let count = 0;
-       while (pStartOffset > -1)
-       {
-           let data;
-           if (pTimeout == undefined)
-               data = db.tablePage(pSql, pDbAlias, pStartOffset, pBlockSize);
-           else
-               data = db.tablePage(pSql, pDbAlias, pStartOffset, pBlockSize, pTimeout);
-
-           pStartOffset += pBlockSize;
-
-           //this happens when all-records % pBlockSize == 0
-           //we do not want to call the callback-fn
-           if (data.length == 0)
-               return true;
-           else if (data.length < pBlockSize || pBlockSize == 0)//blocksize 0 is everything
-               pStartOffset = -1;//call callback the last time
-
-           if (pCallback.call(this, data, ++count) === false)
-               return false;//callback can return false to manually stop the paging-process
-
-       }
-       return true;
-   }
+import("system.translate");
+import("system.vars");
+import("system.db");
+import("system.datetime");
+import("system.tools");
+import("system.SQLTYPES");
+import("Util_lib")
+
+/**
+ * Object for easier handling of conditions;
+ * 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;
+ * @example //TODO: add missing example
+ */
+function SqlCondition(){
+    this._sqlStorage = "";
+}
+/**
+ * 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){
+    if (!cond)
+        return this;
+    if (this._sqlStorage)
+        this._sqlStorage += " and ";
+    this._sqlStorage += cond;
+    return this;
+}
+/**
+ * append with SQL-or; Also paranthesize the existing conditions
+ * @param {String} cond the condition string which shall be appended
+ * @return {Object} current SqlCondition-object
+ */
+SqlCondition.prototype.or = function(cond){
+    if (!cond)
+        return this;
+    if (this._sqlStorage)
+        this._sqlStorage = "(" + this._sqlStorage + ") or (" + cond + ")";
+    else
+        this._sqlStorage = cond;
+    return this;
+}
+/**
+ * ready to use string; does not contain a where keyword at the beginning
+ * @param {String} alternativeCond condition that is returned when nothing has been appended 
+ * @return {String} concatenated SQL-condition; empty string if nothing has been appended or - if passed - the alternativeCond
+ */
+SqlCondition.prototype.toString = function(alternativeCond){
+    if (!this._sqlStorage && alternativeCond)
+        return alternativeCond
+    else
+        return this._sqlStorage;
+}
+/**
+ * ready to use string; does contain a where keyword at the beginning
+ * @param {String} alternativeCond condition that is returned when nothing has been appended 
+ * @return {String} concatenated SQL-condition; empty string if nothing has been appended or - if passed - the alternativeCond
+ */
+SqlCondition.prototype.toWhereString = function(alternativeCond){
+    var cond = this.toString(alternativeCond);
+    if (cond)
+        return " where " + cond;
+    else 
+        return cond;
+}
+
+function SqlMaskingUtils(){
+    //TODO: use callbacks for different handling?
+    /**
+    * masks the function cast of standard sql
+    *
+    * @param {String} field name of the database field that shall be castet
+    * @param {String} [targetDatatype] a SQLTYPES-value of the following: SQLTYPES.CHAR, SQLTYPES.VARCHAR, SQLTYPES.INTEGER, 
+    *                                   SQLTYPES.DECIMAL, SQLTYPES.DATE
+    * @param {int|int[]} targetLength specifies the length of the target data type;
+    *                                   <br/>- char/varchar: length
+    *                                   <br/>- decimal: [length, decimals]
+    * @param {String} [alias=the current alias] the alias where the statement shall be executed (this is needed to determine the database-type)
+    *
+    * @return {String} sql part to be included in sql-statements
+    */
+    this.cast = function (field, targetDatatype, targetLength, alias){
+        /* Some informations if you want to add supported databaseTypes or dataTypes:
+         * You should consider using the _mapDefaults function-expression (details in the functions doc)
+         * However you shouldn't use the function in a "default"-Block of a switch-case because of the following behaviour:
+         * If a datatype is not supported you just have to NOT specify "sqlDataType" (leave it "undefined") -> an error is then raised
+         * Therefore you should explicitly define which Data-type is supported and which is not
+        */
+        var dbType, functionName, sqlPart, sqlDataType, _mapDefaults;
+        if (alias == undefined) 
+            alias = vars.getString("$sys.dbalias");
+        dbType = db.getDatabaseType(alias);
+        functionName = "cast";//overwrite this in the "switch (dbType)" if needed with your DBMS
+
+        /**
+         * handles default-scenarios for mapping input-targetDatatype to a string for a sql-statement
+         * e.g. SQLTYPES.INTEGER --> int
+         * @param {Number} dataType input as a value of "SQLTYPES." that will be mapped to a string
+         * @return {String} the mapped dataType for using in a sql-statement
+         */
+        _mapDefaults = function (dataType){
+            var res;
+            switch(dataType)
+            {
+                case SQLTYPES.CHAR:
+                    res = "char";
+                    break;
+                case SQLTYPES.VARCHAR:
+                    res = "char";
+                    break;
+                case SQLTYPES.INTEGER:
+                    res = "int";
+                    break;
+                case SQLTYPES.DECIMAL:
+                    res = "decimal";
+                    break;
+                case SQLTYPES.DATE:
+                    res = "date";
+                    break;
+            }
+            return res;
+        }
+        switch (dbType) {
+            case db.DBTYPE_DERBY10:
+                switch(targetDatatype) {
+                    case SQLTYPES.VARCHAR:
+                        // Because of a Derby bug, you can't cast INTEGER into VARCHAR
+                        // Therefor first cast to char then to varchar
+                        // https://issues.apache.org/jira/browse/DERBY-2072
+                        field = "rtrim(" + cast(field, SQLTYPES.CHAR, targetLength, alias) + ")";
+                        sqlDataType = "varchar";
+                        break;
+                    case SQLTYPES.CHAR:
+                        //TODO: throw error if(targetLength > 254)? https://db.apache.org/derby/docs/10.14/ref/rrefsqlj13733.html
+                        sqlDataType = "char";
+                        break;
+                    case SQLTYPES.DECIMAL:
+                    case SQLTYPES.INTEGER:
+                    case SQLTYPES.DATE:
+                        sqlDataType = _mapDefaults(dataType);
+                        break;
+                }
+                break;
+            case db.DBTYPE_MARIADB10:
+            case db.DBTYPE_MYSQL4:
+                switch(targetDatatype) {
+                    case SQLTYPES.VARCHAR:
+                    case SQLTYPES.CHAR:
+                    case SQLTYPES.INTEGER:
+                    case SQLTYPES.DECIMAL:
+                    case SQLTYPES.DATE:
+                        sqlDataType = _mapDefaults(targetDatatype);
+                        break;
+                }
+                break;
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_THIN:
+            case db.DBTYPE_ORACLE10_OCI:
+                switch(pDatatype)
+                {
+                    case SQLTYPES.VARCHAR:
+                        datatype = "varchar2";
+                        break;
+                    case SQLTYPES.INTEGER:
+                        datatype = "number";
+                        targetLength = "10"
+                        break;
+                    case SQLTYPES.CHAR:
+                    case SQLTYPES.DECIMAL:
+                    case SQLTYPES.DATE:
+                        sqlDataType = _mapDefaults(targetDatatype);
+                        break;
+                }
+                break;
+            case db.DBTYPE_POSTGRESQL8:
+                switch(pDatatype)
+                {
+                    case SQLTYPES.DATE:
+                    case SQLTYPES.DECIMAL:
+                    case SQLTYPES.INTEGER:
+                    case SQLTYPES.CHAR:
+                    case SQLTYPES.VARCHAR:
+                        sqlDataType = _mapDefaults(targetDatatype);
+                        break;
+                }
+                break;
+            case db.DBTYPE_SQLSERVER2000:
+            case SQLTYPES.DATE:
+            case SQLTYPES.DECIMAL:
+            case SQLTYPES.INTEGER:
+            case SQLTYPES.CHAR:
+            case SQLTYPES.VARCHAR:
+                sqlDataType = _mapDefaults(targetDatatype);
+                break;
+            case db.DBTYPE_FIREBIRD250:
+                //TODO: firebird support?
+                break;
+        }
+        
+        if (sqlDataType == undefined) {
+            throw new Error("sqlDataType");//TODO: add usefull message
+        }
+        
+        if(targetLength == undefined)
+            targetLength = "";
+        else if(targetLength != "")
+        {
+            if(typeof(targetLength == "object") && (targetLength instanceof Array))
+                targetLength = "(" + targetLength.join(", ") + ")";
+            else
+                targetLength = "(" + targetLength + ")";
+        }
+        
+        sqlPart = functionName + "(" + field + " as " + sqlDataType + targetLength + ")";
+        return sqlPart;
+    }
+}
+
+/**
+ *Class containing utilities for SQL
+ *@deprecated use SqlMaskingUtils
+ *@class
+ */
+function LegacySqlUtils()
+{
+    var that = this;
+    /**
+    * masks the cast function for lob datatypes(clob, blob)
+    *
+    * @param {String} pField req the data field
+    * @param {Integer|Interger[]} pLength req the length of the data
+    *                                         decimal: [length, decimals]
+    * @param {String} pAlias req the database alias
+    *
+    * @return {String} (Teil einer SQL-Anweisung)
+    */
+    this.castLob = function(pField, pLength, pAlias)
+    {
+        if(pAlias == undefined) 
+            pAlias = vars.getString("$sys.dbalias");
+        
+        var dbtype = db.getDatabaseType(pAlias);
+
+        switch(Number(dbtype))
+        {
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_THIN:
+            case db.DBTYPE_ORACLE10_OCI:
+                return "DBMS_LOB.SUBSTR(" + pField + ", " + pLength + ", 1)";
+                break;
+            default:
+                return cast(pField, "varchar", pLength, pAlias);
+                break;
+        }
+    }
+    /**
+    * masks the function substring.
+    *
+    * @param {String }pExpression req
+    * @param {Integer} pStart req index of the beginning
+    * @param {String} pAlias req database alias
+    * @param {Integer} pLength req
+    *
+    * @return {String}
+    */
+    this.substring = function(pExpression, pStart, pLength, pAlias)
+    {
+        if(pLength == undefined) 
+            pLength = 100;
+        if(pAlias == undefined) 
+            pAlias = vars.getString("$sys.dbalias");
+        
+        var dbtype = db.getDatabaseType(pAlias);
+        var string = "";
+
+        switch(Number(dbtype))
+        {
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_THIN:
+            case db.DBTYPE_ORACLE10_OCI:
+                string = "substr";
+                break;
+            case db.DBTYPE_DERBY10:
+                string = "substr";
+                break;
+            case db.DBTYPE_POSTGRESQL8:
+                string = "substr";
+                break;
+            case db.DBTYPE_SQLSERVER2000:
+                string = "substring";
+                break;
+            case db.DBTYPE_MYSQL4:
+            case db.DBTYPE_MARIADB10:
+                string = "substring";
+                break;
+        }
+
+        return string + "(" + pExpression + ", " + pStart + ", " + pLength + ")";
+    }
+    
+    /**
+    * masks the function concat.
+    *
+    * @param {Array} pFields req fields that should be concatenated
+    * @param {String} pSeparator opt field separator
+    * @param {String} pAlias opt database alias
+    *
+    * @return {String} part of SQL-querey
+    */
+    this.concat = function(pFields, pSeparator, pAlias)
+    {
+        var i;
+        if(pAlias == undefined || pAlias == "")  
+            pAlias =  vars.getString("$sys.dbalias");
+        
+        var dbtype = db.getDatabaseType(pAlias);
+        var concat_string = " || ";
+        var retstr = "";
+        var blank = "' '";
+        
+        //it must be checked for empty string and null
+        var isNotEmpty =  " != '' ";
+        var isNotNull = " is not null ";
+        if(pSeparator == undefined) 
+            pSeparator = " ";
+        
+        switch(Number(dbtype))
+        {
+            case db.DBTYPE_MYSQL4:
+            case db.DBTYPE_MARIADB10:
+                retstr = " concat_ws( '" + pSeparator + "'";
+                for(i=0; i<pFields.length; i++)
+                {
+                    retstr += ", " + pFields[i];
+                }
+                return retstr + ") ";
+                break;
+
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_THIN:
+            case db.DBTYPE_ORACLE10_OCI:
+                blank = "trim(' ')";
+                isNotEmpty = " is not null "; //needed for oracle
+                break;
+
+            case db.DBTYPE_SQLSERVER2000:
+                concat_string = " + ";
+                break;
+        }
+        pSeparator = concat_string + "'" + pSeparator + "'";
+        for(i = 0; i < pFields.length; i++)
+        {
+            if(retstr != "")  
+                retstr += concat_string;
+            if ( i < pFields.length - 1 ) //Check if another value follows, if not separator is not needed
+                retstr += " case when " + pFields[i] + isNotEmpty + " then case when " + this.trimSql(pFields[i+1], pAlias) + isNotEmpty + " and "
+                + this.trimSql(pFields[i+1], pAlias) + isNotNull + " then " + pFields[i] + pSeparator + " else " + pFields[i] + " end" + " else " + blank + " end ";
+            else
+                retstr += " case when " + pFields[i] + isNotEmpty + " then " + pFields[i] + " else " + blank + " end ";
+        }
+        return retstr;
+    }
+    /**
+    * builds a condition out of multiple conditions
+    *
+    * @param {Array} pArray req Array containing the conditions
+    * @param {String} pOperator req Operator that concatenates the conditions (AND/OR)
+    *
+    * @return {String} concatenated Condition
+    */
+    this.concatConditions = function(pArray, pOperator)
+    {
+        var resultCondition = "";
+
+        for(var i = 0; i < pArray.length; i++)
+        {
+            if(pArray[i] != null && pArray[i] != '')
+            {
+                if(resultCondition.length > 0)
+                    resultCondition += (" " + pOperator + " ");
+
+                resultCondition += pArray[i];
+            }
+        }
+
+        return resultCondition;
+    }
+    /**
+    * Checks if a new entry already exists
+    *
+    * @param {String} pTable req Databasetable(z.B. "comm")
+    * @param {Array} pColumns req colums, like sqlInsert
+    * @param {Array} pTypes req die datatypes, like sqlInsert
+    * @param {Array} pValues req values, like sqlInsert
+    * @param {Array} pExcludeFields opt columns, that should not be checked
+    * @param {String} pAlias opt Database alias
+    *
+    * @return {Integer}
+    */
+    this.isDuplicat = function(pTable, pColumns, pTypes, pValues, pExcludeFields, pAlias)
+    {
+        var col = new Array();
+        var typ = new Array();
+        var val = new Array();
+        var excludefields = ["DATE_NEW" ,"DATE_EDIT" ,"USER_NEW" ,"USER_EDIT", "KEYVALUE",  "KEYSORT", pTable.toUpperCase() + "ID"];
+        
+        if(pExcludeFields != undefined) 
+            excludefields = excludefields.concat(pExcludeFields);
+        if(pAlias == undefined)  
+            pAlias = vars.getString("$sys.dbalias");
+
+        for(var i = 0; i < pColumns.length; i++)
+        {
+            if(!hasElement(excludefields, pColumns[i], true) && pValues[i] != "" && pTypes[i] != SQLTYPES.LONGVARCHAR && pTypes[i] != SQLTYPES.CLOB)
+            {
+                col.push(pColumns[i]);
+                typ.push(pTypes[i]);
+                val.push(pValues[i]);
+            }
+        }
+        var count = db.getRowCount(pTable, col, typ, val, pAlias);
+        return count;
+    }
+    /**
+    *  returns the trim function depending on the database
+    *
+    * @param {String} pField field the should be trimmed
+    * @param {String} pAlias opt database alias
+    *
+    * @return {String}
+    */
+    this.trimSql = function(pField, pAlias)
+    {
+        if(pAlias == undefined || pAlias == "")  
+            pAlias =  vars.getString("$sys.dbalias");
+        
+        var dbtype = db.getDatabaseType(pAlias);
+        var string;
+
+        switch(Number(dbtype))
+        {
+            case db.DBTYPE_SQLSERVER2000:
+                string = "ltrim(rtrim(" + pField + "))";
+                break;
+            default:
+                string = "trim(" + pField + ")"
+                break;
+        }
+        return string;
+    }
+    /**
+    * returns the day of a date
+    *
+    * @param {Datetime} pDate req the date
+    * @param {String} pAlias req database alias
+    *
+    * @return {String}
+    */
+    this.dayFromDate = function(pDate, pAlias)
+    {
+        var usedAlias = pAlias;
+        
+        if(pAlias == undefined) 
+            usedAlias = vars.getString("$sys.dbalias");
+        
+        var dbAlias = db.getDatabaseType(usedAlias);
+        var string = "";
+
+        switch(Number(dbAlias))
+        {
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_THIN:
+            case db.DBTYPE_ORACLE10_OCI:
+                string = "to_char(" + pDate + ",'dd')";
+                break;
+            case db.DBTYPE_DERBY10:
+            case db.DBTYPE_SQLSERVER2000:
+            case db.DBTYPE_MYSQL4:
+            case db.DBTYPE_MARIADB10:
+                string = "DAY(" + pDate + ")";
+                break;
+            case db.DBTYPE_POSTGRESQL8:
+                string = "EXTRACT (DAY from " + pDate + ")";
+                break;
+        }
+        return string;
+    }
+    /**
+    * returns the month of a date
+    *
+    * @param {Datetime} pDate req the date
+    * @param {String} pAlias req database alias
+    *
+    * @return {String}
+    */
+    this.monthFromDate = function(pDate, pAlias)
+    {
+        var usedAlias = pAlias;
+        if(pAlias == undefined) 
+            usedAlias = vars.getString("$sys.dbalias");
+        
+        var dbAlias = db.getDatabaseType(usedAlias);
+        var string = "";
+
+        switch(Number(dbAlias))
+        {
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_THIN:
+            case db.DBTYPE_ORACLE10_OCI:
+                string = "to_char(" + pDate + ",'MM')";
+                break;
+            case db.DBTYPE_DERBY10:
+            case db.DBTYPE_SQLSERVER2000:
+            case db.DBTYPE_MYSQL4:
+            case db.DBTYPE_MARIADB10:
+                string = "MONTH(" + pDate + ")";
+                break;
+            case db.DBTYPE_POSTGRESQL8:
+                string = "EXTRACT (MONTH FROM " + pDate + ")";
+                break;
+        }
+        return string;
+    }
+    /**
+    * returns the year of a date
+    *
+    * @param {Datetime} pDate req the date
+    * @param {String} pAlias req database alias
+    *
+    * @return {String}
+    */
+    this.yearFromDate = function(pDate, pAlias)
+    {
+        var usedAlias = pAlias;
+        if(pAlias == undefined) 
+            usedAlias = vars.getString("$sys.dbalias");
+        
+        var dbAlias = db.getDatabaseType(usedAlias);
+        var string = "";
+
+        switch(Number(dbAlias))
+        {
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_THIN:
+            case db.DBTYPE_ORACLE10_OCI:
+                string = "to_char(" + pDate + ",'yyyy')";
+                break;
+            case db.DBTYPE_DERBY10:
+            case db.DBTYPE_SQLSERVER2000:
+            case db.DBTYPE_MYSQL4:
+            case db.DBTYPE_MARIADB10:
+                string = "YEAR(" + pDate + ")";
+                break;
+            case db.DBTYPE_POSTGRESQL8:
+                string = "EXTRACT (YEAR FROM " + pDate + ")";
+                break;
+        }
+        return string;
+    }
+    /**
+    * returns the function for current date depending on database
+    *
+    * @return {String} expression
+    */
+    this.currentDate = function()
+    {
+        var dbtype = db.getDatabaseType(vars.getString("$sys.dbalias"));
+        var expression = "";
+
+        switch (Number(dbtype))
+        {
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_THIN:
+            case db.DBTYPE_ORACLE10_OCI:
+            case db.DBTYPE_DERBY10:
+                expression = "CURRENT_DATE";
+                break;
+            case db.DBTYPE_SQLSERVER2000:
+                expression = "GETDATE()";
+                break;
+            case db.DBTYPE_MYSQL4:
+            case db.DBTYPE_MARIADB10:
+                expression = "NOW()";
+                break;
+        }
+        return expression;
+    }
+    /**
+    * returns the current search string incl placeholders
+    *
+    * @param {String} pfield req the search field
+    * @param {String} pfind req the search string
+    * @param {String} pIgnoreCase opt (true/false)
+    * @param {String} pPlaceHolder opt (Platzhalter config)
+    *
+    * @return {String}
+    */
+    this.getPlacerholderCondition = function( pfield, pfind, pIgnoreCase, pPlaceHolder )
+    {
+        var user = tools.getCurrentUser();
+        var IgCa;
+        var PlHo;
+
+        //wenn optoinal IgnoreCase und PlaceHolder vorhanden, dann diese verwenden
+        if(pIgnoreCase != undefined)
+            IgCa = pIgnoreCase;
+        else
+            IgCa = user[tools.PARAMS][tools.SELECTION_IGNORECASE];
+
+        if(pPlaceHolder != undefined)
+            PlHo = pPlaceHolder;
+        else
+            PlHo = user[tools.PARAMS][tools.SELECTION_PLACEHOLDER];
+
+        if ( pfind )
+        {
+            pfind = pfind.replace( new RegExp("\\'", "g"), "''");
+            pfind = pfind.replace( new RegExp("\\*", "g"), "%");
+            var ic = (IgCa == "true" ? "UPPER" : "");
+            var cond = "";
+            switch( PlHo )
+            {
+                case "1":
+                    cond = ic + "(" + pfield + ") like " + ic + "('" + pfind + "%')";
+                    break;
+                case "2":
+                    cond = ic + "(" + pfield + ") like " + ic + "('%" + pfind + "')";
+                    break;
+                case "3":
+                    cond = ic + "(" + pfield + ") like " + ic + "('%" + pfind + "%')";
+                    break;
+                case "4":
+                    cond = ic + "(" + pfield + ") like " + ic + "('" + pfind + "')";
+                    break;
+                default:
+                    cond = ic + "(" + pfield + ") = " + ic + "('" + pfind + "')";
+                    break;
+            }
+        }
+        return cond;
+    }
+    /**
+    * returns SQLSystax for a date.
+    *
+    * @param {String} pColumn req Column name
+    * @param {String} pAlias opt Database alias
+    * @param {Boolean} pWithTime opt if true, then add time hh:mm:ss
+    * @param {String} pFormat opt type of the format, e.g. yyyy-MM-dd; possible placeholers are: -dd -MM -yyyy
+    *
+    *@return {String} sqlstr, fully functional select for sql for different types of databases
+    */
+    this.getSqlFormattedDate = function(pColumn, pAlias, pWithTime, pFormat)
+    {
+        if(pAlias == undefined)  
+            pAlias = vars.getString("$sys.dbalias");
+        
+        var pDatabaseType = db.getDatabaseType(pAlias);
+        
+        if (pFormat == undefined)
+            pFormat = translate.text("yyyy-MM-dd");
+        
+        var str = "";
+        
+        switch(Number(pDatabaseType))
+        {
+            case db.DBTYPE_SQLSERVER2000:
+                day = "right('0' + cast(day(" + pColumn + ") as varchar(2)) , 2)";
+                month = "right('0' + cast(month(" + pColumn + ") as varchar(2)) , 2)";
+                year = "cast(year(" + pColumn + ") as char(4))";
+                time = pWithTime == true? that.concat(["' '","cast(cast(" + pColumn + " as time) as char(8))"], "", pAlias) : "";
+                break;
+            case db.DBTYPE_POSTGRESQL8:
+                day = "extract(day from " + pColumn + ")";
+                month = "extract(month from " + pColumn + ")";
+                year = "extract(year from " + pColumn + ")";
+                time = pWithTime == true? that.concat(["' '","extract(time from" + pColumn + ")"], "", pAlias) : "";
+                break;
+            case db.DBTYPE_DERBY10:
+            case db.DBTYPE_MYSQL4:
+            case db.DBTYPE_MARIADB10:
+                // concat will try to have a leading blank space if the number is => 10. This is why we had to use substr.
+                day = that.substring(that.concat(["case when day(" + pColumn + ") <= 9 then '00' else '0' end "
+                    , " trim(cast(day(" + pColumn + ") as char(2)))"], "", pAlias), 2, 2, pAlias);
+                month = that.substring(that.concat(["case when month(" + pColumn + ") <= 9 then '00' else '0' end "
+                    , "trim(cast(month(" + pColumn + ") as char(2)))"], "", pAlias), 2, 2, pAlias);
+                year = "trim(cast(year(" + pColumn + ") as char(4)))";
+                time = pWithTime == true? that.concat(["cast(' ' as char(1))", "trim(cast(time(" + pColumn + ") as char(8)))"], "", pAlias) : "";
+                break;
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_OCI:
+            case db.DBTYPE_ORACLE10_THIN:
+
+                day = "to_char(" + pColumn + ", 'dd') ";
+                month = "to_char(" + pColumn + ", 'MM') ";
+                year = "to_char(" + pColumn + ", 'yyyy') ";
+                time = pWithTime == true ? " to_char(" + pColumn + ", ' hh24:mi:ss')" : "";
+                break;
+            default:
+                str = "cast(" + pColumn + " as varchar (10))";
+                return str;
+                break;
+        }
+
+        var re = /(dd)|(MM)|(yyyy)/g        // Regex to check the date
+        var matchResult;
+        var endOfLastMatch = 0;
+        var res = [];
+        
+        while ((matchResult = re.exec(pFormat)) !== null) 
+        {
+            if( endOfLastMatch != matchResult.index)
+            {
+                res.push("'" + db.quote(pFormat.substring(endOfLastMatch, matchResult.index), pAlias) + "'");     // making sure we get the correct amount of quotations
+            }
+            switch(matchResult[0])
+            {
+                case "dd":
+                    res.push(day);
+                    break;
+                case "MM":
+                    res.push(month);
+                    break;
+                case "yyyy":
+                    res.push(year);
+                    break;
+            }
+            endOfLastMatch = re.lastIndex;
+        }
+        // making sure we get the correct amount of quotations
+        // allows us to add custom strings behind the format which will be shown in the output
+        // e.g. "yyyy-MM-dd 00:00", "date: MM/dd/yyyy"
+        res.push("'" + db.quote(pFormat.slice(endOfLastMatch), pAlias) + "'");
+        
+        if(time != "")
+            res.push(time);
+        
+        str = concat(res, "", pAlias);
+        
+        return str;
+    }
+    /**
+    * returns a SQL operator depending on an integer value, i.e. $local.operator
+    *
+    * @param {int} pVal
+    *
+    * @return {string}
+    */
+    this.getSQLOperator = function(pVal)
+    {
+        var retval = "";
+        switch(Number(pVal))
+        {
+            case 1:
+                retval = "=";
+                break; //equals
+            case 2:
+                retval = "<>";
+                break; //not equal
+            case 3:
+                retval = ">";
+                break; //greater
+            case 4:
+                retval = "<";
+                break; //lesser
+            case 5:
+                retval = "<=";
+                break; //lesser or equal
+            case 6:
+                retval = ">=";
+                break; //greater or equal
+            case 7:
+                retval = "like";
+                break; //contains
+            case 8:
+                retval = "not like";
+                break; //contains not
+            case 9:
+                retval = "";
+                break;
+            case 10:
+                retval = "";
+                break;
+            case 11:
+                retval = "is not null";
+                break;
+            case 12:
+                retval = "is null";
+                break;
+        }
+        return retval;
+    }
+    /**
+    *  returns the function which determines the length of binary data, depending on db type
+    *
+    * @param {String} pField name of the checked field
+    *
+    * @return {String}
+    */
+    this.binDataLength = function(pField)
+    {
+        var dbtype = db.getDatabaseType(vars.getString("$sys.dbalias"));
+        var length;
+
+        switch(Number(dbtype))
+        {
+            case db.DBTYPE_MARIADB10:
+            case db.DBTYPE_MYSQL4:
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_THIN:
+            case db.DBTYPE_ORACLE10_OCI:
+            case db.DBTYPE_POSTGRESQL8:
+            case db.DBTYPE_DERBY10:
+                length = "LENGTH("+pField+")";
+                break;
+            case db.DBTYPE_SQLSERVER2000:
+                length = "DATALENGTH("+pField+")";
+                break;
+        }
+        return length;
+    }
+    /**
+     * returns the function for replacing a null value
+     *
+     * @param {String} pValue req
+     * @param {String} pReplaceWith
+     *
+     * @return {string}
+     */
+    this.isNull = function(pValue, pReplaceWith)
+    {
+        var pAlias = vars.getString("$sys.dbalias");
+        
+        if(pReplaceWith == undefined) 
+            pReplaceWith = 0;
+        
+        var pDatabaseType = db.getDatabaseType(pAlias);
+        
+        switch(Number(pDatabaseType))
+        {
+            case db.DBTYPE_SQLSERVER2000:
+                str = "isnull("+ pValue +", " + pReplaceWith+ ")";
+                break;
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_OCI:
+            case db.DBTYPE_ORACLE10_THIN :
+                str = "NVL("+ pValue +", "+ pReplaceWith+ ")";
+                break;
+            case db.DBTYPE_POSTGRESQL8:
+            case db.DBTYPE_DERBY10:
+            case db.DBTYPE_MYSQL4:
+            case db.DBTYPE_MARIADB10:
+            default:
+                str = "COALESCE("+ pValue +", "+ pReplaceWith+ ")";
+                break;
+        }
+        return str;
+    }
+    /**
+    * returns the concat symbol depending on database type
+    *
+    * @param {String} pAlias opt database alias
+    *
+    * @return {String} Concat Symbol
+    */
+    this.getConcatSymbol = function(pAlias)
+    {
+        if(pAlias == undefined || pAlias == "")  
+            pAlias =  vars.getString("$sys.dbalias");
+        
+        var dbtype = db.getDatabaseType(pAlias);
+        var concatSymbol = " ";
+
+        switch(Number(dbtype))
+        {
+            case db.DBTYPE_SQLSERVER2000:
+                concatSymbol = " + ";
+                break;
+            case db.DBTYPE_MARIADB10:
+            case db.DBTYPE_MYSQL4:
+            case db.DBTYPE_ORACLE10_CLUSTER:
+            case db.DBTYPE_ORACLE10_THIN:
+            case db.DBTYPE_ORACLE10_OCI:
+            case db.DBTYPE_POSTGRESQL8:
+            case db.DBTYPE_DERBY10:
+            default:
+                concatSymbol = " || ";
+                break;
+        }
+
+        return concatSymbol;
+    }
+    /**
+     * Builds a SQL IN condition, while accounting for the 1000 elements maximum
+     * Single conditions are concatenated with OR, which can be devastating for performance!
+     *
+     * @param {String} pFieldname req name of the field with table alias
+     *                                z.B ORGREL.RELATIONID
+     * @param {String[]|String[][]} pData req Data as ID Array
+     * @param {String} pQuoteSymbol opt symbol for quoting values,
+     *                                  Strings i.e.: ' default is no symbol
+     *
+     * @return {String} SQL condition: where VALS in (1,2,3)
+     */
+    this.getSqlInStatement = function(pFieldname, pData, pQuoteSymbol)
+    {
+        if (pData.length == 0)
+            return " 1 = 2 ";
+
+        var res = "";
+        var qs = pQuoteSymbol || "";
+
+        var MAX_COUNT = 1000;
+        //pData.length -1 um für den Fall, dass MAX_COUNT == pData.length ist trotzdem nur einen Aufruf
+        //zu machen
+        var count = ((pData.length -1) / MAX_COUNT) >> 0;//aus kommazahl eine ganzzahl machen
+        //<= verwenden, da bei einer Länge von "126" der Vorgang einmal ausgeführt werden soll
+        for (var i = 0; i <= count; i++)
+        {
+            if (i > 0)
+                res += "or ";
+
+            res += pFieldname + " in (" + qs + pData.slice(i * MAX_COUNT, i * MAX_COUNT + MAX_COUNT)
+            .join(qs + ", " + qs) + qs + ") ";
+        }
+
+        //wenn mehrere Zeilen mit "or" verknüpft wurden nochmal klammern
+        if (count > 0)
+            res = "(" + res + ")";
+
+        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
+    *
+    * @param {Object|String} pSql req sql statement that shall be executed
+    *                                 String: SQL-query in a simple text form
+    *                                 Object: prepared-sql-query: [sqlStr, [[value1, type1], [valueN, typeN]]]
+    * @param {Number} pBlockSize req Amount of records that shall be read per block. (you need to specify an ORDER BY in your SQL-query)
+    *                                "0" <=> all records
+    * @param {Object (function)} pCallback req a callback-function that is called for every block and has the following params:
+    *                                            myCallback(myDataBlockAs2Darray, myLoopCountThatStartsWith1)
+    *                                          If "false" is returned sqlPageData will abort the paging process and return false
+    * @param {String} pDbAlias opt Database-Aliasname, where the SQL-Statement shall be executed; default is the current dbalias
+    * @param {Number} pTimeout opt Timeout in milliseconds; When it's reached the SQL-Statement will abort; default is in PREFERENCES configured
+    * @param {Number} pStartOffset opt Position where to begin with  the data-reading-process; default is 0
+    *
+    *
+    * @return {bool} returns whether the function read all available data or not:
+    *                        false if the callback-function returned false, otherwise true
+    *
+    * @example
+    * var varValues = [];//you've got access to variables declared with 'var'
+    * let letValues = [];//you've got access to variables declared with 'let'
+    * var count = 0;//you cannot overwrite a variable of 'sqlPageData' by accident
+    *
+    * var sql = "select ORGNAME from ORG";
+    * var blockSize = 5 * 1000;
+    *
+    * var allRows = +db.cell("select count(*) from ORG");
+    *
+    * sqlPageData(sql, blockSize, function (pData, pRunNo){
+    *     var j = pData.length;//pData is the current block with data
+    *     logging.log(pRunNo.toString() + "#" + j);//pRunNo is the amount how often the func. has been already called
+    *     //you can calculate the progress easily by: progress = (blockSize* (pRunNo-1) + pData.length) / (allRows - startOffset)
+    *     //example in per cent:
+    *     var startOffset = 0;//we did not pass any startOffset to sqlPageData - this is equivalent to zero
+    *     var progress = (blockSize* (pRunNo-1) + pData.length) / (allRows - startOffset);
+    *     logging.log("progess: " + eMath.roundDec(progress * 100, 2, eMath.ROUND_CEILING) + "%");
+    *
+    *     for (var i = 0; i < j; i++)
+    *     {
+    *         varValues.push(pData[i][0]);
+    *         letValues.push(pData[i][0]);
+    *     }
+    *
+    *     count += pRunNo * 100;
+    *     logging.log("count:" + count);//you cannot overwrite a variable of 'sqlPageData' by accident
+    * });
+    *
+    * logging.show(letValues);//contains orgnames
+    * logging.show(varValues);//contains orgnames
+    */
+    this.sqlPageData = function(pSql, pBlockSize, pCallback, pDbAlias, pTimeout, pStartOffset)
+    {
+        if (pDbAlias == undefined)
+            pDbAlias = db.getCurrentAlias();
+
+        if (pStartOffset == undefined)
+            pStartOffset = 0;
+
+        let count = 0;
+        while (pStartOffset > -1)
+        {
+            let data;
+            if (pTimeout == undefined)
+                data = db.tablePage(pSql, pDbAlias, pStartOffset, pBlockSize);
+            else
+                data = db.tablePage(pSql, pDbAlias, pStartOffset, pBlockSize, pTimeout);
+
+            pStartOffset += pBlockSize;
+
+            //this happens when all-records % pBlockSize == 0
+            //we do not want to call the callback-fn
+            if (data.length == 0)
+                return true;
+            else if (data.length < pBlockSize || pBlockSize == 0)//blocksize 0 is everything
+                pStartOffset = -1;//call callback the last time
+
+            if (pCallback.call(this, data, ++count) === false)
+                return false;//callback can return false to manually stop the paging-process
+
+        }
+        return true;
+    }
 }
\ No newline at end of file
-- 
GitLab