diff --git a/.liquibase/Data_alias/basic/2021.2.2/Mosaico/insert_mosaico_color_keyword.xml b/.liquibase/Data_alias/basic/2021.2.2/Mosaico/insert_mosaico_color_keyword.xml
index a78446865d46f37a72a07412c6ac4db43b3ade9b..a2229c68a8666f714d2402c776c0add77d864d6b 100644
--- a/.liquibase/Data_alias/basic/2021.2.2/Mosaico/insert_mosaico_color_keyword.xml
+++ b/.liquibase/Data_alias/basic/2021.2.2/Mosaico/insert_mosaico_color_keyword.xml
@@ -17,7 +17,7 @@
         <column name="CONTAINER" value="MosaicoColor"/>
         <column name="SORTING" valueNumeric="1"/>
         <column name="ISACTIVE" valueNumeric="1"/>
-        <column name="ISESSENTIAL" valueNumeric="1"/>
+        <column name="ISESSENTIAL" valueNumeric="0"/>
     </insert>
     <insert tableName="AB_KEYWORD_ENTRY">
         <column name="AB_KEYWORD_ENTRYID" value="6f3b9635-679c-47b4-9fe3-0770aaca719c"/>
@@ -27,7 +27,7 @@
         <column name="CONTAINER" value="MosaicoColor"/>
         <column name="SORTING" valueNumeric="2"/>
         <column name="ISACTIVE" valueNumeric="1"/>
-        <column name="ISESSENTIAL" valueNumeric="1"/>
+        <column name="ISESSENTIAL" valueNumeric="0"/>
     </insert>
     <insert tableName="AB_KEYWORD_ENTRY">
         <column name="AB_KEYWORD_ENTRYID" value="b9ce199e-a4e1-4b48-ba61-85ee6139b89c"/>
@@ -37,7 +37,7 @@
         <column name="CONTAINER" value="MosaicoColor"/>
         <column name="SORTING" valueNumeric="3"/>
         <column name="ISACTIVE" valueNumeric="1"/>
-        <column name="ISESSENTIAL" valueNumeric="1"/>
+        <column name="ISESSENTIAL" valueNumeric="0"/>
     </insert>
     <insert tableName="AB_KEYWORD_ENTRY">
         <column name="AB_KEYWORD_ENTRYID" value="09f299f7-9faa-40c4-a53d-e7b5c33dca53"/>
@@ -47,7 +47,17 @@
         <column name="CONTAINER" value="MosaicoColor"/>
         <column name="SORTING" valueNumeric="4"/>
         <column name="ISACTIVE" valueNumeric="1"/>
-        <column name="ISESSENTIAL" valueNumeric="1"/>
+        <column name="ISESSENTIAL" valueNumeric="0"/>
+    </insert>
+    <insert tableName="AB_KEYWORD_ENTRY">
+        <column name="AB_KEYWORD_ENTRYID" value="692699de-d7ad-4500-b71e-153555a2ceac"/>
+        <column name="AB_KEYWORD_CATEGORY_ID" value="dc4cc24d-5df2-481f-a028-8d22ce6f6e64"/>
+        <column name="KEYID" value="FFFFFF"/>
+        <column name="TITLE" value="White"/>
+        <column name="CONTAINER" value="MosaicoColor"/>
+        <column name="SORTING" valueNumeric="5"/>
+        <column name="ISACTIVE" valueNumeric="1"/>
+        <column name="ISESSENTIAL" valueNumeric="0"/>
     </insert>
   </changeSet>
 </databaseChangeLog>
diff --git a/entity/360Degree_entity/entityfields/organisationobjects/children/objecttype_param/valueProcess.js b/entity/360Degree_entity/entityfields/organisationobjects/children/objecttype_param/valueProcess.js
index cc537d09a0f68400d1984bf124d36f8968adf16d..295029c2d703ea7e2e97850fa69eac2ac0b7c3c9 100644
--- a/entity/360Degree_entity/entityfields/organisationobjects/children/objecttype_param/valueProcess.js
+++ b/entity/360Degree_entity/entityfields/organisationobjects/children/objecttype_param/valueProcess.js
@@ -16,6 +16,12 @@ var res = {
         "connectionField":"TASK_REQUESTOR_CONTACT_ID",
         "setGroupBy":"NameFor360"
     },
