diff --git a/entity/BulkMail_entity/entityfields/preview/displayValueProcess.js b/entity/BulkMail_entity/entityfields/preview/displayValueProcess.js
index 68fe28c7b4bc679fd3fec182a85670196adcb12c..9b0b01405e606c3bdc23905986abe160e2a62acc 100644
--- a/entity/BulkMail_entity/entityfields/preview/displayValueProcess.js
+++ b/entity/BulkMail_entity/entityfields/preview/displayValueProcess.js
@@ -1,22 +1,19 @@
-import("system.text");
-import("Employee_lib");
-import("system.vars");
-import("system.result");
-import("system.neon");
-import("DocumentTemplate_lib");
-
-//if this was done for every row, like in a lookup, the performance would be very bad
-if (vars.get("$sys.viewmode") == neon.FRAME_VIEWMODE_MASK) 
-{
-    var templateId = vars.get("$field.DOCUMENTTEMPLATE_ID");
-    var template;
-    if (templateId)
-        template = DocumentTemplate.loadTemplate(templateId);
-    else
-        template = DocumentTemplate.loadTemplate(vars.get("$field.BULKMAILID"), "BULKMAIL");
-
-    var contactId = EmployeeUtils.getCurrentContactId();
-    var preview = template.getReplacedEmailsByContactIds([contactId]);
-
-    result.string(preview[contactId].body);
-}
\ No newline at end of file
+import("Bulkmail_lib");
+import("system.text");
+import("Employee_lib");
+import("system.vars");
+import("system.result");
+import("system.neon");
+import("DocumentTemplate_lib");
+
+//if this was done for every row, like in a lookup, the performance would be very bad
+if (vars.get("$sys.viewmode") == neon.FRAME_VIEWMODE_MASK) 
+{
+    var template = BulkMailUtils.getBulkMailTemplate(vars.get("$field.BULKMAILID"), vars.get("$field.DOCUMENTTEMPLATE_ID"));
+
+    var contactId = EmployeeUtils.getCurrentContactId();
+    var preview = template.getReplacedEmailsByContactIds([contactId]);
+
+    result.string(preview[contactId].body);
+}
+
diff --git a/entity/Organisation_entity/entityfields/newemail/onActionProcess.js b/entity/Organisation_entity/entityfields/newemail/onActionProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..1da710e798dadf34a91770a741d4fa6dd837936f
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/newemail/onActionProcess.js
@@ -0,0 +1,4 @@
+import("system.vars");
+import("Email_lib");
+
+EmailUtils.openNewMail(vars.getString("$field.CONTACTID"));
\ No newline at end of file
diff --git a/entity/Organisation_entity/entityfields/newletter/onActionProcess.js b/entity/Organisation_entity/entityfields/newletter/onActionProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..8fd84c8478f4dcc2778b695da065365ef90fd0bf
--- /dev/null
+++ b/entity/Organisation_entity/entityfields/newletter/onActionProcess.js
@@ -0,0 +1,4 @@
+import("system.vars");
+import("DocumentTemplate_lib");
+
+LetterUtils.openNewLetter(vars.get("$field.CONTACTID"));
\ No newline at end of file
diff --git a/entity/SerialLetter_entity/SerialLetter_entity.aod b/entity/SerialLetter_entity/SerialLetter_entity.aod
index e0c885c4ded9a841ba1c2324516f431f24968236..16104b933b48fcd6d154b04c95dcf270d3addf24 100644
--- a/entity/SerialLetter_entity/SerialLetter_entity.aod
+++ b/entity/SerialLetter_entity/SerialLetter_entity.aod
@@ -1,109 +1,115 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.10" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.10">
-  <name>SerialLetter_entity</name>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <icon>VAADIN:ENVELOPES</icon>
-  <title>Serial letter</title>
-  <contentTitleProcess>%aditoprj%/entity/SerialLetter_entity/contentTitleProcess.js</contentTitleProcess>
-  <recordContainer>db</recordContainer>
-  <entityFields>
-    <entityProvider>
-      <name>#PROVIDER</name>
-      <dependencies>
-        <entityDependency>
-          <name>8cb1a355-eb91-414a-8860-0210b18bd1ba</name>
-          <entityName>SerialLetterAddRecipients_entity</entityName>
-          <fieldName>SerialLetters</fieldName>
-          <isConsumer v="false" />
-        </entityDependency>
-      </dependencies>
-    </entityProvider>
-    <entityActionField>
-      <name>downloadLetter</name>
-      <title>Download letter</title>
-      <onActionProcess>%aditoprj%/entity/SerialLetter_entity/entityfields/downloadletter/onActionProcess.js</onActionProcess>
-      <iconId>VAADIN:DOWNLOAD_ALT</iconId>
-    </entityActionField>
-    <entityField>
-      <name>SERIALLETTERID</name>
-    </entityField>
-    <entityField>
-      <name>DOCUMENTTEMPLATE_ID</name>
-      <title>Document Template</title>
-      <consumer>Templates</consumer>
-    </entityField>
-    <entityConsumer>
-      <name>Recipients</name>
-      <dependency>
-        <name>dependency</name>
-        <entityName>LetterRecipient_entity</entityName>
-        <fieldName>SerialLetterRecipients</fieldName>
-      </dependency>
-      <children>
-        <entityParameter>
-          <name>SerialLetterId_param</name>
-          <valueProcess>%aditoprj%/entity/SerialLetter_entity/entityfields/recipients/children/serialletterid_param/valueProcess.js</valueProcess>
-        </entityParameter>
-      </children>
-    </entityConsumer>
-    <entityField>
-      <name>ICON</name>
-      <contentType>IMAGE</contentType>
-      <valueProcess>%aditoprj%/entity/SerialLetter_entity/entityfields/icon/valueProcess.js</valueProcess>
-    </entityField>
-    <entityConsumer>
-      <name>Templates</name>
-      <dependency>
-        <name>dependency</name>
-        <entityName>DocumentTemplate_entity</entityName>
-        <fieldName>DocumentTemplateProvider</fieldName>
-      </dependency>
-    </entityConsumer>
-    <entityField>
-      <name>TITLE</name>
-      <title>Title</title>
-      <mandatory v="true" />
-    </entityField>
-  </entityFields>
-  <recordContainers>
-    <dbRecordContainer>
-      <name>db</name>
-      <alias>Data_alias</alias>
-      <fromClauseProcess>%aditoprj%/entity/SerialLetter_entity/recordcontainers/db/fromClauseProcess.js</fromClauseProcess>
-      <linkInformation>
-        <linkInformation>
-          <name>5d9c983a-b129-437a-ae9d-203fb8ad03ec</name>
-          <tableName>SERIALLETTER</tableName>
-          <primaryKey>SERIALLETTERID</primaryKey>
-          <isUIDTable v="true" />
-          <readonly v="false" />
-        </linkInformation>
-        <linkInformation>
-          <name>bc81b1c3-ce99-4581-ac70-4e24bebb0c75</name>
-          <tableName>DOCUMENTTEMPLATE</tableName>
-          <primaryKey>DOCUMENTTEMPLATEID</primaryKey>
-          <isUIDTable v="false" />
-          <readonly v="true" />
-        </linkInformation>
-      </linkInformation>
-      <recordFieldMappings>
-        <dbRecordFieldMapping>
-          <name>DOCUMENTTEMPLATE_ID.value</name>
-          <recordfield>SERIALLETTER.DOCUMENTTEMPLATE_ID</recordfield>
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>SERIALLETTERID.value</name>
-          <recordfield>SERIALLETTER.SERIALLETTERID</recordfield>
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>DOCUMENTTEMPLATE_ID.displayValue</name>
-          <recordfield>DOCUMENTTEMPLATE.NAME</recordfield>
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>TITLE.value</name>
-          <recordfield>SERIALLETTER.TITLE</recordfield>
-        </dbRecordFieldMapping>
-      </recordFieldMappings>
-    </dbRecordContainer>
-  </recordContainers>
-</entity>
+    <name>SerialLetter_entity</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <icon>VAADIN:ENVELOPES</icon>
+  <title>Serial letter</title>
+  <contentTitleProcess>%aditoprj%/entity/SerialLetter_entity/contentTitleProcess.js</contentTitleProcess>
+  <recordContainer>db</recordContainer>
+  <entityFields>
+    <entityProvider>
+      <name>#PROVIDER</name>
+      <dependencies>
+        <entityDependency>
+          <name>8cb1a355-eb91-414a-8860-0210b18bd1ba</name>
+          <entityName>SerialLetterAddRecipients_entity</entityName>
+          <fieldName>SerialLetters</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
+      </dependencies>
+    </entityProvider>
+    <entityActionField>
+      <name>downloadLetter</name>
+      <title>Export letter</title>
+      <onActionProcess>%aditoprj%/entity/SerialLetter_entity/entityfields/downloadletter/onActionProcess.js</onActionProcess>
+      <iconId>VAADIN:DOWNLOAD_ALT</iconId>
+    </entityActionField>
+    <entityField>
+      <name>SERIALLETTERID</name>
+    </entityField>
+    <entityField>
+      <name>DOCUMENTTEMPLATE_ID</name>
+      <title>Document Template</title>
+      <consumer>Templates</consumer>
+      <mandatory v="true" />
+    </entityField>
+    <entityConsumer>
+      <name>Recipients</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>LetterRecipient_entity</entityName>
+        <fieldName>SerialLetterRecipients</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>SerialLetterId_param</name>
+          <valueProcess>%aditoprj%/entity/SerialLetter_entity/entityfields/recipients/children/serialletterid_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
+    <entityField>
+      <name>ICON</name>
+      <contentType>IMAGE</contentType>
+      <valueProcess>%aditoprj%/entity/SerialLetter_entity/entityfields/icon/valueProcess.js</valueProcess>
+    </entityField>
+    <entityConsumer>
+      <name>Templates</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>DocumentTemplate_entity</entityName>
+        <fieldName>DocumentTemplateProvider</fieldName>
+      </dependency>
+    </entityConsumer>
+    <entityField>
+      <name>TITLE</name>
+      <title>Title</title>
+      <mandatory v="true" />
+    </entityField>
+    <entityField>
+      <name>DESCRIPTION</name>
+      <title>Description</title>
+      <contentType>LONG_TEXT</contentType>
+    </entityField>
+  </entityFields>
+  <recordContainers>
+    <dbRecordContainer>
+      <name>db</name>
+      <alias>Data_alias</alias>
+      <fromClauseProcess>%aditoprj%/entity/SerialLetter_entity/recordcontainers/db/fromClauseProcess.js</fromClauseProcess>
+      <linkInformation>
+        <linkInformation>
+          <name>5d9c983a-b129-437a-ae9d-203fb8ad03ec</name>
+          <tableName>SERIALLETTER</tableName>
+          <primaryKey>SERIALLETTERID</primaryKey>
+          <isUIDTable v="true" />
+          <readonly v="false" />
+        </linkInformation>
+        <linkInformation>
+          <name>bc81b1c3-ce99-4581-ac70-4e24bebb0c75</name>
+          <tableName>DOCUMENTTEMPLATE</tableName>
+          <primaryKey>DOCUMENTTEMPLATEID</primaryKey>
+          <isUIDTable v="false" />
+          <readonly v="true" />
+        </linkInformation>
+      </linkInformation>
+      <recordFieldMappings>
+        <dbRecordFieldMapping>
+          <name>DOCUMENTTEMPLATE_ID.value</name>
+          <recordfield>SERIALLETTER.DOCUMENTTEMPLATE_ID</recordfield>
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>SERIALLETTERID.value</name>
+          <recordfield>SERIALLETTER.SERIALLETTERID</recordfield>
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>DOCUMENTTEMPLATE_ID.displayValue</name>
+          <recordfield>DOCUMENTTEMPLATE.NAME</recordfield>
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>TITLE.value</name>
+          <recordfield>SERIALLETTER.TITLE</recordfield>
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>DESCRIPTION.value</name>
+          <recordfield>SERIALLETTER.DESCRIPTION</recordfield>
+   /entity>
diff --git a/entity/SerialLetter_entity/entityfields/downloadletter/onActionProcess.js b/entity/SerialLetter_entity/entityfields/downloadletter/onActionProcess.js
index bdf5e858524fedc80fa17146b801349638643407..3661c8f2d267db8ccbbab568c6b407fdfd2bb657 100644
--- a/entity/SerialLetter_entity/entityfields/downloadletter/onActionProcess.js
+++ b/entity/SerialLetter_entity/entityfields/downloadletter/onActionProcess.js
@@ -1,6 +1,13 @@
+import("system.util");
 import("DocumentTemplate_lib");
 import("system.neon");
 import("Bulkmail_lib");
 import("system.vars");
