diff --git a/.liquibase/Data_alias/basic/2021.1.1/EmailFilter/alter_emailFilterHandling.xml b/.liquibase/Data_alias/basic/2021.1.1/EmailFilter/alter_emailFilterHandling.xml
new file mode 100644
index 0000000000000000000000000000000000000000..52178da7d2889205e3ac9ceae47230b2360896af
--- /dev/null
+++ b/.liquibase/Data_alias/basic/2021.1.1/EmailFilter/alter_emailFilterHandling.xml
@@ -0,0 +1,11 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+  <changeSet author="s.listl" id="5ba15adf-e9c9-46ee-989e-7ee02a3a61b7">
+      <addColumn tableName="EMAIL_FILTER_HANDLING">
+          <column name="ACTION_TYPE" type="VARCHAR(36)"/>
+          <column name="WORKFLOWSIGNAL_NAME" type="NVARCHAR(250)"/>
+      </addColumn>
+  </changeSet>
+</databaseChangeLog>
\ No newline at end of file
diff --git a/.liquibase/Data_alias/basic/2021.1.1/EmailFilter/insert_recipientStatusBounced.xml b/.liquibase/Data_alias/basic/2021.1.1/EmailFilter/insert_recipientStatusBounced.xml
new file mode 100644
index 0000000000000000000000000000000000000000..715254b5612bb7e425a511dd133705e0d7c0bc71
--- /dev/null
+++ b/.liquibase/Data_alias/basic/2021.1.1/EmailFilter/insert_recipientStatusBounced.xml
@@ -0,0 +1,27 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+  <changeSet author="s.listl" id="286b9086-b5a3-4ffc-b747-c8836d874666">
+    <insert tableName="AB_KEYWORD_ENTRY">
+        <column name="AB_KEYWORD_ENTRYID" value="f79c7bad-9ff5-45d5-b93e-4ce52bf88c2d"/>
+        <column name="AB_KEYWORD_CATEGORY_ID" value="25cb446a-24cd-4ebd-aad2-320da20830da"/>
+        <column name="KEYID" value="EMAILBOUNCED_SOFT"/>
+        <column name="TITLE" value="Bounce (Soft)"/>
+        <column name="CONTAINER" value="BulkMailRecipientStatus"/>
+        <column name="SORTING" valueNumeric="4"/>
+        <column name="ISACTIVE" valueNumeric="1"/>
+        <column name="ISESSENTIAL" valueNumeric="1"/>
+    </insert>
+    <insert tableName="AB_KEYWORD_ENTRY">
+        <column name="AB_KEYWORD_ENTRYID" value="f42932ab-935a-46e9-957c-dd4e7f82daa8"/>
+        <column name="AB_KEYWORD_CATEGORY_ID" value="25cb446a-24cd-4ebd-aad2-320da20830da"/>
+        <column name="KEYID" value="EMAILBOUNCED_HARD"/>
+        <column name="TITLE" value="Bounce (Hard)"/>
+        <column name="CONTAINER" value="BulkMailRecipientStatus"/>
+        <column name="SORTING" valueNumeric="5"/>
+        <column name="ISACTIVE" valueNumeric="1"/>
+        <column name="ISESSENTIAL" valueNumeric="1"/>
+    </insert>
+  </changeSet>
+</databaseChangeLog>
\ No newline at end of file
diff --git a/.liquibase/Data_alias/basic/2021.1.1/changelog.xml b/.liquibase/Data_alias/basic/2021.1.1/changelog.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dbb03bc9d62c0fea077c10159291a3f25f764e5b
--- /dev/null
+++ b/.liquibase/Data_alias/basic/2021.1.1/changelog.xml
@@ -0,0 +1,7 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+    <include relativeToChangelogFile="true" file="EmailFilter/alter_emailFilterHandling.xml"/>
+    <include relativeToChangelogFile="true" file="EmailFilter/insert_recipientStatusBounced.xml"/>
+</databaseChangeLog>
\ No newline at end of file
diff --git a/.liquibase/Data_alias/changelog.xml b/.liquibase/Data_alias/changelog.xml
index 5266ede8f1709637ccf87f5edfeb27bf5b838afe..d2cd89c296487cbe7bfd4295b95211d16ad8e7b6 100644
--- a/.liquibase/Data_alias/changelog.xml
+++ b/.liquibase/Data_alias/changelog.xml
@@ -24,6 +24,7 @@
     <include relativeToChangelogFile="true" file="basic/2021.0.2/changelog.xml"/>
     <include relativeToChangelogFile="true" file="basic/2021.0.3/changelog.xml"/>
     <include relativeToChangelogFile="true" file="basic/2021.1.0/changelog.xml"/>
