diff --git a/include/class.filter.php b/include/class.filter.php
index 8854ea89e03095d003f2cb3bea407c8b5e062a91..993b7971213aaaa509b577e7b49633e9aba1e20e 100644
--- a/include/class.filter.php
+++ b/include/class.filter.php
@@ -832,19 +832,22 @@ class TicketFilter {
      *    http://msdn.microsoft.com/en-us/library/ee219609(v=exchg.80).aspx
      */
     /* static */
-    function isAutoResponse($headers) {
+    function isAutoReply($headers) {
 
         if($headers && !is_array($headers))
             $headers = Mail_Parse::splitHeaders($headers);
 
         $auto_headers = array(
-            'Auto-Submitted'    => 'AUTO-REPLIED',
+            'Auto-Submitted'    => array('AUTO-REPLIED', 'AUTO-GENERATED'),
             'Precedence'        => array('AUTO_REPLY', 'BULK', 'JUNK', 'LIST'),
-            'Subject'           => array('OUT OF OFFICE', 'AUTO-REPLY:', 'AUTORESPONSE'),
+            'X-Precedence'      => array('AUTO_REPLY', 'BULK', 'JUNK', 'LIST'),
             'X-Autoreply'       => 'YES',
             'X-Auto-Response-Suppress' => array('ALL', 'DR', 'RN', 'NRN', 'OOF', 'AutoReply'),
-            'X-Autoresponse'    => '',
-            'X-Auto-Reply-From' => ''
+            'X-Autoresponse'    => '*',
+            'X-AutoReply-From'  => '*',
+            'X-Autorespond'     => '*',
+            'X-Mail-Autoreply'  => '*',
+            'X-Autogenerated'   => 'REPLY',
         );
 
         foreach ($auto_headers as $header=>$find) {
@@ -860,39 +863,44 @@ class TicketFilter {
                 foreach ($find as $f)
                     if (strpos($value, $f) === 0)
                         return true;
+            } elseif ($find === '*') {
+                return true;
             } elseif (strpos($value, $find) === 0) {
                 return true;
             }
         }
 
-        # Bounces also counts as auto-responses.
-        if(self::isAutoBounce($headers))
-            return true;
-
         return false;
     }
 
-    function isAutoBounce($headers) {
+    static function isBounce($headers) {
 
         if($headers && !is_array($headers))
             $headers = Mail_Parse::splitHeaders($headers);
 
         $bounce_headers = array(
-            'From'          => array('<MAILER-DAEMON@MAILER-DAEMON>', 'MAILER-DAEMON', '<>'),
-            'Subject'       => array('DELIVERY FAILURE', 'DELIVERY STATUS', 'UNDELIVERABLE:'),
+            'From'  => array('stripos',
+                        array('MAILER-DAEMON', '<>'), null, false),
+            'Subject'   => array('stripos',
+                array('DELIVERY FAILURE', 'DELIVERY STATUS',
+                    'UNDELIVERABLE:', 'Undelivered Mail Returned'), 0),
+            'Return-Path'   => array('strcmp', array('<>'), 0),
+            'Content-Type'  => array('stripos', array('report-type=delivery-status'), null, false),
+            'X-Failed-Recipients' => array('strpos', array('@'), null, false)
         );
 
         foreach ($bounce_headers as $header => $find) {
             if(!isset($headers[$header])) continue;
 
-            $value = strtoupper($headers[$header]);
+            @list($func, $searches, $pos, $neg) = $find;
 
-            if (is_array($find)) {
-                foreach ($find as $f)
-                    if (strpos($value, $f) === 0)
-                        return true;
-            } elseif (strpos($value, $find) === 0) {
-                return true;
+            if(!($value = $headers[$header]) || !is_array($searches))
+                continue;
+
+            foreach ($searches as $f) {
+                $result = call_user_func($func, $value, $f);
+                if (($pos === null && $result !== $neg) or ($result === $pos))
+                    return true;
             }
         }
 
diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php
index 882cd91a9d1f7cdbdaa0d0795739ed7a3b825e57..f1ce7fdc75bf590efa9c46eaff30045e78e6795a 100644
--- a/include/class.mailfetch.php
+++ b/include/class.mailfetch.php
@@ -641,12 +641,6 @@ class MailFetcher {
                 return true;
             }
 
-            # check if it's a bounce!
-            if($vars['header'] && TicketFilter::isAutoBounce($vars['header'])) {
-                $ost->logWarning('Bounced email', $vars['message'], false);
-                return true;
-            }
-
             //TODO: Log error..
             return null;
         }
diff --git a/include/class.mailparse.php b/include/class.mailparse.php
index cd66f4e69262442eff83ccf9391051a89acf2d81..eacd62d2a24b44db7a6f66c38411ca9bf5a885f5 100644
--- a/include/class.mailparse.php
+++ b/include/class.mailparse.php
@@ -107,7 +107,7 @@ class Mail_Parse {
         foreach ($headers as $hdr) {
             list($name, $val) = explode(": ", $hdr, 2);
             # Create list of values if header is specified more than once
-            if ($array[$name] && $as_array) {
+            if (isset($array[$name]) && $as_array) {
                 if (is_array($array[$name])) $array[$name][] = $val;
                 else $array[$name] = array($array[$name], $val);
             } else {
diff --git a/include/class.thread.php b/include/class.thread.php
index a05dcedb9446ab36f8241e9e61d846e802f5c467..b0748f69e7522f3ac4113591efab38e0bbea56a9 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -415,8 +415,26 @@ Class ThreadEntry {
         return $this->ht['headers'];
     }
 
-    function isAutoResponse() {
-        return $this->getEmailHeader()?TicketFilter::isAutoResponse($this->getEmailHeader()):false;
+    function isAutoReply() {
+
+        if (!isset($this->is_autoreply))
+            $this->is_autoreply = $this->getEmailHeader()
+                ?  TicketFilter::isAutoReply($this->getEmailHeader()) : false;
+
+        return $this->is_autoreply;
+    }
+
+    function isBounce() {
+
+        if (!isset($this->is_bounce))
+            $this->is_bounce = $this->getEmailHeader()
+                ? TicketFilter::isBounce($this->getEmailHeader()) : false;
+
+        return $this->is_bounce;
+    }
+
+    function isBounceOrAutoReply() {
+        return ($this->isAutoReply() || $this->isBounce());
     }
 
     //Web uploads - caller is expected to format, validate and set any errors.
diff --git a/include/class.ticket.php b/include/class.ticket.php
index e8235b49ea6312d0e7cc7bc2263a0c8e4fa8b1d1..7bfcdc7a662c7227878da332c9c6659e1122403a 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -904,6 +904,10 @@ class Ticket {
             $msg = $this->replaceVars($msg->asArray(), array('message' => $message));
 
             $recipients=$sentlist=array();
+            //Exclude the auto responding email just incase it's from staff member.
+            if ($message->isAutoReply())
+                $sentlist[] = $this->getEmail();
+
             //Alert admin??
             if($cfg->alertAdminONNewTicket()) {
                 $alert = $this->replaceVars($msg, array('recipient' => 'Admin'));
@@ -1543,7 +1547,7 @@ class Ticket {
         if(!$alerts) return $message; //Our work is done...
 
         $autorespond = true;
-        if ($autorespond && $message->isAutoResponse())
+        if ($autorespond && $message->isBounceOrAutoReply())
             $autorespond=false;
 
         $this->onMessage($message, $autorespond); //must be called b4 sending alerts to staff.
@@ -2314,15 +2318,8 @@ class Ticket {
 
         # Messages that are clearly auto-responses from email systems should
         # not have a return 'ping' message
-        if ($autorespond && $message && $message->isAutoResponse())
-            $autorespond=false;
-
-        //Don't auto respond to mailer daemons.
-        if( $autorespond &&
-            (strpos(strtolower($vars['email']),'mailer-daemon@')!==false
-             || strpos(strtolower($vars['email']),'postmaster@')!==false)) {
-            $autorespond=false;
-        }
+        if ($autorespond && $message->isAutoReply())
+            $autorespond = false;
 
         //post canned auto-response IF any (disables new ticket auto-response).
         if ($vars['cannedResponseId']
@@ -2336,6 +2333,11 @@ class Ticket {
         if($autorespond && $dept && !$dept->autoRespONNewTicket())
             $autorespond=false;
 
+        //Don't send alerts to staff when the message is a bounce
+        //  this is necessary to avoid possible loop (especially on new ticket)
+        if ($alertstaff && $message->isBounce())
+            $alertstaff = false;
+
         /***** See if we need to send some alerts ****/
         $ticket->onNewTicket($message, $autorespond, $alertstaff);
 
diff --git a/include/mysqli.php b/include/mysqli.php
index 3b535919e88f18fec8465067c7f7b55d7b4e54f2..d8ce115ccfc454369f8a8a89094dd5ce124c1016 100644
--- a/include/mysqli.php
+++ b/include/mysqli.php
@@ -125,7 +125,13 @@ function db_create_database($database, $charset='utf8',
 function db_query($query, $logError=true) {
     global $ost, $__db;
 
-    $res = $__db->query($query);
+    $tries = 3;
+    do {
+        $res = $__db->query($query);
+        // Retry the query due to deadlock error (#1213)
+        // TODO: Consider retry on #1205 (lock wait timeout exceeded)
+        // TODO: Log warning
+    } while (!$res && --$tries && $__db->errno == 1213);
 
     if(!$res && $logError && $ost) { //error reporting
         $msg='['.$query.']'."\n\n".db_error();