+import("system.notification");
+import("Employee_lib");
 
+//var params = {
+//    binId : "1234"
+//}
+//notification.addNotification(util.getNewUUID(), null, null, null, "DownloadReady", notification.PRIO_NORMAL, 2, notification.STATE_UNSEEN, [EmployeeUtils.getCurrentUserId()], "yes", "desc")
 var document = SerialLetterUtils.buildSerialLetter(vars.get("$field.SERIALLETTERID"));
\ No newline at end of file
diff --git a/entity/targetId/entityfields/role/displayValueProcess.js b/entity/targetId/entityfields/role/displayValueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..42459f2d1c191c1b9cbbc6a543c60017162f420a
--- /dev/null
+++ b/entity/targetId/entityfields/role/displayValueProcess.js
@@ -0,0 +1,10 @@
+import("system.result");
+import("system.vars");
+import("system.tools");
+
+var allRoles = tools.getAllRoles();
+var roleTitle = vars.get("$this.value");
+if (roleTitle in allRoles)
+    roleTitle = allRoles[roleTitle][0];
+
+result.string(roleTitle);
\ No newline at end of file
diff --git a/entity/targetId/entityfields/roles/children/excluderoles_param/valueProcess.js b/entity/targetId/entityfields/roles/children/excluderoles_param/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..5ecb260c23f23d906c17b50bc5dec8539b9594e5
--- /dev/null
+++ b/entity/targetId/entityfields/roles/children/excluderoles_param/valueProcess.js
@@ -0,0 +1,3 @@
+import("system.result");
+
+result.string(JSON.stringify(["INTERNAL_EVERYONE", "INTERNAL_GROUPWARE", "INTERNAL_SNMP", "INTERNAL_DESIGNER", "INTERNAL_TECHNICAL"]));
\ No newline at end of file
diff --git a/entity/targetId/recordcontainers/jdito/contentProcess.js b/entity/targetId/recordcontainers/jdito/contentProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..069f2a6ebcdcea65fbab33a52a769711b643f05c
--- /dev/null
+++ b/entity/targetId/recordcontainers/jdito/contentProcess.js
@@ -0,0 +1,24 @@
+import("system.result");
+import("system.vars");
+import("system.tools");
+
+var roles = [];
+var userTitle = vars.exists("$param.UserTitle_param") && vars.get("$param.UserTitle_param");
+var allRoles = tools.getAllRoles();
+
+if (userTitle && tools.existUsers(userTitle))
+{
+    var existsObj = {};
+    tools.getRoles(userTitle).forEach(function (role)
+    {
+        if (!this[role] && role != "INTERNAL_EVERYONE")
+        {
+            var roleTitle = role;
+            if (role in allRoles)
+                roleTitle = allRoles[role][0];
+            roles.push([role, role, roleTitle]);
+            this[role] = true;
+        }  
+    }, existsObj);
+}
+result.object(roles);
\ No newline at end of file
diff --git a/entity/targetId/recordcontainers/jdito/onDelete.js b/entity/targetId/recordcontainers/jdito/onDelete.js
new file mode 100644
index 0000000000000000000000000000000000000000..6056936e83aa934a4befa89fe82a19d2e7d809f3
--- /dev/null
+++ b/entity/targetId/recordcontainers/jdito/onDelete.js
@@ -0,0 +1,19 @@
+import("system.result");
+import("system.vars");
+import("system.tools");
+
+var userTitle = vars.exists("$param.UserTitle_param") && vars.get("$param.UserTitle_param");
+var role = vars.get("$local.uid");
+
+if (userTitle)
+{    
+    var user = tools.getUser(userTitle);
+    var roles = tools.getRoles(userTitle);
+    roles = roles.filter(function (row)
+    {
+        return row != role;
+    });
+    user[tools.ROLES] = roles;
+    
+    tools.updateUser(user);
+}
\ No newline at end of file
diff --git a/entity/targetId/recordcontainers/jdito/onInsert.js b/entity/targetId/recordcontainers/jdito/onInsert.js
new file mode 100644
index 0000000000000000000000000000000000000000..ed2348095fe17d3de0c9a29028e7697f63450d3a
--- /dev/null
+++ b/entity/targetId/recordcontainers/jdito/onInsert.js
@@ -0,0 +1,23 @@
+import("system.result");
+import("system.vars");
+import("system.tools");
+
+var userTitle = vars.exists("$param.UserTitle_param") && vars.get("$param.UserTitle_param");
+var newRole = vars.get("$local.rowdata")["ROLE.value"];
+
+if (userTitle && tools.existUsers(userTitle) && newRole != "INTERNAL_EVERYONE")
+{    
+    var user = tools.getUser(userTitle);
+    var roles = tools.getRoles(userTitle);
+    var roleObj = {};
+    roles = [newRole].concat(roles)
+        .filter(function (role) 
+        {
+            var exists = role in this;
+            this[role] = true;
+            return !exists;
+        }, roleObj);
+    user[tools.ROLES] = roles;
+    
+    tools.updateUser(user);
+}
\ No newline at end of file
diff --git a/entity/targetId/recordcontainers/jdito/onUpdate.js b/entity/targetId/recordcontainers/jdito/onUpdate.js
new file mode 100644
index 0000000000000000000000000000000000000000..ef9a53fb8daccd44fd12955bcb6b1dc5dfefc666
--- /dev/null
+++ b/entity/targetId/recordcontainers/jdito/onUpdate.js
@@ -0,0 +1,25 @@
+import("system.result");
+import("system.vars");
+import("system.tools");
+
+var userTitle = vars.exists("$param.UserTitle_param") && vars.get("$param.UserTitle_param");
+var oldRole = vars.get("$local.uid");
+var newRole = vars.get("$local.rowdata")["ROLE.value"];
+
+if (userTitle && oldRole != newRole)
+{    
+    var user = tools.getUser(userTitle);
+    var roles = tools.getRoles(userTitle);
+    var roleObj = {};
+    roleObj[oldRole] = true;
+    roles = [newRole].concat(roles)
+        .filter(function (role) 
+        {
+            var exists = role in roleObj;
+            roleObj[role] = true;
+            return !exists;
+        });
+    user[tools.ROLES] = roles;
+    
+    tools.updateUser(user);
+}
\ No newline at end of file
diff --git a/entity/targetId/targetId.aod b/entity/targetId/targetId.aod
new file mode 100644
index 0000000000000000000000000000000000000000..5a18fa7720e52fc4473e23fd063dcc0c75fd5341
--- /dev/null
+++ b/entity/targetId/targetId.aod
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.9" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.9">
+  <name>EmployeeRole_entity</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <title>Role</title>
+  <titlePlural>Roles</titlePlural>
+  <recordContainer>jdito</recordContainer>
+  <entityFields>
+    <entityProvider>
+      <name>#PROVIDER</name>
+    </entityProvider>
+    <entityField>
+      <name>UID</name>
+    </entityField>
+    <entityParameter>
+      <name>UserTitle_param</name>
+      <expose v="true" />
+      <mandatory v="true" />
+      <description>PARAMETER</description>
+    </entityParameter>
+    <entityProvider>
+      <name>EmployeeRoles</name>
+      <dependencies>
+        <entityDependency>
+          <name>3bcec57a-7165-4773-9253-5ecab26ee3f4</name>
+          <entityName>Employee_entity</entityName>
+          <fieldName>EmployeeRoles</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
+      </dependencies>
+      <children>
+        <entityParameter>
+          <name>UserTitle_param</name>
+          <expose v="true" />
+          <mandatory v="true" />
+        </entityParameter>
+      </children>
+    </entityProvider>
+    <entityField>
+      <name>ROLE</name>
+      <title>Role</title>
+      <consumer>Roles</consumer>
+      <linkedContext>Role</linkedContext>
+      <displayValueProcess>%aditoprj%/entity/EmployeeRole_entity/entityfields/role/displayValueProcess.js</displayValueProcess>
+    </entityField>
+    <entityConsumer>
+      <name>Roles</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Role_entity</entityName>
+        <fieldName>FilteredRoles</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>ExcludeRoles_param</name>
+          <valueProcess>%aditoprj%/entity/EmployeeRole_entity/entityfields/roles/children/excluderoles_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
+    <entityField>
+      <name>TARGETCONTEXT</name>
+    </entityField>
+  </entityFields>
+  <recordContainers>
+    <jDitoRecordContainer>
+      <name>jdito</name>
+      <jDitoRecordAlias>Data_alias</jDitoRecordAlias>
+      <contentProcess>%aditoprj%/entity/EmployeeRole_entity/recordcontainers/jdito/contentProcess.js</contentProcess>
+      <onInsert>%aditoprj%/entity/EmployeeRole_entity/recordcontainers/jdito/onInsert.js</onInsert>
+      <onUpdate>%aditoprj%/entity/EmployeeRole_entity/recordcontainers/jdito/onUpdate.js</onUpdate>
+      <onDelete>%aditoprj%/entity/EmployeeRole_entity/recordcontainers/jdito/onDelete.js</onDelete>
+      <recordFieldMappings>
+        <jDitoRecordFieldMapping>
+          <name>UID.value</name>
+        </jDitoRecordFieldMapping>
+        <jDitoRecordFieldMapping>
+          <name>ROLE.value</name>
+        </jDitoRecordFieldMapping>
+        <jDitoRecordFieldMapping>
+          <name>ROLE.displayValue</name>
+        </jDitoRecordFieldMapping>
+        <jDitoRecordFieldMapping>
+          <name>TARGETCONTEXT.value</name>
+        </jDitoRecordFieldMapping>
+      </recordFieldMappings>
+    </jDitoRecordContainer>
+  </recordContainers>
+</entity>
diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
index 1d960af86ebca867194c555c606f741fab9d1ccb..c2db33a6665783df890badd2dce5ae072aace3cb 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -6073,7 +6073,8 @@
       <key>%0 new recipients will be added to the serial letter.</key>
     </entry>
     <entry>
