diff --git a/CRM/Admin/Form/MailSettings.php b/CRM/Admin/Form/MailSettings.php
index 4de49fe41356d291fc316ffdf86127b0ac08e401..70c227b1ede4f976e260ce4a8e65808b81b17487 100644
--- a/CRM/Admin/Form/MailSettings.php
+++ b/CRM/Admin/Form/MailSettings.php
@@ -70,6 +70,9 @@ class CRM_Admin_Form_MailSettings extends CRM_Admin_Form {
     ];
     $this->add('select', 'is_default', ts('Used For?'), $usedfor);
     $this->addField('activity_status', ['placeholder' => FALSE]);
+
+    $this->add('checkbox', 'is_non_case_email_skipped', ts('Skip emails which do not have a Case ID or Case hash'));
+    $this->add('checkbox', 'is_contact_creation_disabled_if_no_match', ts('Do not create new contacts when filing emails'));
   }
 
   /**
@@ -146,6 +149,8 @@ class CRM_Admin_Form_MailSettings extends CRM_Admin_Form {
       'is_ssl',
       'is_default',
       'activity_status',
+      'is_non_case_email_skipped',
+      'is_contact_creation_disabled_if_no_match',
     ];
 
     $params = [];
@@ -153,6 +158,8 @@ class CRM_Admin_Form_MailSettings extends CRM_Admin_Form {
       if (in_array($f, [
         'is_default',
         'is_ssl',
+        'is_non_case_email_skipped',
+        'is_contact_creation_disabled_if_no_match',
       ])) {
         $params[$f] = CRM_Utils_Array::value($f, $formValues, FALSE);
       }
@@ -164,7 +171,7 @@ class CRM_Admin_Form_MailSettings extends CRM_Admin_Form {
     $params['domain_id'] = CRM_Core_Config::domainID();
 
     // assign id only in update mode
-    $status = ts('Your New  Email Settings have been saved.');
+    $status = ts('Your New Email Settings have been saved.');
     if ($this->_action & CRM_Core_Action::UPDATE) {
       $params['id'] = $this->_id;
       $status = ts('Your Email Settings have been updated.');
diff --git a/CRM/Upgrade/Incremental/php/FiveThirtyOne.php b/CRM/Upgrade/Incremental/php/FiveThirtyOne.php
index 8cbbaf1aaed964d849c9d6087674085d7815021d..9b5a859dc0fa1c0fa8440c939cd75d7d84ea5740 100644
--- a/CRM/Upgrade/Incremental/php/FiveThirtyOne.php
+++ b/CRM/Upgrade/Incremental/php/FiveThirtyOne.php
@@ -67,6 +67,19 @@ class CRM_Upgrade_Incremental_php_FiveThirtyOne extends CRM_Upgrade_Incremental_
     $this->addTask('Activate core extension "Greenwich"', 'installGreenwich');
   }
 
+  /**
+   * Upgrade function.
+   *
+   * @param string $rev
+   */
+  public function upgrade_5_31_0($rev) {
+    $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
+    $this->addTask('Add is_non_case_email_skipped column to civicrm_mail_settings', 'addColumn',
+      'civicrm_mail_settings', 'is_non_case_email_skipped', "TINYINT DEFAULT 0 NOT NULL COMMENT 'Skip emails which do not have a Case ID or Case hash'");
+    $this->addTask('Add is_contact_creation_disabled_if_no_match column to civicrm_mail_settings', 'addColumn',
+      'civicrm_mail_settings', 'is_contact_creation_disabled_if_no_match', "TINYINT DEFAULT 0 NOT NULL COMMENT 'If this option is enabled, CiviCRM will not create new contacts when filing emails'");
+  }
+
   public static function enableEwaySingleExtension(CRM_Queue_TaskContext $ctx) {
     $eWAYPaymentProcessorType = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_payment_processor_type WHERE class_name = 'Payment_eWAY'");
     if ($eWAYPaymentProcessorType) {
diff --git a/CRM/Utils/Hook.php b/CRM/Utils/Hook.php
index 7a79fdbf0b9b67e2d1409108efc79359f4de8c83..a987971774b41dc02e2bf2a00254168dff9d95a5 100644
--- a/CRM/Utils/Hook.php
+++ b/CRM/Utils/Hook.php
@@ -1270,6 +1270,28 @@ abstract class CRM_Utils_Hook {
       ->invoke(['caseTypes'], $caseTypes, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_caseTypes');
   }
 
+  /**
+   * This hook is called when getting case email subject patterns.
+   *
+   * All emails related to cases have case hash/id in the subject, e.g:
+   * [case #ab12efg] Magic moment
+   * [case #1234] Magic is here
+   *
+   * Using this hook you can replace/enrich default list with some other
+   * patterns, e.g. include case type categories (see CiviCase extension) like:
+   * [(case|project|policy initiative) #hash]
+   * [(case|project|policy initiative) #id]
+   *
+   * @param array $subjectPatterns
+   *   Cases related email subject regexp patterns.
+   *
+   * @return mixed
+   */
+  public static function caseEmailSubjectPatterns(&$subjectPatterns) {
+    return self::singleton()
+      ->invoke(['caseEmailSubjectPatterns'], $subjectPatterns, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_caseEmailSubjectPatterns');
+  }
+
   /**
    * This hook is called soon after the CRM_Core_Config object has ben initialized.
    * You can use this hook to modify the config object and hence behavior of CiviCRM dynamically.
diff --git a/CRM/Utils/Mail/CaseMail.php b/CRM/Utils/Mail/CaseMail.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b644ea65890848ffdace54bf42743183e19c7be
--- /dev/null
+++ b/CRM/Utils/Mail/CaseMail.php
@@ -0,0 +1,127 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved.                        |
+ |                                                                    |
+ | This work is published under the GNU AGPLv3 license with some      |
+ | permitted exceptions and without any warranty. For full license    |
+ | and copyright information, see https://civicrm.org/licensing       |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC https://civicrm.org/licensing
+ */
+
+/**
+ * Class CRM_Utils_Mail_CaseMail.
+ */
+class CRM_Utils_Mail_CaseMail {
+
+  /**
+   * A word that is used for cases by default (in email subject).
+   *
+   * @var string
+   */
+  private $caseLabel = 'case';
+
+  /**
+   * Default cases related email subject regexp patterns.
+   *
+   * All emails related to cases have case hash/id in the subject, e.g:
+   * [case #ab12efg] Magic moment
+   * [case #1234] Magic is here
+   * This variable is defined in constructor.
+   *
+   * @var array|string[]
+   */
+  private $subjectPatterns = [];
+
+  /**
+   * Cases related email subject regexp patterns extended by hooks.
+   *
+   * @var array|string[]
+   */
+  private $subjectPatternsHooked = [];
+
+  /**
+   * CRM_Utils_Mail_CaseMail constructor.
+   */
+  public function __construct() {
+    $this->subjectPatterns = [
+      '/\[' . $this->caseLabel . ' #([0-9a-f]{7})\]/i',
+      '/\[' . $this->caseLabel . ' #(\d+)\]/i',
+    ];
+  }
+
+  /**
+   * Checks if email is related to cases.
+   *
+   * @param string $subject
+   *   Email subject.
+   *
+   * @return bool
+   *   TRUE if email subject contains case ID or case hash, FALSE otherwise.
+   */
+  public function isCaseEmail ($subject) {
+    $subject = trim($subject);
+    $patterns = $this->getSubjectPatterns();
+    $res = FALSE;
+
+    for ($i = 0; !$res && $i < count($patterns); $i++) {
+      $res = preg_match($patterns[$i], $subject) === 1;
+    }
+
+    return $res;
+  }
+
+  /**
+   * Returns cases related email subject patterns.
+   *
+   * These patterns could be used to check if email is related to cases.
+   *
+   * @return array|string[]
+   */
+  public function getSubjectPatterns() {
+    // Allow others to change patterns using hook.
+    if (empty($this->subjectPatternsHooked)) {
+      $patterns = $this->subjectPatterns;
+      CRM_Utils_Hook::caseEmailSubjectPatterns($patterns);
+      $this->subjectPatternsHooked = $patterns;
+    }
+
+    return !empty($this->subjectPatternsHooked)
+      ? $this->subjectPatternsHooked
+      : $this->subjectPatterns;
+  }
+
+  /**
+   * Returns value of some class property.
+   *
+   * @param string $name
+   *   Property name.
+   *
+   * @return mixed|null
+   *   Property value or null if property does not exist.
+   */
+  public function get($name) {
+    return $this->{$name} ?? NULL;
+  }
+
+  /**
+   * Sets value of some class property.
+   *
+   * @param string $name
+   *   Property name.
+   * @param mixed $value
+   *   New property value.
+   */
+  public function set($name, $value) {
+    if (isset($this->{$name})) {
+      $this->{$name} = $value;
+    }
+  }
+
+}
diff --git a/CRM/Utils/Mail/EmailProcessor.php b/CRM/Utils/Mail/EmailProcessor.php
index a8be02ce0ac02946a493c804388edcb99db5cd52..fe24b02e02721bb1989e7b1f907d46794bc0a177 100644
--- a/CRM/Utils/Mail/EmailProcessor.php
+++ b/CRM/Utils/Mail/EmailProcessor.php
@@ -157,7 +157,7 @@ class CRM_Utils_Mail_EmailProcessor {
     try {
       $store = CRM_Mailing_MailStore::getStore($dao->name);
     }
-    catch (Exception$e) {
+    catch (Exception $e) {
       $message = ts('Could not connect to MailStore for ') . $dao->username . '@' . $dao->server . '<p>';
       $message .= ts('Error message: ');
       $message .= '<pre>' . $e->getMessage() . '</pre><p>';
@@ -224,9 +224,19 @@ class CRM_Utils_Mail_EmailProcessor {
 
         // preseve backward compatibility
         if ($usedfor == 0 || $is_create_activities) {
+          // Mail account may have 'Skip emails which do not have a Case ID
+          // or Case hash' option, if its enabled and email is not related
+          // to cases - then we need to put email to ignored folder.
+          $caseMailUtils = new CRM_Utils_Mail_CaseMail();
+          if (!empty($dao->is_non_case_email_skipped) && !$caseMailUtils->isCaseEmail($mail->subject)) {
+            $store->markIgnored($key);
+            continue;
+          }
+
           // if its the activities that needs to be processed ..
           try {
-            $mailParams = CRM_Utils_Mail_Incoming::parseMailingObject($mail);
+            $createContact = !($dao->is_contact_creation_disabled_if_no_match ?? FALSE);
+            $mailParams = CRM_Utils_Mail_Incoming::parseMailingObject($mail, $createContact, FALSE);
           }
           catch (Exception $e) {
             echo $e->getMessage();
@@ -241,6 +251,7 @@ class CRM_Utils_Mail_EmailProcessor {
           if (!empty($dao->activity_status)) {
             $params['status_id'] = $dao->activity_status;
           }
+
           $result = civicrm_api('activity', 'create', $params);
 
           if ($result['is_error']) {
diff --git a/CRM/Utils/Mail/Incoming.php b/CRM/Utils/Mail/Incoming.php
index 1e2da042236bb3d28b59d7025bd3c2dfd5736439..a11961081250ef2988a6e0ff9fdcfc1ea7d0b544 100644
--- a/CRM/Utils/Mail/Incoming.php
+++ b/CRM/Utils/Mail/Incoming.php
@@ -322,10 +322,12 @@ class CRM_Utils_Mail_Incoming {
 
   /**
    * @param $mail
+   * @param $createContact
+   * @param $requireContact
    *
    * @return array
    */
-  public static function parseMailingObject(&$mail) {
+  public static function parseMailingObject(&$mail, $createContact = TRUE, $requireContact = TRUE) {
 
     $config = CRM_Core_Config::singleton();
 
@@ -342,18 +344,18 @@ class CRM_Utils_Mail_Incoming {
     }
 
     $params['from'] = [];
-    self::parseAddress($mail->from, $field, $params['from'], $mail);
+    self::parseAddress($mail->from, $field, $params['from'], $mail, $createContact);
 
     // we definitely need a contact id for the from address
     // if we dont have one, skip this email
-    if (empty($params['from']['id'])) {
+    if ($requireContact && empty($params['from']['id'])) {
       return NULL;
     }
 
     $emailFields = ['to', 'cc', 'bcc'];
     foreach ($emailFields as $field) {
       $value = $mail->$field;
-      self::parseAddresses($value, $field, $params, $mail);
+      self::parseAddresses($value, $field, $params, $mail, $createContact);
     }
 
     // define other parameters
@@ -396,8 +398,9 @@ class CRM_Utils_Mail_Incoming {
    * @param array $params
    * @param $subParam
    * @param $mail
+   * @param $createContact
    */
-  public static function parseAddress(&$address, &$params, &$subParam, &$mail) {
+  public static function parseAddress(&$address, &$params, &$subParam, &$mail, $createContact = TRUE) {
     // CRM-9484
     if (empty($address->email)) {
       return;
@@ -408,7 +411,7 @@ class CRM_Utils_Mail_Incoming {
 
     $contactID = self::getContactID($subParam['email'],
       $subParam['name'],
-      TRUE,
+      $createContact,
       $mail
     );
     $subParam['id'] = $contactID ? $contactID : NULL;
@@ -419,13 +422,14 @@ class CRM_Utils_Mail_Incoming {
    * @param $token
    * @param array $params
    * @param $mail
+   * @param $createContact
    */
-  public static function parseAddresses(&$addresses, $token, &$params, &$mail) {
+  public static function parseAddresses(&$addresses, $token, &$params, &$mail, $createContact = TRUE) {
     $params[$token] = [];
 
     foreach ($addresses as $address) {
       $subParam = [];
-      self::parseAddress($address, $params, $subParam, $mail);
+      self::parseAddress($address, $params, $subParam, $mail, $createContact);
       $params[$token][] = $subParam;
     }
   }
diff --git a/templates/CRM/Admin/Form/MailSettings.tpl b/templates/CRM/Admin/Form/MailSettings.tpl
index 361ffe09e187932ba91ed2b4adee24be4970f7a0..d003ef89f9ba1c2529b145138645f8579e897612 100644
--- a/templates/CRM/Admin/Form/MailSettings.tpl
+++ b/templates/CRM/Admin/Form/MailSettings.tpl
@@ -9,62 +9,73 @@
 *}
 {* this template is used for adding/editing email settings.  *}
 <div class="crm-block crm-form-block crm-mail-settings-form-block">
-<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div>
-{if $action eq 8}
-  <div class="messages status no-popup">
+  <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div>
+  {if $action eq 8}
+    <div class="messages status no-popup">
       {icon icon="fa-info-circle"}{/icon}
-  {ts}WARNING: Deleting this option will result in the loss of mail settings data.{/ts} {ts}Do you want to continue?{/ts}
-  </div>
+      {ts}WARNING: Deleting this option will result in the loss of mail settings data.{/ts} {ts}Do you want to continue?{/ts}
+    </div>
     <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div>
-{else}
+  {else}
     <table class="form-layout-compressed">
 
-  <tr class="crm-mail-settings-form-block-name"><td class="label">{$form.name.label}</td><td>{$form.name.html}</td></tr>
-  <tr><td class="label">&nbsp;</td><td class="description">{ts}Name of this group of settings.{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-name"><td class="label">{$form.name.label}</td><td>{$form.name.html}</td></tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}Name of this group of settings.{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-server"><td class="label">{$form.server.label}</td><td>{$form.server.html}</td></tr>
-  <tr><td class="label">&nbsp;</td><td class="description">{ts}Name or IP address of mail server machine.{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-server"><td class="label">{$form.server.label}</td><td>{$form.server.html}</td></tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}Name or IP address of mail server machine.{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-username"><td class="label">{$form.username.label}</td><td>{$form.username.html}</td></tr>
-  <tr><td class="label">&nbsp;</td><td class="description">{ts}Username to use when polling (for IMAP and POP3).{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-username"><td class="label">{$form.username.label}</td><td>{$form.username.html}</td></tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}Username to use when polling (for IMAP and POP3).{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-password"><td class="label">{$form.password.label}</td><td>{$form.password.html}</td></tr>
-  <tr><td class="label">&nbsp;</td><td class="description">{ts}Password to use when polling (for IMAP and POP3).{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-password"><td class="label">{$form.password.label}</td><td>{$form.password.html}</td></tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}Password to use when polling (for IMAP and POP3).{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-localpart"><td class="label">{$form.localpart.label}</td><td>{$form.localpart.html}</td></tr>
-  <tr><td class="label">&nbsp;</td><td class="description">{ts}Optional local part (e.g., 'civimail+' for addresses like civimail+s.1.2@example.com).{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-localpart"><td class="label">{$form.localpart.label}</td><td>{$form.localpart.html}</td></tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}Optional local part (e.g., 'civimail+' for addresses like civimail+s.1.2@example.com).{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-domain"><td class="label">{$form.domain.label}</td><td>{$form.domain.html}</td></tr>
-  <tr><td class="label">&nbsp;</td><td class="description">{ts}Email address domain (the part after @).{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-domain"><td class="label">{$form.domain.label}</td><td>{$form.domain.html}</td></tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}Email address domain (the part after @).{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-return_path"><td class="label">{$form.return_path.label}</td><td>{$form.return_path.html}</td><tr>
-        <tr><td class="label">&nbsp;</td><td class="description">{ts}Contents of the Return-Path header.{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-return_path"><td class="label">{$form.return_path.label}</td><td>{$form.return_path.html}</td><tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}Contents of the Return-Path header.{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-protocol"><td class="label">{$form.protocol.label}</td><td>{$form.protocol.html}</td></tr>
-  <tr><td class="label">&nbsp;</td><td class="description">{ts}Name of the protocol to use for polling.{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-protocol"><td class="label">{$form.protocol.label}</td><td>{$form.protocol.html}</td></tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}Name of the protocol to use for polling.{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-source"><td class="label">{$form.source.label}</td><td>{$form.source.html}</td></tr>
-  <tr><td class="label">&nbsp;</td><td class="description">{ts}Folder to poll from when using IMAP (will default to INBOX when empty), path to poll from when using Maildir, etc..{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-source"><td class="label">{$form.source.label}</td><td>{$form.source.html}</td></tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}Folder to poll from when using IMAP (will default to INBOX when empty), path to poll from when using Maildir, etc..{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-is_ssl"><td class="label">{$form.is_ssl.label}</td><td>{$form.is_ssl.html}</td></tr>
-  <tr><td class="label">&nbsp;</td><td class="description">{ts}Whether to use SSL for IMAP and POP3 or not.{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-is_ssl"><td class="label">{$form.is_ssl.label}</td><td>{$form.is_ssl.html}</td></tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}Whether to use SSL for IMAP and POP3 or not.{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-is_default"><td class="label">{$form.is_default.label}</td><td>{$form.is_default.html}</td></tr>
-  <tr><td class="label">&nbsp;</td><td class="description">{ts}How this mail account will be used. Only one box may be used for bounce processing. It will also be used as the envelope email when sending mass mailings.{/ts}</td></tr>
+      <tr class="crm-mail-settings-form-block-is_default"><td class="label">{$form.is_default.label}</td><td>{$form.is_default.html}</td></tr>
+      <tr><td class="label">&nbsp;</td><td class="description">{ts}How this mail account will be used. Only one box may be used for bounce processing. It will also be used as the envelope email when sending mass mailings.{/ts}</td></tr>
 
-  <tr class="crm-mail-settings-form-block-activity_status"><td class="label">{$form.activity_status.label}</td><td>{$form.activity_status.html}</td></tr>
+      <tr class="crm-mail-settings-form-block-is_non_case_email_skipped"><td class="label">&nbsp;</td><td>{$form.is_non_case_email_skipped.html}{$form.is_non_case_email_skipped.label} {help id='is_non_case_email_skipped'}</td></tr>
+
+      <tr class="crm-mail-settings-form-block-is_contact_creation_disabled_if_no_match"><td class="label">&nbsp;</td><td>{$form.is_contact_creation_disabled_if_no_match.html}{$form.is_contact_creation_disabled_if_no_match.label} {help id='is_contact_creation_disabled_if_no_match'}</td></tr>
+
+      <tr class="crm-mail-settings-form-block-activity_status"><td class="label">&nbsp;</td><td>{$form.activity_status.label}<div>{$form.activity_status.html}</div></td></tr>
     </table>
-  <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom"}</div>
-{/if}
+
+    <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom"}</div>
+  {/if}
 </div>
+
 {literal}
 <script type="text/javascript">
   CRM.$(function($) {
     var $form = $('form.{/literal}{$form.formClass}{literal}');
-    function showActivityStatus() {
-      $('.crm-mail-settings-form-block-activity_status', $form).toggle($(this).val() === '0');
+    function showActivityFields() {
+      var fields = [
+        '.crm-mail-settings-form-block-activity_status',
+        '.crm-mail-settings-form-block-is_non_case_email_skipped',
+        '.crm-mail-settings-form-block-is_contact_creation_disabled_if_no_match',
+      ];
+      $(fields.join(', '), $form).toggle($(this).val() === '0');
     }
-    $('select[name=is_default]').each(showActivityStatus).change(showActivityStatus);
+    $('select[name="is_default"]').each(showActivityFields).change(showActivityFields);
   });
 </script>
 {/literal}
diff --git a/templates/CRM/Admin/Page/MailSettings.hlp b/templates/CRM/Admin/Page/MailSettings.hlp
new file mode 100644
index 0000000000000000000000000000000000000000..fac9cf4bc610f88b4c5db3e081d9164fc92ea245
--- /dev/null
+++ b/templates/CRM/Admin/Page/MailSettings.hlp
@@ -0,0 +1,30 @@
+{*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved.                        |
+ |                                                                    |
+ | This work is published under the GNU AGPLv3 license with some      |
+ | permitted exceptions and without any warranty. For full license    |
+ | and copyright information, see https://civicrm.org/licensing       |
+ +--------------------------------------------------------------------+
+*}
+
+{htxt id="is_non_case_email_skipped-title"}
+  {ts}Skip emails which do not have a Case ID or Case hash{/ts}
+{/htxt}
+
+{htxt id="is_non_case_email_skipped"}
+  <p>{ts}CiviCRM has functionality to file emails which contain the Case ID or Case Hash in the subject line in the format [case #1234] against a case record.{/ts}</p>
+  <p>{ts}Where the Case ID or Case Hash is not included CiviCRM will file the email against the contact record, by matching the email addresses on the email with any email addresses of Contact records in CiviCRM.{/ts}</p>
+  <p>{ts}Enabling this option will have CiviCRM skip any emails that do not have the Case ID or Case Hash so that the system will only process emails that can be placed on case records.{/ts}</p>
+  <p>{ts}Any emails that are not processed will be moved to the ignored folder.{/ts}</p>
+  <p>{ts}If email is skipped, no activities or contacts ("from"/"to"/"cc"/"bcc") will be created.{/ts}</p>
+{/htxt}
+
+{htxt id="is_contact_creation_disabled_if_no_match-title"}
+  {ts}Do not create new contacts when filing emails{/ts}
+{/htxt}
+
+{htxt id="is_contact_creation_disabled_if_no_match"}
+  <p>{ts}If this option is enabled, CiviCRM will not create new contacts ("from"/"to"/"cc"/"bcc") when filing emails.{/ts}</p>
+  <p>{ts}If the email subject contains a valid Case ID or Case hash, the email will be filed against the case.{/ts}</p>
+{/htxt}
diff --git a/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php b/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php
index 13a25d78cc1279f28b103354d6061c1a19c80e86..b675125b75616d2285dd4f4d6250b6e50766d48b 100644
--- a/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php
+++ b/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php
@@ -37,7 +37,19 @@ class CRM_Utils_Mail_EmailProcessorTest extends CiviUnitTestCase {
   public function tearDown() {
     CRM_Utils_File::cleanDir(__DIR__ . '/data/mail');
     parent::tearDown();
-    $this->quickCleanup(['civicrm_group', 'civicrm_group_contact', 'civicrm_mailing', 'civicrm_mailing_job', 'civicrm_mailing_event_bounce', 'civicrm_mailing_event_queue', 'civicrm_mailing_group', 'civicrm_mailing_recipients', 'civicrm_contact', 'civicrm_email']);
+    $this->quickCleanup([
+      'civicrm_group',
+      'civicrm_group_contact',
+      'civicrm_mailing',
+      'civicrm_mailing_job',
+      'civicrm_mailing_event_bounce',
+      'civicrm_mailing_event_queue',
+      'civicrm_mailing_group',
+      'civicrm_mailing_recipients',
+      'civicrm_contact',
+      'civicrm_email',
+      'civicrm_activity',
+    ]);
   }
 
   /**
@@ -139,7 +151,6 @@ class CRM_Utils_Mail_EmailProcessorTest extends CiviUnitTestCase {
   }
 
   /**
-   *
    * Wrapper to check for mailing bounces.
    *
    * Normally we would call $this->callAPISuccessGetCount but there is not one & there is resistance to
@@ -169,4 +180,86 @@ class CRM_Utils_Mail_EmailProcessorTest extends CiviUnitTestCase {
     $this->eventQueue = $this->callAPISuccess('MailingEventQueue', 'get', ['api.MailingEventQueue.create' => ['hash' => 'aaaaaaaaaaaaaaaa']]);
   }
 
+  /**
+   * Set up mail account with 'Skip emails which do not have a Case ID or
+   * Case hash' option enabled.
+   */
+  public function setUpSkipNonCasesEmail() {
+    $this->callAPISuccess('MailSettings', 'get', [
+      'api.MailSettings.create' => [
+        'name' => 'mailbox',
+        'protocol' => 'Localdir',
+        'source' => __DIR__ . '/data/mail',
+        'domain' => 'example.com',
+        'is_default' => '0',
+        'is_non_case_email_skipped' => TRUE,
+      ],
+    ]);
+  }
+
+  /**
+   * Test case email processing when is_non_case_email_skipped is enabled.
+   */
+  public function testInboundProcessingCaseEmail() {
+    $this->setUpSkipNonCasesEmail();
+    $mail = 'test_cases_email.eml';
+
+    copy(__DIR__ . '/data/inbound/' . $mail, __DIR__ . '/data/mail/' . $mail);
+    $this->callAPISuccess('job', 'fetch_activities', []);
+    $result = civicrm_api3('Activity', 'get', [
+      'sequential' => 1,
+      'subject' => ['LIKE' => "%[case #214bf6d]%"],
+    ]);
+    $this->assertNotEmpty($result['values'][0]['id']);
+  }
+
+  /**
+   * Test non case email processing when is_non_case_email_skipped is enabled.
+   */
+  public function testInboundProcessingNonCaseEmail() {
+    $this->setUpSkipNonCasesEmail();
+    $mail = 'test_non_cases_email.eml';
+
+    copy(__DIR__ . '/data/inbound/' . $mail, __DIR__ . '/data/mail/' . $mail);
+    $this->callAPISuccess('job', 'fetch_activities', []);
+    $result = civicrm_api3('Activity', 'get', [
+      'sequential' => 1,
+      'subject' => ['LIKE' => "%Love letter%"],
+    ]);
+    $this->assertEmpty($result['values']);
+  }
+
+  /**
+   * Set up mail account with 'Do not create new contacts when filing emails'
+   * option enabled.
+   */
+  public function setUpDoNotCreateContact() {
+    $this->callAPISuccess('MailSettings', 'get', [
+      'api.MailSettings.create' => [
+        'name' => 'mailbox',
+        'protocol' => 'Localdir',
+        'source' => __DIR__ . '/data/mail',
+        'domain' => 'example.com',
+        'is_default' => '0',
+        'is_contact_creation_disabled_if_no_match' => TRUE,
+      ],
+    ]);
+  }
+
+  /**
+   * Test case email processing when is_non_case_email_skipped is enabled.
+   */
+  public function testInboundProcessingDoNotCreateContact() {
+    $this->setUpDoNotCreateContact();
+    $mail = 'test_non_cases_email.eml';
+
+    copy(__DIR__ . '/data/inbound/' . $mail, __DIR__ . '/data/mail/' . $mail);
+    $this->callAPISuccess('job', 'fetch_activities', []);
+    $result = civicrm_api3('Contact', 'get', [
+      'sequential' => 1,
+      'email' => "from@test.test",
+    ]);
+    $this->assertEmpty($result['values']);
+  }
+
 }
diff --git a/tests/phpunit/CRM/Utils/Mail/data/inbound/test_cases_email.eml b/tests/phpunit/CRM/Utils/Mail/data/inbound/test_cases_email.eml
new file mode 100644
index 0000000000000000000000000000000000000000..6d8cccf7370df9484776b0252e70bd7d09754ed4
--- /dev/null
+++ b/tests/phpunit/CRM/Utils/Mail/data/inbound/test_cases_email.eml
@@ -0,0 +1,15 @@
+Delivered-To: to@test.test
+Received: by 10.2.13.84 with SMTP id 1234567890;
+        Wed, 19 Dec 2018 10:01:11 +0100 (CET)
+Return-Path: <>
+Message-ID: <abc.def.fhi@test.test>
+Date: Wed, 19 Dec 2018 10:01:07 +0100
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+From: from@test.test
+To: to@test.test
+Subject: [case #214bf6d] Magic is here
+
+This test case is full of fun.
diff --git a/tests/phpunit/CRM/Utils/Mail/data/inbound/test_non_cases_email.eml b/tests/phpunit/CRM/Utils/Mail/data/inbound/test_non_cases_email.eml
new file mode 100644
index 0000000000000000000000000000000000000000..f5dad50c55af2797d69c42c3212841747d6d2dba
--- /dev/null
+++ b/tests/phpunit/CRM/Utils/Mail/data/inbound/test_non_cases_email.eml
@@ -0,0 +1,15 @@
+Delivered-To: to@test.test
+Received: by 10.2.13.84 with SMTP id 1234567890;
+        Wed, 19 Dec 2018 10:01:11 +0100 (CET)
+Return-Path: <>
+Message-ID: <abc.def.fhi@test.test>
+Date: Wed, 19 Dec 2018 10:01:07 +0100
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+From: from@test.test
+To: to@test.test
+Subject: Love letter
+
+I love you unit test, because you are not related to cases.
diff --git a/xml/schema/Core/MailSettings.xml b/xml/schema/Core/MailSettings.xml
index 0dea26c13b2a70b69035ba34bba08a2512cf559f..e55f0602c3ccd196da63cc53cb1ff858ff9641ae 100644
--- a/xml/schema/Core/MailSettings.xml
+++ b/xml/schema/Core/MailSettings.xml
@@ -150,4 +150,26 @@
       <type>Select</type>
     </html>
   </field>
+  <field>
+    <name>is_non_case_email_skipped</name>
+    <title>Skip emails which do not have a Case ID or Case hash</title>
+    <type>boolean</type>
+    <default>0</default>
+    <html>
+      <type>CheckBox</type>
+    </html>
+    <comment>Enabling this option will have CiviCRM skip any emails that do not have the Case ID or Case Hash so that the system will only process emails that can be placed on case records. Any emails that are not processed will be moved to the ignored folder.</comment>
+    <add>5.31</add>
+  </field>
+  <field>
+    <name>is_contact_creation_disabled_if_no_match</name>
+    <type>boolean</type>
+    <title>Do not create new contacts when filing emails</title>
+    <default>0</default>
+    <html>
+      <type>CheckBox</type>
+    </html>
+    <description>If this option is enabled, CiviCRM will not create new contacts when filing emails.</description>
+    <add>5.31</add>
+  </field>
 </table>