diff --git a/.liquibase/Data_alias/basic/2019.2.1/changelog.xml b/.liquibase/Data_alias/basic/2019.2.1/changelog.xml
index 9826b227ec2cdaac11a2c51871d996aaa279d998..4eaaa3d57c6dd1ae0b7c548cc935a7a0dd465047 100644
--- a/.liquibase/Data_alias/basic/2019.2.1/changelog.xml
+++ b/.liquibase/Data_alias/basic/2019.2.1/changelog.xml
@@ -5,4 +5,5 @@
     
     <include relativeToChangelogFile="true" file="alter_SerialLetter.xml"/>
     <include relativeToChangelogFile="true" file="insert_SerialLetterStatus_keyword.xml"/>
+    <include relativeToChangelogFile="true" file="insert_AttributeType_Theme_keyword.xml"/>
 </databaseChangeLog>
diff --git a/.liquibase/Data_alias/basic/2019.2.1/insert_AttributeType_Theme_keyword.xml b/.liquibase/Data_alias/basic/2019.2.1/insert_AttributeType_Theme_keyword.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d5543dba499f36e83c8dd907e1e8b10ca9284335
--- /dev/null
+++ b/.liquibase/Data_alias/basic/2019.2.1/insert_AttributeType_Theme_keyword.xml
@@ -0,0 +1,22 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+    <changeSet author="s.listl" id="ec0f5419-353e-4643-8f08-03651d530401">
+        <insert tableName="AB_KEYWORD_ENTRY">
+            <column name="AB_KEYWORD_ENTRYID" value="49dc7423-21c7-47b1-ac1e-b01e8eb5c822"/>
+            <column name="KEYID" value="THEME                               "/>
+            <column name="TITLE" value="Theme"/>
+            <column name="CONTAINER" value="AttributeType"/>
+            <column name="SORTING" valueNumeric="11"/>
+            <column name="ISACTIVE" valueNumeric="1"/>
+            <column name="ISESSENTIAL" valueNumeric="1"/>
+        </insert>
+        <update tableName="AB_KEYWORD_ENTRY">
+            <column name="ISACTIVE" valueNumeric="1" />
+            <where>AB_KEYWORD_ENTRYID = ?</where>
+            <whereParams>
+                <param value="75a67526-6b7c-400d-b958-e1f8f45466aa"/>
+            </whereParams>
+        </update>
+    </changeSet>
+</databaseChangeLog>
diff --git a/entity/Attribute_entity/Attribute_entity.aod b/entity/Attribute_entity/Attribute_entity.aod
index 40f63107d36acb1924c34229e46566d54d7fa599..0800311201eb5c1abd813c7f94fa5c1aef548bf5 100644
--- a/entity/Attribute_entity/Attribute_entity.aod
+++ b/entity/Attribute_entity/Attribute_entity.aod
@@ -103,6 +103,10 @@
           <name>GetGroups_param</name>
           <expose v="false" />
         </entityParameter>
+        <entityParameter>
+          <name>AttributeTypes_param</name>
+          <expose v="false" />
+        </entityParameter>
       </children>
     </entityProvider>
     <entityParameter>
@@ -155,6 +159,10 @@
           <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/keywordattributetypes/children/containername_param/valueProcess.js</valueProcess>
           <expose v="true" />
         </entityParameter>
+        <entityParameter>
+          <name>WhitelistIds_param</name>
+          <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/keywordattributetypes/children/whitelistids_param/valueProcess.js</valueProcess>
+        </entityParameter>
       </children>
     </entityConsumer>
     <entityField>
@@ -274,6 +282,10 @@
           <name>ObjectType_param</name>
           <expose v="false" />
         </entityParameter>
+        <entityParameter>
+          <name>AttributeTypes_param</name>
+          <expose v="false" />
+        </entityParameter>
       </children>
     </entityProvider>
     <entityConsumer>
@@ -336,6 +348,10 @@
       <title>Filter</title>
       <contentType>FILTER_TREE</contentType>
     </entityField>
+    <entityParameter>
+      <name>AttributeTypes_param</name>
+      <expose v="true" />
+    </entityParameter>
   </entityFields>
   <recordContainers>
     <jDitoRecordContainer>
