diff --git a/.liquibase/Data_alias/basic/2020.1.2/AddNullableToDateNew.xml b/.liquibase/Data_alias/basic/2020.1.2/AddNullableToDateNew.xml
new file mode 100644
index 0000000000000000000000000000000000000000..86989600807b32fba76fc6b052f08f007cb4f390
--- /dev/null
+++ b/.liquibase/Data_alias/basic/2020.1.2/AddNullableToDateNew.xml
@@ -0,0 +1,13 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+    <changeSet id="0aa81d84-7456-4240-91e0-a915f38abbd7" author="s.pongratz" >
+        <addNotNullConstraint columnName="DATE_NEW" tableName="CAMPAIGNCOST" columnDataType="DATETIME" validate="true"/>
+        <addNotNullConstraint columnName="DATE_NEW" tableName="CAMPAIGNPARTICIPANT" columnDataType="DATETIME" validate="true"/>
+        <addNotNullConstraint columnName="DATE_NEW" tableName="CAMPAIGNSTEP" columnDataType="DATETIME" validate="true"/>
+        <addNotNullConstraint columnName="DATE_NEW" tableName="DOCUMENTTEMPLATELINK" columnDataType="DATETIME" validate="true"/>
+        <addNotNullConstraint columnName="DATE_NEW" tableName="DUPLICATESCANNER" columnDataType="DATETIME" validate="true"/>
+        <addNotNullConstraint columnName="DATE_NEW" tableName="DUPLICATESCANNERRESULTFIELDCONFIG" columnDataType="DATETIME" validate="true"/>
+        <addNotNullConstraint columnName="DATE_NEW" tableName="CAMPAIGN" columnDataType="DATETIME" validate="true"/>
+    </changeSet>
+</databaseChangeLog>
diff --git a/.liquibase/Data_alias/basic/2020.1.2/changelog.xml b/.liquibase/Data_alias/basic/2020.1.2/changelog.xml
index 29f7efdfa26f1934cddfe20e65a5dd102021ffa3..98f643b71426d12718ef4175e9569864d3f0574b 100644
--- a/.liquibase/Data_alias/basic/2020.1.2/changelog.xml
+++ b/.liquibase/Data_alias/basic/2020.1.2/changelog.xml
@@ -2,4 +2,6 @@
 <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
     <include file="AlterDocumentTemplatePlaceOfUseDatatype/changelog.xml" relativeToChangelogFile="true"/>
+    <include file="AddNullableToDateNew.xml" relativeToChangelogFile="true" />
+    <include file="insert_workflowCategory_keyword.xml" relativeToChangelogFile="true"/>
 </databaseChangeLog>
diff --git a/.liquibase/Data_alias/changelog.xml b/.liquibase/Data_alias/changelog.xml
index 50c63b65a63025ae582f679ca7b2051471c3fd9e..a8cc53b406959a8797b32a02af71dd93e1576384 100644
--- a/.liquibase/Data_alias/changelog.xml
+++ b/.liquibase/Data_alias/changelog.xml
@@ -13,6 +13,7 @@
     <include relativeToChangelogFile="true" file="basic/2020.0.3/changelog.xml"/>
     <include relativeToChangelogFile="true" file="basic/2020.1.0/changelog.xml"/>
     <include relativeToChangelogFile="true" file="basic/2020.1.1/changelog.xml"/>
+    <include relativeToChangelogFile="true" file="basic/2020.1.2/changelog.xml"/>
     
     <!--enable this only when you definetly want to overwrite the existing data with demo records:--> 
     <!--<include relativeToChangelogFile="true" file="basic/_demoData/changelog.xml" context="example"/>-->
diff --git a/entity/Activity_entity/Activity_entity.aod b/entity/Activity_entity/Activity_entity.aod
index d4c06eaeedeef0b7f545ecd501cc99da61458769..c9558baefe3e2cfb98c86980090279cc36383154 100644
--- a/entity/Activity_entity/Activity_entity.aod
+++ b/entity/Activity_entity/Activity_entity.aod
@@ -611,6 +611,16 @@
       <title> number of connections</title>
       <valueProcess>%aditoprj%/entity/Activity_entity/entityfields/countlinks/valueProcess.js</valueProcess>
     </entityField>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+      <contentType>NUMBER</contentType>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -712,6 +722,15 @@
           <name>entryDateDateFormat.value</name>
           <expression>%aditoprj%/entity/Activity_entity/recordcontainers/db/recordfieldmappings/entrydatedateformat.value/expression.js</expression>
         </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>ACTIVITY.ACTIVITYID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/Activity_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
       <filterExtensions>
         <filterExtensionSet>
diff --git a/entity/AnyContact_entity/AnyContact_entity.aod b/entity/AnyContact_entity/AnyContact_entity.aod
index 764fffc4fd77721dcdae4ec59576865446464b97..b9e852b3b2ae077b24a41200d051dad37e408a9a 100644
--- a/entity/AnyContact_entity/AnyContact_entity.aod
+++ b/entity/AnyContact_entity/AnyContact_entity.aod
@@ -4,7 +4,7 @@
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <documentation>%aditoprj%/entity/AnyContact_entity/documentation.adoc</documentation>
   <contentTitleProcess>%aditoprj%/entity/AnyContact_entity/contentTitleProcess.js</contentTitleProcess>
-  <afterUiInit>%aditoprj%/entity/AnyContact_entity/afterUiInit.js</afterUiInit>
+  <onInit>%aditoprj%/entity/AnyContact_entity/onInit.js</onInit>
   <imageProcess>%aditoprj%/entity/AnyContact_entity/imageProcess.js</imageProcess>
   <recordContainer>db</recordContainer>
   <entityFields>
diff --git a/entity/Contact_entity/afterUiInit.js b/entity/AnyContact_entity/onInit.js
similarity index 89%
rename from entity/Contact_entity/afterUiInit.js
rename to entity/AnyContact_entity/onInit.js
index ad4324c7682881b8e9ca470e334269ae822ec522..a75a8d405e273b1b3e026251a305676c2ccbd9ad 100644
--- a/entity/Contact_entity/afterUiInit.js
+++ b/entity/AnyContact_entity/onInit.js
@@ -8,7 +8,7 @@ var statusFilterElement = {
         "name":"STATUS",
         "operator":"NOT_EQUAL",
         "key":$KeywordRegistry.contactStatus$inactive(),
-        "contenttype": vars.get("$property.STATUS.contentType")
+        "contenttype": "TEXT"
 };
     
 statusFilterElement.value = KeywordUtils.getViewValue($KeywordRegistry.contactStatus(), statusFilterElement.key);
diff --git a/entity/CampaignParticipant_entity/entityfields/campaign_id/onValueChange.js b/entity/CampaignParticipant_entity/entityfields/campaign_id/onValueChange.js
index f5f6c5c6594a1a57fb3aaa41b59dfd0768bfc430..07c57c1e196e3db902ee7f56434ab85cdcda55af 100644
--- a/entity/CampaignParticipant_entity/entityfields/campaign_id/onValueChange.js
+++ b/entity/CampaignParticipant_entity/entityfields/campaign_id/onValueChange.js
@@ -2,7 +2,7 @@ import("system.neon");
 import("Campaign_lib");
 import("system.vars");
 
