diff --git a/.liquibase/Data_alias/basic/2019.2/AditoBasic/init_AttributeType.xml b/.liquibase/Data_alias/basic/2019.2/AditoBasic/init_AttributeType.xml
index d9d8b0d5c9a7af796f4e305693341aeacc76967b..e8220a7670e18262c8a212abbacbe4c96a1512b7 100644
--- a/.liquibase/Data_alias/basic/2019.2/AditoBasic/init_AttributeType.xml
+++ b/.liquibase/Data_alias/basic/2019.2/AditoBasic/init_AttributeType.xml
@@ -17,6 +17,24 @@
             <column name="ISACTIVE" valueNumeric="1"/>
             <column name="ISESSENTIAL" valueNumeric="1"/>
         </insert>
+        <insert tableName="AB_KEYWORD_ENTRY">
+            <column name="AB_KEYWORD_ENTRYID" value="ee893a1c-d007-46fe-a190-727124c4467b"/>
+            <column name="KEYID" value="MEMO"/>
+            <column name="TITLE" value="Memo"/>
+            <column name="CONTAINER" value="AttributeType"/>
+            <column name="SORTING" valueNumeric="8"/>
+            <column name="ISACTIVE" valueNumeric="1"/>
+            <column name="ISESSENTIAL" valueNumeric="1"/>
+        </insert>
+        <insert tableName="AB_KEYWORD_ENTRY">
+            <column name="AB_KEYWORD_ENTRYID" value="191d7293-3b3f-4dc7-bbe2-9da1a897f7df"/>
+            <column name="KEYID" value="VOID"/>
+            <column name="TITLE" value="Void"/>
+            <column name="CONTAINER" value="AttributeType"/>
+            <column name="SORTING" valueNumeric="9"/>
+            <column name="ISACTIVE" valueNumeric="1"/>
+            <column name="ISESSENTIAL" valueNumeric="1"/>
+        </insert>
         <rollback>
             <delete tableName="AB_KEYWORD_ENTRY">
                 <where>AB_KEYWORD_ENTRYID = ?</where>
@@ -24,6 +42,18 @@
                     <param value="9d2f9605-1a5e-47d3-8920-168f5637e37f"/>
                 </whereParams>
             </delete>
+            <delete tableName="AB_KEYWORD_ENTRY">
+                <where>AB_KEYWORD_ENTRYID = ?</where>
+                <whereParams>
+                    <param value="ee893a1c-d007-46fe-a190-727124c4467b"/>
+                </whereParams>
+            </delete>
+            <delete tableName="AB_KEYWORD_ENTRY">
+                <where>AB_KEYWORD_ENTRYID = ?</where>
+                <whereParams>
+                    <param value="191d7293-3b3f-4dc7-bbe2-9da1a897f7df"/>
+                </whereParams>
+            </delete>
         </rollback>
     </changeSet>
 </databaseChangeLog>
\ No newline at end of file
diff --git a/entity/AttributeRelationTree_entity/AttributeRelationTree_entity.aod b/entity/AttributeRelationTree_entity/AttributeRelationTree_entity.aod
index 4867a9611400b6a61e8136b5fc7051e8ff79775b..1ebda72befd7012f439e2e203fba8ac236578ebe 100644
--- a/entity/AttributeRelationTree_entity/AttributeRelationTree_entity.aod
+++ b/entity/AttributeRelationTree_entity/AttributeRelationTree_entity.aod
@@ -82,8 +82,9 @@
       <title>Value</title>
       <contentTypeProcess>%aditoprj%/entity/AttributeRelationTree_entity/entityfields/value/contentTypeProcess.js</contentTypeProcess>
       <resolution>DAY</resolution>
-      <mandatory v="true" />
+      <mandatoryProcess>%aditoprj%/entity/AttributeRelationTree_entity/entityfields/value/mandatoryProcess.js</mandatoryProcess>
       <possibleItemsProcess>%aditoprj%/entity/AttributeRelationTree_entity/entityfields/value/possibleItemsProcess.js</possibleItemsProcess>
+      <stateProcess>%aditoprj%/entity/AttributeRelationTree_entity/entityfields/value/stateProcess.js</stateProcess>
     </entityField>
     <entityConsumer>
       <name>SpecificAttribute</name>
diff --git a/entity/AttributeRelationTree_entity/entityfields/value/mandatoryProcess.js b/entity/AttributeRelationTree_entity/entityfields/value/mandatoryProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..564b24d9e769f678a1da3de8776adf941e94217e
--- /dev/null
+++ b/entity/AttributeRelationTree_entity/entityfields/value/mandatoryProcess.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("system.result");
+import("Attribute_lib");
+
+var attributeType = AttributeUtil.getAttributeType(vars.get("$field.AB_ATTRIBUTE_ID"));
+result.string(AttributeTypeUtil.getContentType(attributeType) != null);
\ No newline at end of file
diff --git a/entity/AttributeRelationTree_entity/entityfields/value/possibleItemsProcess.js b/entity/AttributeRelationTree_entity/entityfields/value/possibleItemsProcess.js
index da3691199cda4881eb44136b7de67a7004952f83..4a079812c98086f8af4b86b003ad694d0ee263d5 100644
--- a/entity/AttributeRelationTree_entity/entityfields/value/possibleItemsProcess.js
+++ b/entity/AttributeRelationTree_entity/entityfields/value/possibleItemsProcess.js
@@ -42,5 +42,6 @@ else if (attrType == $AttributeTypes.KEYWORD)
     {
         return [row[0], translate.text(row[1])];
     });