+    <include relativeToChangelogFile="true" file="basic/2021.1.1/changelog.xml"/>
     
     <include relativeToChangelogFile="true" file="basic/workflows/changelog.xml" context="workflow"/>
     <!--enable this only when you definetly want to overwrite the existing data with demo records:-->
diff --git a/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod b/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod
index 2f1a06e4716ada4abac58d06429cb80228e835ad..ee0a5b93039f68e19d4786c596e783eb21d5a6d6 100644
--- a/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod
+++ b/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod
@@ -226,6 +226,10 @@
                 <name>Interest</name>
                 <kind v="10077" />
               </entityNode>
+              <entityNode>
+                <name>EmailFilterHandling</name>
+                <kind v="10077" />
+              </entityNode>
             </childNodes>
           </entityNode>
           <entityNode>
diff --git a/entity/BulkMailRecipient_entity/BulkMailRecipient_entity.aod b/entity/BulkMailRecipient_entity/BulkMailRecipient_entity.aod
index 7f856b4de39b2ae6cb730eeec8cc620eef1f0b79..4c13d49a9ff7c5b6a0871afa7cf64807c876a35c 100644
--- a/entity/BulkMailRecipient_entity/BulkMailRecipient_entity.aod
+++ b/entity/BulkMailRecipient_entity/BulkMailRecipient_entity.aod
@@ -161,12 +161,14 @@
           <title>Use for test run</title>
           <onActionProcess>%aditoprj%/entity/BulkMailRecipient_entity/entityfields/testrunactions/children/settestrecipient/onActionProcess.js</onActionProcess>
           <isObjectAction v="false" />
+          <iconId>VAADIN:CHECK</iconId>
         </entityActionField>
         <entityActionField>
           <name>removeTestRecipient</name>
           <title>Don't use for test run</title>
           <onActionProcess>%aditoprj%/entity/BulkMailRecipient_entity/entityfields/testrunactions/children/removetestrecipient/onActionProcess.js</onActionProcess>
           <isObjectAction v="false" />
+          <iconId>VAADIN:CLOSE</iconId>
         </entityActionField>
       </children>
     </entityActionGroup>
diff --git a/entity/BulkMail_entity/BulkMail_entity.aod b/entity/BulkMail_entity/BulkMail_entity.aod
index 4dfdfce86f3537a69b0630d7c5b3431f6f27d6c4..f755fbfd886dd8b588903a8b66f1eb0b7c0a1a89 100644
--- a/entity/BulkMail_entity/BulkMail_entity.aod
+++ b/entity/BulkMail_entity/BulkMail_entity.aod
@@ -336,6 +336,7 @@
     </entityConsumer>
     <entityConsumer>
       <name>BulkMailTestRecipients</name>
+      <selectionMode>MULTI</selectionMode>
       <stateProcess>%aditoprj%/entity/BulkMail_entity/entityfields/bulkmailtestrecipients/stateProcess.js</stateProcess>
       <dependency>
         <name>dependency</name>
diff --git a/entity/EmailData_entity/EmailData_entity.aod b/entity/EmailData_entity/EmailData_entity.aod
index 86a513a1b6ed57606b1ae1f10575f37be7aa905d..609ccf4bd184e3346ab653847da2acea52a8dcde 100644
--- a/entity/EmailData_entity/EmailData_entity.aod
+++ b/entity/EmailData_entity/EmailData_entity.aod
@@ -36,6 +36,10 @@
       <name>BODY_REGEX</name>
       <title>Email body (Regular expression)</title>
     </entityField>
+    <entityField>
+      <name>SENDERROR</name>
+      <title>Error</title>
+    </entityField>
   </entityFields>
   <recordContainers>
     <jDitoRecordContainer>
@@ -66,6 +70,10 @@
           <name>ATTACHMENTCOUNT.value</name>
           <isFilterable v="true" />
         </jDitoRecordFieldMapping>
+        <jDitoRecordFieldMapping>
+          <name>SENDERROR.value</name>
+          <isFilterable v="true" />
+        </jDitoRecordFieldMapping>
       </recordFieldMappings>
     </jDitoRecordContainer>
   </recordContainers>
diff --git a/entity/EmailFilterHandling_entity/EmailFilterHandling_entity.aod b/entity/EmailFilterHandling_entity/EmailFilterHandling_entity.aod
index 2b3ec48be0b04a1e3f76b9818f7a2621134b5dc9..a177320afec6c7c7a03e357f04f79139ce1957e5 100644
--- a/entity/EmailFilterHandling_entity/EmailFilterHandling_entity.aod
+++ b/entity/EmailFilterHandling_entity/EmailFilterHandling_entity.aod
@@ -33,7 +33,7 @@
       <name>WORKFLOWDEFINITION_KEY</name>
       <title>Workflow</title>
       <consumer>Workflows</consumer>
