diff --git a/aliasDefinition/Data_alias/Data_alias.aod b/aliasDefinition/Data_alias/Data_alias.aod
index 96ba3a06d998e071c415c896b6daf07a6adfe95d..74732716d5e430f8c74b65ff3a4cc7c19547b7fa 100644
--- a/aliasDefinition/Data_alias/Data_alias.aod
+++ b/aliasDefinition/Data_alias/Data_alias.aod
@@ -4416,8 +4416,8 @@
                 <name>TYPE</name>
                 <dbName></dbName>
                 <primaryKey v="false" />
-                <columnType v="12" />
-                <size v="100" />
+                <columnType v="1" />
+                <size v="36" />
                 <scale v="0" />
                 <notNull v="true" />
                 <isUnique v="false" />
@@ -4430,8 +4430,8 @@
                 <name>NAME</name>
                 <dbName></dbName>
                 <primaryKey v="false" />
-                <columnType v="1" />
-                <size v="36" />
+                <columnType v="12" />
+                <size v="100" />
                 <scale v="0" />
                 <notNull v="true" />
                 <isUnique v="false" />
@@ -4618,6 +4618,20 @@
                 <title></title>
                 <description></description>
               </entityFieldDb>
+              <entityFieldDb>
+                <name>OBJECT_TITLE</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="12" />
+                <size v="123" />
+                <scale v="0" />
+                <notNull v="true" />
+                <isUnique v="false" />
+                <index v="false" />
+                <documentation></documentation>
+                <title></title>
+                <description></description>
+              </entityFieldDb>
             </entityFields>
           </entityDb>
           <entityDb>
diff --git a/aliasDefinition/Data_alias/indexsearchgroups/pers/affectedIds.js b/aliasDefinition/Data_alias/indexsearchgroups/person/affectedIds.js
similarity index 100%
rename from aliasDefinition/Data_alias/indexsearchgroups/pers/affectedIds.js
rename to aliasDefinition/Data_alias/indexsearchgroups/person/affectedIds.js
diff --git a/aliasDefinition/Data_alias/indexsearchgroups/pers/query.js b/aliasDefinition/Data_alias/indexsearchgroups/person/query.js
similarity index 100%
rename from aliasDefinition/Data_alias/indexsearchgroups/pers/query.js
rename to aliasDefinition/Data_alias/indexsearchgroups/person/query.js
diff --git a/aliasDefinition/Data_alias/indexsearchgroups/pers/subQueries.js b/aliasDefinition/Data_alias/indexsearchgroups/person/subQueries.js
similarity index 100%
rename from aliasDefinition/Data_alias/indexsearchgroups/pers/subQueries.js
rename to aliasDefinition/Data_alias/indexsearchgroups/person/subQueries.js
diff --git a/entity/ActivityLink_entity/recordcontainers/db/conditionProcess.js b/entity/ActivityLink_entity/recordcontainers/db/conditionProcess.js
index d297c7d58bc7596a7d53b5f28fe72c5c1c5d8695..af5991c0cd552dd6b51fe8b99cf7e95139c84c5f 100644
--- a/entity/ActivityLink_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/ActivityLink_entity/recordcontainers/db/conditionProcess.js
@@ -6,5 +6,5 @@ var cond = SqlCondition.begin()
                        .andPrepareVars("ACTIVITYLINK.OBJECT_ROWID", "$param.ObjectRowid_param")
                        .andPrepareVars("ACTIVITYLINK.OBJECT_TYPE", "$param.ObjectType_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/Activity_entity/recordcontainers/db/conditionProcess.js b/entity/Activity_entity/recordcontainers/db/conditionProcess.js
index 42b0bbbe10f5a743361ccfa2e425f8fc5876b24b..f8ca95a041f3a052a2e375692dcaa0bdf90d52f3 100644
--- a/entity/Activity_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/Activity_entity/recordcontainers/db/conditionProcess.js
@@ -16,6 +16,6 @@ if(vars.exists("$param.OnlyInnate_param") && vars.get("$param.OnlyInnate_param")
     cond.andPrepare("ACTIVITY.CREATOR", vars.get("$sys.user"));
 }
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 var resCond = db.translateCondition(cond.build("1 = 1"));
 result.string(resCond);
diff --git a/entity/Address_entity/entityfields/country/displayValueProcess.js b/entity/Address_entity/entityfields/country/displayValueProcess.js
index 11851ccdb25e73e6a78bb0a0b2398b730fd3fd37..22c043fdc3d9ab8fbe1e9b67738a0f105ce7aaee 100644
--- a/entity/Address_entity/entityfields/country/displayValueProcess.js
+++ b/entity/Address_entity/entityfields/country/displayValueProcess.js
@@ -4,7 +4,7 @@ import("system.translate");
 import("system.result");
 import("Sql_lib");
 
-//TODO: temporary testing code
+//TODO: temporary testing code -> will be replaced with title-mechanic
 var isoCode = vars.get("$field.COUNTRY");
 var countryName  = db.cell(SqlCondition.begin().andPrepare("AB_COUNTRYINFO.ISO2", isoCode).buildSql("select AB_COUNTRYINFO.NAME_LATIN from AB_COUNTRYINFO"));
 countryName = translate.text(countryName);
diff --git a/entity/Address_entity/entityfields/zip/onValidation.js b/entity/Address_entity/entityfields/zip/onValidation.js
index 59eb04f1cd774a94fb81801ec515a4f40c063565..4ab5fababa786a02ee290896bd38c6b648fb2150 100644
--- a/entity/Address_entity/entityfields/zip/onValidation.js
+++ b/entity/Address_entity/entityfields/zip/onValidation.js
@@ -10,6 +10,6 @@ var zipCode = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.ZIP"));
 var message = "";
 var isValid = AddressValidationUtils.isValidZip(countryCode, zipCode);
 if (!isValid)
-    message = translate.text("ZIP code is not valid");//TODO: better message text
+    message = translate.text("The ZIP code does not match the format of the country.");
     
 result.string(message);
\ No newline at end of file
diff --git a/entity/AppointmentLink_entity/AppointmentLink_entity.aod b/entity/AppointmentLink_entity/AppointmentLink_entity.aod
index 35cdd9cda3f498036eb3b8c6c90c58fe6fbb4277..a8e6a311a32c93247695deb9e7cfc7065588e7d8 100644
--- a/entity/AppointmentLink_entity/AppointmentLink_entity.aod
+++ b/entity/AppointmentLink_entity/AppointmentLink_entity.aod
@@ -41,6 +41,9 @@
         </entityDependency>
       </dependencies>
     </entityProvider>
+    <entityField>
+      <name>OBJECT_TITLE</name>
+    </entityField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -73,6 +76,10 @@
           <name>OBJECTTYPE.value</name>
           <recordfield>APPOINTMENTLINK.OBJECT_TYPE</recordfield>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>OBJECT_TITLE.value</name>
+          <recordfield>APPOINTMENTLINK.OBJECT_TITLE</recordfield>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
     </dbRecordContainer>
   </recordContainers>
diff --git a/entity/AppointmentLink_entity/recordcontainers/db/conditionProcess.js b/entity/AppointmentLink_entity/recordcontainers/db/conditionProcess.js
index d07a6fc35d714eec0cb968234e7cf24d92dae098..c0867f5bcec0beae07f1db2a06ccb6b60cafd98a 100644
--- a/entity/AppointmentLink_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/AppointmentLink_entity/recordcontainers/db/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = SqlCondition.begin()
                        .andPrepareVars("APPOINTMENTLINK.APPOINTMENT_ID", "$param.AppointmentId_param")
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/Appointment_entity/Appointment_entity.aod b/entity/Appointment_entity/Appointment_entity.aod
index b948527decdf19e9d5309e124c45c20da26648e3..b520a06d5a2fe3115b13e638385f45b487fb1413 100644
--- a/entity/Appointment_entity/Appointment_entity.aod
+++ b/entity/Appointment_entity/Appointment_entity.aod
@@ -120,7 +120,10 @@
       <name>ATTENDEESLENGTH</name>
     </entityField>
     <entityField>
-      <name>LINKS</name>
+      <name>LINKOBJECT</name>
+      <title>Linkobject</title>
+      <consumer>Objects</consumer>
+      <linkedContext>Object_context</linkedContext>
     </entityField>
     <entityField>
       <name>ICON</name>
@@ -164,10 +167,32 @@
       <children>
         <entityParameter>
           <name>ContextId_param</name>
+          <code>%aditoprj%/entity/Appointment_entity/entityfields/contexts/children/contextid_param/code.js</code>
           <documentation>%aditoprj%/entity/Appointment_entity/entityfields/contexts/children/contextid_param/documentation.adoc</documentation>
         </entityParameter>
       </children>
     </entityConsumer>
+    <entityConsumer>
+      <name>Objects</name>
+      <fieldType>DEPENDENCY_OUT</fieldType>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Object_entity</entityName>
+        <fieldName>#PROVIDER</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>ObjectType_param</name>
+          <code>%aditoprj%/entity/Appointment_entity/entityfields/objects/children/objecttype_param/code.js</code>
+        </entityParameter>
+      </children>
+    </entityConsumer>
+    <entityField>
+      <name>LINKTYPE</name>
+      <title>Linktype</title>
+      <consumer>Contexts</consumer>
+      <linkedContext>Context_context</linkedContext>
+    </entityField>
   </entityFields>
   <recordContainers>
     <jDitoRecordContainer>
diff --git a/entity/Appointment_entity/entityfields/contexts/children/contextid_param/code.js b/entity/Appointment_entity/entityfields/contexts/children/contextid_param/code.js
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/entity/Appointment_entity/entityfields/objects/children/objecttype_param/code.js b/entity/Appointment_entity/entityfields/objects/children/objecttype_param/code.js
new file mode 100644
index 0000000000000000000000000000000000000000..b37b4f9781b10ac769cee0a23968486bf6532967
--- /dev/null
+++ b/entity/Appointment_entity/entityfields/objects/children/objecttype_param/code.js
@@ -0,0 +1,5 @@
+import("system.vars");
+import("system.result");
+
+
+result.string(vars.get("$field.LINKTYPE"))
\ No newline at end of file
diff --git a/entity/AttributeRelation_entity/AttributeRelation_entity.aod b/entity/AttributeRelation_entity/AttributeRelation_entity.aod
index 8672e15c2837cc586414f877b1588c7294f9eeeb..13a0974c5c644ec17856688a6ce4c8bee90c7854 100644
--- a/entity/AttributeRelation_entity/AttributeRelation_entity.aod
+++ b/entity/AttributeRelation_entity/AttributeRelation_entity.aod
@@ -50,6 +50,12 @@
           <fieldName>Attributes</fieldName>
           <isConsumer v="false" />
         </entityDependency>
+        <entityDependency>
+          <name>236a52d8-830d-4e46-bf9b-7ffaeef25477</name>
+          <entityName>Attribute_entity</entityName>
+          <fieldName>AttributeChildren</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
       </dependencies>
     </entityProvider>
     <entityParameter>
diff --git a/entity/AttributeUsage_entity/AttributeUsage_entity.aod b/entity/AttributeUsage_entity/AttributeUsage_entity.aod
index 04eb720905cfdf1867504834f6567659fad1eff9..9528f03da58191d446ec9514a6dae736045feddd 100644
--- a/entity/AttributeUsage_entity/AttributeUsage_entity.aod
+++ b/entity/AttributeUsage_entity/AttributeUsage_entity.aod
@@ -12,7 +12,7 @@
     <entityField>
       <name>OBJECT_TYPE</name>
       <title>Context</title>
-      <possibleItemsProcess>%aditoprj%/entity/AttributeUsage_entity/entityfields/object_type/possibleItemsProcess.js</possibleItemsProcess>
+      <consumer>Contexts</consumer>
     </entityField>
     <entityField>
       <name>AB_ATTRIBUTEUSAGEID</name>
@@ -55,6 +55,15 @@
       <searchable v="false" />
       <onValidation>%aditoprj%/entity/AttributeUsage_entity/entityfields/max_count/onValidation.js</onValidation>
     </entityField>
+    <entityConsumer>
+      <name>Contexts</name>
+      <fieldType>DEPENDENCY_OUT</fieldType>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Context_entity</entityName>
+        <fieldName>Context</fieldName>
+      </dependency>
+    </entityConsumer>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
diff --git a/entity/AttributeUsage_entity/entityfields/object_type/possibleItemsProcess.js b/entity/AttributeUsage_entity/entityfields/object_type/possibleItemsProcess.js
deleted file mode 100644
index 06faeee0b81dd0551b4d95af48d75a121eac735f..0000000000000000000000000000000000000000
--- a/entity/AttributeUsage_entity/entityfields/object_type/possibleItemsProcess.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import("system.result");
-
-//TODO: when available, use a function to get the possible contexts
-result.object([["Organisation", "Org"]]);
\ No newline at end of file
diff --git a/entity/Attribute_entity/Attribute_entity.aod b/entity/Attribute_entity/Attribute_entity.aod
index e95bbe7da57a4f4285d84a7c2648efc132a85207..78bf584f6a1129b21d805f2e4141b7166ea4a1f4 100644
--- a/entity/Attribute_entity/Attribute_entity.aod
+++ b/entity/Attribute_entity/Attribute_entity.aod
@@ -14,6 +14,7 @@
       <name>ATTRIBUTE_NAME</name>
       <title>Name</title>
       <mandatory v="true" />
+      <displayValueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_name/displayValueProcess.js</displayValueProcess>
     </entityField>
     <entityField>
       <name>ATTRIBUTE_TYPE</name>
@@ -23,26 +24,47 @@
     </entityField>
     <entityField>
       <name>AB_ATTRIBUTEID</name>
-      <searchable v="false" />
       <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/ab_attributeid/valueProcess.js</valueProcess>
     </entityField>
     <entityField>
       <name>ATTRIBUTE_PARENT_ID</name>
       <title>Parent Attribute</title>
+      <consumer>AttributeChildren</consumer>
+      <linkedContext>Attribute_context</linkedContext>
       <groupable v="true" />
+      <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_parent_id/valueProcess.js</valueProcess>
+      <displayValueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_parent_id/displayValueProcess.js</displayValueProcess>
     </entityField>
     <entityConsumer>
       <name>AttributeChildren</name>
+      <title>Attributes</title>
       <fieldType>DEPENDENCY_OUT</fieldType>
       <dependency>
         <name>dependency</name>
-        <fieldName></fieldName>
+        <entityName>Attribute_entity</entityName>
+        <fieldName>AttributeParent</fieldName>
       </dependency>
+      <children>
+        <entityParameter>
+          <name>attrParentId_param</name>
+          <code>%aditoprj%/entity/Attribute_entity/entityfields/attributechildren/children/attrparentid_param/code.js</code>
+          <triggerRecalculation v="true" />
+          <mandatory v="false" />
+        </entityParameter>
+      </children>
     </entityConsumer>
     <entityProvider>
       <name>AttributeParent</name>
       <fieldType>DEPENDENCY_IN</fieldType>
       <recordContainer>db</recordContainer>
+      <dependencies>
+        <entityDependency>
+          <name>18bd148d-bed3-429f-ba54-c5eac76c5083</name>
+          <entityName>Attribute_entity</entityName>
+          <fieldName>AttributeChildren</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
+      </dependencies>
     </entityProvider>
     <entityParameter>
       <name>attrParentId_param</name>
@@ -108,10 +130,6 @@
           <name>AB_ATTRIBUTEID.value</name>
           <recordfield>AB_ATTRIBUTE.AB_ATTRIBUTEID</recordfield>
         </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>ATTRIBUTE_NAME.value</name>
-          <recordfield>AB_ATTRIBUTE.ATTRIBUTE_NAME</recordfield>
-        </dbRecordFieldMapping>
         <dbRecordFieldMapping>
           <name>ATTRIBUTE_PARENT_ID.value</name>
           <recordfield>AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID</recordfield>
@@ -128,6 +146,10 @@
           <name>ATTRIBUTE_TYPE.displayValue</name>
           <expression>%aditoprj%/entity/Attribute_entity/recordcontainers/db/recordfieldmappings/attribute_type.displayvalue/expression.js</expression>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>ATTRIBUTE_NAME.value</name>
+          <recordfield>AB_ATTRIBUTE.ATTRIBUTE_NAME</recordfield>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
     </dbRecordContainer>
   </recordContainers>
diff --git a/entity/Attribute_entity/entityfields/attribute_name/displayValueProcess.js b/entity/Attribute_entity/entityfields/attribute_name/displayValueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..25d46bcaae41773ca9f297c7dbad700b2298a7cc
--- /dev/null
+++ b/entity/Attribute_entity/entityfields/attribute_name/displayValueProcess.js
@@ -0,0 +1,5 @@
+import("system.vars");
+import("system.result");
+import("Attribute_lib");
+
+result.string(AttributeUtil.getAttributeNameById(vars.get("$field.AB_ATTRIBUTEID")));
\ No newline at end of file
diff --git a/entity/Attribute_entity/entityfields/attribute_parent_id/displayValueProcess.js b/entity/Attribute_entity/entityfields/attribute_parent_id/displayValueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f1862b57265475b757e10d636d9f5ae5a31e2f2
--- /dev/null
+++ b/entity/Attribute_entity/entityfields/attribute_parent_id/displayValueProcess.js
@@ -0,0 +1,7 @@
+import("system.neon");
+import("system.result");
+import("system.vars");
+import("Attribute_lib");
+
+if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW && vars.exists("$param.attrParentId_param") && vars.get("$param.attrParentId_param"))
+    result.string(AttributeUtil.getAttributeNameById(vars.get("$param.attrParentId_param")));
diff --git a/entity/Attribute_entity/entityfields/attribute_parent_id/valueProcess.js b/entity/Attribute_entity/entityfields/attribute_parent_id/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..6698c1cd9bf3b2ee1ef19ced286b6f620fe93df2
--- /dev/null
+++ b/entity/Attribute_entity/entityfields/attribute_parent_id/valueProcess.js
@@ -0,0 +1,7 @@
+import("system.neon");
+import("system.logging");
+import("system.result");
+import("system.vars");
+
+if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW && vars.exists("$param.attrParentId_param") && vars.get("$param.attrParentId_param"))
+    result.string(vars.get("$param.attrParentId_param"));
\ No newline at end of file
diff --git a/entity/Attribute_entity/entityfields/attributechildren/children/attrparentid_param/code.js b/entity/Attribute_entity/entityfields/attributechildren/children/attrparentid_param/code.js
new file mode 100644
index 0000000000000000000000000000000000000000..b0b8a8a60f836bf10861191025d415dcd27122b8
--- /dev/null
+++ b/entity/Attribute_entity/entityfields/attributechildren/children/attrparentid_param/code.js
@@ -0,0 +1,4 @@
+import("system.vars");
+import("system.result");
+
+result.string(vars.getString("$field.AB_ATTRIBUTEID"));
\ No newline at end of file
diff --git a/entity/Attribute_entity/recordcontainers/db/conditionProcess.js b/entity/Attribute_entity/recordcontainers/db/conditionProcess.js
index 2c2d8e0a101e1051fb616a6b74bf859065b787cb..9692e9118a2e8f7f41a6e8d4f901223814f7367f 100644
--- a/entity/Attribute_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/Attribute_entity/recordcontainers/db/conditionProcess.js
@@ -1,6 +1,8 @@
-import("system.vars");
-import("system.result");
-import("Sql_lib");
-
-//if (vars.exists("$field.AB_ATTRIBUTEID") && vars.get("$field.AB_ATTRIBUTEID") != "")
-//    result.string(SqlCondition.begin().andPrepare("ATTRIBUTE_PARENT_ID", vars.get("$field.AB_ATTRIBUTEID")));
\ No newline at end of file
+import("system.vars");
+import("system.result");
+import("Sql_lib");
+
+if (vars.exists("$param.attrParentId_param") && vars.get("$param.attrParentId_param"))
+    result.string("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID = '" + vars.getString("$param.attrParentId_param") + "'");
+else
+    result.string("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID is null");
\ No newline at end of file
diff --git a/entity/Context_entity/Context_entity.aod b/entity/Context_entity/Context_entity.aod
index ebf5d2c1bbe810dbf0a1f875147254a052b81088..4742ecca3f226ea5923f827616939df3a781e919 100644
--- a/entity/Context_entity/Context_entity.aod
+++ b/entity/Context_entity/Context_entity.aod
@@ -49,6 +49,12 @@
           <fieldName>Contexts</fieldName>
           <isConsumer v="false" />
         </entityDependency>