-if(vasr.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
 {
     var stepId = CampaignUtils.getDefaultCampaignStep(vars.get("local.value"));
     neon.setFieldValue("$field.CAMPAIGNSTEP_ID", stepId);
diff --git a/entity/Campaign_entity/Campaign_entity.aod b/entity/Campaign_entity/Campaign_entity.aod
index d67763b95c47c81e4bffb571fdd45f8744f237fd..a9420fd4fbb060bb56b80f2efa888981a719029e 100644
--- a/entity/Campaign_entity/Campaign_entity.aod
+++ b/entity/Campaign_entity/Campaign_entity.aod
@@ -517,6 +517,16 @@
         </entityParameter>
       </children>
     </entityConsumer>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+      <contentType>NUMBER</contentType>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -614,6 +624,15 @@
           <name>CURRENCY.displayValue</name>
           <expression>%aditoprj%/entity/Campaign_entity/recordcontainers/db/recordfieldmappings/currency.displayvalue/expression.js</expression>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/Campaign_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>CAMPAIGN.CAMPAIGNID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
       </recordFieldMappings>
       <filterExtensions>
         <filterExtensionSet>
diff --git a/entity/Contact_entity/Contact_entity.aod b/entity/Contact_entity/Contact_entity.aod
index 5c0c8448cd84839a753fd36b32d653fcbfc16827..82c35b3c618ecc933e74b694daa96ad9f97cbfa4 100644
--- a/entity/Contact_entity/Contact_entity.aod
+++ b/entity/Contact_entity/Contact_entity.aod
@@ -8,7 +8,7 @@
   <grantUpdateProcess>%aditoprj%/entity/Contact_entity/grantUpdateProcess.js</grantUpdateProcess>
   <grantDeleteProcess>%aditoprj%/entity/Contact_entity/grantDeleteProcess.js</grantDeleteProcess>
   <contentTitleProcess>%aditoprj%/entity/Contact_entity/contentTitleProcess.js</contentTitleProcess>
-  <afterUiInit>%aditoprj%/entity/Contact_entity/afterUiInit.js</afterUiInit>
+  <onInit>%aditoprj%/entity/Contact_entity/onInit.js</onInit>
   <onValidation>%aditoprj%/entity/Contact_entity/onValidation.js</onValidation>
   <iconId>VAADIN:USERS</iconId>
   <titlePlural>Contacts</titlePlural>
diff --git a/entity/AnyContact_entity/afterUiInit.js b/entity/Contact_entity/onInit.js
similarity index 100%
rename from entity/AnyContact_entity/afterUiInit.js
rename to entity/Contact_entity/onInit.js
diff --git a/entity/Contract_entity/Contract_entity.aod b/entity/Contract_entity/Contract_entity.aod
index 51dab19fa4733bd1cf91075fa059b823317b0a96..867da2214346c3543ad2601ffebd9fbfe42936f8 100644
--- a/entity/Contract_entity/Contract_entity.aod
+++ b/entity/Contract_entity/Contract_entity.aod
@@ -383,6 +383,15 @@
       <iconId>VAADIN:CURLY_BRACKETS</iconId>
       <stateProcess>%aditoprj%/entity/Contract_entity/entityfields/openadminview/stateProcess.js</stateProcess>
     </entityActionField>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -520,6 +529,15 @@
           <isFilterable v="true" />
           <filtertype>EXTENDED</filtertype>
         </consumerMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/Contract_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>CONTRACT.CONTRACTID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
       </recordFieldMappings>
       <filterExtensions>
         <filterExtensionSet>
diff --git a/entity/ExportTemplateField_entity/entityfields/field/dropDownProcess.js b/entity/ExportTemplateField_entity/entityfields/field/dropDownProcess.js
index f5b8c998801e7aafdb45582d7a566614367a30a2..3c830477d519292b231f502d1caa9cffc392f984 100644
--- a/entity/ExportTemplateField_entity/entityfields/field/dropDownProcess.js
+++ b/entity/ExportTemplateField_entity/entityfields/field/dropDownProcess.js
@@ -9,7 +9,7 @@ import("system.text")
 
     
 var placeholders = PlaceholderUtils.getPlaceholders(null, true).map(function (placeholder){
-    return [placeholder.placeholderName, placeholder.title || placeholder.placeholderName];
+    return [placeholder.getFormattedName(), placeholder.title || placeholder.getFormattedName()];
 })
 
 result.object(placeholders);
\ No newline at end of file
diff --git a/entity/KeywordEntry_entity/KeywordEntry_entity.aod b/entity/KeywordEntry_entity/KeywordEntry_entity.aod
index 1d23aa80c139ba8f466111374bda9a644bdef202..2d0edd64d5ba7e6d9b3e6463f32144b574509094 100644
--- a/entity/KeywordEntry_entity/KeywordEntry_entity.aod
+++ b/entity/KeywordEntry_entity/KeywordEntry_entity.aod
@@ -577,6 +577,12 @@
           <fieldName>KeywordVisitRecommendationPriority</fieldName>
           <isConsumer v="false" />
         </entityDependency>
+        <entityDependency>
+          <name>54410e7f-e5e6-4dd1-8f60-7864ed907aed</name>
+          <entityName>WorkflowDefinition_entity</entityName>
+          <fieldName>CategoryKeyword</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
       </dependencies>
       <children>
         <entityParameter>
diff --git a/entity/Offer_entity/Offer_entity.aod b/entity/Offer_entity/Offer_entity.aod
index 48fe414838b8a3bfa78d78a7a57e768a8f82aa26..0b3a54a7db2a33381db46e8d4d83547f52c16d7d 100644
--- a/entity/Offer_entity/Offer_entity.aod
+++ b/entity/Offer_entity/Offer_entity.aod
@@ -1023,6 +1023,16 @@
       <name>NET_aggregate</name>
       <parentField>NET</parentField>
     </entityAggregateField>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+      <contentType>NUMBER</contentType>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -1261,6 +1271,15 @@
           <recordfield>OFFER.NET</recordfield>
           <aggregateType>SUM</aggregateType>
         </aggregateFieldDbMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/Offer_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>OFFER.OFFER_ID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
       </recordFieldMappings>
       <filterExtensions>
         <filterExtensionSet>
diff --git a/entity/Order_entity/Order_entity.aod b/entity/Order_entity/Order_entity.aod
index 2c8082ea9ffdf2565a44890ffea392bdef4f298d..7610aac58abe7df79a112280b6807f2f1cb5399b 100644
--- a/entity/Order_entity/Order_entity.aod
+++ b/entity/Order_entity/Order_entity.aod
@@ -987,6 +987,16 @@
         <fieldName>Contacts</fieldName>
       </dependency>
     </entityConsumer>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+      <contentType>NUMBER</contentType>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -1201,6 +1211,15 @@
           <name>ISOLANGUAGE.displayValue</name>
           <expression>%aditoprj%/entity/Order_entity/recordcontainers/db/recordfieldmappings/isolanguage.displayvalue/expression.js</expression>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/Order_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>SALESORDER.SALESORDERID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
       </recordFieldMappings>
     </dbRecordContainer>
     <indexRecordContainer>
diff --git a/entity/Organisation_entity/Organisation_entity.aod b/entity/Organisation_entity/Organisation_entity.aod
index 875ad026d6d26f22daffee578b7e83c580b1639e..26fe1fdb3d81b895c3116377537320ae54a77d70 100644
--- a/entity/Organisation_entity/Organisation_entity.aod
+++ b/entity/Organisation_entity/Organisation_entity.aod
@@ -7,7 +7,7 @@
   <title>Company</title>
   <grantDeleteProcess>%aditoprj%/entity/Organisation_entity/grantDeleteProcess.js</grantDeleteProcess>
   <contentTitleProcess>%aditoprj%/entity/Organisation_entity/contentTitleProcess.js</contentTitleProcess>
-  <afterUiInit>%aditoprj%/entity/Organisation_entity/afterUiInit.js</afterUiInit>
+  <onInit>%aditoprj%/entity/Organisation_entity/onInit.js</onInit>
   <afterOperatingState>%aditoprj%/entity/Organisation_entity/afterOperatingState.js</afterOperatingState>
   <iconId>VAADIN:BUILDING</iconId>
   <imageProcess>%aditoprj%/entity/Organisation_entity/imageProcess.js</imageProcess>
@@ -788,7 +788,7 @@
       <title>Turnover Current Year</title>
       <contentType>NUMBER</contentType>
       <outputFormat>#,##0.00€</outputFormat>
-      <groupable v="true" />
+      <groupable v="false" />
       <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/turnovercurrentyear/valueProcess.js</valueProcess>
     </entityField>
     <entityField>
@@ -796,7 +796,7 @@
       <title>Turnover Last Year</title>
       <contentType>NUMBER</contentType>
       <outputFormat>#,##0.00€</outputFormat>
-      <groupable v="true" />
+      <groupable v="false" />
       <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/turnoverlastyear/valueProcess.js</valueProcess>
     </entityField>
     <entityField>
@@ -804,6 +804,7 @@
       <title>Turnover change</title>
       <colorProcess>%aditoprj%/entity/Organisation_entity/entityfields/turnoverpercentdiff/colorProcess.js</colorProcess>
       <contentType>TEXT</contentType>
+      <groupable v="false" />
       <valueProcess>%aditoprj%/entity/Organisation_entity/entityfields/turnoverpercentdiff/valueProcess.js</valueProcess>
     </entityField>
     <entityField>
@@ -1102,6 +1103,16 @@
       <onActionProcess>%aditoprj%/entity/Organisation_entity/entityfields/openlocation/onActionProcess.js</onActionProcess>
       <iconId>NEON:TACKED</iconId>
     </entityActionField>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+      <contentType>NUMBER</contentType>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -1308,6 +1319,15 @@
           <name>STANDARD_ZIP.value</name>
           <recordfield>ADDRESS.ZIP</recordfield>
         </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>ORGANISATION.ORGANISATIONID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/Organisation_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
       <filterExtensions>
         <filterExtensionSet>
diff --git a/entity/Organisation_entity/afterUiInit.js b/entity/Organisation_entity/onInit.js
similarity index 89%
rename from entity/Organisation_entity/afterUiInit.js
rename to entity/Organisation_entity/onInit.js
index 669f54dbb747c656a7723b9795e3e10875eade5c..b9717583554415c62b48c4ad8304aceb87245938 100644
--- a/entity/Organisation_entity/afterUiInit.js
+++ b/entity/Organisation_entity/onInit.js
@@ -1,30 +1,30 @@
-import("Keyword_lib");
-import("KeywordRegistry_basic");
-import("system.neon");
-import("system.vars");
-import("Context_lib");
-import("Attribute_lib");
-
-var statusFilterElement = {
-        "type":"row",
-        "name":"STATUS",
-        "operator":"NOT_EQUAL",
-        "key":$KeywordRegistry.contactStatus$inactive(),
-        "contenttype": vars.get("$property.STATUS.contentType")
-};
-    
-statusFilterElement.value = KeywordUtils.getViewValue($KeywordRegistry.contactStatus(), statusFilterElement.key);
-    
-var filter = {
-        "type":"group",
-        "operator":"AND",
-        "childs": [statusFilterElement]
-};
-    
-filter = JSON.stringify(filter);
-neon.setFilter("#ENTITY", filter);
-
-if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
-{
-    AttributeRelationUtils.presetMandatoryAttributes(ContextUtils.getCurrentContextId(), "Attributes");
-}
+import("Keyword_lib");
+import("KeywordRegistry_basic");
+import("system.neon");
+import("system.vars");
+import("Context_lib");
+import("Attribute_lib");
+
+var statusFilterElement = {
+        "type":"row",
+        "name":"STATUS",
+        "operator":"NOT_EQUAL",
+        "key":$KeywordRegistry.contactStatus$inactive(),
+        "contenttype": "TEXT"
+};
+    
+statusFilterElement.value = KeywordUtils.getViewValue($KeywordRegistry.contactStatus(), statusFilterElement.key);
+    
+var filter = {
+        "type":"group",
+        "operator":"AND",
+        "childs": [statusFilterElement]
+};
+    
+filter = JSON.stringify(filter);
+neon.setFilter("#ENTITY", filter);
+
+if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
+{
+    AttributeRelationUtils.presetMandatoryAttributes(ContextUtils.getCurrentContextId(), "Attributes");
+}
diff --git a/entity/PermissionCalendar_entity/PermissionCalendar_entity.aod b/entity/PermissionCalendar_entity/PermissionCalendar_entity.aod
index 8bd374fd3485951d6ff0cef39ff55d465a66f135..a238832f1d236913854ff9ffa634281c3081d5ec 100644
--- a/entity/PermissionCalendar_entity/PermissionCalendar_entity.aod
+++ b/entity/PermissionCalendar_entity/PermissionCalendar_entity.aod
@@ -90,9 +90,9 @@
       <description></description>
       <children>
         <entityActionField>
-          <name>addNewUserPermissionDealerAction</name>
-          <title>Add new User Permission</title>
-          <onActionProcess>%aditoprj%/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewuserpermissiondealeraction/onActionProcess.js</onActionProcess>
+          <name>receiveNewUserPermissionDealerAction</name>
+          <title>Receive new User Permission</title>
+          <onActionProcess>%aditoprj%/entity/PermissionCalendar_entity/entityfields/addactions/children/receivenewuserpermissiondealeraction/onActionProcess.js</onActionProcess>
           <isMenuAction v="true" />
           <isObjectAction v="false" />
           <isSelectionAction v="false" />
@@ -100,9 +100,9 @@
           <tooltip></tooltip>
         </entityActionField>
         <entityActionField>
-          <name>addNewDepartmentPermissionDealterAction</name>
-          <title>Add new Department Permission</title>
-          <onActionProcess>%aditoprj%/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewdepartmentpermissiondealteraction/onActionProcess.js</onActionProcess>
+          <name>receiveNewDepartmentPermissionDealterAction</name>
+          <title>Receive new Department Permission</title>
+          <onActionProcess>%aditoprj%/entity/PermissionCalendar_entity/entityfields/addactions/children/receivenewdepartmentpermissiondealteraction/onActionProcess.js</onActionProcess>
           <isObjectAction v="false" />
           <state>AUTO</state>
         </entityActionField>
diff --git a/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewdepartmentpermissiondealteraction/onActionProcess.js b/entity/PermissionCalendar_entity/entityfields/addactions/children/receivenewdepartmentpermissiondealteraction/onActionProcess.js
similarity index 100%
rename from entity/PermissionCalendar_entity/entityfields/addactions/children/addnewdepartmentpermissiondealteraction/onActionProcess.js
rename to entity/PermissionCalendar_entity/entityfields/addactions/children/receivenewdepartmentpermissiondealteraction/onActionProcess.js
diff --git a/entity/PermissionCalendar_entity/entityfields/addactions/children/addnewuserpermissiondealeraction/onActionProcess.js b/entity/PermissionCalendar_entity/entityfields/addactions/children/receivenewuserpermissiondealeraction/onActionProcess.js
similarity index 100%
rename from entity/PermissionCalendar_entity/entityfields/addactions/children/addnewuserpermissiondealeraction/onActionProcess.js
rename to entity/PermissionCalendar_entity/entityfields/addactions/children/receivenewuserpermissiondealeraction/onActionProcess.js
diff --git a/entity/Person_entity/Person_entity.aod b/entity/Person_entity/Person_entity.aod
index 61aa30e669c5d98bfa405cc9fb26e8848dfa290c..cbabea32766c97f2a7d1faa4fcc2ede5fd2a3048 100644
--- a/entity/Person_entity/Person_entity.aod
+++ b/entity/Person_entity/Person_entity.aod
@@ -10,7 +10,7 @@
   </siblings>
   <grantDeleteProcess>%aditoprj%/entity/Person_entity/grantDeleteProcess.js</grantDeleteProcess>
   <contentTitleProcess>%aditoprj%/entity/Person_entity/contentTitleProcess.js</contentTitleProcess>
-  <afterUiInit>%aditoprj%/entity/Person_entity/afterUiInit.js</afterUiInit>
+  <onInit>%aditoprj%/entity/Person_entity/onInit.js</onInit>
   <onValidation>%aditoprj%/entity/Person_entity/onValidation.js</onValidation>
   <afterOperatingState>%aditoprj%/entity/Person_entity/afterOperatingState.js</afterOperatingState>
   <iconId>VAADIN:USERS</iconId>
@@ -192,7 +192,7 @@
           <name>ContactId_param</name>
           <valueProcess>%aditoprj%/entity/Person_entity/entityfields/communications/children/contactid_param/valueProcess.js</valueProcess>
           <expose v="false" />
-          <description>This parameter is used for specifing a related &amp;quot;CONTACTID&amp;quot; to a COMMUNICATION-entry. 
+          <description>This parameter is used for specifing a related &amp;quot;CONTACTID&amp;quot; to a COMMUNICATION-entry.
                         Usually this is used for filtering COMMUNICATION-entries by a specified contact or creating a new entry that is related to a contact.</description>
         </entityParameter>
         <entityParameter>
@@ -413,7 +413,7 @@
           <name>ContactId_param</name>
           <valueProcess>%aditoprj%/entity/Person_entity/entityfields/phonecommunications/children/contactid_param/valueProcess.js</valueProcess>
           <expose v="false" />
-          <description>This parameter is used for specifing a related &amp;quot;CONTACTID&amp;quot; to a COMMUNICATION-entry. 
+          <description>This parameter is used for specifing a related &amp;quot;CONTACTID&amp;quot; to a COMMUNICATION-entry.
                         Usually this is used for filtering COMMUNICATION-entries by a specified contact or creating a new entry that is related to a contact.</description>
         </entityParameter>
       </children>
@@ -431,7 +431,7 @@
           <name>ContactId_param</name>
           <valueProcess>%aditoprj%/entity/Person_entity/entityfields/emailcommunications/children/contactid_param/valueProcess.js</valueProcess>
           <expose v="false" />
-          <description>This parameter is used for specifing a related &amp;quot;CONTACTID&amp;quot; to a COMMUNICATION-entry. 
+          <description>This parameter is used for specifing a related &amp;quot;CONTACTID&amp;quot; to a COMMUNICATION-entry.
                         Usually this is used for filtering COMMUNICATION-entries by a specified contact or creating a new entry that is related to a contact.</description>
         </entityParameter>
       </children>
@@ -1266,6 +1266,16 @@
         </entityParameter>
       </children>
     </entityProvider>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+      <contentType>NUMBER</contentType>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -1551,6 +1561,15 @@
           <name>CONTACTROLE.displayValue</name>
           <expression>%aditoprj%/entity/Person_entity/recordcontainers/db/recordfieldmappings/contactrole.displayvalue/expression.js</expression>
         </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>PERSON.PERSONID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/Person_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
       <filterExtensions>
         <filterExtensionSet>
diff --git a/entity/Person_entity/afterUiInit.js b/entity/Person_entity/onInit.js
similarity index 89%
rename from entity/Person_entity/afterUiInit.js
rename to entity/Person_entity/onInit.js
index e756cf590afbc22dfff0537787df1a139a3d47ff..1958e327f289481afe51088aa62d5d57af3a782f 100644
--- a/entity/Person_entity/afterUiInit.js
+++ b/entity/Person_entity/onInit.js
@@ -1,30 +1,30 @@
-import("Keyword_lib");
-import("KeywordRegistry_basic");
-import("system.neon");
-import("system.vars");
-import("Context_lib");
-import("Attribute_lib");
-
-var statusFilterElement = {
-        "type":"row",
-        "name":"STATUS",
-        "operator":"NOT_EQUAL",
-        "key":$KeywordRegistry.contactStatus$inactive(),
-        "contenttype": vars.get("$property.STATUS.contentType")
-};
-    
-statusFilterElement.value = KeywordUtils.getViewValue($KeywordRegistry.contactStatus(), statusFilterElement.key);
-    
-var filter = {
-        "type":"group",
-        "operator":"AND",
-        "childs": [statusFilterElement]
-};
-    
-filter = JSON.stringify(filter);
-neon.setFilter("#ENTITY", filter);   
-
-if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
-{
-    AttributeRelationUtils.presetMandatoryAttributes(ContextUtils.getCurrentContextId(), "Attributes");
-}
+import("Keyword_lib");
+import("KeywordRegistry_basic");
+import("system.neon");
+import("system.vars");
+import("Context_lib");
+import("Attribute_lib");
+
+var statusFilterElement = {
+        "type":"row",
+        "name":"STATUS",
+        "operator":"NOT_EQUAL",
+        "key":$KeywordRegistry.contactStatus$inactive(),
+        "contenttype": "TEXT"
+};
+    
+statusFilterElement.value = KeywordUtils.getViewValue($KeywordRegistry.contactStatus(), statusFilterElement.key);
+    
+var filter = {
+        "type":"group",
+        "operator":"AND",
+        "childs": [statusFilterElement]
+};
+    
+filter = JSON.stringify(filter);
+neon.setFilter("#ENTITY", filter);   
+
+if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
+{
+    AttributeRelationUtils.presetMandatoryAttributes(ContextUtils.getCurrentContextId(), "Attributes");
+}
diff --git a/entity/Product_entity/Product_entity.aod b/entity/Product_entity/Product_entity.aod
index 6b97e94cfbe88f96d63d68a50c202c814691ebfa..aab2dfcb21f200605c77c10973ff927b18217abb 100644
--- a/entity/Product_entity/Product_entity.aod
+++ b/entity/Product_entity/Product_entity.aod
@@ -457,6 +457,16 @@
       <iconId>VAADIN:CURLY_BRACKETS</iconId>
       <stateProcess>%aditoprj%/entity/Product_entity/entityfields/openadminview/stateProcess.js</stateProcess>
     </entityActionField>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+      <contentType>NUMBER</contentType>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -581,6 +591,15 @@
           <isFilterable v="true" />
           <filtertype>EXTENDED</filtertype>
         </consumerMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/Product_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>PRODUCT.PRODUCTID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
       </recordFieldMappings>
       <filterExtensions>
         <filterExtensionSet>
diff --git a/entity/Salesproject_entity/Salesproject_entity.aod b/entity/Salesproject_entity/Salesproject_entity.aod
index 33c8be5fa863f20bd086cdaae53dddae0f233b54..0338b89079f6041156a8a5b1e76bc32a4bb9d143 100644
--- a/entity/Salesproject_entity/Salesproject_entity.aod
+++ b/entity/Salesproject_entity/Salesproject_entity.aod
@@ -627,7 +627,7 @@
     <entityField>
       <name>ClassificationResult</name>
       <title>Classification</title>
-      <groupable v="true" />
+      <groupable v="false" />
       <state>READONLY</state>
       <valueProcess>%aditoprj%/entity/Salesproject_entity/entityfields/classificationresult/valueProcess.js</valueProcess>
     </entityField>
@@ -749,6 +749,16 @@
       <iconId>VAADIN:PLAY</iconId>
       <stateProcess>%aditoprj%/entity/Salesproject_entity/entityfields/startworkflow/stateProcess.js</stateProcess>
     </entityActionField>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+      <contentType>NUMBER</contentType>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -876,6 +886,15 @@
           <isFilterable v="true" />
           <isLookupFilter v="true" />
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/Salesproject_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>SALESPROJECT.SALESPROJECTID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
       </recordFieldMappings>
       <filterExtensions>
         <filterExtensionSet>
diff --git a/entity/SupportTicket_entity/SupportTicket_entity.aod b/entity/SupportTicket_entity/SupportTicket_entity.aod
index db8daa732b8e6ba8ac26517fd2f225314c6575a3..69f29f9e7f9cd60dbc419f66159e5423d41e0096 100644
--- a/entity/SupportTicket_entity/SupportTicket_entity.aod
+++ b/entity/SupportTicket_entity/SupportTicket_entity.aod
@@ -395,6 +395,16 @@
       <name>RowId_param</name>
       <expose v="true" />
     </entityParameter>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+      <contentType>NUMBER</contentType>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -483,9 +493,6 @@
           <name>TASK_REQUESTOR_CONTACT_ID.displayValue</name>
           <expression>%aditoprj%/entity/SupportTicket_entity/recordcontainers/db/recordfieldmappings/task_requestor_contact_id.displayvalue/expression.js</expression>
         </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>TASK_PRIORITY.displayValue</name>
-        </dbRecordFieldMapping>
         <dbRecordFieldMapping>
           <name>TASK_PROGRESS.value</name>
           <recordfield>TASK.PROGRESS</recordfield>
@@ -530,6 +537,15 @@
           <name>TASK_PARENT_CONTEXT.value</name>
           <recordfield>TASK.PARENT_CONTEXT</recordfield>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/SupportTicket_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>TICKET.TICKETID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
       </recordFieldMappings>
     </dbRecordContainer>
   </recordContainers>
diff --git a/entity/Task_entity/Task_entity.aod b/entity/Task_entity/Task_entity.aod
index aa736a459ee93a5fe679f9fcf01cc8c1a86545a4..14cdb18785867088dbb7220fa1bb33afc7b479a3 100644
--- a/entity/Task_entity/Task_entity.aod
+++ b/entity/Task_entity/Task_entity.aod
@@ -6,7 +6,7 @@
   <title>Task</title>
   <grantDeleteProcess>%aditoprj%/entity/Task_entity/grantDeleteProcess.js</grantDeleteProcess>
   <contentTitleProcess>%aditoprj%/entity/Task_entity/contentTitleProcess.js</contentTitleProcess>
-  <afterUiInit>%aditoprj%/entity/Task_entity/afterUiInit.js</afterUiInit>
+  <onInit>%aditoprj%/entity/Task_entity/onInit.js</onInit>
   <onValidation>%aditoprj%/entity/Task_entity/onValidation.js</onValidation>
   <iconId>VAADIN:TASKS</iconId>
   <iconIdProcess>%aditoprj%/entity/Task_entity/iconIdProcess.js</iconIdProcess>
@@ -453,6 +453,16 @@
       <iconId>VAADIN:CURLY_BRACKETS</iconId>
       <stateProcess>%aditoprj%/entity/Task_entity/entityfields/openadminview/stateProcess.js</stateProcess>
     </entityActionField>
+    <entityField>
+      <name>COUNT</name>
+      <title>Count</title>
+      <contentType>NUMBER</contentType>
+    </entityField>
+    <entityAggregateField>
+      <name>COUNT_aggregate</name>
+      <parentField>COUNT</parentField>
+      <title>Count</title>
+    </entityAggregateField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -570,6 +580,15 @@
           <name>TYPE.value</name>
           <recordfield>TASK.KIND</recordfield>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>COUNT.value</name>
+          <expression>%aditoprj%/entity/Task_entity/recordcontainers/db/recordfieldmappings/count.value/expression.js</expression>
+        </dbRecordFieldMapping>
+        <aggregateFieldDbMapping>
+          <name>COUNT_aggregate.value</name>
+          <recordfield>TASK.TASKID</recordfield>
+          <aggregateType>COUNT</aggregateType>
+        </aggregateFieldDbMapping>
       </recordFieldMappings>
     </dbRecordContainer>
   </recordContainers>
diff --git a/entity/Task_entity/afterUiInit.js b/entity/Task_entity/onInit.js
similarity index 93%
rename from entity/Task_entity/afterUiInit.js
rename to entity/Task_entity/onInit.js
index 566c37e5652d388bc77fea8c23183811a2da9f3c..0a610862cbb9ecae7e44e15eabbc31b0b20eceda 100644
--- a/entity/Task_entity/afterUiInit.js
+++ b/entity/Task_entity/onInit.js
@@ -17,7 +17,7 @@ else if (recordState != neon.OPERATINGSTATE_SEARCH)
         "name":"STATUS",
         "operator":"NOT_EQUAL",
         "key":$KeywordRegistry.taskStatus$ended(),
-        "contenttype": vars.get("$property.STATUS.contentType")
+        "contenttype": "TEXT"
     };
     statusFilterElement.value = KeywordUtils.getViewValue($KeywordRegistry.taskStatus(), statusFilterElement.key);
     
diff --git a/entity/WorkflowDefinition_entity/WorkflowDefinition_entity.aod b/entity/WorkflowDefinition_entity/WorkflowDefinition_entity.aod
index 155a2f033dee8feaa814013907c364934edb0bd2..1cd52f7035f12fffa8d282df67384589bd7c0eb5 100644
--- a/entity/WorkflowDefinition_entity/WorkflowDefinition_entity.aod
+++ b/entity/WorkflowDefinition_entity/WorkflowDefinition_entity.aod
@@ -7,7 +7,7 @@
   <grantCreateProcess>%aditoprj%/entity/WorkflowDefinition_entity/grantCreateProcess.js</grantCreateProcess>
   <grantDelete v="false" />
   <contentTitleProcess>%aditoprj%/entity/WorkflowDefinition_entity/contentTitleProcess.js</contentTitleProcess>
-  <afterUiInit>%aditoprj%/entity/WorkflowDefinition_entity/afterUiInit.js</afterUiInit>
+  <onInit>%aditoprj%/entity/WorkflowDefinition_entity/onInit.js</onInit>
   <iconId>VAADIN:DROP</iconId>
   <titlePlural>Workflow definitions</titlePlural>
   <recordContainer>jdito</recordContainer>
@@ -35,6 +35,7 @@
           <name>openModeler</name>
           <title>Open modeler</title>
           <onActionProcess>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/tableactions/children/openmodeler/onActionProcess.js</onActionProcess>
+          <isObjectAction v="false" />
           <iconId>VAADIN:EXTERNAL_LINK</iconId>
           <stateProcess>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/tableactions/children/openmodeler/stateProcess.js</stateProcess>
         </entityActionField>
@@ -42,6 +43,7 @@
           <name>createModel</name>
           <title>Create model</title>
           <onActionProcess>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/tableactions/children/createmodel/onActionProcess.js</onActionProcess>
+          <isObjectAction v="false" />
           <iconId>NEON:PLUS</iconId>
         </entityActionField>
       </children>
@@ -49,11 +51,14 @@
     <entityField>
       <name>CATEGORY</name>
       <title>Category</title>
+      <consumer>CategoryKeyword</consumer>
+      <groupable v="true" />
     </entityField>
     <entityField>
       <name>ISACTIVE</name>
       <title>Active</title>
       <contentType>BOOLEAN</contentType>
+      <groupable v="true" />
       <dropDownProcess>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/isactive/dropDownProcess.js</dropDownProcess>
       <stateProcess>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/isactive/stateProcess.js</stateProcess>
     </entityField>
@@ -214,6 +219,20 @@
       <iconId>VAADIN:EDIT</iconId>
       <tooltip>Edit workflow</tooltip>
     </entityActionField>
+    <entityConsumer>
+      <name>CategoryKeyword</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>KeywordEntry_entity</entityName>
+        <fieldName>SpecificContainerKeywords</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>ContainerName_param</name>
+          <valueProcess>%aditoprj%/entity/WorkflowDefinition_entity/entityfields/categorykeyword/children/containername_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
   </entityFields>
   <recordContainers>
     <jDitoRecordContainer>
@@ -224,6 +243,7 @@
       <contentProcess>%aditoprj%/entity/WorkflowDefinition_entity/recordcontainers/jdito/contentProcess.js</contentProcess>
       <onInsert>%aditoprj%/entity/WorkflowDefinition_entity/recordcontainers/jdito/onInsert.js</onInsert>
       <onUpdate>%aditoprj%/entity/WorkflowDefinition_entity/recordcontainers/jdito/onUpdate.js</onUpdate>
+      <onDelete>%aditoprj%/entity/WorkflowDefinition_entity/recordcontainers/jdito/onDelete.js</onDelete>
       <recordFieldMappings>
         <jDitoRecordFieldMapping>
           <name>UID.value</name>
@@ -238,6 +258,9 @@
           <isFilterable v="true" />
           <isLookupFilter v="true" />
         </jDitoRecordFieldMapping>
+        <jDitoRecordFieldMapping>
+          <name>CATEGORY.displayValue</name>
+        </jDitoRecordFieldMapping>
         <jDitoRecordFieldMapping>
           <name>KEY.value</name>
           <isFilterable v="true" />
diff --git a/entity/WorkflowDefinition_entity/entityfields/categorykeyword/children/containername_param/valueProcess.js b/entity/WorkflowDefinition_entity/entityfields/categorykeyword/children/containername_param/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..d79eb290d58d4f19fbd534e91b252388749224ce
--- /dev/null
+++ b/entity/WorkflowDefinition_entity/entityfields/categorykeyword/children/containername_param/valueProcess.js
@@ -0,0 +1,4 @@
+import("system.result");
+import("KeywordRegistry_basic");
+
+result.string($KeywordRegistry.workflowCategory());
\ No newline at end of file
diff --git a/entity/WorkflowDefinition_entity/afterUiInit.js b/entity/WorkflowDefinition_entity/onInit.js
similarity index 100%
rename from entity/WorkflowDefinition_entity/afterUiInit.js
rename to entity/WorkflowDefinition_entity/onInit.js
diff --git a/entity/WorkflowDefinition_entity/recordcontainers/jdito/contentProcess.js b/entity/WorkflowDefinition_entity/recordcontainers/jdito/contentProcess.js
index aff0261cf5187f58d2b66bafd7d223034036e2a4..bec4b9a0b8c4954217e7d33ed77af5640f95311f 100644
--- a/entity/WorkflowDefinition_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/WorkflowDefinition_entity/recordcontainers/jdito/contentProcess.js
@@ -5,6 +5,7 @@ import("system.result");
 import("Workflow_lib");
 import("system.workflow");
 import("JditoFilter_lib");
+import("KeywordData_lib");
 
 //immediately invoked function is used so that a return statement can be utilized to end the function at any point
 result.object((function ()
@@ -16,7 +17,9 @@ result.object((function ()
     var excludeVersion = vars.get("$param.CurrentVersion_param");
     var context = vars.get("$param.Context_param");
     var idvalues = vars.get("$local.idvalues");
-
+    
+    var categoryMap = KeywordData.getKeyIdMap($KeywordRegistry.workflowCategory());
+    
     var workflowDefs;
 
     if (idvalues)
@@ -48,6 +51,7 @@ result.object((function ()
             def.id,
             def.name,
             def.category,
+            categoryMap[def.category] || "",
             def.key,
             def.version,
             def.active,
@@ -73,14 +77,14 @@ result.object((function ()
     {
         filterFn = function (currDef)
         {
-            return newestVersions[currDef[3]] == currDef[4] && (possibleKeysMap ? possibleKeysMap[currDef[3]] : true);
+            return newestVersions[currDef[4]] == currDef[5] && (possibleKeysMap ? possibleKeysMap[currDef[4]] : true);
         };
     }
     else
     {
         filterFn = function (currDef)
         {
-            return excludeVersion != currDef[4];
+            return excludeVersion != currDef[5];
         };
     }
 
diff --git a/entity/WorkflowDefinition_entity/recordcontainers/jdito/onUpdate.js b/entity/WorkflowDefinition_entity/recordcontainers/jdito/onUpdate.js
index 2afd61402ee0fab203bf051660b1c227da1cdfdd..3dcde8317a8ad1ae4767f4e51f12535bb29d9656 100644
--- a/entity/WorkflowDefinition_entity/recordcontainers/jdito/onUpdate.js
+++ b/entity/WorkflowDefinition_entity/recordcontainers/jdito/onUpdate.js
@@ -4,11 +4,14 @@ import("system.workflow");
 import("Document_lib");
 
 var rowdata = vars.get("$local.rowdata");
+var changedFields = vars.get("$local.changed");
 
-if (vars.get("$local.changed").indexOf("ISACTIVE.value") !== -1)
+if (changedFields.includes("ISACTIVE.value"))
     workflow.setProcessActive(rowdata["UID.value"], rowdata["ISACTIVE.value"] == "true");
-    
 
+if (changedFields.includes("CATEGORY.value"))
+    workflow.setProcessDefinitionCategory(rowdata["UID.value"], rowdata["CATEGORY.value"]);
+    
 var upload = new FileUpload(vars.get("$field.FILEUPLOAD"));
 if (upload.isFilled())
 {
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index d5ea58da85213b73c9564fc16b464911bb063ab9..42409fc7a7206d17e71a75a697b5e057b54e8b27 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -6866,6 +6866,12 @@
     <entry>
       <key>download ready</key>
     </entry>
+    <entry>
+      <key>Add new Department Permission</key>
+    </entry>
+     <entry>
+      <key>Add new User Permission</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
   <sqlModels>
diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
index 205e05e083a3953435d1b30a1c37014f37da2b19..acf1aaac44a21a376a9553e3147140eb8d6f7fa3 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -8128,7 +8128,6 @@ Bitte Datumseingabe prüfen</value>
     </entry>
     <entry>
       <key>Leadimport Reset</key>
-      <value>Leadimport zurücksetzen</value>
     </entry>
     <entry>
       <key>Create notification</key>
@@ -8546,7 +8545,6 @@ Bitte Datumseingabe prüfen</value>
     </entry>
     <entry>
       <key>Lead Import Reset</key>
-      <value>Leadimport zurücksetzen</value>
     </entry>
     <entry>
       <key>Type</key>
@@ -8795,6 +8793,22 @@ Bitte Datumseingabe prüfen</value>
     <entry>
       <key>download ready</key>
     </entry>
+    <entry>
+      <key>Download letter and create Activity</key>
+      <value>Brief herunterladen und Aktivität erstellen</value>
+    </entry>
+    <entry>
+      <key>Add Participants</key>
+      <value>Teilnehmer hinzufügen</value>
+    </entry>
+    <entry>
+      <key>and open Report</key>
+      <value>und Report öffnen</value>
+    </entry>
+    <entry>
+      <key>Add Recipients</key>
+      <value>Empfänger hinzufügen</value>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/neonView/ActivityFilter_view/ActivityFilter_view.aod b/neonView/ActivityFilter_view/ActivityFilter_view.aod
index 09f94a720facdac4607c2410d50b3fe9ddcaf64f..0d59f1b7b3c98f9bf630fee21e641c2801b5022b 100644
--- a/neonView/ActivityFilter_view/ActivityFilter_view.aod
+++ b/neonView/ActivityFilter_view/ActivityFilter_view.aod
@@ -116,5 +116,18 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChart</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>fce2e978-e34d-4c6d-84f0-94d698ae793e</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/CampaignFilter_view/CampaignFilter_view.aod b/neonView/CampaignFilter_view/CampaignFilter_view.aod
index a30c1ab9f1f355ef861347d260fd2e120700499d..0dcb198305db9a4021ace200c99df40b0018904d 100644
--- a/neonView/CampaignFilter_view/CampaignFilter_view.aod
+++ b/neonView/CampaignFilter_view/CampaignFilter_view.aod
@@ -128,5 +128,18 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChart</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>945f1bdd-ae16-4f02-b3ec-d7bdd331adf0</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/ContractFilter_view/ContractFilter_view.aod b/neonView/ContractFilter_view/ContractFilter_view.aod
index f92d2bd17a33c1a20b623fd4e43c14114962124e..b43c2f7fa56d7f2d30204d9369376914532022b8 100644
--- a/neonView/ContractFilter_view/ContractFilter_view.aod
+++ b/neonView/ContractFilter_view/ContractFilter_view.aod
@@ -116,5 +116,18 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChart</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>5c0ec615-90ec-460b-b63f-bd4939ac3e09</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/OfferFilter_view/OfferFilter_view.aod b/neonView/OfferFilter_view/OfferFilter_view.aod
index 28fb45b5ae0dc0f8a90f1205e21d0d28f7c25652..0a1ab5740c5a8ae675bc91f798159175c3fdee75 100644
--- a/neonView/OfferFilter_view/OfferFilter_view.aod
+++ b/neonView/OfferFilter_view/OfferFilter_view.aod
@@ -136,5 +136,31 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChartCount</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>4bbc9650-47fd-4a59-8e1e-bb60ceb85795</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChartSum</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Total in euros</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>e5d14506-5205-43d0-89cb-416bf6debd25</name>
+          <entityField>NET</entityField>
+          <aggregateEntityField>NET_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/OrderFilter_view/OrderFilter_view.aod b/neonView/OrderFilter_view/OrderFilter_view.aod
index 6c1a61083eee585b71fe7f577ebac63b47d25263..8986ad83d38ead3ea35912d1be6ddfa5f3068bbc 100644
--- a/neonView/OrderFilter_view/OrderFilter_view.aod
+++ b/neonView/OrderFilter_view/OrderFilter_view.aod
@@ -120,5 +120,18 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChart</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>b4aa7cf1-5e25-4042-9430-b54a22dd83cf</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/OrganisationFilter_view/OrganisationFilter_view.aod b/neonView/OrganisationFilter_view/OrganisationFilter_view.aod
index 960c454e103af41d7e9cf5740ae51aec1b1047f5..1cc87b9732a33851587d07a0ca3950c4d1c8d8c1 100644
--- a/neonView/OrganisationFilter_view/OrganisationFilter_view.aod
+++ b/neonView/OrganisationFilter_view/OrganisationFilter_view.aod
@@ -134,5 +134,18 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChart</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>52be5c1a-4e19-4f03-862b-a9d68e15778f</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/PermissionCalendarFilterDrawer_view/PermissionCalendarFilterDrawer_view.aod b/neonView/PermissionCalendarFilterDrawer_view/PermissionCalendarFilterDrawer_view.aod
index 32b319f4445dd4838b972b11db7c6193c7833b35..bea5b5d3b4c83c14236e3e3ee1164389370c87fd 100644
--- a/neonView/PermissionCalendarFilterDrawer_view/PermissionCalendarFilterDrawer_view.aod
+++ b/neonView/PermissionCalendarFilterDrawer_view/PermissionCalendarFilterDrawer_view.aod
@@ -5,7 +5,7 @@
   <layout>
     <drawerLayout>
       <name>layout</name>
-      <layoutCaption>of other on this employee's calendar</layoutCaption>
+      <layoutCaption>Permission received</layoutCaption>
       <fixedDrawer v="true" />
     </drawerLayout>
   </layout>
diff --git a/neonView/PermissionCalendarFilterReverse_view/PermissionCalendarFilterReverse_view.aod b/neonView/PermissionCalendarFilterReverse_view/PermissionCalendarFilterReverse_view.aod
index df480a219c345fe0847a2ebdf5c5f62479108e60..ae077ac28d6a0d93a8073361d0467f7abc3a6478 100644
--- a/neonView/PermissionCalendarFilterReverse_view/PermissionCalendarFilterReverse_view.aod
+++ b/neonView/PermissionCalendarFilterReverse_view/PermissionCalendarFilterReverse_view.aod
@@ -7,12 +7,14 @@
   <layout>
     <drawerLayout>
       <name>layout</name>
-      <layoutCaption>of this employee on the calendar of others</layoutCaption>
+      <layoutCaption>granted permission</layoutCaption>
+      <fixedDrawer v="true" />
     </drawerLayout>
   </layout>
   <children>
     <tableViewTemplate>
       <name>PermissionCalendarFilterReverseTable</name>
+      <favoriteActionGroup1>AddReverseAction</favoriteActionGroup1>
       <entityField>#ENTITY</entityField>
       <isCreatable v="false" />
       <isDeletable v="false" />
diff --git a/neonView/PersonFilter_view/PersonFilter_view.aod b/neonView/PersonFilter_view/PersonFilter_view.aod
index 3de6433f11f0721a7a9d21644f7201c33dd0c364..8eaea8f8294ba09c4a94f70dc4b0930a20357b0c 100644
--- a/neonView/PersonFilter_view/PersonFilter_view.aod
+++ b/neonView/PersonFilter_view/PersonFilter_view.aod
@@ -148,5 +148,18 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChart</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>79379ca4-70f2-40c9-8af2-05cbe26e8916</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/ProductFilter_view/ProductFilter_view.aod b/neonView/ProductFilter_view/ProductFilter_view.aod
index 3f86ddd7ed38a5909124edfb0004546921b8305e..87133854a0bf04645764e64768e6037d069b48b9 100644
--- a/neonView/ProductFilter_view/ProductFilter_view.aod
+++ b/neonView/ProductFilter_view/ProductFilter_view.aod
@@ -117,5 +117,18 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChart</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>8e435e30-bd06-4172-81ea-4cd40cb835f2</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/SalesprojectFilter_view/SalesprojectFilter_view.aod b/neonView/SalesprojectFilter_view/SalesprojectFilter_view.aod
index 920128f5ff6cb8f4bb2f8378f524c6b4528e3240..6bfac93548e2b901c3d7952818fa6d21bb0c987a 100644
--- a/neonView/SalesprojectFilter_view/SalesprojectFilter_view.aod
+++ b/neonView/SalesprojectFilter_view/SalesprojectFilter_view.aod
@@ -136,5 +136,18 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChart</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>170e3be6-41e5-4e75-b772-a97312e83268</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/SupportTicketFilter_view/SupportTicketFilter_view.aod b/neonView/SupportTicketFilter_view/SupportTicketFilter_view.aod
index ed3af83d74e6237cd4298704707bde0e2f485502..f233e247a8ea243775ec164648f5d61952f791fd 100644
--- a/neonView/SupportTicketFilter_view/SupportTicketFilter_view.aod
+++ b/neonView/SupportTicketFilter_view/SupportTicketFilter_view.aod
@@ -139,5 +139,18 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChart</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>43e0d3fc-2556-4da9-985f-f46919755ebf</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/TaskFilter_view/TaskFilter_view.aod b/neonView/TaskFilter_view/TaskFilter_view.aod
index 83268457a49e851f0329c787d3b4e498adb9a620..e42baf0ab3dbc846a09889295e65fd2bf9e2df07 100644
--- a/neonView/TaskFilter_view/TaskFilter_view.aod
+++ b/neonView/TaskFilter_view/TaskFilter_view.aod
@@ -135,5 +135,18 @@
         </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
+    <dynamicMultiDataChartViewTemplate>
+      <name>DynamicMultiDataChart</name>
+      <chartType>COLUMN</chartType>
+      <yAxisLabel>Count</yAxisLabel>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonDynamicMultiDataChartColumn>
+          <name>aad9359c-9d5c-480e-9671-68933a08d615</name>
+          <entityField>COUNT</entityField>
+          <aggregateEntityField>COUNT_aggregate</aggregateEntityField>
+        </neonDynamicMultiDataChartColumn>
+      </columns>
+    </dynamicMultiDataChartViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/WorkflowDefinitionFilter_view/WorkflowDefinitionFilter_view.aod b/neonView/WorkflowDefinitionFilter_view/WorkflowDefinitionFilter_view.aod
index a4e33a131b80ffae09321355f1d9a5f6e4d9f621..41ffef96290756599469bfd2da5878612c27a6d2 100644
--- a/neonView/WorkflowDefinitionFilter_view/WorkflowDefinitionFilter_view.aod
+++ b/neonView/WorkflowDefinitionFilter_view/WorkflowDefinitionFilter_view.aod
@@ -9,32 +9,6 @@
     </groupLayout>
   </layout>
   <children>
-    <tableViewTemplate>
-      <name>Table</name>
-      <favoriteActionGroup1>tableActions</favoriteActionGroup1>
-      <entityField>#ENTITY</entityField>
-      <linkedColumns>
-        <element>NAME</element>
-      </linkedColumns>
-      <columns>
-        <neonTableColumn>
-          <name>6a40b78d-422e-4b3f-9d94-c330cf51996d</name>
-          <entityField>NAME</entityField>
-        </neonTableColumn>
-        <neonTableColumn>
-          <name>5d90aabb-74a9-40f2-bb57-6bf9e5302ed3</name>
-          <entityField>CATEGORY</entityField>
-        </neonTableColumn>
-        <neonTableColumn>
-          <name>faf08eb7-7076-4872-975d-c38a399a1b98</name>
-          <entityField>VERSION</entityField>
-        </neonTableColumn>
-        <neonTableColumn>
-          <name>1e1ed75f-a1de-4abb-b81e-6033de520f32</name>
-          <entityField>ISACTIVE</entityField>
-        </neonTableColumn>
-      </columns>
-    </tableViewTemplate>
     <tilesViewTemplate>
       <name>Tiles</name>
       <iconField>DIAGRAM</iconField>
@@ -42,6 +16,7 @@
       <subtitleField>KEY</subtitleField>
       <descriptionField>DESCRIPTION</descriptionField>
       <infoTopField>VERSION_TITLE</infoTopField>
+      <infoBottomField>CATEGORY</infoBottomField>
       <favoriteActionGroup1>tableActions</favoriteActionGroup1>
       <entityField>#ENTITY</entityField>
       <isCreatable v="true" />
diff --git a/neonView/WorkflowDefinitionPreview_view/WorkflowDefinitionPreview_view.aod b/neonView/WorkflowDefinitionPreview_view/WorkflowDefinitionPreview_view.aod
index de087d4217ef8d9c72ab6850fff3f142e215cb04..4b0e3f5af68d91af8afee1ca6aeebdae57f21584 100644
--- a/neonView/WorkflowDefinitionPreview_view/WorkflowDefinitionPreview_view.aod
+++ b/neonView/WorkflowDefinitionPreview_view/WorkflowDefinitionPreview_view.aod
@@ -35,6 +35,10 @@
           <name>9ae7bada-afb2-48d4-9aa0-b2bd5bd17379</name>
           <entityField>ISACTIVE</entityField>
         </entityFieldLink>
+        <entityFieldLink>
+          <name>f5a0addd-becc-4c4f-b381-65612127acaf</name>
+          <entityField>CATEGORY</entityField>
+        </entityFieldLink>
         <entityFieldLink>
           <name>6b06cf99-37b1-4901-a502-81bb590faa92</name>
           <entityField>DESCRIPTION</entityField>
diff --git a/process/Address_lib/process.js b/process/Address_lib/process.js
index d68036c8e52c9e9d3b2248892b57a104eced03bb..ecd34ddbbcc7821e3781a340ba8e55588bfcb4ea 100644
--- a/process/Address_lib/process.js
+++ b/process/Address_lib/process.js
@@ -168,12 +168,12 @@ function fetchAddressData( pCondition, pConfig, AddressID, pPerson)
                 case Placeholder.types.SQLPART: //sql part
                     fields.push( pConfig[i].valueDefinition ); 
                     output.push([pos++, pConfig[i].type]);
-                    header.push( pConfig[i].placeholderName );
+                    header.push( pConfig[i].getFormattedName() );
                     break;
                 case Placeholder.types.SQLPARTFUNCTION: // adito SQL functions
                     fields.push("(" + pConfig[i].valueDefinition.call() + ")");
                     output.push([pos++, pConfig[i].type]);
-                    header.push( pConfig[i].placeholderName );
+                    header.push( pConfig[i].getFormattedName() );
                     break;
                 case Placeholder.types.ADDRESSFORMAT:
                     if ( posaddrfields == -1 )
@@ -184,7 +184,7 @@ function fetchAddressData( pCondition, pConfig, AddressID, pPerson)
                         pos += addrfields.length;								
                     }
                     output.push([posaddrfields, pConfig[i].type, pConfig[i].valueDefinition]);
-                    header.push( pConfig[i].placeholderName );
+                    header.push( pConfig[i].getFormattedName() );
                     break;
                     
                 case "afunction": // adito functions
@@ -192,7 +192,7 @@ function fetchAddressData( pCondition, pConfig, AddressID, pPerson)
                     {
                         fields.push( "'" + evalScript("Address_lib.fetchAddressData", vars.resolveVariables(pConfig[i].valueDefinition), {}, ["Attribute_lib", "Sql_lib", "Keyword_lib", "Person_lib"], true).replace(new RegExp("'","g"), "''") + "'" ); 
                         output.push([pos++, pConfig[i].type]);
-                        header.push( pConfig[i].placeholderName );
+                        header.push( pConfig[i].getFormattedName() );
                     }
                     catch( err )
                     {                      
@@ -209,7 +209,7 @@ function fetchAddressData( pCondition, pConfig, AddressID, pPerson)
                         configJSON.localVars]);
                                     
                     output.push([pos++, pConfig[i].type]);
-                    header.push( pConfig[i].placeholderName );                
+                    header.push( pConfig[i].getFormattedName() );                
                     break;
             }
         }
diff --git a/process/AttributeFilter_lib/process.js b/process/AttributeFilter_lib/process.js
index 5b093fee0e2d95cd7ccb60bf5851513fcc3f7e74..f64477390ffc247d5e6fd9768f2840dae133c1e1 100644
--- a/process/AttributeFilter_lib/process.js
+++ b/process/AttributeFilter_lib/process.js
@@ -1,3 +1,4 @@
+import("Util_lib");
 import("system.SQLTYPES");
 import("system.translate");
 import("Entity_lib");
diff --git a/process/DocumentTemplate_lib/DocumentTemplate_lib.aod b/process/DocumentTemplate_lib/DocumentTemplate_lib.aod
index 9f4fede55f117c4fea142e84087e26eb4bd91be1..f7dede09487b8661444e1673ef88ecca8b415c21 100644
--- a/process/DocumentTemplate_lib/DocumentTemplate_lib.aod
+++ b/process/DocumentTemplate_lib/DocumentTemplate_lib.aod
@@ -2,6 +2,7 @@
 <process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1">
   <name>DocumentTemplate_lib</name>
   <majorModelMode>DISTRIBUTED</majorModelMode>
+  <documentation>%aditoprj%/process/DocumentTemplate_lib/documentation.adoc</documentation>
   <process>%aditoprj%/process/DocumentTemplate_lib/process.js</process>
   <variants>
     <element>LIBRARY</element>
diff --git a/process/DocumentTemplate_lib/documentation.adoc b/process/DocumentTemplate_lib/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..547a9f00eb224a20d88876f161c2f94cc8088230
--- /dev/null
+++ b/process/DocumentTemplate_lib/documentation.adoc
@@ -0,0 +1,76 @@
+= DocumentTemplate
+
+This document explains the functions of the class `DocumentTemplate` and how to use it. Note that it does not cover every single method with the respective parameters in detail.
+
+== Introduction
+
+A DocumentTemplate is a template for generating individualized documents by filling the placeholders inside the template with data. It supports the following file types and formats:
+
+* txt
+* html
+* eml
+* odt
+* docx
+* docm
+* simple strings
+
+== Usage
+
+=== Creating a new DocumentTemplate instance
+
+The most basic way to create a DocumentTemplate is by simply using the constructor, for example:
+[source,js]
+----
+var myTemplate = new DocumentTemplate(myEncodedHtml, DocumentTemplate.types.HTML);
+----
+
+The parameters `pTemplateContent` and `pType` are mandatory, the others are not required for every use case. A new instance of DocumentTemplate can also be created by using these static functions for special situations:
+
+* *DocumentTemplate.fromUpload:* Constructs a template from the given FileUpload object.
+* *DocumentTemplate.loadTemplate:* Creates a template from a document stored in the database.
+
+=== Generating a document and filling placeholders
+
+Placeholders can be replaced by invoking the method `.getReplacedContent`. It only takes one parameter `pReplacements` which has to be an object with the placeholder as keys and the replacement data as values, like this:
+[source,js]
+----
+var replacements = {
+    "{@firstname@}" : "Joseph",
+    "{@lastname@}" : "Juster"
+};
+var myContent = myTemplate.getReplacedContent(replacements);
+----
+
+It's also possible to use contact data with the functions `.getReplacedContentByContactId` (for a single contactId) and `.getReplacedContentByContactIds` (for multiple contactIds at once). If these functions are used, all placeholders defined in the libraries `Placeholder_lib` and `CustomPlaceholder_lib` are available.
+To add extra placeholders that are not necessarily related to the contact, you can put them in the parameter `pAdditionalPlaceholders` which has to be an array of Placeholder objects. For placeholders unrelated to contact data, use these Placeholder types:
+
+* *FIXEDVALUE:* A fixed value that is stored inside the Placeholder object, useful for data that is already available when you define the placeholder (e. g. entity fields).
+* *CALLBACKFUNCTION:* A callback-function inside the Placeholder object that returns the replacement value, it will be called with the contactId as first argument. You can use this type to resolve the placeholder depending on the contactId or to avoid unnecessary code execution because the function will only be called if the placeholder is actually used inside the template.
+
+Here's an example for the usage of `pAdditionalPlaceholders`:
+[source,js]
+----
+var getProductCountFn = function (pContactId)
+{
+    ... //fancy code
+}
+var additionalPlaceholders = [
+    new Placeholder("offercode", Placeholder.types.FIXEDVALUE, vars.get("$field.FullOfferCode")),
+    new Placeholder("productCount", Placeholder.types.CALLBACKFUNCTION, getProductCountFn)
+];
+var myContent = myTemplate.getReplacedContentByContactId(vars.get("$field.CONTACTID"), additionalPlaceholders);
+----
+
+=== Document generation options
+
+Some aspects of the behavior of the document generation can be controlled by setting the `options` property of the DocumentTemplate with `.setOptions`. Available options differ depending on the DocumentTemplate type, that's why the options are wrapped inside an object. These options can currently be used:
+[%header,cols="1,3,2"]
+|===
+| Option | Description | Supported types
+| base64 | Controls if the replaced content will be base64-encoded | txt, html, eml
+| onlyBody | If set to true, only the body of an eml will be used as content | eml
+|===
+
+When a new DocumentTemplate is created, a default set of options will be loaded depending on the type.
+
+//TODO: explain subtemplates, serial letters, (bulk-)emails
\ No newline at end of file
diff --git a/process/DocumentTemplate_lib/process.js b/process/DocumentTemplate_lib/process.js
index 9cbc66c99ce755589192d6344665089148258adc..4ced5f9f03a66cdd93fd5b3836ab474107fa8017 100644
--- a/process/DocumentTemplate_lib/process.js
+++ b/process/DocumentTemplate_lib/process.js
@@ -269,9 +269,13 @@ DocumentTemplate.types = {
                 return {
                     base64 : false
                 };
-            case this.ODT:
             case this.DOCX:
             case this.DOCM:
+                return {
+                    startDelimiter : "{@",
+                    endDelimiter : "@}"
+                };
+            case this.ODT:
             default:
                 return {};
         }
@@ -613,7 +617,7 @@ DocumentTemplate.prototype._getRequiredPlaceholders = function (pForcedPlacehold
     // filter the possible placeholders by all placeholders found
     placeholders = placeholders.filter(function(placeholder)
     {
-        return foundPlaceholders.includes(placeholder.placeholderName) || pForcedPlaceholders.includes(placeholder.placeholderName);
+        return foundPlaceholders.includes(placeholder.getFormattedName()) || pForcedPlaceholders.includes(placeholder.getFormattedName());
     });
     
     return placeholders;
@@ -644,7 +648,7 @@ DocumentTemplate.prototype.getReplacementsByContactIds = function (pContactIds,
                 break;
             case Placeholder.types.FIXEDVALUE:
             case Placeholder.types.CALLBACKFUNCTION:
-                additionalPlaceholders[placeholder.placeholderName] = placeholder;
+                additionalPlaceholders[placeholder.getFormattedName()] = placeholder;
         }
     });
     var contactIdPlaceholder = new Placeholder("contactId", Placeholder.types.SQLPART, "CONTACT.CONTACTID");
@@ -818,10 +822,12 @@ DocumentTemplate.prototype._getReplacedODT = function (pReplacements, pTableData
 DocumentTemplate.prototype._getReplacedDOCX = function (pReplacements)
 {
     var replacements = {};
+    var startDelimiter = this.options.startDelimiter;
+    var endDelimiter = this.options.endDelimiter;
     for (let placeholder in pReplacements)  //removes the prefix and postfix, the process needs it like this
-        replacements[placeholder.slice(2, -2)] = pReplacements[placeholder];
+        replacements[placeholder.slice(startDelimiter.length, -endDelimiter.length)] = pReplacements[placeholder];
 
-    var documentData = DocxtemplaterUtils.generateDocument(this.content, replacements, "{@", "@}");
+    var documentData = DocxtemplaterUtils.generateDocument(this.content, replacements, startDelimiter, endDelimiter);
     
     return documentData;
 }
diff --git a/process/ExportTemplate_lib/process.js b/process/ExportTemplate_lib/process.js
index 0272a91c61e87df64f2112201d4bc984e941bcd8..a8c09911551c8dfd933e082febebfac8d3a25dd3 100644
--- a/process/ExportTemplate_lib/process.js
+++ b/process/ExportTemplate_lib/process.js
@@ -71,7 +71,7 @@ ExportTemplateUtils.buildExport = function (pExportTemplateId, pSelection, pComi
     var affectedPlaceholders = [];
     for (var i = 0; i < fields.length; i++) {
             var placeholderField = placeholders.find(function(placeholder){
-                return placeholder.placeholderName == fields[i];
+                return placeholder.getFormattedName() == fields[i];
             })
             if(placeholderField)
                 affectedPlaceholders.push(placeholderField);
diff --git a/process/ImporterMappingFunctions_lib/process.js b/process/ImporterMappingFunctions_lib/process.js
index a5746a0276df1bc7963975598a51395c10e741b1..27a4b5725fbfc5be68e9d42c5a498c3d132d8a25 100644
--- a/process/ImporterMappingFunctions_lib/process.js
+++ b/process/ImporterMappingFunctions_lib/process.js
@@ -145,7 +145,7 @@ function iAttribute(pObject)
                 var parent = "NULL";
                 // select ab_attributeid from AB_ATTRIBUTE where ATTRIBUTE_NAME = 'Subordinate campaign of' and attribute_parent_id is null
                 id = newSelect(ab_attributeId, alias).from(ab_attribute).where(attribute_name, attributes[i])
-                        .and(attribute_parent_id + "is null").cell();
+                        .and(attribute_parent_id + " is null").cell();
             } 
             else 
             {
diff --git a/process/JditoFilter_lib/process.js b/process/JditoFilter_lib/process.js
index 9e6137b3ebbc088ec3a49495ac7a8b138cd5c7bd..b318e287639603ed313d77088be28239a1b7a6e1 100644
--- a/process/JditoFilter_lib/process.js
+++ b/process/JditoFilter_lib/process.js
@@ -1,6 +1,7 @@
 import("system.tools");
 import("system.logging");
 import("Sql_lib");
+import("system.datetime");
 
 /**
  * object for filtering records
@@ -117,6 +118,8 @@ JditoFilter.prototype.checkRecord = function (pRow)
             case "TIMEFRAME_EQUAL":
             case "TIMEFRAME_COMING":
             case "TIMEFRAME_PAST":
+                var [start, end] = datetime.resolveRelativeDateExpression(pFilterValue);
+                return pRowValue >= start && pRowValue <= end;
         }
     }
 }
@@ -211,16 +214,163 @@ JditoFilterUtils.filterRecords = function (pColumns, pRecords, pFilter, pCustomC
  */
 JditoFilterUtils.getSqlCondition = function (pFilter, pTable, pTableAlias, pColumnOrFnMap)
 {
-    var condition = newWhere();
+    var filterTranslator = new FilterSqlTranslator(pFilter)
+        .table(pTable, pTableAlias);
     
-    var ignoreCase = JditoFilterUtils.isUserIgnoreCase();
-    
-    if (!pFilter)
+    if (pColumnOrFnMap)
+    {
+        for (let fieldName in pColumnOrFnMap)
+        {
+            var columnOrFn = pColumnOrFnMap[fieldName];
+            if (typeof columnOrFn === "function")
+                filterTranslator.addSpecialFieldConditionFn(fieldName, columnOrFn);
+            else
+                filterTranslator.addSqlFieldMapping(fieldName, columnOrFn);
+        }
+    }
+    return filterTranslator.getSqlCondition();
+}
+
+/**
+ * @return {boolean} the selectionIgnoreCase property of the current user, defaults to true
+ */
+JditoFilterUtils.isUserIgnoreCase = function ()
+{
+    var user = tools.getCurrentUser();
+    var ignoreCase = user ? user[tools.PARAMS][tools.SELECTION_IGNORECASE] : "";
+    return ignoreCase == "" || /true/i.test(ignoreCase);
+}
+
+/**
+ * Object for translating a filter object to a sql condition.
+ * 
+ * @param {Object} pFilter the filter object that should be used
+ * @param {String} pTable the database table to build the condition for
+ */
+function FilterSqlTranslator (pFilter, pTable)
+{
+    this._filter = null;
+    this.filter(pFilter);
+    this._table = pTable;
+    this._tableAlias = null;
+    this._dbAlias = null;
+    this._sqlFieldMappings = {};
+    this._fieldConditionFns = {};
+    this._ignoreCase = JditoFilterUtils.isUserIgnoreCase();
+}
+
+/**
+ * Sets the filter of the object
+ * 
+ * @param {Object} pFilter the filter object that should be used
+ * @return {FilterSqlTranslator} current object
+ */
+FilterSqlTranslator.prototype.filter = function (pFilter)
+{
+    if (pFilter)
+    {
+        if (typeof pFilter !== "object")
+            throw new TypeError("FilterSqlTranslator: Wrong type for the filter, expected 'object' but got '" + (typeof pFilter) + "'");
+        this._filter = pFilter.filter || pFilter;
+    }
+    return this;
+}
+
+/**
+ * Sets the filter of the object
+ * 
+ * @param {String} pFilter the filter object that should be used as JSON string
+ * @return {FilterSqlTranslator} current object
+ */
+FilterSqlTranslator.prototype.filterJSON = function (pFilter)
+{
+    return this.filter(JSON.parse(pFilter));
+}
+
+/**
+ * Sets the table of the object
+ * 
+ * @param {String} pTable the database table to build the condition for
+ * @param {String} [pTableAlias] the alias of the table
+ * @return {FilterSqlTranslator} current object
+ */
+FilterSqlTranslator.prototype.table = function (pTable, pTableAlias)
+{
+    this._table = pTable;
+    if (pTableAlias)
+        this._tableAlias = pTableAlias;
+    return this;
+}
+
+/**
+ * Adds a special database field mapping for the given field that will be used for the sql condition
+ * 
+ * @param {String} pFieldName the field name
+ * @param {String|String[]} the database field ("TABLE.COLUMN" or ["TABLE", "COLUMN", "alias"])
+ * @return {FilterSqlTranslator} current object
+ */
+FilterSqlTranslator.prototype.addSqlFieldMapping = function (pFieldName, pDBField)
+{
+    this._sqlFieldMappings[pFieldName] = pDBField;
+    return this;
+}
+
+/**
+ * Adds a special function for building the condition for the given field. The function must return a sql condition (SqlBuilder or String)
+ * 
+ * @param {String} pFieldName the field name
+ * @param {Function} pConditionFn a function that generates the condition
+ * @return {FilterSqlTranslator} current object
+ */
+FilterSqlTranslator.prototype.addSpecialFieldConditionFn = function (pFieldName, pConditionFn)
+{
+    this._fieldConditionFns[pFieldName] = pConditionFn;
+    return this;
+}
+
+/**
+ * Sets the database alias
+ * 
+ * @param {String} pAlias the alias to be used
+ * @return {FilterSqlTranslator} current object
+ */
+FilterSqlTranslator.prototype.dbAlias = function (pAlias)
+{
+    this._dbAlias = pAlias;
+    return this;
+}
+
+/**
+ * Changes whether the condition should be case-insensitive for text
+ * 
+ * @param {boolean} [pIgnoreCase=true] if it should be case-insensitive
+ * @return {FilterSqlTranslator} current object
+ */
+FilterSqlTranslator.prototype.ignoreCase = function (pIgnoreCase)
+{
+    //"", 0 , false -> false, everything else is considered true
+    this._ignoreCase = pIgnoreCase != false;
+    return this;
+}
+
+/**
+ * Builds the sql condition from the filter
+ * 
+ * @return {SqlBuilder} the sql condition
+ */
+FilterSqlTranslator.prototype.getSqlCondition = function ()
+{
+    var condition = new SqlBuilder(this._dbAlias).where();
+    if (!this._filter)
         return condition;
-    if (!pColumnOrFnMap)
-        pColumnOrFnMap = {};
     
-    _addCondition.call(condition, pFilter, pFilter.operator);
+    var table = this._table;
+    var tableAlias = this._tableAlias;
+    var ignoreCase = this._ignoreCase;
+    var sqlFieldMappings = this._sqlFieldMappings;
+    var fieldConditionFns = this._fieldConditionFns;
+    
+    _addCondition.call(condition, this._filter, this._filter.operator);
     
     return condition;
     
@@ -230,47 +380,61 @@ JditoFilterUtils.getSqlCondition = function (pFilter, pTable, pTableAlias, pColu
     {
         if (pFilter.type == "row")
         {
-            if (pFilter.name in pColumnOrFnMap)
+            var sqlField, condition;
+            var filterValue = (pFilter.key || pFilter.value);
+            if (pFilter.name in fieldConditionFns)
             {
-                pFilter.name = pColumnOrFnMap[pFilter.name];
+                var conditionFn = fieldConditionFns[pFilter.name];
+                
+                condition = conditionFn.call(null, filterValue, pFilter.operator);
+                if (pOperator == "AND")
+                    this.andIfSet(condition);
+                else if (pOperator == "OR")
+                    this.orIfSet(condition);
+                
+                return;
+            }
+            
+            if (pFilter.name in sqlFieldMappings)
+            {
+                sqlField = sqlFieldMappings[sqlField];
                 
                 //possibility to explicitly set the value to null/false so that the field is ignored
-                if (pFilter.name === null || pFilter.name === false)
+                if (sqlField === null || sqlField === false)
                     return;
             }
-            else if (pTable && pTableAlias)
-                pFilter.name = [pTable, pFilter.name, pTableAlias];
-            else if (pTable)
-                pFilter.name = pTable + "." + pFilter.name;
-            
-            pFilter.value = (pFilter.key || pFilter.value);
+            else if (table && tableAlias)
+                sqlField = [table, pFilter.name, tableAlias];
+            else if (table)
+                sqlField = table + "." + pFilter.name;
             
-            var condition;
-            if (typeof(pFilter.name) === "function")
+            var generatedCondition = _getCondition(filterValue, pFilter.operator, sqlField);
+            if (generatedCondition instanceof SqlBuilder || typeof generatedCondition === "string")
             {
-                condition = pFilter.name.call(null, pFilter.value, pFilter.operator);
                 if (pOperator == "AND")
-                    this.andIfSet(condition);
+                    this.andIfSet(generatedCondition);
                 else if (pOperator == "OR")
-                    this.orIfSet(condition);
+                    this.orIfSet(generatedCondition);
             }
             else
             {
-                let isStringType, filterValue;
-                [condition, filterValue, isStringType] = _getCondition(pFilter.value, pFilter.operator);
+                var isStringType = pFilter.contenttype != "NUMBER" 
+                    && pFilter.contenttype != "DATE" 
+                    && pFilter.contenttype != "BOOLEAN";
+                [condition, filterValue] = generatedCondition;
                 if (isStringType && ignoreCase)
                     condition = condition.replace("#", "UPPER(#)").replace("?", "UPPER(?)");
-                
+
                 if (pOperator == "AND")
-                    this.andIfSet(pFilter.name, filterValue, condition);
+                    this.andIfSet(sqlField, filterValue, condition);
                 else if (pOperator == "OR")
-                    this.orIfSet(pFilter.name, filterValue, condition);
+                    this.orIfSet(sqlField, filterValue, condition);
             }
         }
         else if (pFilter.type == "group")
         {
-            let subCondition = newWhere();
-            let operator = pFilter.operator;
+            var subCondition = newWhere();
+            var operator = pFilter.operator;
             pFilter.childs.forEach(function (cond)
             {
                 _addCondition.call(subCondition, cond, operator);
@@ -282,45 +446,41 @@ JditoFilterUtils.getSqlCondition = function (pFilter, pTable, pTableAlias, pColu
         }
     }
     
-    //returns [condition, value with wildcards, is a string type] depending on the operator
-    function _getCondition (pValue, pOperator)
+    //returns [condition, value with wildcards] depending on the operator
+    function _getCondition (pValue, pOperator, pField)
     {
         switch (pOperator)
         {
             case "CONTAINS":
-                return [SqlBuilder.LIKE(), "%" + pValue + "%", true];
+                return [SqlBuilder.LIKE(), "%" + pValue + "%"];
             case "CONTAINSNOT":
-                return [SqlBuilder.NOT_LIKE(), "%" + pValue + "%", true];
+                return [SqlBuilder.NOT_LIKE(), "%" + pValue + "%"];
             case "STARTSWITH":
-                return [SqlBuilder.LIKE(), pValue + "%", true];
+                return [SqlBuilder.LIKE(), pValue + "%"];
             case "ENDSWITH":
-                return [SqlBuilder.LIKE(), "%" + pValue, true];
+                return [SqlBuilder.LIKE(), "%" + pValue];
             case "EQUAL":
-                return [SqlBuilder.EQUAL(), pValue, true];
+                return [SqlBuilder.EQUAL(), pValue];
             case "NOT_EQUAL":
-                return [SqlBuilder.NOT_EQUAL(), pValue, true];
+                return [SqlBuilder.NOT_EQUAL(), pValue];
             case "LESS":
-                return [SqlBuilder.LESS(), pValue, false];
+                return [SqlBuilder.LESS(), pValue];
             case "LESS_OR_EQUAL":
-                return [SqlBuilder.LESS_OR_EQUAL(), pValue, false];
+                return [SqlBuilder.LESS_OR_EQUAL(), pValue];
             case "GREATER":
-                return [SqlBuilder.GREATER(), pValue, false];
+                return [SqlBuilder.GREATER(), pValue];
             case "GREATER_OR_EQUAL":
-                return [SqlBuilder.GREATER_OR_EQUAL(), pValue, false];
+                return [SqlBuilder.GREATER_OR_EQUAL(), pValue];
             case "ISNULL":
-                return ["# is null", pValue, false];
+                return pField + " is null";
             case "ISNOTNULL":
-                return ["# is not null", pValue, false];
+                return pField + " is not null";
+            case "TIMEFRAME_EQUAL":
+            case "TIMEFRAME_COMING":
+            case "TIMEFRAME_PAST":
+                var [start, end] = datetime.resolveRelativeDateExpression(pValue);
+                return newWhere(pField, start, SqlBuilder.GREATER_OR_EQUAL())
+                    .and(pField, end, SqlBuilder.LESS_OR_EQUAL());
         }
     }
-}
-
-/**
- * @return {boolean} the selectionIgnoreCase property of the current user, defaults to true
- */
-JditoFilterUtils.isUserIgnoreCase = function ()
-{
-    var user = tools.getCurrentUser();
-    var ignoreCase = user ? user[tools.PARAMS][tools.SELECTION_IGNORECASE] : "";
-    return ignoreCase == "" || /true/i.test(ignoreCase);
-}
+}
\ No newline at end of file
diff --git a/process/KeywordRegistry_basic/process.js b/process/KeywordRegistry_basic/process.js
index b53349181660fe4f0829d5fa6f8b7e03e755f735..2ae7c40b6e90dc3d207d4441cbeb3abeadfd128c 100644
--- a/process/KeywordRegistry_basic/process.js
+++ b/process/KeywordRegistry_basic/process.js
@@ -284,4 +284,6 @@ $KeywordRegistry.visitPlanEntryStatus$Visitreportcreated = function(){return $Ke
 
 $KeywordRegistry.visitRecommendationPrioSource = function(){return $KeywordRegistry._autoPad("VisitRecommendationPrioSource");};
 $KeywordRegistry.visitRecommendationPrioSource$visitFrequency = function(){return $KeywordRegistry._autoPad("VISITFREQUENCY");};
-$KeywordRegistry.visitRecommendationPrioSource$manual = function(){return $KeywordRegistry._autoPad("MANUAL");};
\ No newline at end of file
+$KeywordRegistry.visitRecommendationPrioSource$manual = function(){return $KeywordRegistry._autoPad("MANUAL");};
+
+$KeywordRegistry.workflowCategory = function(){return "WorkflowCategory";};
\ No newline at end of file
diff --git a/process/Placeholder_lib/process.js b/process/Placeholder_lib/process.js
index 7a78b088bb1a38a3ac3b6566f624743c07839ff2..4f271fa114efc53ff3bb909ea0d4692436e8cead 100644
--- a/process/Placeholder_lib/process.js
+++ b/process/Placeholder_lib/process.js
@@ -68,7 +68,7 @@ PlaceholderUtils.getPlaceholders = function (pLocale, pIsExportTemplateField)
                 if(placeholders[i]["target"] != "RECIPIENT"){
                     placeholders.splice(i, 1);
                     i--}
-                else if(placeholders[i]["placeholderName"] == "{@letterSalutation@}"){
+                else if(placeholders[i].getFormattedName() == "{@letterSalutation@}"){
                     placeholders.splice(i, 1);
                      i--}
             }
@@ -106,11 +106,12 @@ PlaceholderUtils.getPlaceholders = function (pLocale, pIsExportTemplateField)
 
 /**
  * Returns the placeholder with the required prefix and postfix added.
- * This function defines the format for placeholders.
+ * 
+ * @deprecated
  */
 PlaceholderUtils.formatPlaceholder = function (pPlaceholder)
 {
-    return "{@" + pPlaceholder + "@}";
+    return Placeholder.getDefaultStartDelimiter() + pPlaceholder + Placeholder.getDefaultEndDelimiter();
 }
 
 /**
@@ -136,16 +137,42 @@ PlaceholderUtils.getRegexpMatchAll = function ()
  */
 function Placeholder (pName, pType, pValueDef, pTarget, pTitle) 
 {
-    this.placeholderName = PlaceholderUtils.formatPlaceholder(pName);
+    this.startDelimiter = Placeholder.getDefaultStartDelimiter();
+    this.endDelimiter = Placeholder.getDefaultEndDelimiter();
+    this.placeholderName = pName;
     this.type = pType;
     this.target = pTarget || Placeholder.targets.RECIPIENT;
     this.valueDefinition = pValueDef;
     this.title = pTitle;
 }
 
+/**
+ * Returns the default placeholder start delimiter
+ */
+Placeholder.getDefaultStartDelimiter = function ()
+{
+    return "{@";
+}
+
+/**
+ * Returns the default placeholder end delimiter
+ */
+Placeholder.getDefaultEndDelimiter = function ()
+{
+    return "@}";
+}
+
+/**
+ * Returns the placeholderName with startDelimiter and endDelimiter added
+ */
+Placeholder.prototype.getFormattedName = function ()
+{
+    return this.startDelimiter + this.placeholderName + this.endDelimiter;
+}
+
 Placeholder.prototype.toString = function ()
 {
-    return this.placeholderName;
+    return this.getFormattedName();
 }
 
 /**