-      <displayValueProcess>%aditoprj%/entity/EmailFilterHandling_entity/entityfields/workflowdefinition_key/displayValueProcess.js</displayValueProcess>
+      <stateProcess>%aditoprj%/entity/EmailFilterHandling_entity/entityfields/workflowdefinition_key/stateProcess.js</stateProcess>
     </entityField>
     <entityConsumer>
       <name>FilterTypeKeyword</name>
@@ -82,6 +82,7 @@
     <entityField>
       <name>WORKFLOWSIGNAL_NAME</name>
       <title>Signal</title>
+      <stateProcess>%aditoprj%/entity/EmailFilterHandling_entity/entityfields/workflowsignal_name/stateProcess.js</stateProcess>
     </entityField>
     <entityField>
       <name>ACTION_TYPE</name>
@@ -89,9 +90,24 @@
     </entityField>
     <entityField>
       <name>ISFALLTHROUGH</name>
+      <title>Continue</title>
       <contentType>BOOLEAN</contentType>
       <valueProcess>%aditoprj%/entity/EmailFilterHandling_entity/entityfields/isfallthrough/valueProcess.js</valueProcess>
     </entityField>
+    <entityConsumer>
+      <name>ActionTypeKeyword</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>KeywordEntry_entity</entityName>
+        <fieldName>SpecificContainerKeywords</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>ContainerName_param</name>
+          <valueProcess>%aditoprj%/entity/EmailFilterHandling_entity/entityfields/actiontypekeyword/children/containername_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
@@ -138,6 +154,13 @@
           <name>ISFALLTHROUGH.value</name>
           <recordfield>EMAIL_FILTER_HANDLING.ISFALLTHROUGH</recordfield>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>DESCRIPTION.value</name>
+          <recordfield>EMAIL_FILTER_HANDLING.DESCRIPTION</recordfield>
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>WORKFLOWSIGNAL_NAME.value</name>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
       <linkInformation>
         <linkInformation>
diff --git a/entity/EmailFilterHandling_entity/entityfields/actiontypekeyword/children/containername_param/valueProcess.js b/entity/EmailFilterHandling_entity/entityfields/actiontypekeyword/children/containername_param/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..e2c2914556c6e5c59be1bec07528c80d65f520db
--- /dev/null
+++ b/entity/EmailFilterHandling_entity/entityfields/actiontypekeyword/children/containername_param/valueProcess.js
@@ -0,0 +1,4 @@
+import("KeywordRegistry_basic");
+import("system.result");
+
+result.string($KeywordRegistry.weblinkActionType());
\ No newline at end of file
diff --git a/entity/EmailFilterHandling_entity/entityfields/workflowdefinition_key/displayValueProcess.js b/entity/EmailFilterHandling_entity/entityfields/workflowdefinition_key/displayValueProcess.js
deleted file mode 100644
index 9b4c511d8c7320136a7cee0848d48822b2c6ca75..0000000000000000000000000000000000000000
--- a/entity/EmailFilterHandling_entity/entityfields/workflowdefinition_key/displayValueProcess.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import("system.vars");
-import("system.result");
-
-if (vars.get("$field.WORKFLOWDEFINITION_KEY"))
-result.string("Werbeeinstellung setzen")
\ No newline at end of file
diff --git a/entity/EmailFilterHandling_entity/entityfields/workflowdefinition_key/stateProcess.js b/entity/EmailFilterHandling_entity/entityfields/workflowdefinition_key/stateProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/entity/EmailFilterHandling_entity/entityfields/workflowsignal_name/stateProcess.js b/entity/EmailFilterHandling_entity/entityfields/workflowsignal_name/stateProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..a8892ce33aa94fa012dd1c30e32963eae278dbf6
--- /dev/null
+++ b/entity/EmailFilterHandling_entity/entityfields/workflowsignal_name/stateProcess.js
@@ -0,0 +1,7 @@
+import("system.result");
+import("system.vars");
+import("KeywordRegistry_basic");
+import("system.neon");
+
+var actionType = vars.get("$field.ACTION_TYPE");
+result.string(actionType == $KeywordRegistry.weblinkActionType$sendWorkflowSignal() ? neon.COMPONENTSTATE_EDITABLE : neon.COMPONENTSTATE_INVISIBLE);
\ No newline at end of file
diff --git a/entity/EmailFilterHandling_entity/recordcontainers/db/orderClauseProcess.js b/entity/EmailFilterHandling_entity/recordcontainers/db/orderClauseProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..40b390ad77d32c93aff3ac8d280095ea8272ca85
--- /dev/null
+++ b/entity/EmailFilterHandling_entity/recordcontainers/db/orderClauseProcess.js
@@ -0,0 +1,6 @@
+import("system.db");
+import("system.result");
+
+result.object({
+    "PRIORITY": db.ASCENDING
+});
\ No newline at end of file
diff --git a/neonView/EmailFilterHandlingPreview_view/EmailFilterHandlingPreview_view.aod b/neonView/EmailFilterHandlingPreview_view/EmailFilterHandlingPreview_view.aod
index cd1dc162ddf476a1e3b38f7844d4ee2d10c5bb1b..11d730a4ab6604c87094d7578136a707ce299fff 100644
--- a/neonView/EmailFilterHandlingPreview_view/EmailFilterHandlingPreview_view.aod
+++ b/neonView/EmailFilterHandlingPreview_view/EmailFilterHandlingPreview_view.aod
@@ -14,5 +14,28 @@
       <titleField>TITLE</titleField>
       <subtitleField>FILTER_TYPE</subtitleField>
     </cardViewTemplate>