+    
     result.object(keywords);
 }
\ No newline at end of file
diff --git a/entity/AttributeRelationTree_entity/entityfields/value/stateProcess.js b/entity/AttributeRelationTree_entity/entityfields/value/stateProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..7eb783c7dfa26f85106d4836ba568ea05641bc6b
--- /dev/null
+++ b/entity/AttributeRelationTree_entity/entityfields/value/stateProcess.js
@@ -0,0 +1,14 @@
+import("system.neon");
+import("system.vars");
+import("system.result");
+import("Attribute_lib");
+
+var attributeType = AttributeUtil.getAttributeType(vars.get("$field.AB_ATTRIBUTE_ID"));
+result.string(AttributeTypeUtil.getContentType(attributeType));
+var fieldState;
+if (AttributeTypeUtil.getContentType(attributeType) != null)
+    fieldState = neon.COMPONENTSTATE_EDITABLE;
+else
+    fieldState = neon.COMPONENTSTATE_READONLY;
+
+result.string(fieldState);
\ No newline at end of file
diff --git a/entity/AttributeRelationTree_entity/recordcontainers/jdito/contentProcess.js b/entity/AttributeRelationTree_entity/recordcontainers/jdito/contentProcess.js
index d887ea8db65ef4766a8182d7ae984c3c8212dfcd..fb2ce69024eef40394e9b3155c30bfffb8ed46e5 100644
--- a/entity/AttributeRelationTree_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/AttributeRelationTree_entity/recordcontainers/jdito/contentProcess.js
@@ -8,9 +8,7 @@ var objectType = vars.get("$param.ObjectType_param");
 var rowId = vars.get("$param.ObjectRowId_param");
 var attributeObj = {};
 var allAttributes = [];
-var sqlSelect = "select AB_ATTRIBUTEID, ATTRIBUTE_PARENT_ID, ATTRIBUTE_NAME, ATTRIBUTE_NAME, ATTRIBUTE_NAME, ATTRIBUTE_NAME, ATTRIBUTE_TYPE from AB_ATTRIBUTE";
-
-
+var sqlSelect = "select AB_ATTRIBUTEID, ATTRIBUTE_PARENT_ID, '', '', AB_ATTRIBUTEID, ATTRIBUTE_NAME, ATTRIBUTE_TYPE from AB_ATTRIBUTE";
 
 var attrCond = SqlCondition.begin()
     .andPrepare("AB_ATTRIBUTERELATION.OBJECT_ROWID", rowId);
@@ -19,8 +17,10 @@ if (objectType != null)
 
 var defaultFields = [
     "AB_ATTRIBUTERELATIONID",
-    "AB_ATTRIBUTE_ID", 
+    "AB_ATTRIBUTE.AB_ATTRIBUTEID", 
+    "AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", 
     "AB_ATTRIBUTE.ATTRIBUTE_TYPE", 
+    "AB_ATTRIBUTE.ATTRIBUTE_NAME", 
     "AB_ATTRIBUTE.KEYWORD_CONTAINER", 
     "COMBOVAL.ATTRIBUTE_NAME"
 ];
@@ -33,15 +33,15 @@ var attributeNameMap = {};
 var attributeValues = db.table(attributeSql).map(function (row) 
 {
     let attributeId = row[1];
-    let attributeName = "";
-    let value = row[AttributeTypeUtil.getTypeColumnIndex(row[2]) + defaultFields.length];
+    let attributeName = row[4];
+    let value = row[AttributeTypeUtil.getTypeColumnIndex(row[3]) + defaultFields.length];
     let viewValue;
-    if (row[2].trim() == $AttributeTypes.COMBO)
-        viewValue = row[4];
+    if (row[3].trim() == $AttributeTypes.COMBO)
+        viewValue = row[6];
     else
-        viewValue = AttributeTypeUtil.getAttributeViewValue(row[2].trim(), value, row[3]);
+        viewValue = AttributeTypeUtil.getAttributeViewValue(row[3].trim(), value, row[5]);
 
-    return [row[0], attributeId, value, viewValue, attributeId, attributeName, row[2]];
+    return [row[0], row[2], value, viewValue, attributeId, attributeName, row[3]];
 });
 
 
diff --git a/entity/AttributeRelation_entity/AttributeRelation_entity.aod b/entity/AttributeRelation_entity/AttributeRelation_entity.aod
index d06a6101b3c5dd8a0a0c2582f4333610b8a91cb5..d9b79a7996e09b8459e2264a8222f4edb8793495 100644
--- a/entity/AttributeRelation_entity/AttributeRelation_entity.aod
+++ b/entity/AttributeRelation_entity/AttributeRelation_entity.aod
@@ -4,7 +4,6 @@
   <title>Attribute Relation</title>
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <documentation>%aditoprj%/entity/AttributeRelation_entity/documentation.adoc</documentation>
-  <afterOperatingState>%aditoprj%/entity/AttributeRelation_entity/afterOperatingState.js</afterOperatingState>
   <recordContainer>db</recordContainer>
   <entityFields>
     <entityProvider>
@@ -41,8 +40,10 @@
       <title>Value</title>
       <contentTypeProcess>%aditoprj%/entity/AttributeRelation_entity/entityfields/valueproxy/contentTypeProcess.js</contentTypeProcess>
       <resolution>DAY</resolution>