+        <entityDependency>
+          <name>628bd4db-3b31-4337-88ac-1c000307836f</name>
+          <entityName>AttributeUsage_entity</entityName>
+          <fieldName>Contexts</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
       </dependencies>
       <children>
         <entityParameter>
diff --git a/entity/Contract_entity/entityfields/contractcode_display_fieldgroup/valueProcess.js b/entity/Contract_entity/entityfields/contractcode_display_fieldgroup/valueProcess.js
index 97ab0469059592de24d761ea6e0ac338f2b42564..3b3d5b96c09bae19240fbc0866f31943de579664 100644
--- a/entity/Contract_entity/entityfields/contractcode_display_fieldgroup/valueProcess.js
+++ b/entity/Contract_entity/entityfields/contractcode_display_fieldgroup/valueProcess.js
@@ -5,4 +5,4 @@ import("Keyword_lib");
 var cType = vars.get("$field.CONTRACTTYPE");
 var cCode = vars.get("$field.CONTRACTCODE");
 
-result.string(KeywordUtils.getViewValue($KeywordRegistry.get.ContractType, cType) + " : " + cCode);
\ No newline at end of file
+result.string(KeywordUtils.getViewValue($KeywordRegistry.get.ContractType, cType) + " " + cCode);
\ No newline at end of file
diff --git a/entity/Contract_entity/recordcontainers/db/conditionProcess.js b/entity/Contract_entity/recordcontainers/db/conditionProcess.js
index 597fc42b0f52aed61d3032cd77276cc4ea048d42..efee86e66ac2e77e2cdd918f417113223a973b47 100644
--- a/entity/Contract_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/Contract_entity/recordcontainers/db/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 
 var cond = SqlCondition.begin().andPrepareVars("CONTRACT.CONTACT_ID", "$param.ContactId_param");
 
-//TODO: use a preparedCondition when available
-result.string(db.translateCondition(cond.build("1 = 1"))); 
\ No newline at end of file
+//TODO: use a preparedCondition when available #1030812 #1034026
+result.string(db.translateCondition(cond.build("1 = 1"))); 
diff --git a/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod b/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod
index e9462ab5b45dfe3f192ff3b568efb142da122d52..5ff0334824392a5c064a44a5a8283051d8d93c36 100644
--- a/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod
+++ b/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod
@@ -3,6 +3,7 @@
   <name>KeywordAttributeRelation_entity</name>
   <title>Keyword Attribute Values</title>
   <majorModelMode>DISTRIBUTED</majorModelMode>
+  <documentation>%aditoprj%/entity/KeywordAttributeRelation_entity/documentation.adoc</documentation>
   <recordContainer>db</recordContainer>
   <entityFields>
     <entityProvider>
@@ -89,6 +90,7 @@
       <documentation>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/documentation.adoc</documentation>
       <title>Value</title>
       <contentTypeProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/contentTypeProcess.js</contentTypeProcess>
+      <mandatory v="true" />
       <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/valueProcess.js</valueProcess>
       <onValueChange>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/onValueChange.js</onValueChange>
     </entityField>
diff --git a/entity/KeywordAttributeRelation_entity/documentation.adoc b/entity/KeywordAttributeRelation_entity/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..cc5756e15cbf9fcaac701ef68176b5f03423e6e2
--- /dev/null
+++ b/entity/KeywordAttributeRelation_entity/documentation.adoc
@@ -0,0 +1,3 @@
+This entity represents the relation between a Keyword-Attribute and a Keyword-Entry.
+There is a reference to a Keyword-Attribute, a Keyword-Entry and some more properties that describe that relation (like the stored value).
+In fact the main reason for this is the stored value which depends on the type of the Keyword-Attribute.
\ No newline at end of file
diff --git a/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_attribute_id/onValueChange.js b/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_attribute_id/onValueChange.js
index a26f98d31481d3a3bfa76a0473c1d40e34c42437..15f4a12ff870ec196506053e91dd9034275dade5 100644
--- a/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_attribute_id/onValueChange.js
+++ b/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_attribute_id/onValueChange.js
@@ -1,5 +1,10 @@
 import("system.vars");
+import("system.neon");
 
-vars.set("$field.CHAR_VALUE", "");
-vars.set("$field.BOOL_VALUE", "");
-vars.set("$field.NUMBER_VALUE", "");
\ No newline at end of file
+var recordState = vars.get("$sys.recordstate");
+if (recordState == neon.OPERATINGSTATE_NEW || recordState == neon.OPERATINGSTATE_EDIT)
+{
+    vars.set("$field.CHAR_VALUE", null);
+    vars.set("$field.BOOL_VALUE", null);
+    vars.set("$field.NUMBER_VALUE", null);
+}
\ No newline at end of file
diff --git a/entity/KeywordAttributeRelation_entity/entityfields/attributetype/valueProcess.js b/entity/KeywordAttributeRelation_entity/entityfields/attributetype/valueProcess.js
index f6990e515424e20b5df112f89c6239bd94b8ac09..17b5f6abe25d8b95f8c1bccf20b80b84b8d1bcc5 100644
--- a/entity/KeywordAttributeRelation_entity/entityfields/attributetype/valueProcess.js
+++ b/entity/KeywordAttributeRelation_entity/entityfields/attributetype/valueProcess.js
@@ -3,6 +3,9 @@ import("system.result");
 import("system.vars");
 import("Sql_lib");
 
+//the attribute type has always to be loaded via a separate sql and not whith a join 
+//because it depends on the Keyword-Attribute and that selected Keyword-Attribute can change in recordstate EDIT
+//in recordsstate NEW the join wouldn't even return something
 var id = vars.get("$field.AB_KEYWORD_ATTRIBUTE_ID");
 var type = null;
 if (id)
diff --git a/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/documentation.adoc b/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/documentation.adoc
index 51ce71eb3b829375c143714f88dd8c10ebfb0096..fd1576ff788042438bb5ae1c351ab1116f5f7986 100644
--- a/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/documentation.adoc
+++ b/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/documentation.adoc
@@ -1 +1,3 @@
-A field that is proxy for the correct value-fields like `CHAR_VALUE`, `CHAR_BOOL`, etc.
\ No newline at end of file
+A field that is proxy for the correct value-fields like `CHAR_VALUE`, `CHAR_BOOL`, etc.
+
+The rendered field in a view depends on the database-type. That means a proxy-field is needed which handles where the actual value is stored, loaded, etc.
\ No newline at end of file
diff --git a/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod b/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod
index 4061a215b27e5eeefbc5529ab48ed631eb1a2f09..1c7b0abdb6b58b86bc7e6f606385d1253d383c1d 100644
--- a/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod
+++ b/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod
@@ -3,6 +3,7 @@
   <name>KeywordAttribute_entity</name>
   <title>Keyword Attribute</title>
   <majorModelMode>DISTRIBUTED</majorModelMode>
+  <documentation>%aditoprj%/entity/KeywordAttribute_entity/documentation.adoc</documentation>
   <iconId>VAADIN:KEY_O</iconId>
   <iconIdProcess>%aditoprj%/entity/KeywordAttribute_entity/iconIdProcess.js</iconIdProcess>
   <titleProcess>%aditoprj%/entity/KeywordAttribute_entity/titleProcess.js</titleProcess>
@@ -13,6 +14,7 @@
     </entityProvider>
     <entityField>
       <name>AB_KEYWORD_ATTRIBUTEID</name>
+      <searchable v="false" />
       <valueProcess>%aditoprj%/entity/KeywordAttribute_entity/entityfields/ab_keyword_attributeid/valueProcess.js</valueProcess>
     </entityField>
     <entityField>
@@ -36,7 +38,7 @@
     <entityProvider>
       <name>SpecificContainerKeywords</name>
       <fieldType>DEPENDENCY_IN</fieldType>
-      <recordContainer>db</recordContainer>
+      <documentation>%aditoprj%/entity/KeywordAttribute_entity/entityfields/specificcontainerkeywords/documentation.adoc</documentation>
       <dependencies>
         <entityDependency>
           <name>1d11c064-1cf2-4f08-b842-9fa941ad3157</name>
@@ -56,6 +58,7 @@
       <name>filterAlreadyUsedByEntryId_param</name>
       <expose v="true" />
       <mandatory v="false" />
+      <documentation>%aditoprj%/entity/KeywordAttribute_entity/entityfields/filteralreadyusedbyentryid_param/documentation.adoc</documentation>
       <description>PARAMETER</description>
     </entityParameter>
     <entityConsumer>