+    "Campaign": {        
+        "subContext":"CampaignParticipant",
+        "childField":"CAMPAIGN_ID",
+        "parentField":"CAMPAIGNID",
+        "contactIdField":"CONTACT_ID"
+    }, 
     "Advertising": {},
     "BulkMail": {        
         "subContext":"BulkMailRecipient",
diff --git a/entity/BulkMail_entity/BulkMail_entity.aod b/entity/BulkMail_entity/BulkMail_entity.aod
index 8453500e38c5d83f14d13a8a19c7f86ddbcc37d4..733499d5e6440d8fd26c4721ec19ff966bf7336f 100644
--- a/entity/BulkMail_entity/BulkMail_entity.aod
+++ b/entity/BulkMail_entity/BulkMail_entity.aod
@@ -6,7 +6,6 @@
   <documentation>%aditoprj%/entity/BulkMail_entity/documentation.adoc</documentation>
   <icon>VAADIN:AT</icon>
   <grantUpdateProcess>%aditoprj%/entity/BulkMail_entity/grantUpdateProcess.js</grantUpdateProcess>
-  <grantDeleteProcess>%aditoprj%/entity/BulkMail_entity/grantDeleteProcess.js</grantDeleteProcess>
   <contentTitleProcess>%aditoprj%/entity/BulkMail_entity/contentTitleProcess.js</contentTitleProcess>
   <contentDescriptionProcess>%aditoprj%/entity/BulkMail_entity/contentDescriptionProcess.js</contentDescriptionProcess>
   <afterUiInit>%aditoprj%/entity/BulkMail_entity/afterUiInit.js</afterUiInit>
diff --git a/entity/BulkMail_entity/entityfields/content/stateProcess.js b/entity/BulkMail_entity/entityfields/content/stateProcess.js
index 24b49f027ede29dea1a30a25c28aee4b839c0a7f..4a4e1bbf91589ad6fa246608d2facdbfda8dbc09 100644
--- a/entity/BulkMail_entity/entityfields/content/stateProcess.js
+++ b/entity/BulkMail_entity/entityfields/content/stateProcess.js
@@ -2,11 +2,19 @@ import("system.result");
 import("system.vars");
 import("system.neon");
 import("DocumentTemplate_lib");
+import("Util_lib");
 
 // in edit mode
-if (vars.get("$sys.recordstate") != neon.OPERATINGSTATE_VIEW && vars.get("$field.templateType") == DocumentTemplate.types.EML) // TODO: invisible for html as there are problems with images which are removed by the html-editor
+if (vars.get("$sys.recordstate") != neon.OPERATINGSTATE_VIEW 
+    && ((vars.get("$field.templateType") == DocumentTemplate.types.EML)
+        || (vars.get("$field.templateType") == DocumentTemplate.types.HTML && (!Utils.isNullOrEmptyString(vars.get("$field.DOCUMENTTEMPLATE_ID")) || !Utils.isNullOrEmptyString(vars.get("$field.MOSAICOTEMPLATE_ID")))))) 
     result.string(neon.COMPONENTSTATE_INVISIBLE);
-else if (vars.get("$field.templateType") == DocumentTemplate.types.EML)
-    result.string(neon.COMPONENTSTATE_READONLY);
+else if (vars.get("$field.templateType") == DocumentTemplate.types.EML 
+            || (vars.get("$field.templateType") == DocumentTemplate.types.HTML && (!Utils.isNullOrEmptyString(vars.get("$field.DOCUMENTTEMPLATE_ID")) || !Utils.isNullOrEmptyString(vars.get("$field.MOSAICOTEMPLATE_ID")))))
+{
+    result.string(neon.COMPONENTSTATE_READONLY);  
+}    
 else
-    result.string(neon.COMPONENTSTATE_EDITABLE);
\ No newline at end of file
+{
+    result.string(neon.COMPONENTSTATE_EDITABLE);   
+}
diff --git a/entity/BulkMail_entity/entityfields/emleditinfo/stateProcess.js b/entity/BulkMail_entity/entityfields/emleditinfo/stateProcess.js
index 4c7e406153cf2cf3cf572311262bdbae39f476ce..c53a60c86cbf94fae4bef118a608937a9aee16b5 100644
--- a/entity/BulkMail_entity/entityfields/emleditinfo/stateProcess.js
+++ b/entity/BulkMail_entity/entityfields/emleditinfo/stateProcess.js
@@ -1,9 +1,11 @@
+import("Util_lib");
 import("system.result");
 import("system.vars");
 import("system.neon");
 import("DocumentTemplate_lib");
 
-if (vars.get("$sys.recordstate") != neon.OPERATINGSTATE_VIEW && vars.get("$field.templateType") == DocumentTemplate.types.EML) // TODO: invisible for html as there are problems with images which are removed by the html-editor
+if (vars.get("$sys.recordstate") != neon.OPERATINGSTATE_VIEW && (vars.get("$field.templateType") == DocumentTemplate.types.EML
+|| (vars.get("$field.templateType") == DocumentTemplate.types.HTML && (!Utils.isNullOrEmptyString(vars.get("$field.DOCUMENTTEMPLATE_ID")) || !Utils.isNullOrEmptyString(vars.get("$field.MOSAICOTEMPLATE_ID"))))))
     result.string(neon.COMPONENTSTATE_READONLY);
 else
     result.string(neon.COMPONENTSTATE_INVISIBLE);
\ No newline at end of file
diff --git a/entity/BulkMail_entity/entityfields/emleditinfo/valueProcess.js b/entity/BulkMail_entity/entityfields/emleditinfo/valueProcess.js
index 4f595f34a49eae691e8feb852048e96b0893e77c..51e6370a137b781581deed76847ed17a64a5bd0d 100644
--- a/entity/BulkMail_entity/entityfields/emleditinfo/valueProcess.js
+++ b/entity/BulkMail_entity/entityfields/emleditinfo/valueProcess.js
@@ -1,4 +1,4 @@
 import("system.translate");
 import("system.result");
 
-result.string(translate.text("EML files can't be edited here. You can download, edit and reupload the template to change the content."))
\ No newline at end of file
+result.string(translate.text("File can't be edited here. You can download, edit and reupload the template to change the content."))
\ No newline at end of file
diff --git a/entity/BulkMail_entity/grantDeleteProcess.js b/entity/BulkMail_entity/grantDeleteProcess.js
deleted file mode 100644
index 28bfe1f78be38012df50953c85c7a033684d3f5e..0000000000000000000000000000000000000000
--- a/entity/BulkMail_entity/grantDeleteProcess.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import("Context_lib");
-import("system.vars");
-import("system.result");
-import("Entity_lib");
-
-var rowId = vars.get("$field.BULKMAILID");
-var currentContext = ContextUtils.getCurrentContextId();
-
-var canDelete = new HasLinkedObjectTester()
-    .andNoEntityRows("BulkMailRecipient_entity", "BulkMailRecipients", {BulkMailId_param : rowId}) //Recipients
-    .andNoEntityRows("Activity_entity", "LinkedObjects", {ObjectId_param : currentContext, RowId_param : rowId}) //Activities
-    .validate();
-
-result.string(canDelete);
\ No newline at end of file
diff --git a/entity/BulkMail_entity/recordcontainers/db/onDBDelete.js b/entity/BulkMail_entity/recordcontainers/db/onDBDelete.js
index aaa02ff8073f59cb12e50e314b8e88b7a39f79cd..104dcc3a1c0d21d885433f28aab40b3993fdf7b2 100644
--- a/entity/BulkMail_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/BulkMail_entity/recordcontainers/db/onDBDelete.js
@@ -1,3 +1,4 @@
+import("Bulkmail_lib");
 import("Document_lib");
 import("Context_lib");
 import("Workflow_lib");
@@ -9,6 +10,29 @@ DocumentUtil.deleteAllUploadedImages("content_IMAGE_UPLOAD");
 
 newWhere("BULKMAILRECIPIENT.BULKMAIL_ID", "$local.uid").deleteData();
 
+BulkMailUtils.deleteAllEmlFiles(vars.get("$local.uid"));
+
+newWhere("ACTIVITYLINK.OBJECT_ROWID","$local.uid").and("ACTIVITYLINK.OBJECT_TYPE","BulkMail").deleteData();
+
+newWhere("WEBLINK_CLICK.MAIL_LOG_ID"
+        ,newSelect("MAIL_LOG.MAIL_LOGID")
+            .from("MAIL_LOG")
+            .join("MAIL_RUN","MAIL_LOG.MAIL_RUN_ID = MAIL_RUN.MAIL_RUNID")
+            .where("MAIL_RUN.OBJECT_TYPE","BulkMail")
+            .and("MAIL_RUN.OBJECT_ROWID","$local.uid")
+        ,SqlBuilder.IN())
+        .deleteData(true,"WEBLINK_CLICK");
+
+newWhere("MAIL_LOG.MAIL_RUN_ID",
+        newSelect("MAIL_RUN.MAIL_RUNID")
+            .from("MAIL_RUN")
+            .where("MAIL_RUN.OBJECT_TYPE","BulkMail")
+            .and("MAIL_RUN.OBJECT_ROWID","$local.uid")
+        ,SqlBuilder.IN())
+        .deleteData(true,"MAIL_LOG");
+
+newWhere("MAIL_RUN.OBJECT_TYPE","BulkMail").and("MAIL_RUN.OBJECT_ROWID","$local.uid").deleteData();
+
 SingleBinaryUtils.remove("BULKMAIL", "DOCUMENT", vars.get("$local.uid"));
 
 WorkflowSignalSender.deleted();
\ No newline at end of file
diff --git a/entity/EmailFilterHandling_entity/entityfields/filterviewactiongroup/children/increasepriority/stateProcess.js b/entity/EmailFilterHandling_entity/entityfields/filterviewactiongroup/children/increasepriority/stateProcess.js
index 46ef593de432a6d610b40dd32f93abf4d98f68ae..ccc413c432dc982e5e33bf5f00dc68328e1f98b3 100644
--- a/entity/EmailFilterHandling_entity/entityfields/filterviewactiongroup/children/increasepriority/stateProcess.js
+++ b/entity/EmailFilterHandling_entity/entityfields/filterviewactiongroup/children/increasepriority/stateProcess.js
@@ -5,7 +5,7 @@ import("system.neon");
 
 var priority = parseInt(vars.get("$field.PRIORITY"));
 
-if (vars.get("$sys.selectionsRecordsRecipe") && priority != 1)
+if (vars.get("$sys.selectionsRecordsRecipe") && priority > 1)
 {
 
     result.string(neon.COMPONENTSTATE_EDITABLE);
diff --git a/entity/Organisation_entity/Organisation_entity.aod b/entity/Organisation_entity/Organisation_entity.aod
index ae049b182743dffc9aec4967208cc1fc064e60b3..1a54cbd02b1c4159ec649c07eb897079c75f6cc2 100644
--- a/entity/Organisation_entity/Organisation_entity.aod
+++ b/entity/Organisation_entity/Organisation_entity.aod
@@ -1333,6 +1333,7 @@
     </entityConsumer>
     <entityConsumer>
       <name>ContactCommunicationSettings</name>
+      <refreshParent v="true" />
       <dependency>
         <name>dependency</name>
         <entityName>CommunicationSettings_entity</entityName>
diff --git a/entity/Person_entity/recordcontainers/db/recordfieldmappings/campaigns/filterConditionProcess.js b/entity/Person_entity/recordcontainers/db/recordfieldmappings/campaigns/filterConditionProcess.js
index 7217d840fee842a5ba7e90b24829446b93fcf038..84ffbb8761e7072c71878d0329e90ab1d4262bc1 100644
--- a/entity/Person_entity/recordcontainers/db/recordfieldmappings/campaigns/filterConditionProcess.js
+++ b/entity/Person_entity/recordcontainers/db/recordfieldmappings/campaigns/filterConditionProcess.js
@@ -3,10 +3,11 @@ import("Sql_lib");
 import("system.result");
 
 result.string(newWhere("CONTACT.PERSON_ID",
-    newSelect("SALESORDER.CONTACT_ID")
+    newSelect("CAMPAIGNPARTICIPANT.CONTACT_ID")
     .from("CONTACT")
-    .join("SALESORDER", 
-        newWhere("CONTACT.CONTACTID = SALESORDER.CONTACT_ID"))
+    .join("CAMPAIGNPARTICIPANT", 
+        newWhere("CONTACT.CONTACTID = CAMPAIGNPARTICIPANT.CONTACT_ID"))
+    .join("CAMPAIGN", "CAMPAIGNPARTICIPANT.CAMPAIGN_ID = CAMPAIGN.CAMPAIGNID")
     .whereIfSet(vars.get("$local.condition")),
     SqlBuilder.IN())
 .toString());
\ No newline at end of file
diff --git a/entity/WeblinkTag_entity/entityfields/tag/displayValueProcess.js b/entity/WeblinkTag_entity/entityfields/tag/displayValueProcess.js
index beebea09168f9f4766bae042d7e7f9ce35a70aed..5e11e8f7a16171e832f253b6554b4ec2b069bfd4 100644
--- a/entity/WeblinkTag_entity/entityfields/tag/displayValueProcess.js
+++ b/entity/WeblinkTag_entity/entityfields/tag/displayValueProcess.js
@@ -1,5 +1,6 @@
 import("system.vars");
 import("Keyword_lib");
 import("system.result");
+import("KeywordRegistry_basic");
 
-result.string(KeywordUtils.getViewValue("LinkTags", vars.get("$field.TAG")));
\ No newline at end of file
+result.string(KeywordUtils.getViewValue($KeywordRegistry.weblinkTags()), vars.get("$field.TAG"));
\ No newline at end of file
diff --git a/entity/Weblink_entity/entityfields/url/onValidation.js b/entity/Weblink_entity/entityfields/url/onValidation.js
index e6206fe51d7947ef870a671ef47fb3089c8f0ce4..ad34bba4f8f454fbfa8d54c5e2e4e08dc69d1fb0 100644
--- a/entity/Weblink_entity/entityfields/url/onValidation.js
+++ b/entity/Weblink_entity/entityfields/url/onValidation.js
@@ -9,7 +9,7 @@ if (vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW && vars.get("$loc
     if (newSelect("URL").from("WEBLINK").where("WEBLINK.URL", vars.get("$local.value")).cell())
         result.string(translate.text("URL must be unique"));
     
-    if (vars.get("$field.ISREDIRECT") == "1" && !/^(?:http(s)?:\/\/)[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/g.test(vars.get("$local.value")))
+    if (vars.get("$field.ISREDIRECT") == "1" && !/^(?:http(s)?:\/\/)[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#%[\]@!\$&'\(\)\*\+,;=.]+$/g.test(vars.get("$local.value")) && !/\/[\w\-\._~:/?#%[\]@!\$&'\(\)\*\+,;=.]+$/g.test(vars.get("$local.value")))
     {
         result.string(translate.text("Redirect needs a full URL with http/https"));
     }
diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
index 97eacea5b556d9b5d3b83156512092194204ea69..a54d9d96636a6a14862a5044eb386e36f6123709 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -563,8 +563,8 @@
       <value>Eigenschaft \"%0\" kann nur einmal mit dem selben Wert ausgewählt werden.</value>
     </entry>
     <entry>
-      <key>EML files can't be edited here. You can download, edit and reupload the template to change the content.</key>
-      <value>Das Bearbeiten von EML-Dateien ist hier nicht möglich. Um den Inhalt zu ändern, können Sie die Vorlage herunterladen, bearbeiten und erneut hochladen.</value>
+      <key>File can't be edited here. You can download, edit and reupload the template to change the content.</key>
+      <value>Das Bearbeiten der-Datei ist hier nicht möglich. Um den Inhalt zu ändern, können Sie die Vorlage herunterladen, bearbeiten und erneut hochladen.</value>
     </entry>
     <entry>
       <key>Date Clicked</key>
diff --git a/neonView/BulkMailAnalysisDeviceTypeChart_view/BulkMailAnalysisDeviceTypeChart_view.aod b/neonView/BulkMailAnalysisDeviceTypeChart_view/BulkMailAnalysisDeviceTypeChart_view.aod
index 870422df4767619bedb31d77c2d8e055c8306cfb..df8146988e016472657942cb6d92acfab4261a21 100644
--- a/neonView/BulkMailAnalysisDeviceTypeChart_view/BulkMailAnalysisDeviceTypeChart_view.aod
+++ b/neonView/BulkMailAnalysisDeviceTypeChart_view/BulkMailAnalysisDeviceTypeChart_view.aod
@@ -11,6 +11,7 @@
       <singleton v="true" />
       <storeRoles>
         <element>PROJECT_Marketing</element>
+        <element>INTERNAL_ADMINISTRATOR</element>
       </storeRoles>
       <icon>NEON:GROUP_APPOINTMENT</icon>
       <categories>
diff --git a/neonView/BulkMailAnalysisScoreCard_view/BulkMailAnalysisScoreCard_view.aod b/neonView/BulkMailAnalysisScoreCard_view/BulkMailAnalysisScoreCard_view.aod
index 650ea5b83a91a0131459a877fadf7cd46230aa5c..1fb0eecc08b3211b5a093f2092b4868a0a2af280 100644
--- a/neonView/BulkMailAnalysisScoreCard_view/BulkMailAnalysisScoreCard_view.aod
+++ b/neonView/BulkMailAnalysisScoreCard_view/BulkMailAnalysisScoreCard_view.aod
@@ -12,6 +12,7 @@
       <singleton v="true" />
       <storeRoles>
         <element>PROJECT_Marketing</element>
+        <element>INTERNAL_ADMINISTRATOR</element>
       </storeRoles>
       <icon>VAADIN:GRID_BIG</icon>
       <categories>
diff --git a/neonView/BulkMailFilter_view/BulkMailFilter_view.aod b/neonView/BulkMailFilter_view/BulkMailFilter_view.aod
index 042e71cb800e3f9f8d63f78d61a5b654469ee418..58a7e0c06ef66dfa3abc8ceb54f97438b116c490 100644
--- a/neonView/BulkMailFilter_view/BulkMailFilter_view.aod
+++ b/neonView/BulkMailFilter_view/BulkMailFilter_view.aod
@@ -12,6 +12,7 @@
       <singleton v="true" />
       <storeRoles>
         <element>PROJECT_Marketing</element>
+        <element>INTERNAL_ADMINISTRATOR</element>
       </storeRoles>
       <icon>VAADIN:AT</icon>
       <categories>
diff --git a/neonView/CampaignCostChart_view/CampaignCostChart_view.aod b/neonView/CampaignCostChart_view/CampaignCostChart_view.aod
index 79fa24a99a23064c9911773632f1e97b2261104b..b1b48e8a6a46f1d87accd01025ec8c81aa27eb6b 100644
--- a/neonView/CampaignCostChart_view/CampaignCostChart_view.aod
+++ b/neonView/CampaignCostChart_view/CampaignCostChart_view.aod
@@ -11,6 +11,7 @@
       <singleton v="true" />
       <storeRoles>
         <element>PROJECT_Marketing</element>
+        <element>INTERNAL_ADMINISTRATOR</element>
       </storeRoles>
       <icon>VAADIN:MONEY</icon>
       <categories>
diff --git a/neonView/CampaignFilter_view/CampaignFilter_view.aod b/neonView/CampaignFilter_view/CampaignFilter_view.aod
index 648fbef2a5fddef0c2f5f3faf17246a5ca0bddb1..53acd27360a994b95b7d70dcb5e232be3bc22955 100644
--- a/neonView/CampaignFilter_view/CampaignFilter_view.aod
+++ b/neonView/CampaignFilter_view/CampaignFilter_view.aod
@@ -14,6 +14,7 @@
       <singleton v="true" />
       <storeRoles>
         <element>PROJECT_Marketing</element>
+        <element>INTERNAL_ADMINISTRATOR</element>
       </storeRoles>
       <icon>NEON:GROUP_APPOINTMENT</icon>
       <categories>
@@ -37,6 +38,7 @@
       <singleton v="true" />
       <storeRoles>
         <element>PROJECT_Marketing</element>
+        <element>INTERNAL_ADMINISTRATOR</element>
       </storeRoles>
       <icon>NEON:GROUP_APPOINTMENT</icon>
       <categories>
diff --git a/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod b/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod
index 399ceef3cf82a9f802a367463c4a248715a7a5b8..88fd31802025e9ce3a64403bd5e9b3bd0295f7ab 100644
--- a/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod
+++ b/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod
@@ -105,7 +105,19 @@
     <customStringProperty>
       <name>bulkmail.baseReplacementURL</name>
       <description>Base url for replacement of redirectlinks in bulkmails</description>
-      <property></property>
+    </customStringProperty>
+    <customStringProperty>
+      <name>bulkmail.fileStorage</name>
+      <description>Save Location for send Mails. When empty %aditodata% gets used.</description>
+    </customStringProperty>
+    <customStringProperty>
+      <name>bulkmail.user</name>
+      <description>Title of the useraccount that is used to send bulkmails</description>
+      <property>mailbridge</property>
+    </customStringProperty>
+    <customStringProperty>
+      <name>mosaico.url</name>
+      <description>Url of the Mosaico Email Editor</description>
     </customStringProperty>
   </customConfigProperties>
   <customProperties>
@@ -205,24 +217,10 @@
       <description></description>
       <property v="false" />
     </customBooleanProperty>
-    <customStringProperty>
-      <name>bulkmail.fileStorage</name>
-      <description>Save Location for send Mails. Path is relative to Serverpath</description>
-      <property>/bulkMailFiles/</property>
-    </customStringProperty>
     <customIntegerProperty>
       <name>ews.syncsize</name>
       <description>Defines how big a filter for synchronizing to Outlook may be</description>
       <property v="7200" />
     </customIntegerProperty>
-    <customStringProperty>
-      <name>bulkmail.user</name>
-      <description>Title of the useraccount that is used to send bulkmails</description>
-      <property>mailbridgeDev</property>
-    </customStringProperty>
-    <customStringProperty>
-      <name>mosaico.url</name>
-      <description>Url of the Mosaico Email Editor</description>
-    </customStringProperty>
   </customProperties>
 </preferences>
diff --git a/process/Bulkmail_lib/process.js b/process/Bulkmail_lib/process.js
index 931c3562926a2f9b7e2c6f97c45018534f95df4c..0a4abe43994a04bfa2febe4d21de4e20fa6c8c5c 100644
--- a/process/Bulkmail_lib/process.js
+++ b/process/Bulkmail_lib/process.js
@@ -28,6 +28,7 @@ import("Document_lib");
 import("system.db");
 import("system.workflow");
 import("system.tools");
+import("FileUtil_lib");
 
 /**
  * Functions for bulk mails.
@@ -90,7 +91,7 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun, pUser, pAddition
     {
         pIsTestRun = false;
     }
-    var sendUserTitle = project.getPreferenceValue("custom.bulkmail.user");
+    var sendUserTitle = project.getInstanceConfigValue("custom.bulkmail.user");
     
     var [templateId, subject, emailSender, createActivity, bulkMailName, useTemplateAttachments, mosaicoTemplateId] = 
                 newSelect("DOCUMENTTEMPLATE_ID, SUBJECT, SENDER_EMAIL_ADDRESS, CREATEACTIVITIES, NAME, USE_TEMPLATE_ATTACHMENTS, MOSAICOTEMPLATE_ID")
@@ -946,13 +947,27 @@ BulkMailUtils.createFromMosaicoTemplate = function(pMosaicoTemplateId)
  **/
 BulkMailUtils.storeEmlFile = function (pBulkMailId, pMailRunId, pMailLogId, pFile)
 {
-    var locationoption = project.getPreferenceValue("bulkmail.fileStorage", "/bulkMailFiles/");
-    var path = vars.get("$sys.serverdata") + locationoption + pBulkMailId + "/" + pMailRunId + "/";
+    var locationOption = project.getInstanceConfigValue("bulkmail.fileStorage", vars.get("$sys.serverdata"));
+    var path = locationOption + (locationOption.substr(locationOption.length-1) == "/" ? "" : "/" )+ "bulkmailfiles/" + pBulkMailId + "/" + pMailRunId + "/";
     var filename = pMailLogId + ".eml"
     var fullPath = path + filename;
     fileIO.storeData(fullPath, pFile, util.DATA_BINARY, false);
 }
 
+/*
+ *Deletes all stored eml files for a bulk mail
+ *
+ *@param {String} pBulkMailId           <p>
+ *                                      The id of the bulk mail.<br>
+ *
+ **/
+BulkMailUtils.deleteAllEmlFiles = function (pBulkMailId)
+{
+    var locationOption = project.getInstanceConfigValue("bulkmail.fileStorage", vars.get("$sys.serverdata"));
+    var path = locationOption + (locationOption.substr(locationOption.length-1) == "/" ? "" : "/" )+ "bulkmailfiles/" + pBulkMailId;
+    FileUtils.removeFolder(path);    
+}
+
 /*
  * Stores the eml file of a bounce in the filesystem
  *
@@ -962,8 +977,8 @@ BulkMailUtils.storeEmlFile = function (pBulkMailId, pMailRunId, pMailLogId, pFil
  **/
 BulkMailUtils.storeBounceEmlFile = function (pBounceId, pFile)
 {
-    var locationoption = project.getPreferenceValue("bulkmail.fileStorage", "/bulkMailFiles/");
-    var path = vars.get("$sys.serverdata") + locationoption +  "Bounces/";
+    var locationOption = project.getInstanceConfigValue("bulkmail.fileStorage", vars.get("$sys.serverdata"));
+    var path = locationOption + (locationOption.substr(locationOption.length-1) == "/" ? "" : "/" )+ "bulkmailfiles/bounces/";
     var filename = pBounceId + ".eml"
     var fullPath = path + filename;
     fileIO.storeData(fullPath, pFile, util.DATA_TEXT, false);
@@ -983,8 +998,8 @@ BulkMailUtils.storeBounceEmlFile = function (pBounceId, pFile)
  **/
 BulkMailUtils.getEmlFile = function(pBulkMailId,pMailRunId, pMailLogId)
 {
-    var locationoption = project.getPreferenceValue("bulkmail.fileStorage","/bulkMailFiles/");
-    var path = vars.get("$sys.serverdata")+locationoption +pBulkMailId+"/"+pMailRunId+"/";
+    var locationOption = project.getInstanceConfigValue("bulkmail.fileStorage", vars.get("$sys.serverdata"));
+    var path = locationOption + (locationOption.substr(locationOption.length-1) == "/" ? "" : "/" )+ "bulkmailfiles/" + pBulkMailId + "/" + pMailRunId + "/";
     var filename = pMailLogId+".eml"
     var fullPath = path + filename;
     return (fileIO.getData(fullPath,util.DATA_BINARY));
@@ -995,15 +1010,22 @@ BulkMailUtils.getEmlFile = function(pBulkMailId,pMailRunId, pMailLogId)
  *
  * @param {String} pLinkId          <p>
  *                                      The id of the link.<br>
+ * @param {String} pBaseUrl          <p>
+ *                                      The base url for relative links<br>                                      
  *                                      
  * @return {String}                 <p>
  *                                      The url<br>                                          
  **/
-BulkMailUtils.getRedirectLink = function(pLinkId)
+BulkMailUtils.getRedirectLink = function(pLinkId, pBaseUrl)
 {
     if (pLinkId)
     {
-        return newSelect("WEBLINK.URL").from("WEBLINK").where("WEBLINK.WEBLINKID", pLinkId).cell();
+        var link = newSelect("WEBLINK.URL").from("WEBLINK").where("WEBLINK.WEBLINKID", pLinkId).cell();
+        if(link[0] == "/")
+        {
+            link = pBaseUrl + link;
+        }
+        return link;
     }
     return null;
 }
diff --git a/process/DocumentTemplate_lib/process.js b/process/DocumentTemplate_lib/process.js
index 7700b24877d7f879d04e344f177d856fc09b1b77..f6af351bfa937adc769ba5ee92156b0a01ceb438 100644
--- a/process/DocumentTemplate_lib/process.js
+++ b/process/DocumentTemplate_lib/process.js
@@ -407,7 +407,7 @@ DocumentTemplate.getSelectedTemplate = function (pTemplateId, pDocumentUpload, p
     else
         template = new DocumentTemplate(null, pDefaultType || DocumentTemplate.types.TXT, null, true);
     
-    if (pEditedContent)
+    if (pEditedContent || (!pTemplateId && !pDocumentUpload.isFilled()))
     {
         if (template.type == DocumentTemplate.types.EML || template.type == DocumentTemplate.types.HTML)
             pEditedContent = "<html>" + pEditedContent + "</html>";
diff --git a/process/FileUtil_lib/FileUtil_lib.aod b/process/FileUtil_lib/FileUtil_lib.aod
new file mode 100644
index 0000000000000000000000000000000000000000..a32531311b3d57d1ae3da5981ba76bd3a1c43fbb
--- /dev/null
+++ b/process/FileUtil_lib/FileUtil_lib.aod
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.2">
+  <name>FileUtil_lib</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <process>%aditoprj%/process/FileUtil_lib/process.js</process>
+  <variants>
+    <element>LIBRARY</element>
+  </variants>
+</process>
diff --git a/process/FileUtil_lib/process.js b/process/FileUtil_lib/process.js
new file mode 100644
index 0000000000000000000000000000000000000000..52627abc975976a6b831787d0060a21c633211cb
--- /dev/null
+++ b/process/FileUtil_lib/process.js
@@ -0,0 +1,34 @@
+import("system.fileIO");
+
+/**
+ * functions for files
+ * Do not create an instance of this!
+ * 
+ * @class
+ */
+function FileUtils () {}
+
+/**
+ * deletes a folder.
+ * @param {String} pPath location of the folder
+ */
+FileUtils.removeFolder = function(pPath)
+{
+    if (!fileIO.isDirectory(pPath))
+    {
+        return;
+    }
+    fileIO.listFiles(pPath).forEach(function (pFileOrFolder)
+    {
+        var newPath = pPath+"/"+pFileOrFolder;
+        if(fileIO.isDirectory(newPath))
+        {
+            FileUtils.removeFolder(newPath);
+        }
+        else
+        {
+            fileIO.remove(newPath);
+        }
+    });
+    fileIO.remove(pPath);
+}
\ No newline at end of file
diff --git a/process/MosaicoTemplate_lib/process.js b/process/MosaicoTemplate_lib/process.js
index 849855de8a1626632e7cd732482b5a69155b2b12..e967d3efa6add0372fb1d566469e3d30de308da0 100644
--- a/process/MosaicoTemplate_lib/process.js
+++ b/process/MosaicoTemplate_lib/process.js
@@ -24,8 +24,9 @@ function MosaicoUtils () {}
  */
 MosaicoUtils.openInMosaico = function (pMosaicoTemplateId)
 {
-    var baseurl = project.getPreferenceValue("custom.mosaico.url");
-
+    var defaultUrl = vars.get("$sys.origin").replace("https://","https://mosaico.");
+    var baseurl = project.getInstanceConfigValue("custom.mosaico.url",defaultUrl);
+    
     var aditoWebserviceBaseUrl = vars.get("$sys.origin");
 
     var baseTemplate = newSelect("BASETEMPLATE")
diff --git a/process/redirect_rest/process.js b/process/redirect_rest/process.js
index 694fde826961826549e7df25671027f4948e06e6..eb1da60e6fc71fb4c8eca92f8bf88c0a795b13c5 100644
--- a/process/redirect_rest/process.js
+++ b/process/redirect_rest/process.js
@@ -15,7 +15,8 @@ function restget (pRequest)
     var workflowInstanceId = request.query.workflowinstance;
     var workflowKey = request.query.workflowkey
     var ipAddress = BulkMailUtils.getIpAddressFromHeader(request.header);
-    var redirectLink = BulkMailUtils.getRedirectLink(linkId);
+    var origin =request.header["X-forwarded-proto"]+"://"+request.header["X-forwarded-host"]
+    var redirectLink = BulkMailUtils.getRedirectLink(linkId, origin);
     var UserAgentObject = new UAParser(request.header["User-agent"]).getResult();
 
     BulkMailUtils.insertClick(mailLogId, ipAddress, linkId, UserAgentObject.browser.name, UserAgentObject.os.name, UserAgentObject.device.type);