-      <mandatory v="true" />
+      <mandatory v="false" />
+      <mandatoryProcess>%aditoprj%/entity/AttributeRelation_entity/entityfields/valueproxy/mandatoryProcess.js</mandatoryProcess>
       <possibleItemsProcess>%aditoprj%/entity/AttributeRelation_entity/entityfields/valueproxy/possibleItemsProcess.js</possibleItemsProcess>
+      <stateProcess>%aditoprj%/entity/AttributeRelation_entity/entityfields/valueproxy/stateProcess.js</stateProcess>
       <valueProcess>%aditoprj%/entity/AttributeRelation_entity/entityfields/valueproxy/valueProcess.js</valueProcess>
       <displayValueProcess>%aditoprj%/entity/AttributeRelation_entity/entityfields/valueproxy/displayValueProcess.js</displayValueProcess>
       <onValueChange>%aditoprj%/entity/AttributeRelation_entity/entityfields/valueproxy/onValueChange.js</onValueChange>
diff --git a/entity/AttributeRelation_entity/afterOperatingState.js b/entity/AttributeRelation_entity/afterOperatingState.js
deleted file mode 100644
index d3061e715463d1b8fb004c30a3750ff6b0a2d4a6..0000000000000000000000000000000000000000
--- a/entity/AttributeRelation_entity/afterOperatingState.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import("system.vars");
-import("system.neon");
-
-if (vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_VIEW) 
-    neon.refresh();
\ No newline at end of file
diff --git a/entity/AttributeRelation_entity/entityfields/valueproxy/mandatoryProcess.js b/entity/AttributeRelation_entity/entityfields/valueproxy/mandatoryProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..564b24d9e769f678a1da3de8776adf941e94217e
--- /dev/null
+++ b/entity/AttributeRelation_entity/entityfields/valueproxy/mandatoryProcess.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("system.result");
+import("Attribute_lib");
+
+var attributeType = AttributeUtil.getAttributeType(vars.get("$field.AB_ATTRIBUTE_ID"));
+result.string(AttributeTypeUtil.getContentType(attributeType) != null);
\ No newline at end of file
diff --git a/entity/AttributeRelation_entity/entityfields/valueproxy/onValueChange.js b/entity/AttributeRelation_entity/entityfields/valueproxy/onValueChange.js
index 150cb4b05da6e73456d57d8573aa7b77865a2960..44aaa91f083773956443f739a0d9cb8e6705330a 100644
--- a/entity/AttributeRelation_entity/entityfields/valueproxy/onValueChange.js
+++ b/entity/AttributeRelation_entity/entityfields/valueproxy/onValueChange.js
@@ -9,25 +9,27 @@ attrValue = ProcessHandlingUtils.getOnValidationValue(attrValue);
 if (attrValue != null)
 {
     var attributeType = AttributeUtil.getAttributeType(vars.get("$field.AB_ATTRIBUTE_ID"));
-    var attrField = (function ()
+    var attrField = (function (pType)
     {
-        switch (this)
+        switch (pType)
         {
-            case $AttributeTypes.TEXT:
+            case $AttributeTypes.TEXT.toString():
+            case $AttributeTypes.MEMO.toString():
                 return "$field.CHAR_VALUE";
-            case $AttributeTypes.DATE:
+            case $AttributeTypes.DATE.toString():
                 return "$field.DATE_VALUE";
-            case $AttributeTypes.NUMBER:
+            case $AttributeTypes.NUMBER.toString():
                 return "$field.NUMBER_VALUE";
-            case $AttributeTypes.BOOLEAN:
+            case $AttributeTypes.BOOLEAN.toString():
                 return "$field.INT_VALUE";
-            case $AttributeTypes.COMBO:
-            case $AttributeTypes.KEYWORD:
+            case $AttributeTypes.COMBO.toString():
+            case $AttributeTypes.KEYWORD.toString():
                 return "$field.ID_VALUE";
             default:
                 return null;
         }
-    }).call(attributeType);
+    }).call(null, attributeType);
+
     if (attrField)
         neon.setFieldValue(attrField, attrValue);
 }
\ No newline at end of file
diff --git a/entity/AttributeRelation_entity/entityfields/valueproxy/stateProcess.js b/entity/AttributeRelation_entity/entityfields/valueproxy/stateProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..7eb783c7dfa26f85106d4836ba568ea05641bc6b
--- /dev/null
+++ b/entity/AttributeRelation_entity/entityfields/valueproxy/stateProcess.js
@@ -0,0 +1,14 @@
+import("system.neon");
+import("system.vars");
+import("system.result");
+import("Attribute_lib");
+
+var attributeType = AttributeUtil.getAttributeType(vars.get("$field.AB_ATTRIBUTE_ID"));
+result.string(AttributeTypeUtil.getContentType(attributeType));
+var fieldState;
+if (AttributeTypeUtil.getContentType(attributeType) != null)
+    fieldState = neon.COMPONENTSTATE_EDITABLE;
+else
+    fieldState = neon.COMPONENTSTATE_READONLY;
+
+result.string(fieldState);
\ No newline at end of file
diff --git a/entity/AttributeRelation_entity/entityfields/valueproxy/valueProcess.js b/entity/AttributeRelation_entity/entityfields/valueproxy/valueProcess.js
index 572e01f1e130b05c78e5bf8762959e16daa895d0..10d3aadcf50110dd9da7e5b189729ebd2f8174dd 100644
--- a/entity/AttributeRelation_entity/entityfields/valueproxy/valueProcess.js
+++ b/entity/AttributeRelation_entity/entityfields/valueproxy/valueProcess.js
@@ -1,4 +1,3 @@
-import("system.logging");
 import("system.neon");
 import("system.result");
 import("system.vars");