diff --git a/entity/KeywordAttribute_entity/documentation.adoc b/entity/KeywordAttribute_entity/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..decc1751fd305427095b6e74c801feef205c70d6
--- /dev/null
+++ b/entity/KeywordAttribute_entity/documentation.adoc
@@ -0,0 +1,10 @@
+Keyword Attributes
+==================
+
+Keyword attributes are an extension of simple keywords.
+You can specify special attributes per Keyword-container. 
+`KeywordAttribute_entity` is used for that definition.
+
+It describes which Keyword-Attribute can be set - not which Keyword-Attribute-value is set on which entry.
+
+Do not confuse the Keyword-Attributes with the standard Attributes (-> `Attribute_entity`). While the way it works is similar, the Keyword-Attributes are specifically developed for keywords and provide therefore different functionality.
\ No newline at end of file
diff --git a/entity/KeywordAttribute_entity/entityfields/filteralreadyusedbyentryid_param/documentation.adoc b/entity/KeywordAttribute_entity/entityfields/filteralreadyusedbyentryid_param/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..9095374bc2619c424604bfb88abb26a8ba86b2e4
--- /dev/null
+++ b/entity/KeywordAttribute_entity/entityfields/filteralreadyusedbyentryid_param/documentation.adoc
@@ -0,0 +1,4 @@
+This param is used for filtering Keyword-Attributes that are already in-use for a Keyword-Entry.
+A Keyword-Attribute has to be unique for every entry.
+
+You've to pass a Keyword-Entry-Id.
\ No newline at end of file
diff --git a/entity/KeywordAttribute_entity/entityfields/specificcontainerkeywords/documentation.adoc b/entity/KeywordAttribute_entity/entityfields/specificcontainerkeywords/documentation.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..fd15bd93129b743f7e989cca53f46702e926d48f
--- /dev/null
+++ b/entity/KeywordAttribute_entity/entityfields/specificcontainerkeywords/documentation.adoc
@@ -0,0 +1 @@
+Provides Keyword-Attributes for a specific Keyword-Containername.
\ No newline at end of file
diff --git a/entity/KeywordEntry_entity/KeywordEntry_entity.aod b/entity/KeywordEntry_entity/KeywordEntry_entity.aod
index 0c83ef04ae1fc24984ad89752fd56cb99288aee3..0956d55dd069ab00e2eb860698f67a8da90576d8 100644
--- a/entity/KeywordEntry_entity/KeywordEntry_entity.aod
+++ b/entity/KeywordEntry_entity/KeywordEntry_entity.aod
@@ -25,6 +25,7 @@
     </entityField>
     <entityField>
       <name>AB_KEYWORD_ENTRYID</name>
+      <searchable v="false" />
       <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/ab_keyword_entryid/valueProcess.js</valueProcess>
     </entityField>
     <entityField>
@@ -238,6 +239,12 @@
           <fieldName>KeywordAttributeType</fieldName>
           <isConsumer v="false" />
         </entityDependency>
+        <entityDependency>
+          <name>718fe5a2-c75f-49ed-b67e-fc4fbf63ff1d</name>
+          <entityName>Salesproject_entity</entityName>
+          <fieldName>KeywordProbabilties</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
       </dependencies>
       <children>
         <entityParameter>
diff --git a/entity/KeywordEntry_entity/documentation.adoc b/entity/KeywordEntry_entity/documentation.adoc
index d883975a6c34707b902a5d30bc5153c48af056ad..c08c1063283cc9a2af7c27a614f5f5718ba89737 100644
--- a/entity/KeywordEntry_entity/documentation.adoc
+++ b/entity/KeywordEntry_entity/documentation.adoc
@@ -51,9 +51,9 @@ digraph g {
 ----
 
 
-Take a look at the following table. Beware that these are not the acutal db-column-names but the information what's represented.
+Take a look at the following table. Beware that these are not the actual db-column-names but the information what's represented.
 
-.simplified, abstract representation how keywords are acutllay stored
+.simplified, abstract representation how keywords are actually stored
 [options="header", cols="m,m,d,d"]
 |=======
 |UID |key-ID |tile | container
@@ -83,7 +83,7 @@ And, to clarify an example:
 === Extended Key-Value lists with special Attributes ===
 
 Basically this is a extension of the <<Simple Key-Value lists>>.
-Sometimes it's neccesary to have some more propierties within a keyword-entry.
+Sometimes it's necessary to have some more properties within a keyword-entry.
 Example:
 
 You've got a Keyword-container for Types of Communication with basically the following values:
@@ -98,8 +98,8 @@ If you want to add a general type of information like "PHONE", "MAIL", "WEB" you
 
 === Complex Keyword as own entity ===
 
-Sometimes you've a special case where the keyword entity cannot provide all the functioality. 
+Sometimes you've a special case where the keyword entity cannot provide all the functionality. 
 
-In that case you can always define you own entity and create your own database strucutre to represent all the information and provide all the functions you need.
+In that case you can always define you own entity and create your own database structure to represent all the information and provide all the functions you need.
 
 As an example, this could be the `Country_Entity`
\ No newline at end of file
diff --git a/entity/KeywordEntry_entity/onValidation.js b/entity/KeywordEntry_entity/onValidation.js
index ae813d018848dcb847a752c1eedb985090518c16..f1f568a35c02d5f14032daa227f765538d92b5a1 100644
--- a/entity/KeywordEntry_entity/onValidation.js
+++ b/entity/KeywordEntry_entity/onValidation.js
@@ -1,3 +1,4 @@
+import("system.translate");
 import("system.db");
 import("system.vars");
 import("system.text");
@@ -15,7 +16,7 @@ if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
         var newCodeNumber = db.cell(cond.buildSql("select " + maskingHelper.max("AB_KEYWORD_ENTRY.SORTING") + " from AB_KEYWORD_ENTRY", "1 = 2"));
         newCodeNumber = Number(newCodeNumber);//if no number exists till no, start value will be 1 (due to: ++0)
         if (isNaN(newCodeNumber))
-            throw new TypeError();//TODO:add Message
+            throw new TypeError(translate.text("The code number is not a valid number."));
         neon.setFieldValue("$field.SORTING", ++newCodeNumber);
     }
 }
\ No newline at end of file
diff --git a/entity/KeywordEntry_entity/recordcontainers/db/onDBUpdate.js b/entity/KeywordEntry_entity/recordcontainers/db/onDBUpdate.js
index 0f9d6cbdbc13c88271967f572ce1709fd1ad6519..d9f8978acd6592e20a2851d1e46b490b2ff398d7 100644
--- a/entity/KeywordEntry_entity/recordcontainers/db/onDBUpdate.js
+++ b/entity/KeywordEntry_entity/recordcontainers/db/onDBUpdate.js
@@ -1,3 +1,4 @@
+import("system.translate");
 import("system.db");
 import("system.vars");
 import("system.text");
@@ -7,7 +8,7 @@ import("Sql_lib");
 var changedFields = vars.get("$local.changed");
 //whenever the container is changed data that depends on the keyword-container has be "fixed" to keep consistency
 //this could be information like Keyword-attributes or the sorting-position