-      <key>Download letter</key>
+      <key>Export letter</key>
+      <value>Brief exportieren</value>
     </entry>
     <entry>
       <key>Add to serial letter</key>
diff --git a/neonNotificationType/DownloadReady/onResultOpen.js b/neonNotificationType/DownloadReady/onResultOpen.js
index 05f211c5511cd30430f3c0141712fe4a7a903367..36c2e4242a33907fbc3744b4776675dd74b58459 100644
--- a/neonNotificationType/DownloadReady/onResultOpen.js
+++ b/neonNotificationType/DownloadReady/onResultOpen.js
@@ -1,7 +1,18 @@
 import("system.logging");
 import("system.vars");
 
-var varses = ["$"];
+var varses = [
+    "$local.content",
+    "$local.data",
+    "$local.description",
+    "$local.idvalue",
+    "$local.idvalues",
+    "$local.row",
+    "$local.row_id",
+    "$local.rowdata",
+    "$local.uid",
+    "$local.binId",
+];
 var existses = {};
 varses.forEach(function (v) {
     this[v] = vars.exists(v);
diff --git a/process/Bulkmail_lib/process.js b/process/Bulkmail_lib/process.js
index aa9a59ff63531e8ea617a175ed1493335ae5b8df..b01eb588b490dd10bbad3a8d77eba1a0bc941cb7 100644
--- a/process/Bulkmail_lib/process.js
+++ b/process/Bulkmail_lib/process.js
@@ -10,6 +10,7 @@ import("system.db");
 import("DocumentTemplate_lib");
 import("Email_lib");
 import("system.process");
+import("system.notification");
 
 /**
  * functions for bulk mails
@@ -51,11 +52,7 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId)
         .andPrepare("BULKMAIL.BULKMAILID", pBulkMailId)
         .buildSql("select DOCUMENTTEMPLATE_ID, SUBJECT, SENDER from BULKMAIL", "1=2")
     );
-    var template;
-    if (templateId)
-        template = DocumentTemplate.loadTemplate(templateId);
-    else
-        template = DocumentTemplate.loadTemplate(pBulkMailId, "BULKMAIL");
+    var template = BulkMailUtils.getBulkMailTemplate(pBulkMailId, templateId);
     
     var recipientData = db.table(SqlCondition.begin()
         .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
@@ -155,6 +152,23 @@ BulkMailUtils.addRecipients = function (pBulkMailId, pContactIds)
     db.inserts(inserts);
 }
 
+/**
+ * Loads the document template of a bulk mail. If the bulk mail itself has a
+ * template, it is preferred over the documentTemplate-id.
+ * 
+ * @param {String} pBulkMailId bulkmail id
+ * @param {String} pDocumentTemplateId documentTemplate id
+ * 
+ * @return {DocumentTemplate} the document template, null if no content was found.
+ */
+BulkMailUtils.getBulkMailTemplate = function (pBulkMailId, pDocumentTemplateId)
+{
+    var template = DocumentTemplate.loadTemplate(pBulkMailId, "BULKMAIL");
+    if (template === null)
+        template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
+    return template;
+}
+
 function SerialLetterUtils () {}
 
 SerialLetterUtils.addRecipients = function (pBulkMailId, pContactIds)
@@ -183,7 +197,12 @@ SerialLetterUtils.openAddRecipientView = function (pContactIds)
 
 SerialLetterUtils.buildSerialLetter = function (pSerialLetterId)
 {
-    process.executeAsync("buildSerialLetter_serverProcess", {
+    process.execute("buildSerialLetter_serverProcess", {
         "serialLetterId" : pSerialLetterId
-    }, false, "_____USER_bcdfb521-c7d0-4ef1-8916-78e7d3232046", process.THREADPRIORITY_VERYHIGH);
+    });
+}
+
+SerialLetterUtils.makeDownloadNotification = function (pTitle, pBinaryId, pUser)
+{
+    notification.addNotification(pContentId, pLinkInfo, pImageInfo, pOriginatorName, pType, pForcedPriority, pDaysToLive, pState, pUser, pCaption, pDescription)
 }
\ No newline at end of file
diff --git a/process/DocumentTemplate_lib/process.js b/process/DocumentTemplate_lib/process.js
index 4198d8c2bdb353edb4c11d907fc6ea5f28dafa50..3e77cfe558d1cc29bd4b23d7dd4851ebdbca360b 100644
--- a/process/DocumentTemplate_lib/process.js
+++ b/process/DocumentTemplate_lib/process.js
@@ -135,7 +135,7 @@ DocumentTemplate.prototype.getReplacedContent = function (pReplacements)
     {
         case DocumentTemplate.types.HTML:
             for (let i in pReplacements)
-                pReplacements[i] = text.replaceAll(pReplacements[i], {"\n" : "<br>"});
+                pReplacements[i] = text.text2html(pReplacements[i], false);
         case DocumentTemplate.types.TXT:
             let decodedContent = util.decodeBase64String(this.content)
             return DocumentTemplate._replaceText(decodedContent, pReplacements);
@@ -194,7 +194,6 @@ DocumentTemplate.prototype.getSerialLetterByContactIds = function (pContactIds)
     {
         let replaceArray = [];
         for (let i = 0, l = pContactIds.length; i < l; i++)
-            for (let ii = 0; ii < 1000; ii++)
             replaceArray.push(replacements[pContactIds[i]]);
         return this._getReplacedODT(replaceArray);
     }
@@ -223,8 +222,8 @@ DocumentTemplate.prototype.getReplacedEmailsByContactIds = function (pContactIds
         else
         {
             let body = this.getReplacedContent(replacements[contactId]);
-            if (this.type == DocumentTemplate.types.TXT)
-                body = text.replaceAll(body, {"\n" : "<br>"});
+            if (this.type == DocumentTemplate.types.TXT || this.type == DocumentTemplate.types.PLAIN)
+                body = text.text2html(body, false);
             emailObj[contactId] = new Email(null, null, null, body);
         }
     }
diff --git a/process/buildSerialLetter_serverProcess/process.js b/process/buildSerialLetter_serverProcess/process.js
index 2ad448bad7ed33c636a69df3b55c9798fc76dcad..b64862650ceacc004ac7cf87b66beb9b0f1c48d9 100644
--- a/process/buildSerialLetter_serverProcess/process.js
+++ b/process/buildSerialLetter_serverProcess/process.js
@@ -1,4 +1,3 @@
-import("system.logging");
 import("system.result");
 import("system.vars");
 import("KeywordRegistry_basic");
@@ -20,6 +19,5 @@ var contactIds = db.table(SqlCondition.begin()
     .buildSql("select CONTACT_ID from LETTERRECIPIENT join CONTACT on LETTERRECIPIENT.CONTACT_ID = CONTACT.CONTACTID", "1=2")
 );
 var document = template.getSerialLetterByContactIds(contactIds);
-logging.log("ja")
 if (document)
     neon.download(document, template.filename);
\ No newline at end of file