@@ -9,33 +8,33 @@ if(vars.get("$sys.recordstate") != neon.OPERATINGSTATE_NEW)
     var rowId = vars.get("$param.ObjectRowId_param");
     var objectType = vars.get("$param.ObjectType_param");
     var attributeId = vars.get("$field.AB_ATTRIBUTE_ID");
-    logging.log(AttributeRelationUtils.getAttribute(attributeId, rowId, objectType))
-    logging.log(AttributeRelationUtils.getAttribute(attributeId, rowId, objectType, true))
-    
     
     var attributeType = AttributeUtil.getAttributeType(vars.get("$field.AB_ATTRIBUTE_ID"));
-    var attrField = (function ()
+    var attrField = (function (type)
     {
-        switch (this)
+        switch (type)
         {
-            case $AttributeTypes.TEXT:
+            case $AttributeTypes.TEXT.toString():
+            case $AttributeTypes.MEMO.toString():
                 return "$field.CHAR_VALUE";
-            case $AttributeTypes.DATE:
+            case $AttributeTypes.DATE.toString():
                 return "$field.DATE_VALUE";
-            case $AttributeTypes.NUMBER:
+            case $AttributeTypes.NUMBER.toString():
                 return "$field.NUMBER_VALUE";
-            case $AttributeTypes.BOOLEAN:
+            case $AttributeTypes.BOOLEAN.toString():
                 return "$field.INT_VALUE";
-            case $AttributeTypes.COMBO:
-            case $AttributeTypes.KEYWORD:
+            case $AttributeTypes.COMBO.toString():
+            case $AttributeTypes.KEYWORD.toString():
                 return "$field.ID_VALUE";
         }
-    }).call(attributeType);
+    }).call(null, attributeType);
     var value = null;
     if (attrField != null) //load the value from the correct field for the type
         value = vars.get(attrField);
     
     if(value != null && value != "")
-        result.string(value); 
+        result.string(value);
+    else if (attributeType == $AttributeTypes.VOID)
+        result.string("");
 }
 
diff --git a/entity/Attribute_entity/Attribute_entity.aod b/entity/Attribute_entity/Attribute_entity.aod
index c453e2a87ae59728697f2b1beab93517727895b8..abf185d281213be116809f7dccbf0a1b3d5b8ab7 100644
--- a/entity/Attribute_entity/Attribute_entity.aod
+++ b/entity/Attribute_entity/Attribute_entity.aod
@@ -28,11 +28,6 @@
       <displayValueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_type/displayValueProcess.js</displayValueProcess>
       <onValueChange>%aditoprj%/entity/Attribute_entity/entityfields/attribute_type/onValueChange.js</onValueChange>
     </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>Superordinate Attribute</title>
@@ -93,9 +88,6 @@
           <name>AttrParentId_param</name>
           <expose v="true" />
         </entityParameter>
-        <entityParameter>
-          <name>GetGroups_param</name>
-        </entityParameter>
       </children>
     </entityProvider>
     <entityParameter>
@@ -146,14 +138,6 @@
         </entityParameter>
       </children>
     </entityConsumer>
-    <entityField>
-      <name>ATTRIBUTE_LEVEL</name>
-      <title>Level</title>
-      <description>The level is required in the order-by to make sure that superordinate attributes come before their subordinates for the tree</description>
-      <contentType>NUMBER</contentType>
-      <state>INVISIBLE</state>
-      <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_level/valueProcess.js</valueProcess>
-    </entityField>
     <entityField>
       <name>KEYWORD_CONTAINER</name>
       <title>Keyword</title>
@@ -175,7 +159,7 @@
     <entityProvider>
       <name>SpecificAttribute</name>
       <fieldType>DEPENDENCY_IN</fieldType>
-      <lookupIdfield>AB_ATTRIBUTEID</lookupIdfield>
+      <lookupIdfield>UID</lookupIdfield>
       <dependencies>
         <entityDependency>
           <name>342e8ba6-db61-411b-9f79-e9271335b00f</name>
@@ -309,7 +293,6 @@
       <onDelete>%aditoprj%/entity/Attribute_entity/recordcontainers/jdito/onDelete.js</onDelete>
       <recordFields>
         <element>UID.value</element>
-        <element>AB_ATTRIBUTEID.value</element>
         <element>ATTRIBUTE_ACTIVE.value</element>
         <element>ATTRIBUTE_NAME.value</element>
         <element>ATTRIBUTE_PARENT_ID.value</element>