+    <genericViewTemplate>
+      <name>Generic</name>
+      <showDrawer v="true" />
+      <drawerCaption>Details</drawerCaption>
+      <fields>
+        <entityFieldLink>
+          <name>a71ac88f-f0c3-4de7-9d1f-a989212bed71</name>
+          <entityField>ISACTIVE</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>6cbad6d9-8434-4328-8d82-6010240a5a7f</name>
+          <entityField>ISFALLTHROUGH</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>2adc5e19-553a-41e6-8bd0-40e3b7fc98f6</name>
+          <entityField>ACTION_TYPE</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>560c1795-60ff-4ea6-b17b-19f49610bc8f</name>
+          <entityField>WORKFLOWDEFINITION_KEY</entityField>
+        </entityFieldLink>
+      </fields>
+    </genericViewTemplate>
   </children>
 </neonView>
diff --git a/process/BulkmailAnalysis_lib/process.js b/process/BulkmailAnalysis_lib/process.js
index 7a8a4b42171a080a6cb25100abc09082aab9a5a1..6077fbb5e0119cee32fa70d3de2492baef0ace63 100644
--- a/process/BulkmailAnalysis_lib/process.js
+++ b/process/BulkmailAnalysis_lib/process.js
@@ -117,10 +117,9 @@ BulkMailAnalysisSql.countSelects =
    CLICKCOUNT:"count(distinct WEBLINK_CLICK.WEBLINK_CLICKID)",
    UNIQUECLICKCOUNT:"count(distinct WEBLINK_CLICK.MAIL_LOG_ID)",
    OPENERCOUNT:"count(distinct MAIL_LOG.OPENER_LINK_CLICK_ID)",
-   //todo: Keywordregistry verwenden wenn bounces mit drin sind.
-   BOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS in ('EMAILBOUNCED_HARD','EMAILBOUNCED_SOFT') then MAIL_LOG.MAIL_LOGID else null end)",
-   SOFTBOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS ='EMAILBOUNCED_SOFT' then MAIL_LOG.MAIL_LOGID else null end)",
-   HARDBOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS ='EMAILBOUNCED_HARD' then MAIL_LOG.MAIL_LOGID else null end)",   
+   BOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS in ('"+$KeywordRegistry.bulkMailRecipientStatus$softBounce()+"','"+$KeywordRegistry.bulkMailRecipientStatus$hardBounce()+"') then MAIL_LOG.MAIL_LOGID else null end)",
+   SOFTBOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS ='"+$KeywordRegistry.bulkMailRecipientStatus$softBounce()+"' then MAIL_LOG.MAIL_LOGID else null end)",
+   HARDBOUNCECOUNT:"count (distinct case when MAIL_LOG.STATUS ='"+$KeywordRegistry.bulkMailRecipientStatus$hardBounce()+"' then MAIL_LOG.MAIL_LOGID else null end)",   
    SENDCOUNT:"count (distinct MAIL_LOG.MAIL_LOGID)",
    RECEIVEDCOUNT:"count (distinct case when MAIL_LOG.STATUS='"+$KeywordRegistry.bulkMailRecipientStatus$sent()+"' then MAIL_LOG.MAIL_LOGID else null end)",
    UNSUBSCRIBECOUNT:"count (distinct  case when WEBLINK_CLICK.WEBLINK_ID = '"+newSelect(["WEBLINK.WEBLINKID"]).from("WEBLINK").where("WEBLINK.PLACEHOLDER","rejectEmail").cell()+"' then WEBLINK_CLICK.MAIL_LOG_ID else null end)"