-//maybe it'd be better to lock KeywordContainer as read-only after creation
+// TODO: maybe it'd be better to lock KeywordContainer as read-only after creation
 if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_EDIT && changedFields.indexOf("AB_KEYWORD_ENTRY.CONTAINER") > -1)
 {
     var keyContainer = vars.get("$field.CONTAINER");
@@ -18,7 +19,7 @@ if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_EDIT && changedFields.in
         var newCodeNumber = db.cell(cond.buildSql("select " + maskingHelper.max("AB_KEYWORD_ENTRY.SORTING") + " from AB_KEYWORD_ENTRY", "1 = 2"));
         newCodeNumber = Number(newCodeNumber);//if no number exists till no, start value will be 1 (due to: ++0)
         if (isNaN(newCodeNumber))
-            throw new TypeError();//TODO:add Message
+            throw new TypeError(translate.text("The code number is not a valid number."));
 
         var cols = ["SORTING"];
         var vals = [++newCodeNumber];
diff --git a/entity/Object_entity/Object_entity.aod b/entity/Object_entity/Object_entity.aod
index 613a2e2e90d967fefebb5ec24f4c9d660f486196..fa0bdde3012f9c2e94bd4c27c01b2ea25da7bc3a 100644
--- a/entity/Object_entity/Object_entity.aod
+++ b/entity/Object_entity/Object_entity.aod
@@ -8,6 +8,15 @@
   <entityFields>
     <entityProvider>
       <name>#PROVIDER</name>
+      <recordContainer>jdito</recordContainer>
+      <dependencies>
+        <entityDependency>
+          <name>e7a31d3c-69f5-43f9-8e66-c35bcc058883</name>
+          <entityName>Appointment_entity</entityName>
+          <fieldName>Objects</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
+      </dependencies>
       <children>
         <entityParameter>
           <name>ObjectRowId_param</name>
@@ -24,6 +33,7 @@
     <entityParameter>
       <name>ObjectType_param</name>
       <expose v="true" />
+      <mandatory v="true" />
       <description>PARAMETER</description>
     </entityParameter>
     <entityParameter>
diff --git a/entity/Offer_entity/conditionProcess.js b/entity/Offer_entity/conditionProcess.js
index 7cab12160289270ffdc06a05fbcafde1151be07e..46b77172c421062e7a3ca794200ae6c992f04147 100644
--- a/entity/Offer_entity/conditionProcess.js
+++ b/entity/Offer_entity/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("OFFER.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/Offer_entity/recordcontainers/db/conditionProcess.js b/entity/Offer_entity/recordcontainers/db/conditionProcess.js
index 7cab12160289270ffdc06a05fbcafde1151be07e..46b77172c421062e7a3ca794200ae6c992f04147 100644
--- a/entity/Offer_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/Offer_entity/recordcontainers/db/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("OFFER.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/Offeritem_entity/Offeritem_entity.aod b/entity/Offeritem_entity/Offeritem_entity.aod
index 691c6b9950b17f8186cbbb24c59b8c26ac9e6e92..916eea0cb49d768d7545700d27ce26f29307fff7 100644
--- a/entity/Offeritem_entity/Offeritem_entity.aod
+++ b/entity/Offeritem_entity/Offeritem_entity.aod
@@ -62,7 +62,8 @@
       <name>PRODUCT_ID</name>
       <documentation>%aditoprj%/entity/Offeritem_entity/entityfields/product_id/documentation.adoc</documentation>
       <title>Article</title>
-      <possibleItemsProcess>%aditoprj%/entity/Offeritem_entity/entityfields/product_id/possibleItemsProcess.js</possibleItemsProcess>
+      <consumer>Products</consumer>
+      <linkedContext>Product_context</linkedContext>
       <onValueChange>%aditoprj%/entity/Offeritem_entity/entityfields/product_id/onValueChange.js</onValueChange>
       <onValueChangeTypes>
         <element>MASK</element>
@@ -178,6 +179,15 @@
         </entityParameter>
       </children>
     </entityConsumer>
+    <entityConsumer>
+      <name>Products</name>
+      <fieldType>DEPENDENCY_OUT</fieldType>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Product_entity</entityName>
+        <fieldName>#PROVIDER</fieldName>
+      </dependency>
+    </entityConsumer>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -267,6 +277,10 @@
           <name>UNIT.displayValue</name>
           <expression>%aditoprj%/entity/Offeritem_entity/recordcontainers/db/recordfieldmappings/unit.displayvalue/expression.js</expression>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>PRODUCT_ID.displayValue</name>
+          <expression>%aditoprj%/entity/Offeritem_entity/recordcontainers/db/recordfieldmappings/product_id.displayvalue/expression.js</expression>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
     </dbRecordContainer>
   </recordContainers>
diff --git a/entity/Offeritem_entity/entityfields/info/valueProcess.js b/entity/Offeritem_entity/entityfields/info/valueProcess.js
index 522166c5f78fbd4dc448006857286c7860a55635..199fc1e677e27d82f50e7728d4e6d9b66cb22c69 100644
--- a/entity/Offeritem_entity/entityfields/info/valueProcess.js
+++ b/entity/Offeritem_entity/entityfields/info/valueProcess.js
@@ -6,7 +6,7 @@ import("Sql_lib");
 
 if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
 {
-    // TODO: loading from db until loading from dfo is possible.
+    // TODO: loading from db until loading from Consumer is possible.
     var productId = vars.get("$field.PRODUCT_ID");
     result.string(db.cell(SqlCondition.begin().andPrepareVars("PRODUCT.PRODUCTID", "$field.PRODUCT_ID").buildSql("select INFO from PRODUCT", "1=2")));
 }
\ No newline at end of file
diff --git a/entity/Offeritem_entity/entityfields/product_id/possibleItemsProcess.js b/entity/Offeritem_entity/entityfields/product_id/possibleItemsProcess.js
deleted file mode 100644
index e19938f82d7f21dbf4c8d427e08312291222547b..0000000000000000000000000000000000000000
--- a/entity/Offeritem_entity/entityfields/product_id/possibleItemsProcess.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import("system.result");
-import("system.db");
-import("Sql_lib");
-
-//TODO: change field to lookup field
-var sqlUtils = new SqlMaskingUtils();
-var prodsSql = "select PRODUCTID, " + sqlUtils.concat(["PRODUCTCODE", "PRODUCTNAME"], "/") 
-                    + " from PRODUCT";
-
-var prods = db.table(prodsSql);
-
-var retArray = [];
-for(var i = 0; i < prods.length; i++)
-    retArray.push(prods[i]);
-
-result.object(retArray);
\ No newline at end of file
diff --git a/entity/Offeritem_entity/recordcontainers/db/recordfieldmappings/product_id.displayvalue/expression.js b/entity/Offeritem_entity/recordcontainers/db/recordfieldmappings/product_id.displayvalue/expression.js
new file mode 100644
index 0000000000000000000000000000000000000000..505fda0b8e840a2c32054647dcc52469f8fc199d
--- /dev/null
+++ b/entity/Offeritem_entity/recordcontainers/db/recordfieldmappings/product_id.displayvalue/expression.js
@@ -0,0 +1,5 @@
+import("system.vars");
+import("system.result");
+
+// TODO: remove when #title is used as display value for lookups
+result.string("(select PRODUCT.PRODUCTNAME from PRODUCT where OFFERITEM.PRODUCT_ID = PRODUCT.PRODUCTID)");
\ No newline at end of file
diff --git a/entity/Order_entity/recordcontainers/db/conditionProcess.js b/entity/Order_entity/recordcontainers/db/conditionProcess.js
index d470d3cb07db83d573e4cd6e894eff89351cac12..11dd858114ebf04db6ef1e00f817003e5a0c2b7b 100644
--- a/entity/Order_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/Order_entity/recordcontainers/db/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESORDER.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/Orderitem_entity/Orderitem_entity.aod b/entity/Orderitem_entity/Orderitem_entity.aod
index ae3ec522497d3f7e869e6391c700af597405db11..14b2e4111b7f0fd824d2ee2cdcdb08cd553f298f 100644
--- a/entity/Orderitem_entity/Orderitem_entity.aod
+++ b/entity/Orderitem_entity/Orderitem_entity.aod
@@ -62,7 +62,8 @@
       <name>PRODUCT_ID</name>
       <documentation>%aditoprj%/entity/Orderitem_entity/entityfields/product_id/documentation.adoc</documentation>
       <title>Article</title>
-      <possibleItemsProcess>%aditoprj%/entity/Orderitem_entity/entityfields/product_id/possibleItemsProcess.js</possibleItemsProcess>
+      <consumer>Products</consumer>
+      <linkedContext>Product_context</linkedContext>
       <onValueChange>%aditoprj%/entity/Orderitem_entity/entityfields/product_id/onValueChange.js</onValueChange>
       <onValueChangeTypes>
         <element>MASK</element>
@@ -182,6 +183,15 @@
         </entityParameter>
       </children>
     </entityConsumer>
+    <entityConsumer>
+      <name>Products</name>
+      <fieldType>DEPENDENCY_OUT</fieldType>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Product_entity</entityName>
+        <fieldName>#PROVIDER</fieldName>
+      </dependency>
+    </entityConsumer>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -271,6 +281,10 @@
           <name>UNIT.displayValue</name>
           <expression>%aditoprj%/entity/Orderitem_entity/recordcontainers/db/recordfieldmappings/unit.displayvalue/expression.js</expression>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>PRODUCT_ID.displayValue</name>
+          <expression>%aditoprj%/entity/Orderitem_entity/recordcontainers/db/recordfieldmappings/product_id.displayvalue/expression.js</expression>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
     </dbRecordContainer>
   </recordContainers>
diff --git a/entity/Orderitem_entity/entityfields/product_id/possibleItemsProcess.js b/entity/Orderitem_entity/entityfields/product_id/possibleItemsProcess.js
deleted file mode 100644
index e19938f82d7f21dbf4c8d427e08312291222547b..0000000000000000000000000000000000000000
--- a/entity/Orderitem_entity/entityfields/product_id/possibleItemsProcess.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import("system.result");
-import("system.db");
-import("Sql_lib");
-
-//TODO: change field to lookup field
-var sqlUtils = new SqlMaskingUtils();
-var prodsSql = "select PRODUCTID, " + sqlUtils.concat(["PRODUCTCODE", "PRODUCTNAME"], "/") 
-                    + " from PRODUCT";
-
-var prods = db.table(prodsSql);
-
-var retArray = [];
-for(var i = 0; i < prods.length; i++)
-    retArray.push(prods[i]);
-
-result.object(retArray);
\ No newline at end of file
diff --git a/entity/Orderitem_entity/recordcontainers/db/recordfieldmappings/product_id.displayvalue/expression.js b/entity/Orderitem_entity/recordcontainers/db/recordfieldmappings/product_id.displayvalue/expression.js
new file mode 100644
index 0000000000000000000000000000000000000000..c356272a55066e5913df7b5cbaa668d875d88983
--- /dev/null
+++ b/entity/Orderitem_entity/recordcontainers/db/recordfieldmappings/product_id.displayvalue/expression.js
@@ -0,0 +1,5 @@
+import("system.vars");
+import("system.result");
+
+// TODO: remove when #title is used as display value for lookups
+result.string("(select PRODUCT.PRODUCTNAME from PRODUCT where SALESORDERITEM.PRODUCT_ID = PRODUCT.PRODUCTID)");
\ No newline at end of file
diff --git a/entity/Organisation_entity/recordcontainers/db/conditionProcess.js b/entity/Organisation_entity/recordcontainers/db/conditionProcess.js
index 0c6aae84bba48f30903a0a7d7d900d605992280a..6e3446d992205ac3fe28c2db4ab869102f71fa72 100644
--- a/entity/Organisation_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/Organisation_entity/recordcontainers/db/conditionProcess.js
@@ -4,7 +4,7 @@ import("system.db");
 import("system.result");
 import("Sql_lib");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(
                 SqlCondition.begin()
                             .andPrepareVars("ORGANISATION.ORGANISATIONID", "$param.ContactId_param")
diff --git a/entity/Person_entity/conditionProcess.js b/entity/Person_entity/conditionProcess.js
index a19303b9872d89bd503a36a2a3d9567f77f98868..0c7d6ef5de8bd86e31f3946d8927293186fe2c07 100644
--- a/entity/Person_entity/conditionProcess.js
+++ b/entity/Person_entity/conditionProcess.js
@@ -7,5 +7,5 @@ cond.andPrepareVars("CONTACT.ORGANISATION_ID", "$param.OrgId_param");
 cond.andPrepareVars("PERSON.CONTACT_ID", "$param.ContactId_param");
 
 //TODO; add OBJECT_ID (probably another param)
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/Person_entity/entityfields/image/onValueChange.js b/entity/Person_entity/entityfields/image/onValueChange.js
index f7fffb124f892cacb684ac531a608d61bae0ad4e..86a4f85653ae6eb9a622f17318dd0e4782e75ee3 100644
--- a/entity/Person_entity/entityfields/image/onValueChange.js
+++ b/entity/Person_entity/entityfields/image/onValueChange.js
@@ -1,4 +1,4 @@
 import("Entity_lib");
 
-// TODO: also there is currently no good way to do updates with fields not connected to the record container. Workaround: imagevariable and update in onDBUpdate Process
+// TODO: also there is currently no good way to do updates with fields not connected to the record container. Workaround: imagevariable and update in onDBUpdate Process #1030023
 FieldChanges.setChange("$field.IMAGE");
\ No newline at end of file
diff --git a/entity/Person_entity/entityfields/standard_email_comm/onValueChange.js b/entity/Person_entity/entityfields/standard_email_comm/onValueChange.js
index 25c5a67ac861d7df3fec7904a7c03cc2259d533f..972cb181d553b480c039c0d77fca8da35a528c71 100644
--- a/entity/Person_entity/entityfields/standard_email_comm/onValueChange.js
+++ b/entity/Person_entity/entityfields/standard_email_comm/onValueChange.js
@@ -1,4 +1,4 @@
 import("Entity_lib");
 
-// TODO: also there is currently no good way to do updates with fields not connected to the record container. Workaround: imagevariable and update in onDBUpdate Process
+// TODO: also there is currently no good way to do updates with fields not connected to the record container. Workaround: imagevariable and update in onDBUpdate Process #1030023
 FieldChanges.setChange("$field.STANDARD_EMAIL_COMMUNICATION");
\ No newline at end of file
diff --git a/entity/Person_entity/entityfields/standard_phone_comm/onValueChange.js b/entity/Person_entity/entityfields/standard_phone_comm/onValueChange.js
index fd9905c4cde0fbf215614f72b3ba3a72fc5221a6..991c92d38d0731524a8de4eb6d0adabb661a71c3 100644
--- a/entity/Person_entity/entityfields/standard_phone_comm/onValueChange.js
+++ b/entity/Person_entity/entityfields/standard_phone_comm/onValueChange.js
@@ -1,4 +1,4 @@
 import("Entity_lib");
 
-// TODO: also there is currently no good way to do updates with fields not connected to the record container. Workaround: imagevariable and update in onDBUpdate Process
+// TODO: also there is currently no good way to do updates with fields not connected to the record container. Workaround: imagevariable and update in onDBUpdate Process #1030023
 FieldChanges.setChange("$field.STANDARD_PHONE_COMMUNICATION");
\ No newline at end of file
diff --git a/entity/Person_entity/recordcontainers/db/conditionProcess.js b/entity/Person_entity/recordcontainers/db/conditionProcess.js
index b65379fa6d403b265f33fea2fadb1d19b9cb272c..e8302d00414fecb5dee552bfcacb6ff20a4a7f77 100644
--- a/entity/Person_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/Person_entity/recordcontainers/db/conditionProcess.js
@@ -6,5 +6,5 @@ var cond = new SqlCondition();
 cond.andPrepareVars("CONTACT.ORGANISATION_ID", "$param.OrgId_param");
 cond.andPrepareVars("PERSON.CONTACT_ID", "$param.ContactId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/Person_entity/recordcontainers/db/onDBUpdate.js b/entity/Person_entity/recordcontainers/db/onDBUpdate.js
index ebda79e51184b78501f01b875ed379b6e70069fb..c1aaada5945950cf44c87edc3e7688fba2a518ad 100644
--- a/entity/Person_entity/recordcontainers/db/onDBUpdate.js
+++ b/entity/Person_entity/recordcontainers/db/onDBUpdate.js
@@ -3,7 +3,7 @@ import("Person_lib");
 import("Communication_lib");
 import("Entity_lib");
 
-// TODO: this is a workaround for missing possibility to react on changes of fields not connected to record Contqainer
+// TODO: this is a workaround for missing possibility to react on changes of fields not connected to record Contqainer #1030023
 FieldChanges.assimilateChangeAndDispose("$field.IMAGE", function(state, value){
     if (state == FieldChanges.STATE_CHANGED())
         PersUtils.setImage(vars.get("$field.PERSONID"), value);
diff --git a/entity/Product_entity/Product_entity.aod b/entity/Product_entity/Product_entity.aod
index da0c900b6fbce3e532cffec790482f4c9e257fed..2cd464e46c26353a7790d6bbf77fc1bb5679c6fe 100644
--- a/entity/Product_entity/Product_entity.aod
+++ b/entity/Product_entity/Product_entity.aod
@@ -146,6 +146,20 @@
     <entityProvider>
       <name>#PROVIDER</name>
       <recordContainer>db</recordContainer>
+      <dependencies>
+        <entityDependency>
+          <name>edd8a3af-d168-4a3b-871d-39db964c700b</name>
+          <entityName>Offeritem_entity</entityName>
+          <fieldName>Products</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
+        <entityDependency>
+          <name>e4ba4c26-a777-4560-ab68-311ffae76e2f</name>
+          <entityName>Orderitem_entity</entityName>
+          <fieldName>Products</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
+      </dependencies>
     </entityProvider>
     <entityConsumer>
       <name>ProductLinks</name>
diff --git a/entity/Product_entity/entityfields/image/onValueChange.js b/entity/Product_entity/entityfields/image/onValueChange.js
index 4997061690d757b4a7e50c905c0331a6f8897d40..1fc5daeeea2101848906d4ec2c0f78ebc23fd634 100644
--- a/entity/Product_entity/entityfields/image/onValueChange.js
+++ b/entity/Product_entity/entityfields/image/onValueChange.js
@@ -1,5 +1,5 @@
 import("system.vars");
 import("Entity_lib");
 
-// TODO: also there is currently no good way to do updates with fields not connected to the record container. Workaround: imagevariable and update in onDBUpdate Process
+// TODO: also there is currently no good way to do updates with fields not connected to the record container. Workaround: imagevariable and update in onDBUpdate Process #1030023
 FieldChanges.setChange("$field.IMAGE");
\ No newline at end of file
diff --git a/entity/Product_entity/recordcontainers/db/onDBUpdate.js b/entity/Product_entity/recordcontainers/db/onDBUpdate.js
index de4985229e60c54dd9a0d801d432350214f14eb7..11c4f6b2dd52dd21b4935cdf8f9bb011d9cbc4c6 100644
--- a/entity/Product_entity/recordcontainers/db/onDBUpdate.js
+++ b/entity/Product_entity/recordcontainers/db/onDBUpdate.js
@@ -2,7 +2,7 @@ import("system.vars");
 import("Product_lib");
 import("Entity_lib");
 
-// TODO: this is a workaround for missing possibility to react on changes of fields not connected to record Contqainer
+// TODO: this is a workaround for missing possibility to react on changes of fields not connected to record Contqainer #1030023
 FieldChanges.assimilateChangeAndDispose("$field.IMAGE", function(state, value){
     if (state == FieldChanges.STATE_CHANGED())
         ProductUtils.setImage(vars.get("$field.PRODUCTID"), value);
diff --git a/entity/SalesprojectCompetition_entity/conditionProcess.js b/entity/SalesprojectCompetition_entity/conditionProcess.js
index 7211c893151bd82720da39955215dc913e23d244..f28e2da06f6d02e7faa5dee5adb832f282dadf59 100644
--- a/entity/SalesprojectCompetition_entity/conditionProcess.js
+++ b/entity/SalesprojectCompetition_entity/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESPROJECT_COMPETITION.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/SalesprojectCompetition_entity/recordcontainers/db/conditionProcess.js b/entity/SalesprojectCompetition_entity/recordcontainers/db/conditionProcess.js
index 7211c893151bd82720da39955215dc913e23d244..f28e2da06f6d02e7faa5dee5adb832f282dadf59 100644
--- a/entity/SalesprojectCompetition_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/SalesprojectCompetition_entity/recordcontainers/db/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESPROJECT_COMPETITION.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/SalesprojectCycle_entity/conditionProcess.js b/entity/SalesprojectCycle_entity/conditionProcess.js
index be87512e0c943b8c20fe1f1e80875e199fbf8c5d..01636c9c6c0e376f52c0a692d6d6bd7e8d755e9b 100644
--- a/entity/SalesprojectCycle_entity/conditionProcess.js
+++ b/entity/SalesprojectCycle_entity/conditionProcess.js
@@ -6,5 +6,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESPROJECT_CYCLE.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/SalesprojectCycle_entity/recordcontainers/db/conditionProcess.js b/entity/SalesprojectCycle_entity/recordcontainers/db/conditionProcess.js
index be87512e0c943b8c20fe1f1e80875e199fbf8c5d..01636c9c6c0e376f52c0a692d6d6bd7e8d755e9b 100644
--- a/entity/SalesprojectCycle_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/SalesprojectCycle_entity/recordcontainers/db/conditionProcess.js
@@ -6,5 +6,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESPROJECT_CYCLE.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/SalesprojectForecast_entity/conditionProcess.js b/entity/SalesprojectForecast_entity/conditionProcess.js
index ab985582570e10b3e838ec36f7f0d225bc21f1d2..647c25565dad24ef03a9efcfd30688ff06124f4f 100644
--- a/entity/SalesprojectForecast_entity/conditionProcess.js
+++ b/entity/SalesprojectForecast_entity/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESPROJECT_FORECAST.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/SalesprojectForecast_entity/recordcontainers/db/conditionProcess.js b/entity/SalesprojectForecast_entity/recordcontainers/db/conditionProcess.js
index ab985582570e10b3e838ec36f7f0d225bc21f1d2..647c25565dad24ef03a9efcfd30688ff06124f4f 100644
--- a/entity/SalesprojectForecast_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/SalesprojectForecast_entity/recordcontainers/db/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESPROJECT_FORECAST.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/SalesprojectMember_entity/conditionProcess.js b/entity/SalesprojectMember_entity/conditionProcess.js
index d7a57bbf3f47f3082a2b6db23040612a3224c94e..bfd5554266b3eafe24dfbfcaba9c62957b4b6edb 100644
--- a/entity/SalesprojectMember_entity/conditionProcess.js
+++ b/entity/SalesprojectMember_entity/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESPROJECT_MEMBER.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/SalesprojectMember_entity/recordcontainers/db/conditionProcess.js b/entity/SalesprojectMember_entity/recordcontainers/db/conditionProcess.js
index d7a57bbf3f47f3082a2b6db23040612a3224c94e..bfd5554266b3eafe24dfbfcaba9c62957b4b6edb 100644
--- a/entity/SalesprojectMember_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/SalesprojectMember_entity/recordcontainers/db/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESPROJECT_MEMBER.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/SalesprojectSource_entity/conditionProcess.js b/entity/SalesprojectSource_entity/conditionProcess.js
index e319b875ebe8be3ed307ad2d140029378eb3e4a0..073fed32ea8fe5e90c22f5083a6d2bd22cdadf6a 100644
--- a/entity/SalesprojectSource_entity/conditionProcess.js
+++ b/entity/SalesprojectSource_entity/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESPROJECT_SOURCE.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/SalesprojectSource_entity/recordcontainers/db/conditionProcess.js b/entity/SalesprojectSource_entity/recordcontainers/db/conditionProcess.js
index e319b875ebe8be3ed307ad2d140029378eb3e4a0..073fed32ea8fe5e90c22f5083a6d2bd22cdadf6a 100644
--- a/entity/SalesprojectSource_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/SalesprojectSource_entity/recordcontainers/db/conditionProcess.js
@@ -5,5 +5,5 @@ import("Sql_lib");
 var cond = new SqlCondition();
 cond.andPrepareVars("SALESPROJECT_SOURCE.SALESPROJECT_ID", "$param.SalesprojectId_param");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(cond.build("1 = 1")));
\ No newline at end of file
diff --git a/entity/Salesproject_entity/Salesproject_entity.aod b/entity/Salesproject_entity/Salesproject_entity.aod
index 85fe7caad56b5ff8e2656602f96e4718cf2b315b..187aeefd5659a4287be44398fc10894bdb9d090f 100644
--- a/entity/Salesproject_entity/Salesproject_entity.aod
+++ b/entity/Salesproject_entity/Salesproject_entity.aod
@@ -107,7 +107,7 @@
     <entityField>
       <name>PROBABILITY</name>
       <title>Probability</title>
-      <possibleItemsProcess>%aditoprj%/entity/Salesproject_entity/entityfields/probability/possibleItemsProcess.js</possibleItemsProcess>
+      <consumer>KeywordProbabilties</consumer>
     </entityField>
     <entityConsumer>
       <name>SalesprojectSources</name>
@@ -372,6 +372,21 @@
       <description>Opens the time tracking context in new-mode for the selected salesproject</description>
       <onActionProcess>%aditoprj%/entity/Salesproject_entity/entityfields/newtimetracking/onActionProcess.js</onActionProcess>
     </entityActionField>
+    <entityConsumer>
+      <name>KeywordProbabilties</name>
+      <fieldType>DEPENDENCY_OUT</fieldType>
+      <dependency>
+        <name>dependency</name>
+        <entityName>KeywordEntry_entity</entityName>
+        <fieldName>SpecificContainerKeywords</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>containerName_param</name>
+          <code>%aditoprj%/entity/Salesproject_entity/entityfields/keywordprobabilties/children/containername_param/code.js</code>
+        </entityParameter>
+      </children>
+    </entityConsumer>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -458,6 +473,10 @@
           <name>VOLUME.displayValue</name>
           <expression>%aditoprj%/entity/Salesproject_entity/recordcontainers/db/recordfieldmappings/volume.displayvalue/expression.js</expression>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>PROBABILITY.displayValue</name>
+          <expression>%aditoprj%/entity/Salesproject_entity/recordcontainers/db/recordfieldmappings/probability.displayvalue/expression.js</expression>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
     </dbRecordContainer>
   </recordContainers>
diff --git a/entity/Salesproject_entity/entityfields/keywordprobabilties/children/containername_param/code.js b/entity/Salesproject_entity/entityfields/keywordprobabilties/children/containername_param/code.js
new file mode 100644
index 0000000000000000000000000000000000000000..4eecf47c8cf65b769844277ca6d404f996267724
--- /dev/null
+++ b/entity/Salesproject_entity/entityfields/keywordprobabilties/children/containername_param/code.js
@@ -0,0 +1,4 @@
+import("system.result");
+import("Keyword_lib");
+
+result.string($KeywordRegistry.get.SalesprojectProbability);
\ No newline at end of file
diff --git a/entity/Salesproject_entity/entityfields/probability/possibleItemsProcess.js b/entity/Salesproject_entity/entityfields/probability/possibleItemsProcess.js
deleted file mode 100644
index bea9f367e4a778352426678a9ef9ad69ced0ed5a..0000000000000000000000000000000000000000
--- a/entity/Salesproject_entity/entityfields/probability/possibleItemsProcess.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import("system.result");
-import("Keyword_lib");
-
-result.object(LegacyKeywordUtils.getStandardArray("SALESPROJECT.PROBABILITY"));
\ No newline at end of file
diff --git a/entity/Salesproject_entity/recordcontainers/db/recordfieldmappings/probability.displayvalue/expression.js b/entity/Salesproject_entity/recordcontainers/db/recordfieldmappings/probability.displayvalue/expression.js
new file mode 100644
index 0000000000000000000000000000000000000000..a5769eccec40249640f8612dacb4ecede39106f4
--- /dev/null
+++ b/entity/Salesproject_entity/recordcontainers/db/recordfieldmappings/probability.displayvalue/expression.js
@@ -0,0 +1,5 @@
+import("system.result");
+import("Keyword_lib");
+
+var sql = KeywordUtils.getResolvedTitleSqlPart($KeywordRegistry.get.SalesprojectProbability, "SALESPROJECT.PROBABILITY");
+result.string(sql);
diff --git a/entity/Timetracking_entity/recordcontainers/db/conditionProcess.js b/entity/Timetracking_entity/recordcontainers/db/conditionProcess.js
index 78f4834ba957291f36dc11c14be72cbf03298c37..453de018514acca0b31ecd289b38c76bf3c1c0f8 100644
--- a/entity/Timetracking_entity/recordcontainers/db/conditionProcess.js
+++ b/entity/Timetracking_entity/recordcontainers/db/conditionProcess.js
@@ -4,7 +4,7 @@ import("system.db");
 import("system.result");
 import("Sql_lib");
 
-//TODO: use a preparedCondition when available
+//TODO: use a preparedCondition when available #1030812 #1034026
 result.string(db.translateCondition(SqlCondition.begin()
             .andPrepareVars("TIMETRACKING.OBJECT_ID", "$param.ObjectId_param")
             .andPrepareVars("TIMETRACKING.ROW_ID", "$param.RowId_param")
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index c1c8d1700a6f29e348e3a21a08aa7d2925d86e80..a9229f28932caa73253a6bcd62852533e74d4f90 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -69,9 +69,6 @@
     <entry>
       <key>Contactmanagement</key>
     </entry>
-    <entry>
-      <key>United Kingdom</key>
-    </entry>
     <entry>
       <key>Mobile</key>
     </entry>
@@ -738,9 +735,6 @@
     <entry>
       <key>Native Name</key>
     </entry>
-    <entry>
-      <key>ZIP code is not valid</key>
-    </entry>
     <entry>
       <key>Rabatt</key>
     </entry>
@@ -1104,9 +1098,6 @@
     <entry>
       <key>priority</key>
     </entry>
-    <entry>
-      <key>zusagen</key>
-    </entry>
     <entry>
       <key>{$TASK_PRIORITY_HIGH}</key>
     </entry>
@@ -1152,9 +1143,6 @@
     <entry>
       <key>Firma</key>
     </entry>
-    <entry>
-      <key>absagen</key>
-    </entry>
     <entry>
       <key>type</key>
     </entry>
@@ -1167,9 +1155,6 @@
     <entry>
       <key>{$TASK_PRIORITY_NONE}</key>
     </entry>
-    <entry>
-      <key>vielleicht</key>
-    </entry>
     <entry>
       <key>Ihr zuständiger Betreuer:</key>
     </entry>
@@ -2286,6 +2271,66 @@
     <entry>
       <key>SAL</key>
     </entry>
+    <entry>
+      <key>Checkbox</key>
+    </entry>
+    <entry>
+      <key>Numeric value</key>
+    </entry>
+    <entry>
+      <key>decline</key>
+    </entry>
+    <entry>
+      <key>Text</key>
+    </entry>
+    <entry>
+      <key>Group</key>
+    </entry>
+    <entry>
+      <key>Combobox</key>
+    </entry>
+    <entry>
+      <key>tentative</key>
+    </entry>
+    <entry>
+      <key>${NUMBER}</key>
+    </entry>
+    <entry>
+      <key>Name \&amp;quot;%0\&amp;quot; already used for container \&amp;quot;%1\&amp;quot;</key>
+    </entry>
+    <entry>
+      <key>CHAR_VALUE</key>
+    </entry>
+    <entry>
+      <key>Keyword Attribute</key>
+    </entry>
+    <entry>
+      <key>in</key>
+    </entry>
+    <entry>
+      <key>Keyword Attribute Values</key>
+    </entry>
+    <entry>
+      <key>Boolean value</key>
+    </entry>
+    <entry>
+      <key>accept</key>
+    </entry>
+    <entry>
+      <key>The ZIP code does not match the format of the country.</key>
+    </entry>
+    <entry>
+      <key>String value</key>
+    </entry>
+    <entry>
+      <key>The code number is not a valid number.</key>
+    </entry>
+    <entry>
+      <key>Linkobject</key>
+    </entry>
+    <entry>
+      <key>Linktype</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 65445eea66285151213f41a569765fca398c94b2..0959f7869c2d312efd87811a0d3ff7ace0ee2325 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -138,10 +138,6 @@
       <key>Contactmanagement</key>
       <value>Kontaktmanagement</value>
     </entry>
-    <entry>
-      <key>United Kingdom</key>
-      <value>Vereinigtes Königreich</value>
-    </entry>
     <entry>
       <key>Mobile</key>
       <value>Mobil</value>
@@ -1206,9 +1202,6 @@
     <entry>
       <key>Native Name</key>
     </entry>
-    <entry>
-      <key>ZIP code is not valid</key>
-    </entry>
     <entry>
       <key>Rabatt</key>
     </entry>
@@ -1494,9 +1487,6 @@
       <key>{$TASK_EDITOR}</key>
       <value>Bearbeiter</value>
     </entry>
-    <entry>
-      <key>zusagen</key>
-    </entry>
     <entry>
       <key>{$TASK_PRIORITY_HIGH}</key>
       <value>hoch</value>
@@ -1548,9 +1538,6 @@
     <entry>
       <key>Firma</key>
     </entry>
-    <entry>
-      <key>absagen</key>
-    </entry>
     <entry>
       <key>type</key>
       <value>Typ</value>
@@ -1565,9 +1552,6 @@
       <key>{$TASK_PRIORITY_NONE}</key>
       <value>keine</value>
     </entry>
-    <entry>
-      <key>vielleicht</key>
-    </entry>
     <entry>
       <key>Ihr zuständiger Betreuer:</key>
     </entry>
@@ -2638,6 +2622,70 @@
     <entry>
       <key>SAL</key>
     </entry>
+    <entry>
+      <key>Checkbox</key>
+    </entry>
+    <entry>
+      <key>Numeric value</key>
+    </entry>
+    <entry>
+      <key>decline</key>
+    </entry>
+    <entry>
+      <key>Text</key>
+    </entry>
+    <entry>
+      <key>Group</key>
+    </entry>
+    <entry>
+      <key>Combobox</key>
+    </entry>
+    <entry>
+      <key>tentative</key>
+    </entry>
+    <entry>
+      <key>${NUMBER}</key>
+    </entry>
+    <entry>
+      <key>Name \&amp;quot;%0\&amp;quot; already used for container \&amp;quot;%1\&amp;quot;</key>
+    </entry>
+    <entry>
+      <key>CHAR_VALUE</key>
+    </entry>
+    <entry>
+      <key>Keyword Attribute</key>
+      <value>Schlüsselwort-Attribut</value>
+    </entry>
+    <entry>
+      <key>in</key>
+    </entry>
+    <entry>
+      <key>Keyword Attribute Values</key>
+      <value>Schlüsselwort-Attribut-Werte</value>
+    </entry>
+    <entry>
+      <key>Boolean value</key>
+    </entry>
+    <entry>
+      <key>accept</key>
+    </entry>
+    <entry>
+      <key>The ZIP code does not match the format of the country.</key>
+      <value>Die Postleitzahl hat nicht das Format des ausgewählten Landes.</value>
+    </entry>
+    <entry>
+      <key>String value</key>
+    </entry>
+    <entry>
+      <key>The code number is not a valid number.</key>
+      <value>The code number is not a valid number.</value>
+    </entry>
+    <entry>
+      <key>Linkobject</key>
+    </entry>
+    <entry>
+      <key>Linktype</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index ae7af90419dbdfe808f9464dccbeef705be97346..5d720094ac3eb4cb891c1e6fc0d4db7851b70213 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -74,9 +74,6 @@
     <entry>
       <key>Contactmanagement</key>
     </entry>
-    <entry>
-      <key>United Kingdom</key>
-    </entry>
     <entry>
       <key>Mobile</key>
     </entry>
@@ -747,9 +744,6 @@
     <entry>
       <key>Native Name</key>
     </entry>
-    <entry>
-      <key>ZIP code is not valid</key>
-    </entry>
     <entry>
       <key>Rabatt</key>
     </entry>
@@ -1117,9 +1111,6 @@
     <entry>
       <key>priority</key>
     </entry>
-    <entry>
-      <key>zusagen</key>
-    </entry>
     <entry>
       <key>{$TASK_PRIORITY_HIGH}</key>
       <value>high</value>
@@ -1168,9 +1159,6 @@
     <entry>
       <key>Firma</key>
     </entry>
-    <entry>
-      <key>absagen</key>
-    </entry>
     <entry>
       <key>type</key>
     </entry>
@@ -1181,9 +1169,6 @@
       <key>{$TASK_PRIORITY_NONE}</key>
       <value>none</value>
     </entry>
-    <entry>
-      <key>vielleicht</key>
-    </entry>
     <entry>
       <key>Datum</key>
     </entry>
@@ -2308,6 +2293,66 @@
     <entry>
       <key>SAL</key>
     </entry>
+    <entry>
+      <key>Checkbox</key>
+    </entry>
+    <entry>
+      <key>Numeric value</key>
+    </entry>
+    <entry>
+      <key>decline</key>
+    </entry>
+    <entry>
+      <key>Text</key>
+    </entry>
+    <entry>
+      <key>Group</key>
+    </entry>
+    <entry>
+      <key>Combobox</key>
+    </entry>
+    <entry>
+      <key>tentative</key>
+    </entry>
+    <entry>
+      <key>${NUMBER}</key>
+    </entry>
+    <entry>
+      <key>Name \&amp;quot;%0\&amp;quot; already used for container \&amp;quot;%1\&amp;quot;</key>
+    </entry>
+    <entry>
+      <key>CHAR_VALUE</key>
+    </entry>
+    <entry>
+      <key>Keyword Attribute</key>
+    </entry>
+    <entry>
+      <key>in</key>
+    </entry>
+    <entry>
+      <key>Keyword Attribute Values</key>
+    </entry>
+    <entry>
+      <key>Boolean value</key>
+    </entry>
+    <entry>
+      <key>accept</key>
+    </entry>
+    <entry>
+      <key>The ZIP code does not match the format of the country.</key>
+    </entry>
+    <entry>
+      <key>String value</key>
+    </entry>
+    <entry>
+      <key>The code number is not a valid number.</key>
+    </entry>
+    <entry>
+      <key>Linkobject</key>
+    </entry>
+    <entry>
+      <key>Linktype</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/neonContext/Attribute/Attribute.aod b/neonContext/Attribute/Attribute.aod
index e157e7bc53cbfd71638f601b84e5df8fce123f6b..3504918a02b55108b0a0b0d7985b65676c4551c4 100644
--- a/neonContext/Attribute/Attribute.aod
+++ b/neonContext/Attribute/Attribute.aod
@@ -8,6 +8,7 @@
   <filterview>AttributeFilter_view</filterview>
   <editview>AttributeEdit_view</editview>
   <preview>AttributePreview_view</preview>
+  <lookupview>AttributeFilter_view</lookupview>
   <entity>Attribute_entity</entity>
   <references>
     <neonViewReference>
@@ -26,5 +27,9 @@
       <name>05d998e7-7364-4425-aefe-3cf284933d52</name>
       <view>AttributeMain_view</view>
     </neonViewReference>
+    <neonViewReference>
+      <name>6ab8d733-544c-4e48-ade9-b5210a5e5355</name>
+      <view>AttributeTree_view</view>
+    </neonViewReference>
   </references>
 </neonContext>
diff --git a/neonView/AppointmentEdit_view/AppointmentEdit_view.aod b/neonView/AppointmentEdit_view/AppointmentEdit_view.aod
index 1f551da997bef91635ac50563b6ea83c402255e2..68581d6336cf998f5963361f1f428d10b09a002b 100644
--- a/neonView/AppointmentEdit_view/AppointmentEdit_view.aod
+++ b/neonView/AppointmentEdit_view/AppointmentEdit_view.aod
@@ -31,6 +31,7 @@
       <masterEndField>MASTEREND</masterEndField>
       <reminderField>REMINDER</reminderField>
       <appointmentLinkField>LINKS</appointmentLinkField>
+      <appointmentLinkTypeField>LINKTYPE</appointmentLinkTypeField>
       <entityField>#ENTITY</entityField>
     </appointmentEditViewTemplate>
     <neonViewReference>
diff --git a/neonView/AppointmentLinkFilter_view/AppointmentLinkFilter_view.aod b/neonView/AppointmentLinkFilter_view/AppointmentLinkFilter_view.aod
index 7a2a9c8fe9001cb857e64cdc3e9202fe09490371..5b3687e15985f31e096b02f1773fe9401a34de96 100644
--- a/neonView/AppointmentLinkFilter_view/AppointmentLinkFilter_view.aod
+++ b/neonView/AppointmentLinkFilter_view/AppointmentLinkFilter_view.aod
@@ -12,22 +12,14 @@
       <name>Links</name>
       <entityField>#ENTITY</entityField>
       <columns>
-        <neonTableColumn>
-          <name>a9c230fa-dbfd-40c6-975b-7778dea6ef78</name>
-          <entityField>APPOINTMENTLINKID</entityField>
-        </neonTableColumn>
-        <neonTableColumn>
-          <name>0da4bab5-6a9a-4411-92db-517b7cb327de</name>
-          <entityField>APPOINTMENT_ID</entityField>
-        </neonTableColumn>
-        <neonTableColumn>
-          <name>4b89082a-c6c0-4af8-ab94-b3ad8bfb6c04</name>
-          <entityField>OBJECTID</entityField>
-        </neonTableColumn>
         <neonTableColumn>
           <name>17c0a8a9-354c-4095-a5d4-5c2613c897a3</name>
           <entityField>OBJECTTYPE</entityField>
         </neonTableColumn>
+        <neonTableColumn>
+          <name>7c5f9eae-7a47-4ee4-a168-06f7265fa1ef</name>
+          <entityField>OBJECT_TITLE</entityField>
+        </neonTableColumn>
       </columns>
     </tableViewTemplate>
   </children>
diff --git a/neonView/AttributeEdit_view/AttributeEdit_view.aod b/neonView/AttributeEdit_view/AttributeEdit_view.aod
index 6662e966bccccb1b1e1f04cd2cb9fd4d81595ad9..e68bf0bc073627df37ef7548b26597b685bc879a 100644
--- a/neonView/AttributeEdit_view/AttributeEdit_view.aod
+++ b/neonView/AttributeEdit_view/AttributeEdit_view.aod
@@ -13,6 +13,10 @@
       <editMode v="true" />
       <entityField>#ENTITY</entityField>
       <fields>
+        <entityFieldLink>
+          <name>2d269ed7-a664-40c3-aadb-f274f7c00a66</name>
+          <entityField>ATTRIBUTE_PARENT_ID</entityField>
+        </entityFieldLink>
         <entityFieldLink>
           <name>0c6cd7c6-cced-4719-b0c5-08f8e3d13f2f</name>
           <entityField>ATTRIBUTE_NAME</entityField>
diff --git a/neonView/AttributeMain_view/AttributeMain_view.aod b/neonView/AttributeMain_view/AttributeMain_view.aod
index 3e3b69fbba6fa6eb521067884c38357530389024..657bbd1e9b0995bdcc9a05b76b51e69da409ce36 100644
--- a/neonView/AttributeMain_view/AttributeMain_view.aod
+++ b/neonView/AttributeMain_view/AttributeMain_view.aod
@@ -15,9 +15,9 @@
       <view>AttributePreview_view</view>
     </neonViewReference>
     <neonViewReference>
-      <name>d8009eea-f473-4f65-8796-a1ab48ef3b49</name>
-      <entityField>#ENTITY</entityField>
-      <view>AttributeFilter_view</view>
+      <name>634c58b7-74db-42d3-a90c-029678e4fed4</name>
+      <entityField>AttributeChildren</entityField>
+      <view>AttributeTree_view</view>
     </neonViewReference>
     <neonViewReference>
       <name>5dee1c0b-c670-4eb9-bd95-6f6474709aa2</name>
diff --git a/neonView/AttributePreview_view/AttributePreview_view.aod b/neonView/AttributePreview_view/AttributePreview_view.aod
index 39928da62cb424594ac8ab1cd284a8743a01ccbf..278a72ae11a46c33de1ba4b5ef02edcf6169aec8 100644
--- a/neonView/AttributePreview_view/AttributePreview_view.aod
+++ b/neonView/AttributePreview_view/AttributePreview_view.aod
@@ -1,18 +1,18 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.1">
-  <name>AttributePreview_view</name>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <layout>
-    <boxLayout>
-      <name>layout</name>
-    </boxLayout>
-  </layout>
-  <children>
-    <cardViewTemplate>
-      <name>Attr_template</name>
-      <titleField>ATTRIBUTE_NAME</titleField>
-      <descriptionField>ATTRIBUTE_TYPE</descriptionField>
-      <entityField>#ENTITY</entityField>
-    </cardViewTemplate>
-  </children>
-</neonView>
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.1">
+  <name>AttributePreview_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <cardViewTemplate>
+      <name>Attr_template</name>
+      <titleField>ATTRIBUTE_NAME</titleField>
+      <subtitleField>ATTRIBUTE_TYPE</subtitleField>
+      <entityField>#ENTITY</entityField>
+    </cardViewTemplate>
+  </children>
+</neonView>
diff --git a/neonView/AttributeTree_view/AttributeTree_view.aod b/neonView/AttributeTree_view/AttributeTree_view.aod
new file mode 100644
index 0000000000000000000000000000000000000000..b1bb94f4487d39a4d56c56d9706b3c3b99eebcc5
--- /dev/null
+++ b/neonView/AttributeTree_view/AttributeTree_view.aod
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.1">
+  <name>AttributeTree_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <treetableViewTemplate>
+      <name>Treetable</name>
+      <parentField>ATTRIBUTE_PARENT_ID</parentField>
+      <titleField>ATTRIBUTE_NAME</titleField>
+      <descriptionField>ATTRIBUTE_TYPE</descriptionField>
+      <entityField>#ENTITY</entityField>
+    </treetableViewTemplate>
+  </children>
+</neonView>
diff --git a/others/db_changes/data_alias/data/AditoBasic/ab_keyword_attribute.xml b/others/db_changes/data_alias/data/AditoBasic/ab_keyword_attribute.xml
index c3c086c020b41f4e785473ae0de007836a4eb020..f16b870ba5123e70c249b87a3bf09309f50897fb 100644
--- a/others/db_changes/data_alias/data/AditoBasic/ab_keyword_attribute.xml
+++ b/others/db_changes/data_alias/data/AditoBasic/ab_keyword_attribute.xml
@@ -1,4 +1,4 @@
 <?xml version="1.1" encoding="UTF-8" standalone="no"?>
 <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
-    <include relativeToChangelogFile="true" file="ab_keyword_attribute/init_SalesprojectProbability_points.xml"/>
+    <include relativeToChangelogFile="true" file="ab_keyword_attribute/init_SalesprojectProbability_percentValue.xml"/>
 </databaseChangeLog>
diff --git a/others/db_changes/data_alias/data/AditoBasic/ab_keyword_attribute/init_SalesprojectProbability_percentValue.xml b/others/db_changes/data_alias/data/AditoBasic/ab_keyword_attribute/init_SalesprojectProbability_percentValue.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e7425b24dcd38e28003820d50f3e5f846c0e7b66
--- /dev/null
+++ b/others/db_changes/data_alias/data/AditoBasic/ab_keyword_attribute/init_SalesprojectProbability_percentValue.xml
@@ -0,0 +1,41 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+    <changeSet author="j.goderbauer" id="a2375d469a-1eda-4b40-802b-312323d9f2e7">
+        <insert tableName="AB_KEYWORD_ATTRIBUTE">
+            <column name="AB_KEYWORD_ATTRIBUTEID" value="2fabbd9a-89d2-49e3-b3aa-1dcbc77252c7"/>
+            <column name="NAME" value="percentValue"/>
+            <column name="TYPE" value="NUMBER_VALUE"/>
+            <column name="CONTAINER" value="SalesprojectProbability"/>
+        </insert>
+        <insert tableName="AB_KEYWORD_ATTRIBUTERELATION">
+            <column name="AB_KEYWORD_ATTRIBUTERELATIONID" value="8b719177-b9a1-44f8-bfba-34b678d84daa"/>
+            <column name="AB_KEYWORD_ATTRIBUTE_ID" value="2fabbd9a-89d2-49e3-b3aa-1dcbc77252c7"/>
+            <column name="AB_KEYWORD_ENTRY_ID" value="ab44bd2c-dffa-4731-8a24-fad31f069c46"/>
+            <column name="NUMBER_VALUE" valueNumeric="0"/>
+        </insert>
+        <insert tableName="AB_KEYWORD_ATTRIBUTERELATION">
+            <column name="AB_KEYWORD_ATTRIBUTERELATIONID" value="1a233346-a284-49a8-ac51-c3a214474e88"/>
+            <column name="AB_KEYWORD_ATTRIBUTE_ID" value="2fabbd9a-89d2-49e3-b3aa-1dcbc77252c7"/>
+            <column name="AB_KEYWORD_ENTRY_ID" value="e59169d3-c0d9-4718-b8b6-e315857948a0"/>
+            <column name="NUMBER_VALUE" valueNumeric="25"/>
+        </insert>
+        <insert tableName="AB_KEYWORD_ATTRIBUTERELATION">
+            <column name="AB_KEYWORD_ATTRIBUTERELATIONID" value="2d8b8da4-1241-4094-abf5-54d8cacadcaf"/>
+            <column name="AB_KEYWORD_ATTRIBUTE_ID" value="2fabbd9a-89d2-49e3-b3aa-1dcbc77252c7"/>
+            <column name="AB_KEYWORD_ENTRY_ID" value="415f1cf0-8c5b-4b6e-9900-0d0d6d72381c"/>
+            <column name="NUMBER_VALUE" valueNumeric="50"/>
+        </insert>
+        <insert tableName="AB_KEYWORD_ATTRIBUTERELATION">
+            <column name="AB_KEYWORD_ATTRIBUTERELATIONID" value="d02adcf4-fdc0-4614-ad44-88fa9de77a37"/>
+            <column name="AB_KEYWORD_ATTRIBUTE_ID" value="2fabbd9a-89d2-49e3-b3aa-1dcbc77252c7"/>
+            <column name="AB_KEYWORD_ENTRY_ID" value="6182cc48-df2b-4ba9-893a-bcedfd0e1e4b"/>
+            <column name="NUMBER_VALUE" valueNumeric="75"/>
+        </insert>
+        <insert tableName="AB_KEYWORD_ATTRIBUTERELATION">
+            <column name="AB_KEYWORD_ATTRIBUTERELATIONID" value="f25f0406-998b-4b29-9432-4dafa378f1eb"/>
+            <column name="AB_KEYWORD_ATTRIBUTE_ID" value="2fabbd9a-89d2-49e3-b3aa-1dcbc77252c7"/>
+            <column name="AB_KEYWORD_ENTRY_ID" value="f5b601a5-451b-4ab6-9167-b95077e90c62"/>
+            <column name="NUMBER_VALUE" valueNumeric="100"/>
+        </insert>
+    </changeSet>
+</databaseChangeLog>
\ No newline at end of file
diff --git a/others/db_changes/data_alias/data/AditoBasic/ab_keyword_attribute/init_SalesprojectProbability_points.xml b/others/db_changes/data_alias/data/AditoBasic/ab_keyword_attribute/init_SalesprojectProbability_points.xml
deleted file mode 100644
index 4f026375759b21e39e16f06cda5e53d3a0a3cb18..0000000000000000000000000000000000000000
--- a/others/db_changes/data_alias/data/AditoBasic/ab_keyword_attribute/init_SalesprojectProbability_points.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.1" encoding="UTF-8" standalone="no"?>
-<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
-    <changeSet author="j.goderbauer" id="a2375d469a-1eda-4b40-802b-312323d9f2e7">
-        <insert tableName="AB_KEYWORD_ATTRIBUTE">
-            <column name="AB_KEYWORD_ATTRIBUTEID" value="2fabbd9a-89d2-49e3-b3aa-1dcbc77252c7"/>
-            <column name="NAME" value="points"/>
-            <column name="TYPE" value="NUMBER_VALUE"/>
-            <column name="CONTAINER" value="SalesprojectProbability"/>
-        </insert>
-    </changeSet>
-</databaseChangeLog>
\ No newline at end of file
diff --git a/others/db_changes/data_alias/data/example_salesproject/SALESPROJECT_gfk.xml b/others/db_changes/data_alias/data/example_salesproject/SALESPROJECT_gfk.xml
index f6d33a88ac80334ea43da4d69dc0cada95e47d6b..78e3fb27480d753b524aa5aa9b5ed5f370c4d41d 100644
--- a/others/db_changes/data_alias/data/example_salesproject/SALESPROJECT_gfk.xml
+++ b/others/db_changes/data_alias/data/example_salesproject/SALESPROJECT_gfk.xml
@@ -1,4 +1,4 @@
-<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
 <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
 <changeSet author="j.hoermanns" id="76912d9-ced7-4626-a031-d7138dfc948e">
     <insert tableName="SALESPROJECT">
@@ -15,7 +15,7 @@
         <column name="ENDDATE" valueDate="2017-10-14T09:03:43"/>
         <column name="ESTIMATION" value="; 2; 4; 11; "/>
         <column name="ESTIMATIONVALUE" valueNumeric="2"/>
-        <column name="PROBABILITY" valueNumeric="30"/>
+        <column name="PROBABILITY" value="b981a107-7e20-42a6-baf4-3fc09a939cd7"/>
     </insert>
     <insert tableName="AB_OBJECTRELATION">
         <column name="AB_OBJECTRELATIONID" value="6dd516b2-7887-4a17-930a-d39607c8b626"/>
diff --git a/others/db_changes/data_alias/data/example_salesproject/SALESPROJECT_jkl.xml b/others/db_changes/data_alias/data/example_salesproject/SALESPROJECT_jkl.xml
index 6f5ae0997e577053bab1b6aa43677db3c86324d8..530eacad2339a51bb508c32ce79e65f0b7ecff18 100644
--- a/others/db_changes/data_alias/data/example_salesproject/SALESPROJECT_jkl.xml
+++ b/others/db_changes/data_alias/data/example_salesproject/SALESPROJECT_jkl.xml
@@ -15,7 +15,7 @@
         <column name="ENDDATE" valueDate="2017-10-14T09:03:43"/>
         <column name="ESTIMATION" value="; 2; 4; 11; "/>
         <column name="ESTIMATIONVALUE" valueNumeric="2"/>
-        <column name="PROBABILITY" valueNumeric="30"/>
+        <column name="PROBABILITY" value="b981a107-7e20-42a6-baf4-3fc09a939cd7"/>
     </insert>
 
     <rollback>			
diff --git a/others/db_changes/data_alias/struct/AditoBasic/create_ab_keyword_attribute.xml b/others/db_changes/data_alias/struct/AditoBasic/create_ab_keyword_attribute.xml
index baffb14652f6ea01e9601b911a457f939c0ebbdc..a39bf989d429478b93618c47e518fe3f908f768b 100644
--- a/others/db_changes/data_alias/struct/AditoBasic/create_ab_keyword_attribute.xml
+++ b/others/db_changes/data_alias/struct/AditoBasic/create_ab_keyword_attribute.xml
@@ -6,10 +6,10 @@
                 <constraints primaryKey="true" primaryKeyName="PK_AB_KEYWORD_ATTRIBUTEID"/>
             </column>
 
-            <column name="NAME" type="CHAR(36)">
+            <column name="NAME" type="VARCHAR(100)">
                 <constraints nullable="false"/>
             </column>
-            <column name="TYPE" type="NVARCHAR(100)">
+            <column name="TYPE" type="CHAR(36)">
                 <constraints nullable="false"/>
             </column>
             <column name="CONTAINER" type="VARCHAR(80)">
diff --git a/others/db_changes/data_alias/struct/create_appointmentlink.xml b/others/db_changes/data_alias/struct/create_appointmentlink.xml
index 7d5a08a68ebef16508e15af7f29a199d06dd0f5c..1f894be5d0e0415504d85666e51379f6bb77bffb 100644
--- a/others/db_changes/data_alias/struct/create_appointmentlink.xml
+++ b/others/db_changes/data_alias/struct/create_appointmentlink.xml
@@ -14,7 +14,9 @@
             <column name="OBJECT_ROWID" type="CHAR(36)">
                 <constraints nullable="false"/>
             </column>
-            
+            <column name="OBJECT_TITLE" type="VARCHAR(123)">
+                <constraints nullable="false"/>
+            </column>
         </createTable>
     </changeSet>
 </databaseChangeLog>
\ No newline at end of file
diff --git a/others/db_changes/data_alias/struct/create_salesproject.xml b/others/db_changes/data_alias/struct/create_salesproject.xml
index 6fc8e7ce27a514f8f526cc9dcf7529eaac15263d..1a18e814008c98a7093a6ed5648f0f19ae3d4db4 100644
--- a/others/db_changes/data_alias/struct/create_salesproject.xml
+++ b/others/db_changes/data_alias/struct/create_salesproject.xml
@@ -18,7 +18,7 @@
             <column name="ENDDATE" type="DATETIME"/>
             <column name="ESTIMATION" type="NVARCHAR(50)"/>
             <column name="ESTIMATIONVALUE" type="INTEGER"/>
-            <column name="PROBABILITY" type="INTEGER"/>
+            <column name="PROBABILITY" type="CHAR(36)"/>
 
             <column name="SALESPROJECTID" type="CHAR(36)">
                 <constraints primaryKey="true" primaryKeyName="PK_SALESPROJECT_SALESPROJECTID"/>
diff --git a/others/db_changes/system_alias/struct/create_asys_calendarbackend.xml b/others/db_changes/system_alias/struct/create_asys_calendarbackend.xml
index b53fa28d896392c8e23f4f9d0e71d9341b3ad554..682a7b9ecbdd5e3ea76b6e83a822e9587b8cd2ed 100644
--- a/others/db_changes/system_alias/struct/create_asys_calendarbackend.xml
+++ b/others/db_changes/system_alias/struct/create_asys_calendarbackend.xml
@@ -2,13 +2,11 @@
 <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
 <changeSet author="a.schindlbeck" id="647ddc15-7bde-4b04-81e4-9a62a24aa5b7">
     <createTable tableName="ASYS_CALENDARBACKEND">
-        <column name="ELEMENTUID" type="VARCHAR(512)">
-            <constraints primaryKey="true" primaryKeyName="PK_ASYS_CALENDARBACKEND_ELEMENTUID"/>
-        </column>
-        <column name="CLASSIFICATION" type="INTEGER"/>
         <column name="DATASETID" type="CHAR(36)">
-            <constraints nullable="false"/>
+            <constraints nullable="false" primaryKey="true" primaryKeyName="PK_ASYS_CALENDARBACKEND_ELEMENTUID"/>
         </column>
+        <column name="ELEMENTUID" type="VARCHAR(512)"/>
+        <column name="CLASSIFICATION" type="INTEGER"/>
         <column name="DTEND" type="DATETIME"/>
         <column name="DTSTART" type="DATETIME"/>
         <column name="ENDTIME" type="DATETIME"/>
diff --git a/process/Attribute_lib/process.js b/process/Attribute_lib/process.js
index d8692505d9e5f89e7db063fa7b57e491e450bf1b..43b6114339dbbcee6399d1955235b7c67149b696 100644
--- a/process/Attribute_lib/process.js
+++ b/process/Attribute_lib/process.js
@@ -1,232 +1,260 @@
-import("system.translate");
-import("system.neon");
-import("system.vars");
-import("system.db");
-import("Sql_lib");
-
-/**
- * Provides functions for the work with attributes, like setting or getting the value of an attribute
- * or listing the available attributes for a context.
- * Don't instanciate this!
- * 
- * @class
- */
-function AttributeUtil () {}
-
-/**
- * Gives a list of all available attributes for a context. This is used in the possibleItems
- * process for the attribute id in AttributeRelation
- * 
- * @param {String} pObjectType the object type (= context)
- * 
- * @return {String[][]} two-dimensional array of attributeIds and names
- */
-AttributeUtil.getPossibleAttributes = function (pObjectType)
-{
-    if (pObjectType == null)
-        return [];
-    
-    var attrSql = "select AB_ATTRIBUTEID, ATTRIBUTE_NAME from AB_ATTRIBUTE"
-        + " join AB_ATTRIBUTEUSAGE  on AB_ATTRIBUTEID = AB_ATTRIBUTE_ID";
-    attrSql = SqlCondition.begin()
-        .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType)
-        .and("ATTRIBUTE_ACTIVE = 1")
-        .buildSql(attrSql);
-
-    return db.table(attrSql);
-}
-
-/**
- * gets the value of an attribute for one dataset (e. g. a person)
- */
-AttributeUtil.getAttribute = function (pAttributeId, pObjectType, pObjectRowId, pGetIdValue)
-{
-    //TODO: implement
-}
-
-AttributeUtil.getAttributes = function ()
-{
-    //TODO: implement maybe
-}
-
-/**
- * sets the value of an attribute for one dataset (e. g. a person)
- */
-AttributeUtil.setAttribute = function ()
-{
-    //TODO: implement
-}
-
-
-/**
- * This is used in the AttributeRelation enitiy to make the work with attributes there
- * easier. You probaly won't need this for anything else.
- * 
- * @param {String} pAttrId the id of the attribute
- */
-function AttributeHandler (pAttrId)   //TODO: find out if this class is necessary, maybe there is a more elegant solution, this could also be static
-{
-    this.attributeId = pAttrId;
-    this._attributeType = null;
-}
-
-AttributeHandler.begin = function (pAttrId)
-{
-    return new AttributeHandler(pAttrId);
-}
-
-/**
- * gets the type of the attribute by the attributeId, after the first call the value
- * is stored so that the sql selection is done only once
- * 
- * @return {String} attribute type
- */
-AttributeHandler.prototype._getAttributeType = function () //TODO: maybe the type should be an own field in the entity instead of getting the type from the attribute id
-{
-    if (this._attributeType == null && this.attributeId != null)
-    {
-        var attrTypeSelect = "select ATTRIBUTE_TYPE from AB_ATTRIBUTE";
-        attrTypeSelect = SqlCondition.begin()
-            .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", this.attributeId)
-            .buildSql(attrTypeSelect);
-        this._attributeType = db.cell(attrTypeSelect).trim();
-    }
-    return this._attributeType;
-}
-
-/**
- * returns the field that belongs to the type of the attribute
- * 
- * @return {String} attribute field
- */
-AttributeHandler.prototype.getAttributeField = function ()
-{
-    return AttributeTypes.getEntityField(this._getAttributeType());
-}
-
-/**
- * returns the content type that belongs to the type of the attribute
- * 
- * @return {String} attribute field
- */
-AttributeHandler.prototype.getAttributeContentType = function ()
-{
-    return AttributeTypes.getContentType(this._getAttributeType());
-}
-
-AttributeHandler.prototype.setAttributeValue = function (pValue)
-{
-    var field = "$field." + this.getAttributeField();
-    if (field != null && vars.exists(field))
-        neon.setFieldValue(field, pValue)
-    return pValue;
-}
-
-/**
- * Object for the enumeration and management of all attribute types.
- * This Object is only for the general definition of attribute types and for getting
- * data about every type, anything that has to do with a specific attribute (= the function requires an attribute id)
- * should be done in AttributeUtils.
- * The values for each type are:
- * 
- * contentType = the value that is returned in the contentType process for the attribute
- * databaseField = the database field that holds values of attributes with the type
- * entityField = the field in the AttributeRelation enity that holds the value of the attribute for that type
- * 
- * The display name is controlled by the keyword 'AttributeType'
- */
-var AttributeTypes = {
-    TEXT : { 
-        toString : function () {return "TEXT"},
-        contentType : "TEXT", 
-        databaseField : "CHAR_VALUE", 
-        entityField : "CHAR_VALUE"
-    },
-    DATE : {
-        toString : function () {return "DATE"},
-        contentType : "DATE", 
-        databaseField : "DATE_VALUE", 
-        entityField : "DATE_VALUE"
-    },
-    NUMBER : {
-        toString : function () {return "NUMBER"},
-        contentType : "NUMBER", 
-        databaseField : "NUMBER_VALUE", 
-        entityField : "NUMBER_VALUE"
-    },
-    BOOLEAN : {
-        toString : function () {return "BOOLEAN"},
-        contentType : "BOOLEAN", 
-        databaseField : "BOOL_VALUE", 
-        entityField : "BOOL_VALUE"
-    },
-    COMBO : {
-        toString : function () {return "COMBO"},
-        contentType : "TEXT", 
-        databaseField : "ID_VALUE", 
-        entityField : "ID_VALUE"
-    },
-    GROUP : {
-        toString : function () {return "GROUP"},
-        contentType : null, 
-        databaseField : null, 
-        entityField : null
-    }
-};
-
-
-/**
- * returns the required contentType for the given attribute type
- * 
- * @param {String} pAttributeType the attribute type 
- *                  (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT)
- * @return {String} the contentType for the attribute
- */
-AttributeTypes.getContentType = function (pAttributeType)
-{
-    if (pAttributeType in AttributeTypes)
-        return AttributeTypes[pAttributeType].contentType;
-    return null;
-}
-
-/**
- * returns the entity field for the given attribute type that holds the value of the attribute
- * 
- * @param {String} pAttributeType the attribute type 
- *                  (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT)
- * @return {String} the field for the attribute
- */
-AttributeTypes.getEntityField = function (pAttributeType)
-{
-    if (pAttributeType in AttributeTypes)
-        return AttributeTypes[pAttributeType].entityField;
-    return null;
-}
-
-/**
- * returns the database field for the given attribute type that holds the value of the attribute
- * 
- * @param {String} pAttributeType the attribute type 
- *                  (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT)
- * @return {String} the database field for the attribute
- */
-AttributeTypes.getDatabaseField = function (pAttributeType)
-{
-    if (pAttributeType in AttributeTypes)
-        return AttributeTypes[pAttributeType].databaseField;
-    return null;
-}
-
-/**
- * returns the name of the given attribute type
- * 
- * @param {String} pAttributeType the attribute type 
- *                  (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT)
- * @return {String} the name the attribute
- */
-AttributeTypes.getName = function (pAttributeType)
-{
-    if (pAttributeType in AttributeTypes)
-        return translate.text(AttributeTypes[pAttributeType].displayName);
-    return null;
-}
+import("system.translate");
+import("system.neon");
+import("system.vars");
+import("system.db");
+import("Sql_lib");
+
+/**
+ * Provides functions for the work with attributes, like setting or getting the value of an attribute
+ * or listing the available attributes for a context.
+ * Don't instanciate this!
+ * 
+ * @class
+ */
+function AttributeUtil () {}
+
+/**
+ * Gives a list of all available attributes for a context. This is used in the possibleItems
+ * process for the attribute id in AttributeRelation
+ * 
+ * @param {String} pObjectType the object type (= context)
+ * 
+ * @return {String[][]} two-dimensional array of attributeIds and names
+ */
+AttributeUtil.getPossibleAttributes = function (pObjectType)
+{
+    if (pObjectType == null)
+        return [];
+    
+    var attrSql = "select AB_ATTRIBUTEID, ATTRIBUTE_NAME from AB_ATTRIBUTE"
+        + " join AB_ATTRIBUTEUSAGE  on AB_ATTRIBUTEID = AB_ATTRIBUTE_ID";
+    attrSql = SqlCondition.begin()
+        .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType)
+        .and("ATTRIBUTE_ACTIVE = 1")
+        .buildSql(attrSql);
+
+    return db.table(attrSql);
+}
+
+/**
+ * returns the name of an attribute
+ * 
+ * @param {String} pAttributeId the id of the attribute
+ * 
+ * @return {String} the name of the attribute
+ */
+AttributeUtil.getAttributeNameById = function (pAttributeId) 
+{
+    var attributeNames = [];
+    var attribute;
+    do {
+        attribute = db.array(db.ROW, SqlCondition.begin()
+            .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", pAttributeId)
+            .buildSql("select ATTRIBUTE_NAME, ATTRIBUTE_PARENT_ID from AB_ATTRIBUTE")
+        );
+        if (attribute.length > 0)
+        {
+            attributeNames.push(attribute[0]);
+            pAttributeId = attribute[1];
+        }
+        else
+            pAttributeId = "";
+    } while (pAttributeId);
+    
+    return attributeNames.reverse().join(" / ");
+}
+
+/**
+ * gets the value of an attribute for one dataset (e. g. a person)
+ */
+AttributeUtil.getAttribute = function (pAttributeId, pObjectType, pObjectRowId, pGetIdValue)
+{
+    //TODO: implement
+}
+
+AttributeUtil.getAttributes = function ()
+{
+    //TODO: implement maybe
+}
+
+/**
+ * sets the value of an attribute for one dataset (e. g. a person)
+ */
+AttributeUtil.setAttribute = function ()
+{
+    //TODO: implement
+}
+
+
+/**
+ * This is used in the AttributeRelation enitiy to make the work with attributes there
+ * easier. You probaly won't need this for anything else.
+ * 
+ * @param {String} pAttrId the id of the attribute
+ */
+function AttributeHandler (pAttrId)   //TODO: find out if this class is necessary, maybe there is a more elegant solution, this could also be static
+{
+    this.attributeId = pAttrId;
+    this._attributeType = null;
+}
+
+AttributeHandler.begin = function (pAttrId)
+{
+    return new AttributeHandler(pAttrId);
+}
+
+/**
+ * gets the type of the attribute by the attributeId, after the first call the value
+ * is stored so that the sql selection is done only once
+ * 
+ * @return {String} attribute type
+ */
+AttributeHandler.prototype._getAttributeType = function () //TODO: maybe the type should be an own field in the entity instead of getting the type from the attribute id
+{
+    if (this._attributeType == null && this.attributeId != null)
+    {
+        var attrTypeSelect = "select ATTRIBUTE_TYPE from AB_ATTRIBUTE";
+        attrTypeSelect = SqlCondition.begin()
+            .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", this.attributeId)
+            .buildSql(attrTypeSelect);
+        this._attributeType = db.cell(attrTypeSelect).trim();
+    }
+    return this._attributeType;
+}
+
+/**
+ * returns the field that belongs to the type of the attribute
+ * 
+ * @return {String} attribute field
+ */
+AttributeHandler.prototype.getAttributeField = function ()
+{
+    return AttributeTypes.getEntityField(this._getAttributeType());
+}
+
+/**
+ * returns the content type that belongs to the type of the attribute
+ * 
+ * @return {String} attribute field
+ */
+AttributeHandler.prototype.getAttributeContentType = function ()
+{
+    return AttributeTypes.getContentType(this._getAttributeType());
+}
+
+AttributeHandler.prototype.setAttributeValue = function (pValue)
+{
+    var field = "$field." + this.getAttributeField();
+    if (field != null && vars.exists(field))
+        neon.setFieldValue(field, pValue)
+    return pValue;
+}
+
+/**
+ * Object for the enumeration and management of all attribute types.
+ * This Object is only for the general definition of attribute types and for getting
+ * data about every type, anything that has to do with a specific attribute (= the function requires an attribute id)
+ * should be done in AttributeUtils.
+ * The values for each type are:
+ * 
+ * contentType = the value that is returned in the contentType process for the attribute
+ * databaseField = the database field that holds values of attributes with the type
+ * entityField = the field in the AttributeRelation enity that holds the value of the attribute for that type
+ * 
+ * The display name is controlled by the keyword 'AttributeType'
+ */
+var AttributeTypes = {
+    TEXT : { 
+        toString : function () {return "TEXT"},
+        contentType : "TEXT", 
+        databaseField : "CHAR_VALUE", 
+        entityField : "CHAR_VALUE"
+    },
+    DATE : {
+        toString : function () {return "DATE"},
+        contentType : "DATE", 
+        databaseField : "DATE_VALUE", 
+        entityField : "DATE_VALUE"
+    },
+    NUMBER : {
+        toString : function () {return "NUMBER"},
+        contentType : "NUMBER", 
+        databaseField : "NUMBER_VALUE", 
+        entityField : "NUMBER_VALUE"
+    },
+    BOOLEAN : {
+        toString : function () {return "BOOLEAN"},
+        contentType : "BOOLEAN", 
+        databaseField : "BOOL_VALUE", 
+        entityField : "BOOL_VALUE"
+    },
+    COMBO : {
+        toString : function () {return "COMBO"},
+        contentType : "TEXT", 
+        databaseField : "ID_VALUE", 
+        entityField : "ID_VALUE"
+    },
+    GROUP : {
+        toString : function () {return "GROUP"},
+        contentType : null, 
+        databaseField : null, 
+        entityField : null
+    }
+};
+
+
+/**
+ * returns the required contentType for the given attribute type
+ * 
+ * @param {String} pAttributeType the attribute type 
+ *                  (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT)
+ * @return {String} the contentType for the attribute
+ */
+AttributeTypes.getContentType = function (pAttributeType)
+{
+    if (pAttributeType in AttributeTypes)
+        return AttributeTypes[pAttributeType].contentType;
+    return null;
+}
+
+/**
+ * returns the entity field for the given attribute type that holds the value of the attribute
+ * 
+ * @param {String} pAttributeType the attribute type 
+ *                  (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT)
+ * @return {String} the field for the attribute
+ */
+AttributeTypes.getEntityField = function (pAttributeType)
+{
+    if (pAttributeType in AttributeTypes)
+        return AttributeTypes[pAttributeType].entityField;
+    return null;
+}
+
+/**
+ * returns the database field for the given attribute type that holds the value of the attribute
+ * 
+ * @param {String} pAttributeType the attribute type 
+ *                  (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT)
+ * @return {String} the database field for the attribute
+ */
+AttributeTypes.getDatabaseField = function (pAttributeType)
+{
+    if (pAttributeType in AttributeTypes)
+        return AttributeTypes[pAttributeType].databaseField;
+    return null;
+}
+
+/**
+ * returns the name of the given attribute type
+ * 
+ * @param {String} pAttributeType the attribute type 
+ *                  (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT)
+ * @return {String} the name the attribute
+ */
+AttributeTypes.getName = function (pAttributeType)
+{
+    if (pAttributeType in AttributeTypes)
+        return translate.text(AttributeTypes[pAttributeType].displayName);
+    return null;
+}
diff --git a/process/Keyword_lib/process.js b/process/Keyword_lib/process.js
index b043f2597c2b12691d9244da8c4597c7c72455e4..4827e4fa1a0045c62aea4b40cd915402337df88e 100644
--- a/process/Keyword_lib/process.js
+++ b/process/Keyword_lib/process.js
@@ -77,7 +77,7 @@ KeywordUtils.getResolvedTitleSqlPart = function(pContainerName, pDbFieldName, pL
 /**
  * returns a specific name (translated) - this is normally the view-value - of a given keyword;
  * <br/>if the key could not be found an empty string "" is returned 
- * @param {String} keywordType specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY"
+ * @param {String} keywordContainer specifies the type of the keyword and therefore the list elements; e.g. "COUNTRY"
  * @param {String} key id value of the keyword where the view-value shall be searched
  * @return {String} representation of the translated name of the keyword-key
  * @example
@@ -87,13 +87,10 @@ KeywordUtils.getResolvedTitleSqlPart = function(pContainerName, pDbFieldName, pL
  *     result.string(vars.get("$field.SUBJECT") + " (" + LegacyKeywordUtils.getViewValue("ACTIVITY.MEDIUM", histMedium) + ")");
  * }
  */
-KeywordUtils.getViewValue = function(keywordType, key)
+KeywordUtils.getViewValue = function(keywordContainer, key)
 {
-    if (!$KeywordRegistry.get[keywordType])
-        return "";
-
     var sql = SqlCondition.begin()
-                          .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", keywordType)
+                          .andPrepare("AB_KEYWORD_ENTRY.CONTAINER", keywordContainer)
                           .andPrepare("AB_KEYWORD_ENTRY.KEYID", key)
                           .buildSql("select AB_KEYWORD_ENTRY.TITLE from AB_KEYWORD_ENTRY");
     var originalTitle = db.cell(sql);
@@ -101,7 +98,55 @@ KeywordUtils.getViewValue = function(keywordType, key)
         return "";
     var translatedTitle = translate.text(originalTitle);
     return translatedTitle;
-}
+};
+
+/**
+ * collects possible and defined keyword-attributes per keyword entry and returns them
+ * 
+ * @param {String} pEntryId id that identifies the keyword-entry whoes attributes are collected
+ * @return {Object} key-value-pair of the keyword-attributes; contains all attribute-keys for the keywords-entries container; 
+ *                                  if there is no value set for a key the null-value is given
+ */
+KeywordUtils.getKeywordAttributeRelations = function (pEntryId)
+{
+    var sql = SqlCondition.begin()
+        .andPrepare("AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID", pEntryId)
+        .buildSql("select AB_KEYWORD_ATTRIBUTE.NAME, AB_KEYWORD_ATTRIBUTE.TYPE, \n\
+                AB_KEYWORD_ATTRIBUTERELATION.CHAR_VALUE, AB_KEYWORD_ATTRIBUTERELATION.NUMBER_VALUE, AB_KEYWORD_ATTRIBUTERELATION.BOOL_VALUE \n\
+                from AB_KEYWORD_ENTRY \n\
+                left join AB_KEYWORD_ATTRIBUTE on (AB_KEYWORD_ATTRIBUTE.CONTAINER = AB_KEYWORD_ENTRY.CONTAINER) \n\
+                left join AB_KEYWORD_ATTRIBUTERELATION \n\
+                    on (AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTE_ID = AB_KEYWORD_ATTRIBUTE.AB_KEYWORD_ATTRIBUTEID\n\
+                        and AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ENTRY_ID = AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID)");
+
+    var data = db.table(sql);
+    var res = {};
+    var name, type, charVal, numVal, boolVal;
+    
+    for (var i = 0, l = data.length; i < l; i++)
+    {
+        [name, type, charVal, numVal, boolVal] = data[i];
+        name = name.trim();
+        type = type.trim();
+        var parsedValue = null;
+        switch(type)
+        {
+            case "NUMBER_VALUE":
+                parsedValue = numVal == "" ? null : Number(numVal);
+                break;
+            case "BOOL_VALUE":
+                parsedValue = boolVal == "" ? null : (boolVal == "1");
+                break;
+            case "CHAR_VALUE":
+                parsedValue = charVal == "" ? null : charVal;
+                break;
+        }
+
+        res[name] = parsedValue;
+    }
+    return res;
+};
+
 
 /**
 * provides a distinctive list of all keyword-container-names in the system
@@ -347,15 +392,6 @@ function LegacyKeywordUtils(){}
                      })
                 ]);
                 break;
-            case "SALESPROJECT.PROBABILITY":
-                valueContainer = _createKeywordEntriesContainer([
-                     _createKeywordEntry("1", translate.text("0 %", locale), null, {percentValue: 0})
-                    ,_createKeywordEntry("2", translate.text("25 %", locale), null, {percentValue: 25})
-                    ,_createKeywordEntry("3", translate.text("50 %", locale), null, {percentValue: 50})
-                    ,_createKeywordEntry("4", translate.text("75 %", locale), null, {percentValue: 75})
-                    ,_createKeywordEntry("5", translate.text("100 %", locale), null, {percentValue: 100})
-                ]);
-                break;
             case "CLASS.BRANCHE":
                 valueContainer = _createKeywordEntriesContainer([
                      _createKeywordEntry("1", translate.text("Industry 1", locale), null, {points: 50})
diff --git a/process/OfferOrder_lib/process.js b/process/OfferOrder_lib/process.js
index c4af78a93e33b85be5760a2026ffe4d4c0da557a..a2004d9bac18bdd97e1e977bd820063d6b1b879f 100644
--- a/process/OfferOrder_lib/process.js
+++ b/process/OfferOrder_lib/process.js
@@ -136,21 +136,6 @@ function ItemUtils(pOfferOrderId, pTableName) {
     }
 }
 
-/**
- * get a new SqlCondition Object with tablename + "ITEM." + tablename + "ITEMID" = pItemId
- * 
- * @param {String} pItemId item id
- * @param {String} [pTableName=this.tableName] table name, if this is not available
- * 
- * @return {SqlCondition}
- */
-ItemUtils.prototype.getNewItemIdCondition = function(pItemId, pTableName)
-{
-    if (pTableName == undefined) 
-        pTableName = this.tableName;
-    return SqlCondition.begin().andPrepare(pTableName + "ITEM." + pTableName + "ITEMID", pItemId);
-}
-
 /**
  * get netto and vat for all items or for all given items.
  * 
@@ -350,7 +335,6 @@ ItemUtils.prototype.insertPartsList = function(columns, productId, assignedTo, c
  */
 ItemUtils.prototype.deletePartsList = function(itemId) {
     var deletedItemIds = [];
-        
     //save address for this here to get class variables in recursive sub function __itemDeleteStatement
     var self = this;
     var statements = [];
@@ -365,11 +349,14 @@ ItemUtils.prototype.deletePartsList = function(itemId) {
     return deletedItemIds;
     
     //recursive function for building item delete statements 
-    function __itemDeleteStatement(itemId) {
+    function __itemDeleteStatement(itemId) {        
         var itemsToDelete = self.ItemTree[itemId].ids;
         for (var i = 0; i < itemsToDelete.length; i++) {
-            //unshift due to foreign key constraints (Delete hierarchically starting at the bottom)
-            statements.unshift(self.getNewItemIdCondition(itemsToDelete[i], self.tableName).build("1 = 2"));
+            //unshift due to foreign key constraints (Delete hierarchically starting at the bottom)                                           
+            statements.unshift([self.tableName + "ITEM", SqlCondition.begin()
+                                           .andPrepare(self.tableName + "ITEM." + self.tableName + "ITEMID", itemsToDelete[i])
+                                           .build("1 = 2")]);
+                                           
             deletedItemIds.push(itemsToDelete[i]);
             __itemDeleteStatement(itemsToDelete[i]);
         }