diff --git a/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js b/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js
index 94b08b434bc0674e06a52691e4bc5d80767f1b50..8c6709ec5b1ce2236dbb00e36c756b62b7e6bae4 100644
--- a/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js
+++ b/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js
@@ -12,11 +12,7 @@ if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_EDIT || vars.get("$sys.r
 {
     var type = vars.get("$field.ATTRIBUTE_TYPE").trim();
     var parentType = AttributeUtil.getAttributeType(vars.get("$field.ATTRIBUTE_PARENT_ID"));
-    if (parentType == $AttributeTypes.COMBO || parentType == $AttributeTypes.VOID)
-    {
-        state = neon.COMPONENTSTATE_READONLY;
-    }
-    else if (AttributeTypeUtil.isGroupType(type))
+    if (AttributeTypeUtil.isGroupType(type))
     {
         var hasSubordinate = db.cell(SqlCondition.begin()
             .andPrepareVars("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", "$field.UID")
diff --git a/entity/Attribute_entity/entityfields/attribute_type/valueProcess.js b/entity/Attribute_entity/entityfields/attribute_type/valueProcess.js
index 4578988623607a371183c603776847748b0a392d..f71767310af882089ae2d9f01355f052721e2979 100644
--- a/entity/Attribute_entity/entityfields/attribute_type/valueProcess.js
+++ b/entity/Attribute_entity/entityfields/attribute_type/valueProcess.js
@@ -7,10 +7,7 @@ import("Attribute_lib");
 if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW && vars.get("$field.ATTRIBUTE_PARENT_ID") != "")
 {
     var type = AttributeUtil.getAttributeType(vars.get("$field.ATTRIBUTE_PARENT_ID"));
-    if (type == $AttributeTypes.COMBO)
-        result.string($AttributeTypes.COMBOVALUE);
-    else if (type == $AttributeTypes.VOID)
-        result.string($AttributeTypes.VOID);
-    else if (vars.get("$this.value") == $AttributeTypes.COMBOVALUE)
-        result.string("");
+    var possibleTypes = AttributeTypeUtil.getPossibleChildren(type);
+    if (possibleTypes && possibleTypes.length === 1)
+        result.string(possibleTypes[0]);
 }
\ No newline at end of file
diff --git a/entity/Attribute_entity/entityfields/keywordattributetypes/children/whitelistids_param/valueProcess.js b/entity/Attribute_entity/entityfields/keywordattributetypes/children/whitelistids_param/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..7b6ff8c9c50d32b31512f753bbbb26440fc24382
--- /dev/null
+++ b/entity/Attribute_entity/entityfields/keywordattributetypes/children/whitelistids_param/valueProcess.js
@@ -0,0 +1,25 @@
+import("system.logging");
+import("system.db");
+import("system.neon");
+import("system.result");
+import("system.vars");
+import("Attribute_lib");
+
+if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW || vars.get("$sys.recordstate") == neon.OPERATINGSTATE_EDIT)
+{
+    var possibleTypes;
+    if (vars.get("$field.ATTRIBUTE_PARENT_ID"))
+    {
+        var type = AttributeUtil.getAttributeType(vars.get("$field.ATTRIBUTE_PARENT_ID"));
+        possibleTypes = AttributeTypeUtil.getPossibleChildren(type);
+    }
+    if (!possibleTypes)
+    {
+        possibleTypes = [];
+        for (let attrType in $AttributeTypes)
+            if ($AttributeTypes[attrType].toString() != $AttributeTypes.COMBOVALUE.toString())
+                possibleTypes.push($AttributeTypes[attrType].toString());
+    }
+    logging.log(JSON.stringify(possibleTypes, null, "\t"))
+    result.object(possibleTypes);
+}
\ No newline at end of file
diff --git a/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js b/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js
index 016b432ba387c332027c8d13771fd7d000c805b0..4cd396cf5193d5e94c80d43250d22d0f8eeab41e 100644
--- a/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js
@@ -48,9 +48,11 @@ else if (objectType)  //if there's an objectType, it comes from the AttributeRel
 {
     var filteredAttributes = null;
     
-    if (vars.exists("$param.FilteredAttributeIds_param") && vars.getString("$param.FilteredAttributeIds_param")) {
+    if (vars.exists("$param.AttributeTypes_param") && vars.getString("$param.AttributeTypes_param"))
+        condition.andIn("AB_ATTRIBUTE.ATTRIBUTE_TYPE", JSON.parse(vars.getString("$param.AttributeTypes_param")));
+    
+    if (vars.exists("$param.FilteredAttributeIds_param") && vars.getString("$param.FilteredAttributeIds_param"))
         filteredAttributes = JSON.parse(vars.getString("$param.FilteredAttributeIds_param"));
-    }
     
     var attributeCount;
     if (vars.exists("$param.AttributeCount_param") && vars.get("$param.AttributeCount_param"))
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index 33440988299a15eaf49bb064a5227a66fab5e3bb..af4e16b2b954f8a954cb35bfe618956388ff0744 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -4890,6 +4890,9 @@
     <entry>
       <key>No letters</key>
     </entry>
+    <entry>
+      <key>Download template</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 9a498c53f6438a76c5172334778dd325f80ea227..31e223a455fc9efff3827d8caa801bb6d582cfa9 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -62,6 +62,10 @@
       <key>Anonymization</key>
       <value>Anonymisierung</value>
     </entry>
+    <entry>
+      <key>Theme</key>
+      <value>Thema</value>
+    </entry>
     <entry>
       <key>Turnover change</key>
       <value>Entwicklung Umsatz</value>
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index 414b543211b35a1b3b3927391f527325f21e4d7c..14013a81b4c1c5830ce18d8c44c0566e0445eb2d 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -4940,6 +4940,9 @@
     <entry>
       <key>No letters</key>
     </entry>
+    <entry>
+      <key>Download template</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/process/Attribute_lib/process.js b/process/Attribute_lib/process.js
index 5a9235fa19681fc63304cc64136b2809685f9ff5..bf397d874cb4a77486935932f978e110f3f2eac3 100644
--- a/process/Attribute_lib/process.js
+++ b/process/Attribute_lib/process.js
@@ -711,7 +711,8 @@ $AttributeTypes.COMBO = {
     toString : function () {return "COMBO";},
     contentType : "UNKNOWN",
     databaseField : "ID_VALUE",
-    isGroup : true
+    isGroup : true,
+    possibleChildren : ["COMBOVALUE"]
 };
 $AttributeTypes.COMBOVALUE = {
     toString : function () {return "COMBOVALUE";},
@@ -744,7 +745,8 @@ $AttributeTypes.VOID = {
     toString : function () {return "VOID";},
     contentType : null,
     databaseField : null,
-    isGroup : true
+    isGroup : true,
+    possibleChildren : ["VOID"]
 };
 $AttributeTypes.MEMO = { 
     toString : function () {return "MEMO";},
@@ -783,7 +785,13 @@ $AttributeTypes.OBJECTSELECTION = {
             return dropDownList;
         }
 };
-
+$AttributeTypes.THEME = {
+    toString : function () {return "THEME";},
+    contentType : "LONG_TEXT",
+    databaseField : "CHAR_VALUE",
+    isGroup : true,
+    possibleChildren : ["THEME"]
+};
 
 function AttributeTypeUtil () {}
 
@@ -842,6 +850,24 @@ AttributeTypeUtil.getDatabaseField = function (pAttributeType)
     return null;
 }
 
+/**
+ * returns the possible children types 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 possible children types
+ */
+AttributeTypeUtil.getPossibleChildren = function (pAttributeType)
+{
+    if (pAttributeType)
+    {
+        pAttributeType = pAttributeType.trim();
+        if (pAttributeType in $AttributeTypes)
+            return $AttributeTypes[pAttributeType].possibleChildren;
+    }
+    return null;
+}
+
 AttributeTypeUtil.getAttributeViewValue = function (pAttributeType, pValue, pKeyword)
 {
     if (pAttributeType in $AttributeTypes && $AttributeTypes[pAttributeType].getViewValue)