diff --git a/process/Bulkmail_lib/process.js b/process/Bulkmail_lib/process.js
index ee1dcd82028793f2f4f6016f8ae48b111a21e3e8..4acdb432a1085fc183c0465bcf2b61afc6a5c870 100644
--- a/process/Bulkmail_lib/process.js
+++ b/process/Bulkmail_lib/process.js
@@ -1,402 +1,391 @@
-import("system.translate");
-import("ActivityTask_lib");
-import("system.util");
-import("Contact_lib");
-import("system.datetime");
-import("system.neon");
-import("Employee_lib");
-import("system.vars");
-import("KeywordRegistry_basic");
-import("Sql_lib");
-import("system.db");
-import("DocumentTemplate_lib");
-import("Communication_lib");
-import("Email_lib");
-import("system.process");
-import("system.notification");
-
-/**
- * functions for bulk mails
- */
-function BulkMailUtils () {}
-
-/**
- * Executes a process to send bulk mails on the server and creates a notification when finished.
- * 
- * @param {String} pBulkMailId id of the bulk mail
- * @param {Array} [pTestRecipients] overwrite the recipients (e.g. for testing)
- * @param {String} [pUser=currentUser] User that will get the notification, if null (not undefined!), no notification
- *                                      will be created.
- */
-BulkMailUtils.sendBulkMailOnServer = function (pBulkMailId, pTestRecipients, pUser)
-{
-    if (pUser === undefined)
-        pUser = EmployeeUtils.getCurrentUserId();
-    process.execute("sendBulkMail_serverProcess", 
-        {
-            bulkMailId : pBulkMailId,
-            testRecipients : JSON.stringify(pTestRecipients),
-            user : pUser || ""
-        }
-    );
-}
-
-/**
- * Sends a bulk mail. You should only call this function on the server because it
- * can take some time to execute, use BulkMailUtils.sendBulkMailOnServer instead.
- * 
- * @param {String} pBulkMailId id of the bulk mail 
- * @param {Array} [pTestRecipients] overwrite the recipients (e.g. for testing)
- * 
- * @return {Object} count of sucessful and failed mails 
- */
-BulkMailUtils.sendBulkMail = function (pBulkMailId, pTestRecipients)
-{
-    var [templateId, subject, emailSender, createActivity, bulkMailName] = db.array(db.ROW, SqlCondition.begin()
-        .andPrepare("BULKMAIL.BULKMAILID", pBulkMailId)
-        .buildSql("select DOCUMENTTEMPLATE_ID, SUBJECT, SENDER, CREATEACTIVITIES, NAME from BULKMAIL", "1=2")
-    );
-    var template = BulkMailUtils.getBulkMailTemplate(pBulkMailId, templateId);
-    
-    var recipientData;
-    if (pTestRecipients)
-    {
-        recipientData = pTestRecipients.map(function (row)
-        {
-            return ["", row[0], row[1], "", ""];
-        });
-    }
-    else
-    {
-        recipientData = db.table(SqlBuilder.begin()
-            .select("BULKMAILRECIPIENTID, BULKMAILRECIPIENT.CONTACT_ID, (" + CommUtil.getStandardSubSqlMail() + "), PERSON_ID, ORGANISATION_ID")
-            .from("CONTACT")
-            .join("BULKMAILRECIPIENT", "BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
-            .where(SqlCondition.begin()
-                .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
-                .andPrepare("BULKMAILRECIPIENT.STATUS", $KeywordRegistry.bulkMailRecipientStatus$sent(), "# != ?")
-                .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true)))
-            .build()
-        );
-    }
-    var contactIds = recipientData.map(function (e) {return e[1];});
-    var successIds = [];
-    var failedIds = [];
-    var sentDate = vars.get("$sys.date");
-    var mails = template.getReplacedEmailsByContactIds(contactIds);
-    
-    var subjectTemplate = new DocumentTemplate(subject, DocumentTemplate.types.PLAIN);
-    var subjects = subjectTemplate.getReplacedContentByContactIds(contactIds);
-    
-    var bulkMailLink = [["BulkMail", pBulkMailId]];
-    var activitySubject = translate.withArguments("Bulk mail \"%0\" sent", [bulkMailName]);
-    
-    for (let i = 0, l = recipientData.length; i < l; i++)
-    {
-        let isSuccess = false;
-        let contactId = recipientData[i][1];
-        let email = mails[contactId];
-        if (email !== undefined && recipientData[i][2])
-        {
-            email.toRecipients = [recipientData[i][2]];
-            email.sender = emailSender;
-            email.subject = subjects[contactId];
-
-            isSuccess = email.send();
-        }
-        if (recipientData[i][0])    //set the recipient status to 'sent' or 'failed'
-        {
-            Array.prototype.push.call(isSuccess ? successIds : failedIds, recipientData[i][0]);
-            if (isSuccess && createActivity == "1")
-            {
-                let activityData = {
-                    categoryKeywordId : $KeywordRegistry.activityCategory$mail(),
-                    directionKeywordId : $KeywordRegistry.activityDirection$outgoing(),
-                    subject : activitySubject,
-                    content : email.body
-                };
-                let contactLink = [[ContactUtils.getContextByPersOrg(recipientData[i][3], recipientData[i][4]), recipientData[i][1]]];
-                ActivityUtils.insertNewActivity(activityData, bulkMailLink.concat(contactLink));
-            }
-        }
-    }
-    if (successIds.length > 0)
-        db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$sent(), sentDate], 
-            SqlCondition.begin()
-                .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", successIds)
-                .build("1=2")
-        );
-    if (failedIds.length > 0)
-        db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$failed(), sentDate], 
-            SqlCondition.begin()
-                .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", failedIds)
-                .build("1=2")
-        );
-    
-    if (!pTestRecipients) //if its just a test run, don't set the status to sent
-        db.updateData("BULKMAIL", ["STATUS"], null, [$KeywordRegistry.bulkMailStatus$sent()], 
-            SqlCondition.equals("BULKMAIL.BULKMAILID", pBulkMailId, "1=2"));
-        
-    return {
-        sucessful : successIds.length,
-        failed : failedIds.length
-    };
-}
-
-/**
- * opens a context to select a bulk mail to add recipients to
- * 
- * @param {String[]} pContactIds recipients that should be added
- */
-BulkMailUtils.openAddRecipientView = function (pContactIds)
-{
-    var params = {
-        "ContactIds_param" : pContactIds
-    };
-    neon.openContext("BulkMailAddRecipients", "BulkMailAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
-}
-
-/**
- * deletes all bulk mail recipients that have a commrestriction for emails
- * 
- * @param {String} pBulkMailId
- */
-BulkMailUtils.removeCommRestrictionRecipients = function (pBulkMailId)
-{
-    var recipientIds = db.array(db.COLUMN, SqlBuilder.begin()
-        .select("BULKMAILRECIPIENTID")
-        .from("BULKMAILRECIPIENT")
-        .join("CONTACT", SqlCondition.begin()
-            .and("BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
-            .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail())))
-        .where(SqlCondition.begin()
-            .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId))
-        .build());
-
-    if (recipientIds.length)
-    {
-        db.deleteData("BULKMAILRECIPIENT", SqlCondition.begin()
-            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", recipientIds)
-            .build("1=2"));
-    }
-}
-
-/**
- * adds recipients to a bulkmail
- * 
- * @param {String} pBulkMailId bulk mail id
- * @param {String[]} pContactIds contact ids of the recipients
- */
-BulkMailUtils.addRecipients = function (pBulkMailId, pContactIds)
-{
-    var columns = [
-        "BULKMAILRECIPIENTID",
-        "BULKMAIL_ID",
-        "CONTACT_ID",
-        "STATUS"
-    ];
-    var inserts = [];
-    for (let i = 0, l = pContactIds.length; i < l; i++)
-    {
-        inserts.push(["BULKMAILRECIPIENT", columns, null, [util.getNewUUID(), pBulkMailId, pContactIds[i], $KeywordRegistry.bulkMailRecipientStatus$pending()]]);
-    }
-    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.content)
-        template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
-    return template;
-}
-
-/**
- * checks if a contact is a recipient of a bulk mail
- * 
- * @param {String} pBulkMailId bulkmail id
- * @param {String} pContactId contact id
- * @param {String} pRecipientId bulkmailrecipient id
- * @return {boolean} true, if the contact is a recipient
- */
-BulkMailUtils.isRecipient = function (pBulkMailId, pContactId, pRecipientId)
-{
-    return db.cell(SqlCondition.begin()
-        .andPrepare("BULKMAILRECIPIENT.CONTACT_ID", pContactId)
-        .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
-        .andPrepareIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", pRecipientId, "# != ?")
-        .buildSql("select count(*) from BULKMAILRECIPIENT") //TODO: is there a way exists could be used?
-    ) != "0";
-}
-
-/**
- * opens the BulkMail context in new mode
- * 
- * @param {String[]} [pRecipients] recipients that should be added after creation
- */
-BulkMailUtils.newBulkMail = function (pRecipients)
-{
-    var params = {
-        "PresetRecipients_param" : JSON.stringify(pRecipients)
-    };
-    neon.openContext("BulkMail", "BulkMailEdit_view", null, neon.OPERATINGSTATE_NEW, params);
-}
-
-/**
- * Filters the given contactIds if they can be added as new recipients.
- * Checks if a contact is already a recipient or if there is a advertising ban.
- * 
- * @param {String} pBulkMailId id of the bulk mail the contacts should be added to
- * @param {String[]} pContactIds contacts to filter
- * @return {String[]} contacts that can be added as recipients
- */
-BulkMailUtils.filterNewRecipients = function (pBulkMailId, pContactIds)
-{
-    var existsQuery = "not exists(select BULKMAILRECIPIENTID from BULKMAILRECIPIENT where BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID and # = ?)";
-    var query = SqlCondition.begin()
-        .andIn("CONTACT.CONTACTID", pContactIds)
-        .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId, existsQuery) //only add contacts that aren't already recipients
-        .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true))  //check if there's a commrestriction
-        .buildSql("select CONTACTID from CONTACT");
-
-    return db.array(db.COLUMN, query); 
-}
-
-/**
- * opens the given bulk mail
- */
-BulkMailUtils.openBulkMail = function (pBulkMailId)
-{
-    neon.openContext("BulkMail", "BulkMailMain_view", [pBulkMailId], neon.OPERATINGSTATE_VIEW, null);
-}
-
-/**
- * checks is the given mime type can be used for a bulk mail
- * 
- * @param {String} pMimeType mime type
- * @return {Boolean} wheter the type is usable or not
- */
-BulkMailUtils.isValidMimeType = function (pMimeType)
-{
-    var templateType = DocumentTemplate.types.fromMimeType(pMimeType);
-    return BulkMailUtils.isValidTemplateType(templateType)
-}
-
-/**
- * checks is the given template type can be used for a bulk mail
- * 
- * @param {String} pTemplateType template type
- * @return {Boolean} wheter the type is usable or not
- */
-BulkMailUtils.isValidTemplateType = function (pTemplateType)
-{
-    switch (pTemplateType)
-    {
-        case DocumentTemplate.types.EML:
-        case DocumentTemplate.types.HTML:
-        case DocumentTemplate.types.TXT:
-            return true;
-        default:
-            return false;
-    }
-}
-
-function SerialLetterUtils () {}
-
-/**
- * adds recipients to a serial letter
- * 
- * @param {String} pSerialLetterId serial letter id
- * @param {String[]} pContactIds contact ids of the recipients
- */
-SerialLetterUtils.addRecipients = function (pSerialLetterId, pContactIds)
-{
-    var columns = [
-        "LETTERRECIPIENTID",
-        "SERIALLETTER_ID",
-        "CONTACT_ID"
-    ];
-    var inserts = [];
-    for (let i = 0, l = pContactIds.length; i < l; i++)
-    {
-        inserts.push(["LETTERRECIPIENT", columns, null, [util.getNewUUID(), pSerialLetterId, pContactIds[i]]]);
-    }
-    db.inserts(inserts);
-}
-
-/**
- * opens a context to select a serial letter to add recipients to
- * 
- * @param {String[]} pContactIds recipients that should be added
- */
-SerialLetterUtils.openAddRecipientView = function (pContactIds)
-{
-    var params = {
-        "ContactIds_param" : pContactIds
-    };
-    neon.openContext("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
-}
-
-/**
- * executes a server process that builds a serial letter
- * 
- * @param {String} pSerialLetterId serial letter id
- * @param {String[]} [pRecipientIds] Letter recipient ids of that should be used.
- *                                    If omitted, all recipients of the letter will be used.
- */
-SerialLetterUtils.buildSerialLetter = function (pSerialLetterId, pRecipientIds)
-{
-    process.execute("buildSerialLetter_serverProcess", {
-        "serialLetterId" : pSerialLetterId,
-        "recipientIds" : JSON.stringify(pRecipientIds)
-    });
-}
-
-/**
- * checks if a contact is a recipient of a serial letter
- * 
- * @param {String} pSerialLetterId serial letter id
- * @param {String} pContactId contact id
- * @param {String} [pRecipientId] letter recipient id
- * @return {boolean} true, if the contact is a recipient
- */
-SerialLetterUtils.isRecipient = function (pSerialLetterId, pContactId, pRecipientId)
-{
-    return db.cell(SqlCondition.begin()
-        .andPrepare("LETTERRECIPIENT.CONTACT_ID", pContactId)
-        .andPrepare("LETTERRECIPIENT.SERIALLETTER_ID", pSerialLetterId)
-        .andPrepareIfSet("LETTERRECIPIENT.LETTERRECIPIENTID", pRecipientId, "# != ?")
-        .buildSql("select count(*) from LETTERRECIPIENT") //TODO: is there a way exists could be used?
-    ) != "0";
-}
-
-SerialLetterUtils.openSerialLetter = function (pSerialLetterId)
-{
-    neon.openContext("SerialLetter", "SerialLetterMain_view", [pSerialLetterId], neon.OPERATINGSTATE_VIEW, null);
-}
-
-/**
- * Loads the document template of a serial letter. If the serial letter itself has a
- * template, it is preferred over the documentTemplate-id.
- * 
- * @param {String} pLetterId serial letter id
- * @param {String} pDocumentTemplateId documentTemplate id
- * 
- * @return {DocumentTemplate} the document template
- */
-SerialLetterUtils.getSerialLetterTemplate = function (pLetterId, pDocumentTemplateId)
-{
-    var template = DocumentTemplate.loadTemplate(pLetterId, "SERIALLETTER");
-    if (!template.type)
-        template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
-    return template;
+import("system.translate");
+import("ActivityTask_lib");
+import("system.util");
+import("Contact_lib");
+import("system.datetime");
+import("system.neon");
+import("Employee_lib");
+import("system.vars");
+import("KeywordRegistry_basic");
+import("Sql_lib");
+import("system.db");
+import("DocumentTemplate_lib");
+import("Communication_lib");
+import("Email_lib");
+import("system.process");
+import("system.notification");
+
+/**
+ * functions for bulk mails
+ */
+function BulkMailUtils () {}
+
+/**
+ * Executes a process to send bulk mails on the server and creates a notification when finished.
+ * 
+ * @param {String} pBulkMailId id of the bulk mail
+ * @param {Array} [pTestRecipients] overwrite the recipients (e.g. for testing)
+ * @param {String} [pUser=currentUser] User that will get the notification, if null (not undefined!), no notification
+ *                                      will be created.
+ */
+BulkMailUtils.sendBulkMailOnServer = function (pBulkMailId, pTestRecipients, pUser)
+{
+    if (pUser === undefined)
+        pUser = EmployeeUtils.getCurrentUserId();
+    process.execute("sendBulkMail_serverProcess", 
+        {
+            bulkMailId : pBulkMailId,
+            testRecipients : JSON.stringify(pTestRecipients),
+            user : pUser || ""
+        }
+    );
+}
+
+/**
+ * Sends a bulk mail. You should only call this function on the server because it
+ * can take some time to execute, use BulkMailUtils.sendBulkMailOnServer instead.
+ * 
+ * @param {String} pBulkMailId id of the bulk mail 
+ * @param {Array} [pTestRecipients] overwrite the recipients (e.g. for testing)
+ * 
+ * @return {Object} count of sucessful and failed mails 
+ */
+BulkMailUtils.sendBulkMail = function (pBulkMailId, pTestRecipients)
+{
+    var [templateId, subject, emailSender, createActivity, bulkMailName] = db.array(db.ROW, SqlCondition.begin()
+        .andPrepare("BULKMAIL.BULKMAILID", pBulkMailId)
+        .buildSql("select DOCUMENTTEMPLATE_ID, SUBJECT, SENDER, CREATEACTIVITIES, NAME from BULKMAIL", "1=2")
+    );
+    var template = BulkMailUtils.getBulkMailTemplate(pBulkMailId, templateId);
+    
+    var recipientData;
+    if (pTestRecipients)
+    {
+        recipientData = pTestRecipients.map(function (row)
+        {
+            return ["", row[0], row[1], "", ""];
+        });
+    }
+    else
+    {
+        recipientData = db.table(SqlBuilder.begin()
+            .select("BULKMAILRECIPIENTID, BULKMAILRECIPIENT.CONTACT_ID, (" + CommUtil.getStandardSubSqlMail() + "), PERSON_ID, ORGANISATION_ID")
+            .from("CONTACT")
+            .join("BULKMAILRECIPIENT", "BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
+            .where(SqlCondition.begin()
+                .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
+                .andPrepare("BULKMAILRECIPIENT.STATUS", $KeywordRegistry.bulkMailRecipientStatus$sent(), "# != ?")
+                .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true)))
+            .build()
+        );
+    }
+    var contactIds = recipientData.map(function (e) {return e[1];});
+    var successIds = [];
+    var failedIds = [];
+    var sentDate = vars.get("$sys.date");
+    var mails = template.getReplacedEmailsByContactIds(contactIds);
+    
+    var subjectTemplate = new DocumentTemplate(subject, DocumentTemplate.types.PLAIN);
+    var subjects = subjectTemplate.getReplacedContentByContactIds(contactIds);
+    
+    var bulkMailLink = [["BulkMail", pBulkMailId]];
+    var activitySubject = translate.withArguments("Bulk mail \"%0\" sent", [bulkMailName]);
+    
+    for (let i = 0, l = recipientData.length; i < l; i++)
+    {
+        let isSuccess = false;
+        let contactId = recipientData[i][1];
+        let email = mails[contactId];
+        if (email !== undefined && recipientData[i][2])
+        {
+            email.toRecipients = [recipientData[i][2]];
+            email.sender = emailSender;
+            email.subject = subjects[contactId];
+
+            isSuccess = email.send();
+        }
+        if (recipientData[i][0])    //set the recipient status to 'sent' or 'failed'
+        {
+            Array.prototype.push.call(isSuccess ? successIds : failedIds, recipientData[i][0]);
+            if (isSuccess && createActivity == "1")
+            {
+                let activityData = {
+                    categoryKeywordId : $KeywordRegistry.activityCategory$mail(),
+                    directionKeywordId : $KeywordRegistry.activityDirection$outgoing(),
+                    subject : activitySubject,
+                    content : email.body
+                };
+                let contactLink = [[ContactUtils.getContextByPersOrg(recipientData[i][3], recipientData[i][4]), recipientData[i][1]]];
+                ActivityUtils.insertNewActivity(activityData, bulkMailLink.concat(contactLink));
+            }
+        }
+    }
+    if (successIds.length > 0)
+        db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$sent(), sentDate], 
+            SqlCondition.begin()
+                .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", successIds)
+                .build("1=2")
+        );
+    if (failedIds.length > 0)
+        db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$failed(), sentDate], 
+            SqlCondition.begin()
+                .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", failedIds)
+                .build("1=2")
+        );
+    
+    if (!pTestRecipients) //if its just a test run, don't set the status to sent
+        db.updateData("BULKMAIL", ["STATUS"], null, [$KeywordRegistry.bulkMailStatus$sent()], 
+            SqlCondition.equals("BULKMAIL.BULKMAILID", pBulkMailId, "1=2"));
+        
+    return {
+        sucessful : successIds.length,
+        failed : failedIds.length
+    };
+}
+
+/**
+ * opens a context to select a bulk mail to add recipients to
+ * 
+ * @param {String[]} pContactIds recipients that should be added
+ */
+BulkMailUtils.openAddRecipientView = function (pContactIds)
+{
+    var params = {
+        "ContactIds_param" : pContactIds
+    };
+    neon.openContext("BulkMailAddRecipients", "BulkMailAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
+}
+
+/**
+ * deletes all bulk mail recipients that have a commrestriction for emails
+ * 
+ * @param {String} pBulkMailId
+ */
+BulkMailUtils.removeCommRestrictionRecipients = function (pBulkMailId)
+{
+    var recipientIds = db.array(db.COLUMN, SqlBuilder.begin()
+        .select("BULKMAILRECIPIENTID")
+        .from("BULKMAILRECIPIENT")
+        .join("CONTACT", SqlCondition.begin()
+            .and("BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
+            .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail())))
+        .where(SqlCondition.begin()
+            .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId))
+        .build());
+
+    if (recipientIds.length)
+    {
+        db.deleteData("BULKMAILRECIPIENT", SqlCondition.begin()
+            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", recipientIds)
+            .build("1=2"));
+    }
+}
+
+/**
+ * adds recipients to a bulkmail
+ * 
+ * @param {String} pBulkMailId bulk mail id
+ * @param {String[]} pContactIds contact ids of the recipients
+ */
+BulkMailUtils.addRecipients = function (pBulkMailId, pContactIds)
+{
+    var columns = [
+        "BULKMAILRECIPIENTID",
+        "BULKMAIL_ID",
+        "CONTACT_ID",
+        "STATUS"
+    ];
+    var inserts = [];
+    for (let i = 0, l = pContactIds.length; i < l; i++)
+    {
+        inserts.push(["BULKMAILRECIPIENT", columns, null, [util.getNewUUID(), pBulkMailId, pContactIds[i], $KeywordRegistry.bulkMailRecipientStatus$pending()]]);
+    }
+    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.content)
+        template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
+    return template;
+}
+
+/**
+ * checks if a contact is a recipient of a bulk mail
+ * 
+ * @param {String} pBulkMailId bulkmail id
+ * @param {String} pContactId contact id
+ * @param {String} pRecipientId bulkmailrecipient id
+ * @return {boolean} true, if the contact is a recipient
+ */
+BulkMailUtils.isRecipient = function (pBulkMailId, pContactId, pRecipientId)
+{
+    return db.cell(SqlCondition.begin()
+        .andPrepare("BULKMAILRECIPIENT.CONTACT_ID", pContactId)
+        .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
+        .andPrepareIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", pRecipientId, "# != ?")
+        .buildSql("select count(*) from BULKMAILRECIPIENT") //TODO: is there a way exists could be used?
+    ) != "0";
+}
+
+/**
+ * opens the BulkMail context in new mode
+ * 
+ * @param {String[]} [pRecipients] recipients that should be added after creation
+ */
+BulkMailUtils.newBulkMail = function (pRecipients)
+{
+    var params = {
+        "PresetRecipients_param" : JSON.stringify(pRecipients)
+    };
+    neon.openContext("BulkMail", "BulkMailEdit_view", null, neon.OPERATINGSTATE_NEW, params);
+}
+
+/**
+ * Filters the given contactIds if they can be added as new recipients.
+ * Checks if a contact is already a recipient or if there is a advertising ban.
+ * 
+ * @param {String} pBulkMailId id of the bulk mail the contacts should be added to
+ * @param {String[]} pContactIds contacts to filter
+ * @return {String[]} contacts that can be added as recipients
+ */
+BulkMailUtils.filterNewRecipients = function (pBulkMailId, pContactIds)
+{
+    var existsQuery = "not exists(select BULKMAILRECIPIENTID from BULKMAILRECIPIENT where BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID and # = ?)";
+    var query = SqlCondition.begin()
+        .andIn("CONTACT.CONTACTID", pContactIds)
+        .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId, existsQuery) //only add contacts that aren't already recipients
+        .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true))  //check if there's a commrestriction
+        .buildSql("select CONTACTID from CONTACT");
+
+    return db.array(db.COLUMN, query); 
+}
+
+/**
+ * opens the given bulk mail
+ */
+BulkMailUtils.openBulkMail = function (pBulkMailId)
+{
+    neon.openContext("BulkMail", "BulkMailMain_view", [pBulkMailId], neon.OPERATINGSTATE_VIEW, null);
+}
+
+/**
+ * checks is the given mime type can be used for a bulk mail
+ * 
+ * @param {String} pMimeType mime type
+ * @return {Boolean} wheter the type is usable or not
+ */
+BulkMailUtils.isValidMimeType = function (pMimeType)
+{
+    var templateType = DocumentTemplate.types.fromMimeType(pMimeType);
+    switch (templateType)
+    {
+        case DocumentTemplate.types.EML:
+        case DocumentTemplate.types.HTML:
+        case DocumentTemplate.types.TXT:
+            return true;
+        default:
+            return false;
+    }
+}
+
+function SerialLetterUtils () {}
+
+/**
+ * adds recipients to a serial letter
+ * 
+ * @param {String} pSerialLetterId serial letter id
+ * @param {String[]} pContactIds contact ids of the recipients
+ */
+SerialLetterUtils.addRecipients = function (pSerialLetterId, pContactIds)
+{
+    var columns = [
+        "LETTERRECIPIENTID",
+        "SERIALLETTER_ID",
+        "CONTACT_ID"
+    ];
+    var inserts = [];
+    for (let i = 0, l = pContactIds.length; i < l; i++)
+    {
+        inserts.push(["LETTERRECIPIENT", columns, null, [util.getNewUUID(), pSerialLetterId, pContactIds[i]]]);
+    }
+    db.inserts(inserts);
+}
+
+/**
+ * opens a context to select a serial letter to add recipients to
+ * 
+ * @param {String[]} pContactIds recipients that should be added
+ */
+SerialLetterUtils.openAddRecipientView = function (pContactIds)
+{
+    var params = {
+        "ContactIds_param" : pContactIds
+    };
+    neon.openContext("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
+}
+
+/**
+ * executes a server process that builds a serial letter
+ * 
+ * @param {String} pSerialLetterId serial letter id
+ * @param {String[]} [pRecipientIds] Letter recipient ids of that should be used.
+ *                                    If omitted, all recipients of the letter will be used.
+ */
+SerialLetterUtils.buildSerialLetter = function (pSerialLetterId, pRecipientIds)
+{
+    process.execute("buildSerialLetter_serverProcess", {
+        "serialLetterId" : pSerialLetterId,
+        "recipientIds" : JSON.stringify(pRecipientIds)
+    });
+}
+
+/**
+ * checks if a contact is a recipient of a serial letter
+ * 
+ * @param {String} pSerialLetterId serial letter id
+ * @param {String} pContactId contact id
+ * @param {String} [pRecipientId] letter recipient id
+ * @return {boolean} true, if the contact is a recipient
+ */
+SerialLetterUtils.isRecipient = function (pSerialLetterId, pContactId, pRecipientId)
+{
+    return db.cell(SqlCondition.begin()
+        .andPrepare("LETTERRECIPIENT.CONTACT_ID", pContactId)
+        .andPrepare("LETTERRECIPIENT.SERIALLETTER_ID", pSerialLetterId)
+        .andPrepareIfSet("LETTERRECIPIENT.LETTERRECIPIENTID", pRecipientId, "# != ?")
+        .buildSql("select count(*) from LETTERRECIPIENT") //TODO: is there a way exists could be used?
+    ) != "0";
+}
+
+SerialLetterUtils.openSerialLetter = function (pSerialLetterId)
+{
+    neon.openContext("SerialLetter", "SerialLetterMain_view", [pSerialLetterId], neon.OPERATINGSTATE_VIEW, null);
+}
+
+/**
+ * Loads the document template of a serial letter. If the serial letter itself has a
+ * template, it is preferred over the documentTemplate-id.
+ * 
+ * @param {String} pLetterId serial letter id
+ * @param {String} pDocumentTemplateId documentTemplate id
+ * 
+ * @return {DocumentTemplate} the document template
+ */
+SerialLetterUtils.getSerialLetterTemplate = function (pLetterId, pDocumentTemplateId)
+{
+    var template = DocumentTemplate.loadTemplate(pLetterId, "SERIALLETTER");
+    if (!template.type)
+        template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
+    return template;
 }
\ No newline at end of file
diff --git a/process/Email_lib/process.js b/process/Email_lib/process.js
index 4f744b744b0574da562bdd2cf755606c13b71709..930a43edf290a2c5a9cadeb9aceb029bf480b380 100644
--- a/process/Email_lib/process.js
+++ b/process/Email_lib/process.js
@@ -61,15 +61,14 @@ EmailWritingUtils.getMailbridgeAddress = function ()
  * object for handling emails
  * 
  * @param {String|Array} [pToRecipients=[]] recipient email address or array of recipient email addresses
- * @param {String} [pSender=undefined] email address of the sender
- * @param {String} [pSubject=undefined] subject
- * @param {String} [pBody=undefined] mail body
+ * @param {String} [pSender=null] email address of the sender
+ * @param {String} [pSubject=null] subject
+ * @param {String} [pBody=null] mail body
  * @param {Array} [pCcRecipients=[]] array of recipient cc addresses
  * @param {Array} [pBccRecipients=[]] array of recipient bcc addresses
- * @param {String} [pOriginalRfcBase64=undefined] if existing, this file is used as base for creating an eml
  * @class
  */
-function Email (pToRecipients, pSender, pSubject, pBody, pCcRecipients, pBccRecipients, pOriginalRfcBase64)
+function Email (pToRecipients, pSender, pSubject, pBody, pCcRecipients, pBccRecipients)
 {
     if (pToRecipients && typeof(pToRecipients) == "string")
         pToRecipients = [pToRecipients];
@@ -80,7 +79,6 @@ function Email (pToRecipients, pSender, pSubject, pBody, pCcRecipients, pBccReci
     this.toRecipients = pToRecipients || [];
     this.ccRecipients = pCcRecipients || [];
     this.bccRecipients = pBccRecipients || [];
-    this.originalRfc = pOriginalRfcBase64;
 }
 
 /**
@@ -96,7 +94,7 @@ Email.fromRFC = function (pBase64RFC)
     var sender = mailData[mail.MAIL_SENDER];
     var subject = mailData[mail.MAIL_SUBJECT];
     
-    return new Email(null, sender, subject, body, undefined, undefined, pBase64RFC);
+    return new Email(null, sender, subject, body);
 }
 
 /**
@@ -114,18 +112,10 @@ Email.prototype.setTemplate = function (pTemplateId, pContactId, pBindata)
         if (BulkMailUtils.isValidMimeType(pBindata.mimeType))
         {
             template = new DocumentTemplate(pBindata.bindata, DocumentTemplate.types.fromMimeType(pBindata.mimeType), pBindata.filename, true);
-            this.originalRfc = pBindata.bindata;
         }
     }
     else
-    {
         template = DocumentTemplate.loadTemplate(pTemplateId);
-        if (BulkMailUtils.isValidTemplateType(template.type))
-        {
-            this.originalRfc = template.content;
-        }
-    }
-        
     var email = template.getReplacedEmailsByContactIds([pContactId])[pContactId];
     this.sender = email.sender;
     this.body = email.body;
@@ -174,31 +164,18 @@ Email.prototype.getMailtoUrl = function ()
  */
 Email.prototype.getRFCmail = function ()
 {
-    // disable generating mail via originalRfc for now as it doesn*t work as expected.
-    // --> undefined
-    this.originalRfc = undefined
-    
     var ENCODING = "UTF-8";
     var mailId;
-    var originalRfcDecoded = this.originalRfc ? util.decodeBase64String(this.originalRfc) : null;
-   
-   logging.log(originalRfcDecoded.substr(0,300));
     try 
     {
-        if (originalRfcDecoded)
-            mailId = mail.newMail(originalRfcDecoded, mail.FORMAT_MIME);
-        else
-            mailId = mail.newMail();
+        mailId = mail.newMail();
     }
     catch(ex)
     {
         //TODO: fix this dirty workaround [waiting for #1038963], since newMail causes an error on the first call after a user logged in
         logging.log(ex);
         util.sleep(1500);
-        if (originalRfcDecoded)
-            mailId = mail.newMail(originalRfcDecoded, mail.FORMAT_MIME);
-        else
-            mailId = mail.newMail();
+        mailId = mail.newMail();
     }