diff --git a/entity/Attribute_entity/afterUiInit.js b/entity/Attribute_entity/afterUiInit.js
index 87febc93d555370828def178d66937ba02b37a7e..4bfd7805a27d3e9e0b27292222ffc1f4a101cd9b 100644
--- a/entity/Attribute_entity/afterUiInit.js
+++ b/entity/Attribute_entity/afterUiInit.js
@@ -1,27 +1,27 @@
-import("system.util");
-import("system.db");
-import("system.neon");
-import("system.vars");
-import("Context_lib");
-import("Attribute_lib");
-
-if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW 
-    && vars.get("$field.ATTRIBUTE_TYPE").trim() != $AttributeTypes.COMBOVALUE
-    && vars.exists("$param.AttrParentId_param") && vars.get("$param.AttrParentId_param"))
-{
-    var parentId = vars.get("$param.AttrParentId_param");
-    var attributeId = vars.get("$field.AB_ATTRIBUTEID");
-
-    var usageSql = SqlCondition.begin()
-        .andPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", parentId)
-        .buildSql("select OBJECT_TYPE from AB_ATTRIBUTEUSAGE", "1=0");
-    var usages = db.array(db.COLUMN, usageSql);
-
-    //preset the usages with the ones from the parent
-    usages.forEach(function (usage) 
-    {
-        neon.addRecord(null, "AttributeUsages", {
-            "OBJECT_TYPE" : usage
-        });
-    });
+import("system.util");
+import("system.db");
+import("system.neon");
+import("system.vars");
+import("Context_lib");
+import("Attribute_lib");
+
+if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW 
+    && vars.get("$field.ATTRIBUTE_TYPE").trim() != $AttributeTypes.COMBOVALUE
+    && vars.exists("$param.AttrParentId_param") && vars.get("$param.AttrParentId_param"))
+{
+    var parentId = vars.get("$param.AttrParentId_param");
+    var attributeId = vars.get("$field.UID");
+
+    var usageSql = SqlCondition.begin()
+        .andPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", parentId)
+        .buildSql("select OBJECT_TYPE from AB_ATTRIBUTEUSAGE", "1=0");
+    var usages = db.array(db.COLUMN, usageSql);
+
+    //preset the usages with the ones from the parent
+    usages.forEach(function (usage) 
+    {
+        neon.addRecord(null, "AttributeUsages", {
+            "OBJECT_TYPE" : usage
+        });
+    });
 }
\ No newline at end of file
diff --git a/entity/Attribute_entity/entityfields/ab_attributeid/valueProcess.js b/entity/Attribute_entity/entityfields/ab_attributeid/valueProcess.js
deleted file mode 100644
index 7df83b4096e7df4d63cc4d81f8fadf0884444479..0000000000000000000000000000000000000000
--- a/entity/Attribute_entity/entityfields/ab_attributeid/valueProcess.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import("system.util");
-import("system.result");
-import("system.neon");
-import("system.vars");
-
-if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
-    result.string(util.getNewUUID());
\ No newline at end of file
diff --git a/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js b/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js
index f663dddf570f4246c8ae5babd6035026d2bc2ffc..20869c2a59b127f4fab232b9ffaa33f4baa79c71 100644
--- a/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js
+++ b/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js
@@ -1,31 +1,31 @@
-import("system.db");
-import("system.neon");
-import("system.result");
-import("system.vars");
-import("Attribute_lib");
-import("Sql_lib");
-
-var type = vars.get("$field.ATTRIBUTE_TYPE").trim();
-var state = neon.COMPONENTSTATE_AUTO
-if (type == $AttributeTypes.COMBOVALUE)
-{
-    state = neon.COMPONENTSTATE_READONLY;
-}
-else if (type == $AttributeTypes.GROUP || type == $AttributeTypes.COMBO)
-{
-    var hasSubordinate = db.cell(SqlCondition.begin()
-        .andPrepareVars("AB_ATTRIBUTE.AB_ATTRIBUTEID", "$field.AB_ATTRIBUTEID")
-        .buildSql(
-            "select exists ("
-            +    "select SUB.AB_ATTRIBUTEID from AB_ATTRIBUTE SUB "
-            +    "where SUB.ATTRIBUTE_PARENT_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID"
-            + ") from AB_ATTRIBUTE", "1=2"
-        )
-    ) == "true";
-    if (hasSubordinate)
-        state = neon.COMPONENTSTATE_READONLY;
-}
-else if (AttributeUtil.hasRelations(vars.get("$field.AB_ATTRIBUTEID")))
-        state = neon.COMPONENTSTATE_READONLY;
-
+import("system.db");
+import("system.neon");
+import("system.result");
+import("system.vars");
+import("Attribute_lib");
+import("Sql_lib");
+
+var type = vars.get("$field.ATTRIBUTE_TYPE").trim();
+var state = neon.COMPONENTSTATE_AUTO
+if (type == $AttributeTypes.COMBOVALUE)
+{
+    state = neon.COMPONENTSTATE_READONLY;
+}
+else if (AttributeTypeUtil.isGroupType(type))
+{
+    var hasSubordinate = db.cell(SqlCondition.begin()
+        .andPrepareVars("AB_ATTRIBUTE.AB_ATTRIBUTEID", "$field.UID")
+        .buildSql(
+            "select exists ("
+            +    "select SUB.AB_ATTRIBUTEID from AB_ATTRIBUTE SUB "
+            +    "where SUB.ATTRIBUTE_PARENT_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID"
+            + ") from AB_ATTRIBUTE", "1=2"
+        )
+    ) == "true";
+    if (hasSubordinate)
+        state = neon.COMPONENTSTATE_READONLY;
+}
+else if (AttributeUtil.hasRelations(vars.get("$field.UID")))
+        state = neon.COMPONENTSTATE_READONLY;
+
 result.string(state)