diff --git a/process/Bulkmail_lib/process.js b/process/Bulkmail_lib/process.js
index 47d89a46ea5ec55ba9f3d56712e2e5c37be4bed6..a2edd886efa103efd448a1f78f0225491e92ef98 100644
--- a/process/Bulkmail_lib/process.js
+++ b/process/Bulkmail_lib/process.js
@@ -1,3 +1,5 @@
+import("CommunicationBlacklist_lib");
+import("EmailFilterHandling_lib");
 import("system.logging");
 import("system.entities");
 import("MarketingCondition_lib");
@@ -97,6 +99,8 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
     
     recipientData = entities.getRows(recipientLoadConfig);
     
+    var blacklist = new CommunicationBlacklist().loadBlacklistRecipients(pBulkMailId);
+    
     if (pIsTestRun)
     {
         testRecipientData = newSelect("BULKMAILTESTRECIPIENT.CONTACT_ID, BULKMAILTESTRECIPIENT.EMAIL_ADDRESS")
@@ -152,6 +156,8 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
     
     var successIds = [];
     var failedIds = [];
+    var bouncedSoftIds = [];
+    var bouncedHardIds = [];
     var sentDate = vars.get("$sys.date");
     var mails = template.getReplacedEmailsByContactIds(contactIds, additionalPlaceholders);
     
@@ -160,11 +166,15 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
     
     var bulkMailLink = [["BulkMail", pBulkMailId]];
     var activitySubject = translate.withArguments("Bulk mail \"%0\" sent", [bulkMailName]);
+    
+    var emailFilterProcessor = new IncomingEmailFilterProcessor().loadFilters();
+    
     if (!pIsTestRun)
     {
         recipientData.forEach(function (recipient)
         {
             let isSuccess = false;
+            let bouncedStatus = null;
             let recipientId = recipient["BULKMAILRECIPIENTID"];
             let contactId = recipient["CONTACT_ID"];
             let emailAddress = recipient["EMAIL_ADDRESS"];
@@ -172,6 +182,7 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
             let organisationId = recipient["ORGANISATION_ID"];
             let email = mails[contactId];
             let mailLogId = mailLogIds.get(contactId);
+            let recipientStatus = $KeywordRegistry.bulkMailRecipientStatus$sent();
             if (email !== undefined && emailAddress)
             {
                 email.toRecipients = [emailAddress];
@@ -180,6 +191,17 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
 
                 BulkMailUtils.storeEmlFile(pBulkMailId, mailrunId, mailLogId,email.getEML());
                 isSuccess = email.send();
+                if (!isSuccess)
+                {
+                    var errorMessage = logging.toLogString(email.getMailError(), true);
+                    var filterType = emailFilterProcessor.processError(errorMessage, contactId, emailAddress);
+                    if (filterType == $KeywordRegistry.emailFilterType$bounceHard())
+                        bouncedStatus = $KeywordRegistry.bulkMailRecipientStatus$hardBounce();
+                    else if (filterType == $KeywordRegistry.emailFilterType$bounceSoft())
+                        bouncedStatus = $KeywordRegistry.bulkMailRecipientStatus$softBounce();
+                    
+                    recipientStatus = bouncedStatus || $KeywordRegistry.bulkMailRecipientStatus$failed();
+                }
             }
 
             //set the recipient status to 'sent' or 'failed'
@@ -189,7 +211,7 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
                     "MAIL_LOGID": mailLogId,
                     "MAIL_RUN_ID": mailrunId,
                     "CONTACT_ID": contactId,
-                    "STATUS": isSuccess ? $KeywordRegistry.bulkMailRecipientStatus$sent() : $KeywordRegistry.bulkMailRecipientStatus$failed(),
+                    "STATUS": recipientStatus,
                     "SENDER_EMAIL": emailSender,
                     "RECIPIENT_EMAIL": emailAddress,
                     "MAILING_SUBJECT": subjects[contactId],
@@ -197,7 +219,22 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
                 });
                 
             //TODO: Klären was von alter Logik noch bleiben soll. Status macht nur Sinn wenn jede Bulkmail nur einmal gesendet wird. Bleiben Activitys?
-            Array.prototype.push.call(isSuccess ? successIds : failedIds, recipientId);
+            if (isSuccess)
+            {
+                sucessIds.push(recipientId);
+            }
+            else if (bouncedStatus == $KeywordRegistry.bulkMailRecipientStatus$softBounce())
+            {
+                bouncedSoftIds.push(recipientId);
+            }
+            else if (bouncedStatus == $KeywordRegistry.bulkMailRecipientStatus$hardBounce())
+            {
+                bouncedHardIds.push(recipientId);
+            }
+            else
+            {
+                failedIds.push(recipientId);
+            }
             if (isSuccess && createActivity == "1")
             {
                 let activityData = {
@@ -223,6 +260,18 @@ BulkMailUtils.sendBulkMail = function (pBulkMailId, pIsTestRun)
                 "SENTDATE": sentDate
             });
 
+        newWhereIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", bouncedSoftIds, SqlBuilder.IN())
+            .updateFields({
+                "STATUS": $KeywordRegistry.bulkMailRecipientStatus$softBounce(),
+                "SENTDATE": sentDate
+            });
+        
+        newWhereIfSet("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", bouncedHardIds, SqlBuilder.IN())
+            .updateFields({
+                "STATUS": $KeywordRegistry.bulkMailRecipientStatus$hardBounce(),
+                "SENTDATE": sentDate
+            });
+            
         newWhere("MAIL_RUN.MAIL_RUNID", mailrunId)
             .updateFields({
                 "STATUS": $KeywordRegistry.bulkMailStatus$sent(),
diff --git a/process/CommunicationBlacklist_lib/process.js b/process/CommunicationBlacklist_lib/process.js
index 238bf50b48bba7de016b8b7af07cfbe35367e94c..5c350a27f2fda0fd164a35c167cdf38b057d77ac 100644
--- a/process/CommunicationBlacklist_lib/process.js
+++ b/process/CommunicationBlacklist_lib/process.js
@@ -1,3 +1,5 @@
+import("KeywordRegistry_basic");
+import("system.entities");
 import("Util_lib");
 import("Sql_lib");
 import("system.vars");
@@ -5,17 +7,18 @@ import("system.vars");
 
 function CommunicationBlacklist () 
 {
-    this.filter = null;
+    this.filter = CommunicationBlacklist.getMailRecipientBlacklistFilter();
+    this.blacklistContactIds = new Set();
 }
 
 /**
  * @return {CommunicationBlacklist}
  */
-CommunicationBlacklist.getMailRecipientBlacklist = function ()
+CommunicationBlacklist.getMailRecipientBlacklistFilter = function ()
 {
     var filters = newSelect("FILTER")
         .from("EMAIL_FILTER_HANDLING")
-        .where("COMMUNICATIONBLACKLIST.BLACKLIST_TYPE", $KeywordRegistry.communicationBlacklistType$emailRecipientFilter())
+        .where("EMAIL_FILTER_HANDLING.FILTER_TYPE", $KeywordRegistry.emailFilterType$blacklist())
         .table();
     
     var filterMappingFn = function ([blacklistFilter])
@@ -27,19 +30,34 @@ CommunicationBlacklist.getMailRecipientBlacklist = function ()
         return blacklistFilter.filter;
     };
     
-    var blacklist = new CommunicationBlacklist();
-    blacklist.filter = {
+    return {
         type: "group",
         operator: "AND",
         childs: filters.map(filterMappingFn).filter(Utils.isObject)
     };
-    return blacklist;
 }
 
-CommunicationBlacklist.prototype.getCondition = function ()
+CommunicationBlacklist.prototype.getFilter = function ()
 {
-    return new FilterSqlTranslator()
-        .filter(this.filter)
-        .table("BULKMAILRECIPIENT")
-        .getSqlCondition();
-}
\ No newline at end of file
+    return this.filter;
+}
+
+CommunicationBlacklist.prototype.loadBlacklistRecipients = function (pBulkMailId)
+{
+    var blacklistLoadConfig = entities.createConfigForLoadingRows()
+        .fields(["CONTACT_ID"])
+        .entity("BulkmailRecipient_entity")
+        .provider("RecipientsToBeMailed")
+        .addParameter("BulkMailId_param", pBulkMailId)
+        .filter(JSON.stringify(this.filter));
+    var blacklist = entities.getRows(blacklistLoadConfig);
+    blacklist.forEach(function (recipient)
+    {
+        this.blacklistContactIds.add(recipient["CONTACT_ID"]);
+    }, this);
+}
+
+CommunicationBlacklist.prototype.hasContactId = function (pContactId)
+{
+    return this.blacklistContactIds.has(pContactId);
+}
diff --git a/process/EmailFilterHandling_lib/process.js b/process/EmailFilterHandling_lib/process.js
index 15db9b516dc61fe98c6918b331de7ae2b361d875..1ef6f1da890bbd522858995737735672bb8aec1f 100644
--- a/process/EmailFilterHandling_lib/process.js
+++ b/process/EmailFilterHandling_lib/process.js
@@ -18,8 +18,8 @@ IncomingEmailFilterProcessor.prototype.loadFilters = function ()
     var bounceFilters = newSelect(["TITLE", "FILTER_TYPE", "FILTER", "WORKFLOWDEFINITION_KEY"])
         .from("EMAIL_FILTER_HANDLING")
         .where("EMAIL_FILTER_HANDLING.ISACTIVE", "1")
-        .and(newWhere("EMAIL_FILTER.FILTER_TYPE", $KeywordRegistry.emailFilterType$bounceSoft())
-            .or("EMAIL_FILTER.FILTER_TYPE", $KeywordRegistry.emailFilterType$bounceHard()))
+        .and(newWhere("EMAIL_FILTER_HANDLING.FILTER_TYPE", $KeywordRegistry.emailFilterType$bounceSoft())
+            .or("EMAIL_FILTER_HANDLING.FILTER_TYPE", $KeywordRegistry.emailFilterType$bounceHard()))
         .orderBy("PRIORITY asc")
         .table();
     
@@ -27,6 +27,7 @@ IncomingEmailFilterProcessor.prototype.loadFilters = function ()
     {
         return new IncomingEmailFilter(title, type, filterJson, workflowKey);
     });
+    return this;
 }
 
 /**
@@ -34,13 +35,30 @@ IncomingEmailFilterProcessor.prototype.loadFilters = function ()
  */
 IncomingEmailFilterProcessor.prototype.process = function (pEmail)
 {
+    var bouncedStatus = null;
     this.emailFilters.forEach(function (emailFilter)
     {
         if (emailFilter.checkEmail(pEmail))
         {
             emailFilter.startWorkflow();
+            bouncedStatus = emailFilter.type;
         }
     });
+    return bouncedStatus;
+}
+
+IncomingEmailFilterProcessor.prototype.processError = function (pErrorMessage, pContactId, pEmailAddress)
+{
+    var bouncedStatus = null;
+    this.emailFilters.forEach(function (emailFilter)
+    {
+        if (emailFilter.checkEmailError(pErrorMessage))
+        {
+            emailFilter.startWorkflow(pContactId, pEmailAddress);
+            bouncedStatus = emailFilter.type;
+        }
+    });
+    return bouncedStatus;
 }
 
 /**
@@ -52,7 +70,7 @@ function IncomingEmailFilter (pTitle, pType, pFilterJson, pWorkflowKey)
     this.type = pType;
     this.filter = new JditoFilter()
         .filterJSON(pFilterJson)
-        .fieldOrder(["SENDER", "SUBJECT", "BODY_PLAIN", "BODY_REGEX", "ATTACHMENTCOUNT"])
+        .fieldOrder(["SENDER", "SUBJECT", "BODY_PLAIN", "BODY_REGEX", "ATTACHMENTCOUNT", "SENDERROR"])
         .addSpecialCheckFn("BODY_REGEX", function (rowValue, filterValue, operator) 
         {
             var regExParts = filterValue.match(new RegExp('^/(.*?)/([gimy]*)$'));
@@ -64,7 +82,7 @@ function IncomingEmailFilter (pTitle, pType, pFilterJson, pWorkflowKey)
             return regEx.test(rowValue);
         }, this);
     this.workflowKey = pWorkflowKey;
-    this.isFallthrough = pIsFallthrough;
+    this.isFallthrough = false;
 }
 
 /**
@@ -79,11 +97,17 @@ IncomingEmailFilter.prototype.checkEmail = function (pEmail)
     var subject = pEmail[mail.MAIL_SUBJECT];
     var body = pEmail[mail.MAIL_TEXT];
     var attachmentCount = pEmail[mail.MAIL_ATTACHMENTCOUNT];
-    var emailRecord = [sender, subject, body, body, attachmentCount];
+    var emailRecord = [sender, subject, body, body, attachmentCount, ""];
     
     return this.filter.checkRecord(emailRecord);
 }
 
+IncomingEmailFilter.prototype.checkEmailError = function (pError)
+{
+    var emailRecord = ["", "", "", "", "", pError];
+    return this.filter.checkRecord(emailRecord);
+}
+
 /**
  * Inserts an entry into the MAIL_LOG table to protocol the received email.
  * 
@@ -94,18 +118,22 @@ IncomingEmailFilter.prototype.writeMailLog = function (pEmail)
 {
     new SqlBuilder.insertFields({
         "MAIL_LOGID": util.getNewUUID()
+        
     }, pTableName);
 }
 
 /**
  * Starts the workflow that has been defined for the email filter.
  */
-IncomingEmailFilter.prototype.startWorkflow = function ()
+IncomingEmailFilter.prototype.startWorkflow = function (pContactId, pEmailAddress)
 {
     if (this.workflowKey)
     {
         workflow.startProcessByKey(this.workflowKey, {
-            
+            contactId: pContactId,
+            emailAddress: pEmailAddress,
+            channelType: $KeywordRegistry.communicationChannelType$communication(),
+            medium: $KeywordRegistry.communicationMediumCampaign$mail()
         });
     }
 }
diff --git a/process/Email_lib/process.js b/process/Email_lib/process.js
index 1c2acdb21f9f2c28b2b1f9d2dae3c643d69d4538..68f07458d6610719aa259d47419ef72169fe63fb 100644
--- a/process/Email_lib/process.js
+++ b/process/Email_lib/process.js
@@ -169,6 +169,7 @@ function Email(pBody)
     this.bccRecipients = [];
     this.attachmentTemplates = [];
     this.emlFile = null;
+    this._error = null; //caches the error if sending fails
 }
 
 /**
@@ -409,12 +410,24 @@ Email.prototype.send = function (pUser)
                 question.showMessage(translate.withArguments("Mailbridge failed: user '%0' is unknown, contact an administrator.", [mailbridgeTitle]), question.ERROR, translate.text("Error"));
         }
         // remove from cache
-        mail.deleteMail(mailId)
+        mail.deleteMail(mailId);
+        this._error = null;
         return sentMails > 0;
     }
     catch (ex)
     {
+        this._error = ex;
         logging.log(ex);
         return false;
     }
+}
+
+/**
+ * Returns the error from sending the email
+ * 
+ * @return {Error} error if sending failed, or null if it was sucessful
+ */
+Email.prototype.getMailError = function ()
+{
+    return this._error;
 }
