diff --git a/include/api.tickets.php b/include/api.tickets.php
index 55dc5cf1ea6ceccd93a54fb51e7a5467ff7c6991..7268d0ffabaacedf3707c9a50071a955b17809e0 100644
--- a/include/api.tickets.php
+++ b/include/api.tickets.php
@@ -72,6 +72,15 @@ class TicketApiController extends ApiController {
                     if(!($attachment['data'] = base64_decode($attachment['data'], true)))
                         $attachment['error'] = sprintf('%s: Poorly encoded base64 data', Format::htmlchars($attachment['name']));
                 }
+                if (!$attachment['error']
+                        && ($size = $ost->getConfig()->getMaxFileSize())
+                        && ($fsize = $attachment['size'] ?: strlen($attachment['data']))
+                        && $fsize > $size) {
+                    $attachment['error'] = sprintf('File %s (%s) is too big. Maximum of %s allowed',
+                            Format::htmlchars($attachment['name']),
+                            Format::file_size($fsize),
+                            Format::file_size($size));
+                }
             }
             unset($attachment);
         }
diff --git a/include/class.mailer.php b/include/class.mailer.php
index c80421fcb798e51b2aa7011c902e78f9d6e30615..1c43398bcf4d3af04540fdbe6c01fbc181d2f2e2 100644
--- a/include/class.mailer.php
+++ b/include/class.mailer.php
@@ -206,21 +206,38 @@ class Mailer {
         $body = $mime->get($encodings);
         //encode the headers.
         $headers = $mime->headers($headers, true);
+
+        // Cache smtp connections made during this request
+        static $smtp_connections = array();
         if(($smtp=$this->getSMTPInfo())) { //Send via SMTP
-            $mail = mail::factory('smtp',
-                    array ('host' => $smtp['host'],
-                           'port' => $smtp['port'],
-                           'auth' => $smtp['auth'],
-                           'username' => $smtp['username'],
-                           'password' => $smtp['password'],
-                           'timeout'  => 20,
-                           'debug' => false,
-                           ));
+            $key = sprintf("%s:%s:%s", $smtp['host'], $smtp['port'],
+                $smtp['username']);
+            if (!isset($smtp_connections[$key])) {
+                $mail = mail::factory('smtp', array(
+                    'host' => $smtp['host'],
+                    'port' => $smtp['port'],
+                    'auth' => $smtp['auth'],
+                    'username' => $smtp['username'],
+                    'password' => $smtp['password'],
+                    'timeout'  => 20,
+                    'debug' => false,
+                    'persist' => true,
+                ));
+                if ($mail->connect())
+                    $smtp_connections[$key] = $mail;
+            }
+            else {
+                // Use persistent connection
+                $mail = $smtp_connections[$key];
+            }
 
             $result = $mail->send($to, $headers, $body);
             if(!PEAR::isError($result))
                 return $messageId;
 
+            // Force reconnect on next ->send()
+            unset($smtp_connections[$key]);
+
             $alert=sprintf("Unable to email via SMTP:%s:%d [%s]\n\n%s\n",
                     $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage());
             $this->logError($alert);
diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php
index efddf6404d228d2512985f1d60cc81f6d14e39f9..73ac6184521639c58142324c269127d185b51c0f 100644
--- a/include/class.mailfetch.php
+++ b/include/class.mailfetch.php
@@ -20,6 +20,7 @@ require_once(INCLUDE_DIR.'class.dept.php');
 require_once(INCLUDE_DIR.'class.email.php');
 require_once(INCLUDE_DIR.'class.filter.php');
 require_once(INCLUDE_DIR.'html2text.php');
+require_once(INCLUDE_DIR.'tnef_decoder.php');
 
 class MailFetcher {
 
@@ -30,6 +31,8 @@ class MailFetcher {
 
     var $charset = 'UTF-8';
 
+    var $tnef = false;
+
     function MailFetcher($email, $charset='UTF-8') {
 
 
@@ -377,6 +380,10 @@ class MailFetcher {
             }
         }
 
+        if ($this->tnef && !strcasecmp($mimeType, 'text/html')
+                && ($content = $this->tnef->getBody('text/html', $encoding)))
+            return $content;
+
         //Do recursive search
         $text='';
         if($struct && $struct->parts && $recurse) {
@@ -512,6 +519,10 @@ class MailFetcher {
     }
 
     function getPriority($mid) {
+        if ($this->tnef && isset($this->tnef->Importance))
+            // PidTagImportance is 0, 1, or 2
+            // http://msdn.microsoft.com/en-us/library/ee237166(v=exchg.80).aspx
+            return $this->tnef->Importance + 1;
         return Mail_Parse::parsePriority($this->getHeader($mid));
     }
 
@@ -570,6 +581,23 @@ class MailFetcher {
 	        return true; //Report success (moved or delete)
         }
 
+        // Parse MS TNEF emails
+        if (($struct = imap_fetchstructure($this->mbox, $mid))
+                && ($attachments = $this->getAttachments($struct))) {
+            foreach ($attachments as $i=>$info) {
+                if (0 === strcasecmp('application/ms-tnef', $info['type'])) {
+                    $data = $this->decode(imap_fetchbody($self->mbox,
+                        $mid, $info['index']), $info['encoding']);
+                    $tnef = new TnefStreamParser($data);
+                    $this->tnef = $tnef->getMessage();
+                    // No longer considered an attachment
+                    unset($attachments[$i]);
+                    // There should only be one of these
+                    break;
+                }
+            }
+        }
+
         $vars = $mailinfo;
         $vars['name'] = $mailinfo['name'];
         $vars['subject'] = $mailinfo['subject'] ? $mailinfo['subject'] : '[No Subject]';
@@ -604,10 +632,18 @@ class MailFetcher {
         $seen = false;
 
         // Fetch attachments if any.
-        if($ost->getConfig()->allowEmailAttachments()
-                && ($struct = imap_fetchstructure($this->mbox, $mid))
-                && ($attachments=$this->getAttachments($struct))) {
-
+        if($ost->getConfig()->allowEmailAttachments()) {
+            // Include TNEF attachments in the attachments list
+            if ($this->tnef) {
+                foreach ($this->tnef->attachments as $at) {
+                    $attachments[] = array(
+                        'cid' => @$at->AttachContentId ?: false,
+                        'data' => $at->Data,
+                        'type' => @$at->AttachMimeTag ?: false,
+                        'name' => $at->getName(),
+                    );
+                }
+            }
             $vars['attachments'] = array();
             foreach($attachments as $a ) {
                 $file = array('name' => $a['name'], 'type' => $a['type']);
diff --git a/include/class.mailparse.php b/include/class.mailparse.php
index 7cbb910c6c462ffa12708433e0ede6aa79bd9d96..6883cdaf6a7560437c4ee0fcc5a00886bf111004 100644
--- a/include/class.mailparse.php
+++ b/include/class.mailparse.php
@@ -400,7 +400,6 @@ class Mail_Parse {
                     'data' => $at->Data,
                     'type' => @$at->AttachMimeTag ?: false,
                     'name' => $at->getName(),
-                    'encoding' => @$at->AttachEncoding ?: false,
                 );
             }
             return $files;
diff --git a/include/class.ostsession.php b/include/class.ostsession.php
index db51e89e771caaaff6fe9bdb1d3e2808b96e548c..beb344f9f3734f5e286e9d2e4aff0060d6406cb2 100644
--- a/include/class.ostsession.php
+++ b/include/class.ostsession.php
@@ -26,8 +26,12 @@ class osTicketSession {
         if(!$this->ttl)
             $this->ttl=SESSION_TTL;
 
+        // Set osTicket specific session name.
         session_name('OSTSESSID');
 
+        // Forced cleanup on shutdown
+        register_shutdown_function('session_write_close');
+
         if (OsticketConfig::getDBVersion())
             return session_start();
 
@@ -56,8 +60,6 @@ class osTicketSession {
             array(&$this, 'destroy'),
             array(&$this, 'gc')
         );
-        //Forced cleanup.
-        register_shutdown_function('session_write_close');
 
         //Start the session.
         session_start();
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 855d4650431164713b28c85ee2390e4482c7f258..df83644a8da74e58bda87435ab10701eb9adf1a2 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -2234,6 +2234,10 @@ class Ticket {
         # function
         if (isset($vars['autorespond'])) $autorespond=$vars['autorespond'];
 
+        # Apply filter-specific priority
+        if ($vars['priorityId'])
+            $form->setAnswer('priority', null, $vars['priorityId']);
+
         // OK...just do it.
         $deptId=$vars['deptId']; //pre-selected Dept if any.
         $source=ucfirst($vars['source']);
diff --git a/include/tnef_decoder.php b/include/tnef_decoder.php
index f0eba4e792914621fefbbbdf4f2f1cd5f9c94e76..18e95d697c5eba8bb218ff81d5e9c903b2cedbd7 100644
--- a/include/tnef_decoder.php
+++ b/include/tnef_decoder.php
@@ -110,10 +110,13 @@ class TnefStreamReader implements Iterator {
     }
 
     function check($block) {
-        $sum = 0;
-        for ($i=0, $k=strlen($block['data']); $i < $k; $i++)
-            $sum += ord($block['data'][$i]);
-        if ($block['checksum'] != ($sum % 65536))
+        $sum = 0; $bytes = strlen($block['data']); $bs = 1024;
+        for ($i=0; $i < $bytes; $i+=$bs) {
+            $b = unpack('C*', substr($block['data'], $i, min($bs, $bytes-$i)));
+            $sum += array_sum($b);
+            $sum = $sum % 65536;
+        }
+        if ($block['checksum'] != $sum)
             throw new TnefException('Corrupted block. Invalid checksum');
     }