\ No newline at end of file
diff --git a/entity/Attribute_entity/entityfields/attributeactions/children/newchildattribute/onActionProcess.js b/entity/Attribute_entity/entityfields/attributeactions/children/newchildattribute/onActionProcess.js
index cb209fd2f503d12661c8c35b76f6ce767bf7b0bc..0ccfa2e4bf15531b52a7d33d316b14af3d0c1819 100644
--- a/entity/Attribute_entity/entityfields/attributeactions/children/newchildattribute/onActionProcess.js
+++ b/entity/Attribute_entity/entityfields/attributeactions/children/newchildattribute/onActionProcess.js
@@ -8,8 +8,8 @@ if (vars.exists("$local.rows"))
     var row = JSON.parse(vars.get("$local.rows"));
     
     var type = row[0].ATTRIBUTE_TYPE.trim();
-    if (type == $AttributeTypes.GROUP || type == $AttributeTypes.COMBO)
-        params["AttrParentId_param"] = row[0].AB_ATTRIBUTEID;
+    if (AttributeTypeUtil.isGroupType(type))
+        params["AttrParentId_param"] = row[0].UID;
     else if (row[0].ATTRIBUTE_PARENT_ID)
         params["AttrParentId_param"] = row[0].ATTRIBUTE_PARENT_ID;
 }
diff --git a/entity/Attribute_entity/entityfields/attributechildren/children/attrparentid_param/valueProcess.js b/entity/Attribute_entity/entityfields/attributechildren/children/attrparentid_param/valueProcess.js
index b68489b6e02b29d34ae67b14c7371f985305f014..7bef0e16cef98c0686c4062dea4f92127436826c 100644
--- a/entity/Attribute_entity/entityfields/attributechildren/children/attrparentid_param/valueProcess.js
+++ b/entity/Attribute_entity/entityfields/attributechildren/children/attrparentid_param/valueProcess.js
@@ -3,5 +3,5 @@ import("system.result");
 import("Attribute_lib");
 
 var type = vars.get("$field.ATTRIBUTE_TYPE").trim();
-if (type == $AttributeTypes.GROUP || type == $AttributeTypes.COMBO)
-    result.string(vars.getString("$field.AB_ATTRIBUTEID"));
+if (AttributeTypeUtil.isGroupType(type))
+    result.string(vars.getString("$field.UID"));
diff --git a/entity/Attribute_entity/entityfields/attributechildren/stateProcess.js b/entity/Attribute_entity/entityfields/attributechildren/stateProcess.js
index 9dd65f6721c8cca1bc4672b5fd812aeafd8f9e29..b1a6d07e3863f8959fe3923888d7e366becd9e34 100644
--- a/entity/Attribute_entity/entityfields/attributechildren/stateProcess.js
+++ b/entity/Attribute_entity/entityfields/attributechildren/stateProcess.js
@@ -4,7 +4,7 @@ import("system.vars");
 import("Attribute_lib");
 
 var type = vars.get("$field.ATTRIBUTE_TYPE").trim();
-if (type == $AttributeTypes.GROUP || type == $AttributeTypes.COMBO)
+if (AttributeTypeUtil.isGroupType(type))
     result.string(neon.COMPONENTSTATE_EDITABLE);
 else
     result.string(neon.COMPONENTSTATE_INVISIBLE);
\ No newline at end of file
diff --git a/entity/Attribute_entity/entityfields/attributegroup/children/attrparentid_param/valueProcess.js b/entity/Attribute_entity/entityfields/attributegroup/children/attrparentid_param/valueProcess.js
index 033bf9a666c5254c8945077776b2834560164e56..16c85500b5355a72548030867e3d300661e9d4aa 100644
--- a/entity/Attribute_entity/entityfields/attributegroup/children/attrparentid_param/valueProcess.js
+++ b/entity/Attribute_entity/entityfields/attributegroup/children/attrparentid_param/valueProcess.js
@@ -1,4 +1,4 @@
-import("system.vars");
-import("system.result");
-
-result.string(vars.get("$field.AB_ATTRIBUTEID"));
\ No newline at end of file
+import("system.vars");
+import("system.result");
+
+result.string(vars.get("$field.UID"));
\ No newline at end of file
diff --git a/entity/Attribute_entity/entityfields/attributeusages/children/attributeid_param/valueProcess.js b/entity/Attribute_entity/entityfields/attributeusages/children/attributeid_param/valueProcess.js
index f7ac89492841d22780c3d2eb1d38d4b0aa7de476..d2802861c77c62c37f3274882eba0e5c90cc8074 100644
--- a/entity/Attribute_entity/entityfields/attributeusages/children/attributeid_param/valueProcess.js
+++ b/entity/Attribute_entity/entityfields/attributeusages/children/attributeid_param/valueProcess.js
@@ -1,4 +1,4 @@
 import("system.vars");
 import("system.result");
 