\ No newline at end of file
diff --git a/process/KeywordRegistry_basic/process.js b/process/KeywordRegistry_basic/process.js
index 5fc995435666ed19b5a5eb716a1b02db218bdd7b..86bfc662594e207c5911ec0f786cde055b67d34d 100644
--- a/process/KeywordRegistry_basic/process.js
+++ b/process/KeywordRegistry_basic/process.js
@@ -237,6 +237,8 @@ $KeywordRegistry.bulkMailRecipientStatus = function(){return "BulkMailRecipientS
 $KeywordRegistry.bulkMailRecipientStatus$pending = function(){return "EMAILPENDING";};
 $KeywordRegistry.bulkMailRecipientStatus$sent = function(){return "EMAILSENT";};
 $KeywordRegistry.bulkMailRecipientStatus$failed = function(){return "EMAILFAILED";};
+$KeywordRegistry.bulkMailRecipientStatus$softBounce = function(){return "EMAILBOUNCED_SOFT";};
+$KeywordRegistry.bulkMailRecipientStatus$hardBounce = function(){return "EMAILBOUNCED_HARD";};
 
 $KeywordRegistry.bulkMailStatus = function(){return "BulkMailStatus";};
 $KeywordRegistry.bulkMailStatus$notSent = function(){return "BULKMAILNOTSENT";};
@@ -426,5 +428,5 @@ $KeywordRegistry.advertisingDelivery$mail = function(){return "ADVERTDELIVERYMAI
 
 $KeywordRegistry.emailFilterType = function(){return "EmailFilterType";};
 $KeywordRegistry.emailFilterType$blacklist = function(){return "EMAIL_FILTER_BLACKLIST";};
-$KeywordRegistry.emailFilterType$bounceSoft = function(){return "EMAIL_FILTER_BOUNCEHARD";};
-$KeywordRegistry.emailFilterType$bounceHard = function(){return "EMAIL_FILTER_BOUNCESOFT";};
\ No newline at end of file
+$KeywordRegistry.emailFilterType$bounceSoft = function(){return "EMAIL_FILTER_BOUNCESOFT";};
+$KeywordRegistry.emailFilterType$bounceHard = function(){return "EMAIL_FILTER_BOUNCEHARD";};
\ No newline at end of file
diff --git a/process/mailbridge/process.js b/process/mailbridge/process.js
index 88f17d8b32509fd74629bb49748cf66968984268..3d5144d29fdd14251a0918d11ea3b900a800a823 100644
--- a/process/mailbridge/process.js
+++ b/process/mailbridge/process.js
@@ -1,4 +1,5 @@
 import("IncomingEmailExecutor_lib");
+import("EmailFilterHandling_lib");
 import("system.text");
 import("system.vars");
 import("system.mail");
@@ -9,4 +10,5 @@ var recipients = text.decodeMS(vars.getString("$local.recipients"));
 var mailObj = mail.resolveMail(vars.getString("$local.mail"));
 
 var incomingMailExec = new IncomingEmailExecutor(mailObj);
+incomingMailExec.attachProcessor(new IncomingEmailFilterProcessor().loadFilters());
 incomingMailExec.autoProcess();
\ No newline at end of file