diff --git a/include/class.draft.php b/include/class.draft.php
index a4942ecb4bc5611fd9fa4572a3c0e1d022f893b0..cc6ad1fef9a2d7291c407ed61149dc690aa1eb4f 100644
--- a/include/class.draft.php
+++ b/include/class.draft.php
@@ -154,7 +154,8 @@ class Draft {
         // Keep client drafts for two weeks (14 days)
         $sql = 'DELETE FROM '.DRAFT_TABLE
             ." WHERE `namespace` LIKE 'ticket.client.%'
-            AND datediff(now(), updated) > 14";
+            AND ((updated IS NULL AND datediff(now(), created) > 14)
+                OR datediff(now(), updated) > 14)";
         return db_query($sql);
     }
 }
diff --git a/include/class.orm.php b/include/class.orm.php
index 0e8b3065429ef53e1a1bceb9d82dc99f6bf60ac4..b403617b2e71a0b5211d0274eb0942c1fc2e948a 100644
--- a/include/class.orm.php
+++ b/include/class.orm.php
@@ -485,7 +485,7 @@ class FlatArrayIterator extends ModelInstanceIterator {
     function fillTo($index) {
         while ($this->resource && $index >= count($this->cache)) {
             if ($row = $this->resource->getRow()) {
-                $this->cache += $row;
+                $this->cache[] = $row;
             } else {
                 $this->resource->close();
                 $this->resource = null;
@@ -988,7 +988,10 @@ class MysqlExecutor {
                 .' '.$this->sql);
         if (count($this->params))
             $this->_bind($this->params);
-        return $this->stmt->execute();
+        if (!$this->stmt->execute()) {
+            throw new OrmException('Unable to execute query: ' . $this->stmt->error);
+        }
+        return true;
     }
 
     function _bind($params) {
@@ -1028,7 +1031,7 @@ class MysqlExecutor {
     function next() {
         $status = $this->stmt->fetch();
         if ($status === false)
-            throw new Exception($this->stmt->error_list . db_error());
+            throw new OrmException($this->stmt->error);
         elseif ($status === null) {
             $this->close();
             return false;
diff --git a/include/class.thread.php b/include/class.thread.php
index decd0db5f8641e6f5e87dfb8f35ed40f5ba9e31f..c69eb28549412bd25454a24f7df97334299331aa 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -1272,6 +1272,11 @@ class ThreadBody /* extends SplString */ {
         if (!in_array($type, static::$types))
             throw new Exception($type.': Unsupported ThreadBody type');
         $this->body = (string) $body;
+        if (strlen($this->body) > 250000) {
+            $max_packet = db_get_variable('max_allowed_packet', 'global');
+            // Truncate just short of the max_allowed_packet
+            $this->body = substr($this->body, $max_packet - 2048) . ' ... (truncated)';
+        }
         $this->type = $type;
         $this->options = array_merge($this->options, $options);
     }
diff --git a/include/class.ticket.php b/include/class.ticket.php
index d46734e7d19de60c56386fb00cf0875a985353d0..c3f49246957ab049d5cc504b7f9e5abb94fb3bd8 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -2181,7 +2181,8 @@ class Ticket {
      *
      *  $autorespond and $alertstaff overrides config settings...
      */
-    function create($vars, &$errors, $origin, $autorespond=true, $alertstaff=true) {
+    static function create($vars, &$errors, $origin, $autorespond=true,
+            $alertstaff=true) {
         global $ost, $cfg, $thisclient, $_FILES;
 
         // Don't enforce form validation for email
@@ -2499,7 +2500,7 @@ class Ticket {
             $collabs = array();
             foreach ($org->allMembers() as $u) {
                 if ($members || ($pris && $u->isPrimaryContact())) {
-                    if ($c = $this->addCollaborator($u, $settings, $errors)) {
+                    if ($c = $ticket->addCollaborator($u, $settings, $errors)) {
                         $collabs[] = (string) $c;
                     }
                 }
@@ -2507,7 +2508,7 @@ class Ticket {
             //TODO: Can collaborators add others?
             if ($collabs) {
                 //TODO: Change EndUser to name of  user.
-                $this->logNote(sprintf('Collaborators for %s organization added',
+                $ticket->logNote(sprintf('Collaborators for %s organization added',
                         $org->getName()),
                     implode("<br>", $collabs), $org->getName(), false);
             }
diff --git a/include/client/open.inc.php b/include/client/open.inc.php
index dc481b3b9ee25b0e61d777308a7b86a2d84384b2..26b6d30edf9ab857dd1fb5b25f63bcfbc5a22c3e 100644
--- a/include/client/open.inc.php
+++ b/include/client/open.inc.php
@@ -52,7 +52,7 @@ if ($info['topicId'] && ($topic=Topic::lookup($info['topicId']))) {
         if (!$thisclient) {
             $uform = UserForm::getUserForm()->getForm($_POST);
             if ($_POST) $uform->isValid();
-            $uform->render(false, 'Your Information');
+            $uform->render(false);
         }
         else { ?>
             <tr><td colspan="2"><hr /></td></tr>
@@ -94,7 +94,13 @@ if ($info['topicId'] && ($topic=Topic::lookup($info['topicId']))) {
 <hr/>
   <p style="text-align:center;">
         <input type="submit" value="Create Ticket">
-        <input type="reset" value="Reset">
-        <input type="button" value="Cancel" onClick='window.location.href="index.php"'>
+        <input type="reset" name="reset" value="Reset">
+        <input type="button" name="cancel" value="Cancel" onclick="javascript:
+            $('.richtext').each(function() {
+                var redactor = $(this).data('redactor');
+                if (redactor && redactor.opts.draftDelete)
+                    redactor.deleteDraft();
+            });
+            window.location.href='index.php';">
   </p>
 </form>
diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php
index dbf2180e3c7494cc9bb38d537cc7fa115e826c35..d14f7e98e393e6ed10d5a03c9ce5523e8fdbe6a8 100644
--- a/include/staff/ticket-open.inc.php
+++ b/include/staff/ticket-open.inc.php
@@ -373,10 +373,17 @@ if ($info['topicId'] && ($topic=Topic::lookup($info['topicId']))) {
         </tr>
     </tbody>
 </table>
-<p style="padding-left:250px;">
+<p style="text-align:center;">
     <input type="submit" name="submit" value="Open">
     <input type="reset"  name="reset"  value="Reset">
-    <input type="button" name="cancel" value="Cancel" onclick='window.location.href="tickets.php"'>
+    <input type="button" name="cancel" value="Cancel" onclick="javascript:
+        $('.richtext').each(function() {
+            var redactor = $(this).data('redactor');
+            if (redactor && redactor.opts.draftDelete)
+                redactor.deleteDraft();
+        });
+        window.location.href='tickets.php';
+    ">
 </p>
 </form>
 <script type="text/javascript">
diff --git a/js/redactor-osticket.js b/js/redactor-osticket.js
index cd306c2421cba8ec05f1721fc993578f8d798d38..afaf21c9ce0fdcf27ce4bc7e61dc0e912114445a 100644
--- a/js/redactor-osticket.js
+++ b/js/redactor-osticket.js
@@ -77,7 +77,8 @@ RedactorPlugins.draft = {
         });
     },
     setupDraftUpdate: function(data) {
-        this.$draft_saved.show().delay(5000).fadeOut();
+        if (this.get())
+            this.$draft_saved.show().delay(5000).fadeOut();
 
         // Slight workaround. Signal the 'keyup' event normally signaled
         // from typing in the <textarea>
@@ -273,13 +274,11 @@ $(function() {
         });
     },
     cleanupRedactorElements = function() {
-        // Drop the added redactor_air bars
-        $('.redactor_air').remove();
-        // Cancel autosave
+        // Tear down redactor editors on this page
         $('.richtext').each(function() {
             var redactor = $(this).data('redactor');
             if (redactor)
-                redactor.opts.autosave = false;
+                redactor.destroy();
         });
     };
     findRichtextBoxes();
@@ -287,3 +286,17 @@ $(function() {
     $(document).on('pjax:success', findRichtextBoxes);
     $(document).on('pjax:start', cleanupRedactorElements);
 });
+
+$(document).ajaxError(function(event, request, settings) {
+    if (settings.url.indexOf('ajax.php/draft') != -1) {
+        $('.richtext').each(function() {
+            var redactor = $(this).data('redactor');
+            if (redactor) {
+                clearInterval(redactor.autosaveInterval);
+            }
+        });
+        $('#overlay').show();
+        alert('Unable to save draft. Refresh the current page to restore and continue your draft.');
+        $('#overlay').hide();
+    }
+});
diff --git a/scp/js/scp.js b/scp/js/scp.js
index d7706021201b7c37c47e20644365300f35d55270..cc9db7daa65f77928b7152e7d4ccd645efb495f5 100644
--- a/scp/js/scp.js
+++ b/scp/js/scp.js
@@ -632,8 +632,7 @@ getConfig = (function() {
 })();
 
 $(document).on('pjax:click', function(options) {
-    if (window.ticket_refresh !== undefined)
-        clearInterval(window.ticket_refresh);
+    clearTimeout(window.ticket_refresh);
     // Release ticket lock (maybe)
     if ($.autoLock !== undefined)
         $.autoLock.releaseLock();
diff --git a/scp/js/ticket.js b/scp/js/ticket.js
index 19dd87940528b8044ba025b862532b1783fe5f57..93604d5923299ab5fe0544578a889dd4739edbf1 100644
--- a/scp/js/ticket.js
+++ b/scp/js/ticket.js
@@ -314,6 +314,11 @@ $.showImagesInline = function(urls, thread_id) {
     });
 };
 
+$.refreshTicketView = function() {
+    if (0 === $('.dialog:visible').length)
+        $.pjax({url: document.location.href, container:'#pjax-container'});
+}
+
 var ticket_onload = function($) {
     $('#response_options form').hide();
     $('#ticket_notes').hide();
diff --git a/scp/tickets.php b/scp/tickets.php
index dcc41fbc2923f7f0ff9a1b5aa260763205d2808c..82f0e569fd6926ba949f1d41aa6458e3c647e170 100644
--- a/scp/tickets.php
+++ b/scp/tickets.php
@@ -583,6 +583,10 @@ if($thisstaff->canCreateTickets()) {
 }
 
 
+$ost->addExtraHeader('<script type="text/javascript" src="js/ticket.js"></script>');
+$ost->addExtraHeader('<meta name="tip-namespace" content="tickets.queue" />',
+    "$('#content').data('tipNamespace', 'tickets.queue');");
+
 $inc = 'tickets.inc.php';
 if($ticket) {
     $ost->setPageTitle('Ticket #'.$ticket->getNumber());
@@ -615,16 +619,15 @@ if($ticket) {
         $nav->setActiveSubMenu(-1);
 
     //set refresh rate if the user has it configured
-    if(!$_POST && !$_REQUEST['a'] && ($min=$thisstaff->getRefreshRate()))
-        $ost->addExtraHeader('',
-            "window.ticket_refresh = setTimeout(function() { $.pjax({url: document.location.href, container:'#pjax-container'});},"
-            .($min*60000).");");
+    if(!$_POST && !$_REQUEST['a'] && ($min=$thisstaff->getRefreshRate())) {
+        $js = "clearTimeout(window.ticket_refresh);
+               window.ticket_refresh = setTimeout($.refreshTicketView,"
+            .($min*60000).");";
+        $ost->addExtraHeader('<script type="text/javascript">'.$js.'</script>',
+            $js);
+    }
 }
 
-$ost->addExtraHeader('<script type="text/javascript" src="js/ticket.js"></script>');
-$ost->addExtraHeader('<meta name="tip-namespace" content="tickets.queue" />',
-    "$('#content').data('tipNamespace', 'tickets.queue');");
-
 require_once(STAFFINC_DIR.'header.inc.php');
 require_once(STAFFINC_DIR.$inc);
 require_once(STAFFINC_DIR.'footer.inc.php');