-result.string(vars.get("$field.AB_ATTRIBUTEID"));
+result.string(vars.get("$field.UID"));
diff --git a/entity/Attribute_entity/entityfields/usagelist/valueProcess.js b/entity/Attribute_entity/entityfields/usagelist/valueProcess.js
index 6205c80b1197a27513819bf6f91aa0e6cb3a612b..130b4cc5a16fb171b4613faf46c3a3734725750f 100644
--- a/entity/Attribute_entity/entityfields/usagelist/valueProcess.js
+++ b/entity/Attribute_entity/entityfields/usagelist/valueProcess.js
@@ -9,7 +9,7 @@ var retStr = "\u00A0"; // \u00A0 -> space character that doesn't get trimmed
 if (vars.get("$field.ATTRIBUTE_TYPE").trim() != $AttributeTypes.COMBOVALUE)
 {
     var usages = db.array(db.COLUMN, SqlCondition.begin()
-        .andPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", vars.get("$field.AB_ATTRIBUTEID"))
+        .andPrepareVars("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", "$field.UID")
         .buildSql("select OBJECT_TYPE from AB_ATTRIBUTEUSAGE"));
     if (usages.length)
         retStr = usages.join(", ");
diff --git a/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js b/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js
index e82365497605a662d78f0d4e2c652c3e0ff5051e..0eb7f5b41e04ea0f4d791eafc7ffd3c73d55f888 100644
--- a/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js
@@ -1,4 +1,3 @@
-import("system.logging");
 import("system.datetime");
 import("JditoFilter_lib");
 import("KeywordRegistry_basic");
@@ -9,7 +8,7 @@ import("system.result");
 import("Sql_lib");
 import("Attribute_lib");
 
-var sqlSelect = "select AB_ATTRIBUTEID, AB_ATTRIBUTEID, ATTRIBUTE_ACTIVE, " 
+var sqlSelect = "select AB_ATTRIBUTEID, ATTRIBUTE_ACTIVE, " 
     + "ATTRIBUTE_NAME, ATTRIBUTE_PARENT_ID, ATTRIBUTE_TYPE, " 
     + KeywordUtils.getResolvedTitleSqlPart($KeywordRegistry.attributeType(), "ATTRIBUTE_TYPE")
     + ", KEYWORD_CONTAINER from AB_ATTRIBUTE";
@@ -25,8 +24,13 @@ else if (getGroups)
 {
     //this is for the selection of the superordinate attribute, this condition
     //filters out the own id and the children to prevent loops
+    
+    var isGroupCondition = new SqlCondition();
+    for (let type in $AttributeTypes)
+        if ($AttributeTypes[type].isGroup && $AttributeTypes[type] != $AttributeTypes.COMBO)
+            isGroupCondition.orPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes[type]);
     condition.andSqlCondition(SqlCondition.begin()
-        .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.GROUP)
+        .andSqlCondition(isGroupCondition)
         .andPrepareVars("AB_ATTRIBUTE.AB_ATTRIBUTEID", "$param.AttrParentId_param", "# != ?")
         .and("AB_ATTRIBUTE.AB_ATTRIBUTEID not in ('" + AttributeUtil.getAllChildren(vars.getString("$param.AttrParentId_param")).join("','") + "')")
     );
@@ -74,8 +78,8 @@ function _sortArrayForTree (pArray)
 {
     var rows = {};
     var allIds = {};
-    var idIndex = 1;
-    var parentIdIndex = 4;
+    var idIndex = 0;
+    var parentIdIndex = 3;
     
     pArray.forEach(function (row) {allIds[row[idIndex]] = true;});
     
diff --git a/entity/Employee_entity/Employee_entity.aod b/entity/Employee_entity/Employee_entity.aod
index 6a4abbc912058b9bc777eb6f4c75e5276fb55337..c30ec05447ad422a3e6424361bef02c4140138f4 100644
--- a/entity/Employee_entity/Employee_entity.aod
+++ b/entity/Employee_entity/Employee_entity.aod
@@ -37,11 +37,13 @@
     <entityField>
       <name>FIRSTNAME</name>
       <title>Firstname</title>
+      <state>READONLY</state>
     </entityField>
     <entityField>
       <name>LASTNAME</name>
       <title>Lastname</title>
       <mandatory v="false" />
+      <state>READONLY</state>
     </entityField>
     <entityField>
       <name>ISACTIVE</name>
diff --git a/neonContext/AttributeRelationTree/AttributeRelationTree.aod b/neonContext/AttributeRelationTree/AttributeRelationTree.aod
index be8de92fa69a5d08edd83d856cb8f2dc0516a26c..9acb4ce97d8d3d086df679b67f01a23ac945eb63 100644
--- a/neonContext/AttributeRelationTree/AttributeRelationTree.aod
+++ b/neonContext/AttributeRelationTree/AttributeRelationTree.aod
@@ -2,7 +2,6 @@
 <neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.1.0">
   <name>AttributeRelationTree</name>
   <majorModelMode>DISTRIBUTED</majorModelMode>
-  <editview>AttributeRelationTreeEdit_view</editview>
   <entity>AttributeRelationTree_entity</entity>
   <references>
     <neonViewReference>
diff --git a/neonView/AttributeRelationTree_view/AttributeRelationTree_view.aod b/neonView/AttributeRelationTree_view/AttributeRelationTree_view.aod
index 0dbe7b672e013f65aec5bdb8f094a0b52aa983ae..1eee2f28de6b9b5b3cc9b459b211176b261aa5ef 100644
--- a/neonView/AttributeRelationTree_view/AttributeRelationTree_view.aod
+++ b/neonView/AttributeRelationTree_view/AttributeRelationTree_view.aod
@@ -8,11 +8,21 @@
     </boxLayout>
   </layout>
   <children>
-    <treeViewTemplate>
-      <name>AttributeRelationTree</name>
+    <treeTableViewTemplate>
+      <name>TreeTable</name>
       <parentField>PARENT_ID</parentField>
-      <titleField>VALUE</titleField>
+      <showChildrenCount v="false" />
       <entityField>#ENTITY</entityField>
-    </treeViewTemplate>
+      <columns>
+        <neonTableColumn>
+          <name>840551af-5a99-4965-a96a-ed134efb28a9</name>
+          <entityField>AB_ATTRIBUTE_ID</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>7844082c-fd31-4878-9e57-024cb2b2b627</name>
+          <entityField>VALUE</entityField>
+        </neonTableColumn>
+      </columns>
+    </treeTableViewTemplate>
   </children>
 </neonView>
diff --git a/process/Attribute_lib/process.js b/process/Attribute_lib/process.js
index 77622496e39d17b337328ae1a7c66461aeb10bde..a5dc1d48142c32188b217cc22ab06b5b907873b6 100644
--- a/process/Attribute_lib/process.js
+++ b/process/Attribute_lib/process.js
@@ -272,6 +272,41 @@ AttributeRelationUtils.getAllAttributes = function (pObjectRowId, pObjectType, p
     return attributeValues;
 }
 
+/**
+ * gets the correct attribute value from a map with values depending on the attribute id
+ * 
+ * @param {String} pAttributeId the attribute id
+ * @param {Object} pValueMap a map with the attribute values and the db fields as keys
+ * @param {Boolean} [pGetViewValue=false] if true, get the view value
+ * 
+ * @return {String|null} the value of the attribute or null if the attribute doesn't exist
+ */
+AttributeRelationUtils.selectAttributeValue = function (pAttributeId, pValueMap, pGetViewValue)
+{
+    var sqlSelect = "select ATTRIBUTE_TYPE, KEYWORD_CONTAINER from AB_ATTRIBUTE";
+    var type = db.array(db.ROW, SqlCondition.begin()
+        .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", pAttributeId)
+        .buildSql(sqlSelect)
+    );
+    if (!type.length)
+        return null;
+    
+    type[0] = type[0].trim();
+    var field = AttributeTypeUtil.getDatabaseField(type[0]);
+    var value = pValueMap[field];
+    if (pGetViewValue && type[0] == $AttributeTypes.COMBO)
+    {
+        value = db.cell(SqlCondition.begin()
+            .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", value)
+            .buildSql("select ATTRIBUTE_NAME from AB_ATTRIBUTE")
+        );
+    }
+    else if (pGetViewValue)
+        value = AttributeTypeUtil.getAttributeViewValue(type[0], value, type[1]);
+    
+    return value;
+}
+
 AttributeRelationUtils.getAttributes = function ()
 {
     //TODO: implement maybe
@@ -339,7 +374,8 @@ $AttributeTypes.COMBO = {
     toString : function () {return this.keyword},
     keyword : "COMBO",
     contentType : "UNKNOWN",
-    databaseField : "ID_VALUE"
+    databaseField : "ID_VALUE",
+    isGroup : true
 };
 $AttributeTypes.COMBOVALUE = {
     toString : function () {return this.keyword},
@@ -351,7 +387,8 @@ $AttributeTypes.GROUP = {
     toString : function () {return this.keyword},
     keyword : "GROUP",
     contentType : null, 
-    databaseField : null
+    databaseField : null,
+    isGroup : true
 };
 $AttributeTypes.KEYWORD = {
     toString : function () {return this.keyword},
@@ -363,7 +400,19 @@ $AttributeTypes.KEYWORD = {
             return KeywordUtils.getViewValue(pKeyword, pValue);
         }
 };
-
+$AttributeTypes.VOID = {
+    toString : function () {return this.keyword},
+    keyword : "VOID",
+    contentType : null,
+    databaseField : null,
+    isGroup : true
+};
+$AttributeTypes.MEMO = { 
+    toString : function () {return this.keyword},
+    keyword : "MEMO",
+    contentType : "LONG_TEXT", 
+    databaseField : "CHAR_VALUE"
+};
 
 function AttributeTypeUtil () {}
 
@@ -382,16 +431,16 @@ AttributeTypeUtil.getContentType = function (pAttributeType)
 }
 
 /**
- * returns the entity field for the given attribute type that holds the value of the attribute
+ * returns if the type is a group type
  * 
  * @param {String} pAttributeType the attribute type 
  *                  (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT)
- * @return {String} the field for the attribute
+ * @return {Boolean} if the type is a group type
  */
-AttributeTypeUtil.getEntityField = function (pAttributeType)
+AttributeTypeUtil.isGroupType = function (pAttributeType)
 {
     if (pAttributeType in $AttributeTypes)
-        return $AttributeTypes[pAttributeType].entityField;
+        return $AttributeTypes[pAttributeType].isGroup || false;
     return null;
 }
 
diff --git a/process/Organisation_lib/process.js b/process/Organisation_lib/process.js
index 6072424e6228442074a63db68852cf478a1ecfe0..e661ac0b18472e351423da60acb074d19e5e52db 100644
--- a/process/Organisation_lib/process.js
+++ b/process/Organisation_lib/process.js
@@ -122,7 +122,7 @@ OrgUtils.openOrgReport = function(pOrgId)
     histData = ReportData.begin(["ENTRYDATE", "MEDIUM", "LOGIN", "INFO"]).add(histData);
     
     var attr = AttributeRelationUtils.getAllAttributes(pOrgId)
-        .map(function (row) {return row.join(": ")})
+        .map(function (row) {return row[1] ? row.join(": ") : row[0]})
         .join("\n");
     
     //tasks