diff --git a/include/class.ticket.php b/include/class.ticket.php
index dc6f5fe311c7b65be9b4231649a7cbd553447554..07c8bfebdf10e7a520974ab0732204a9040f7701 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -526,6 +526,23 @@ class Ticket {
         return $this->ht['status_id'];
     }
 
+    /**
+     * setStatusId
+     *
+     * Forceably set the ticket status ID to the received status ID. No
+     * checks are made. Use ::setStatus() to change the ticket status
+     */
+    // XXX: Use ::setStatus to change the status. This can be used as a
+    //      fallback if the logic in ::setStatus fails.
+    function setStatusId($id) {
+        $sql = 'UPDATE '.TICKET_TABLE.' SET updated=NOW() '.
+               ' ,status_id='.db_input($status->getId()) .
+               ' WHERE ticket_id='.db_input($this->getId());
+
+        if (!db_query($sql) || !db_affected_rows())
+            return false;
+    }
+
     function getStatus() {
 
         if (!$this->status && $this->getStatusId())
@@ -1076,7 +1093,7 @@ class Ticket {
     function setStatus($status, $comments='', &$errors=array(), $set_closing_agent=true) {
         global $thisstaff;
 
-        if (!$thisstaff || !($role=$thisstaff->getRole($this->getDeptId())))
+        if ($thisstaff && !($role=$thisstaff->getRole($this->getDeptId())))
             return false;
 
         if ($status && is_numeric($status))
@@ -1085,19 +1102,21 @@ class Ticket {
         if (!$status || !$status instanceof TicketStatus)
             return false;
 
-        // Double check permissions
-        switch ($status->getState()) {
-        case 'closed':
-            if (!($role->hasPerm(TicketModel::PERM_CLOSE)))
+        // Double check permissions (when changing status)
+        if ($role && $this->getStatusId()) {
+            switch ($status->getState()) {
+            case 'closed':
+                if (!($role->hasPerm(TicketModel::PERM_CLOSE)))
+                    return false;
+                break;
+            case 'deleted':
+                // XXX: intercept deleted status and do hard delete
+                if ($role->hasPerm(TicketModel::PERM_DELETE))
+                    return $this->delete($comments);
+                // Agent doesn't have permission to delete  tickets
                 return false;
-            break;
-        case 'deleted':
-            // XXX: intercept deleted status and do hard delete
-            if ($role->hasPerm(TicketModel::PERM_DELETE))
-                return $this->delete($comments);
-            // Agent doesn't have permission to delete  tickets
-            return false;
-            break;
+                break;
+            }
         }
 
         if ($this->getStatusId() == $status->getId())
@@ -1244,10 +1263,14 @@ class Ticket {
                 return false;  //bail out...missing stuff.
         }
 
-        $options = array(
-            'inreplyto'=>$message->getEmailMessageId(),
-            'references'=>$message->getEmailReferences(),
-            'thread'=>$message);
+        $options = array();
+        if ($message instanceof ThreadEntry) {
+            $options += array(
+                'inreplyto'=>$message->getEmailMessageId(),
+                'references'=>$message->getEmailReferences(),
+                'thread'=>$message
+            );
+        }
 
         //Send auto response - if enabled.
         if($autorespond
@@ -1275,7 +1298,7 @@ class Ticket {
 
             $recipients=$sentlist=array();
             //Exclude the auto responding email just incase it's from staff member.
-            if ($message->isAutoReply())
+            if ($message instanceof ThreadEntry && $message->isAutoReply())
                 $sentlist[] = $this->getEmail();
 
             //Alert admin??
@@ -2019,7 +2042,7 @@ class Ticket {
         return $message;
     }
 
-    function postCannedReply($canned, $msgId, $alert=true) {
+    function postCannedReply($canned, $message, $alert=true) {
         global $ost, $cfg;
 
         if((!is_object($canned) && !($canned=Canned::lookup($canned))) || !$canned->isEnabled())
@@ -2036,7 +2059,7 @@ class Ticket {
             $response = new TextThreadEntryBody(
                     $this->replaceVars($canned->getPlainText()));
 
-        $info = array('msgId' => $msgId,
+        $info = array('msgId' => $message instanceof ThreadEntry ? $message->getId() : 0,
                       'poster' => __('SYSTEM (Canned Reply)'),
                       'response' => $response,
                       'cannedattachments' => $files);
@@ -2715,15 +2738,11 @@ class Ticket {
             }
         }
 
-        if (!$form->isValid($field_filter('ticket')))
-            $errors += $form->errors();
-
         if ($vars['uid'])
             $user = User::lookup($vars['uid']);
 
         $id=0;
         $fields=array();
-        $fields['message']  = array('type'=>'*',     'required'=>1, 'error'=>__('Message content is required'));
         switch (strtolower($origin)) {
             case 'web':
                 $fields['topicId']  = array('type'=>'int',  'required'=>1, 'error'=>__('Select a help topic'));
@@ -2756,11 +2775,11 @@ class Ticket {
                 $errors['duedate']=__('Due date must be in the future');
         }
 
+        $topic_forms = array();
         if (!$errors) {
 
             // Handle the forms associate with the help topics. Instanciate the
             // entries, disable and track the requested disabled fields.
-            $topic_forms = array();
             if ($vars['topicId']) {
                 if ($__topic=Topic::lookup($vars['topicId'])) {
                     foreach ($__topic->getForms() as $idx=>$__F) {
@@ -2846,6 +2865,9 @@ class Ticket {
             }
         }
 
+        if (!$form->isValid($field_filter('ticket')))
+            $errors += $form->errors();
+
         if ($vars['topicId']) {
             if ($topic=Topic::lookup($vars['topicId'])) {
                 foreach ($topic_forms as $topic_form) {
@@ -3053,8 +3075,12 @@ class Ticket {
         // Apply requested status — this should be done AFTER assignment,
         // because if it is requested to be closed, it should not cause the
         // ticket to be reopened for assignment.
-        if ($statusId)
-            $ticket->setStatus($statusId, false, $errors, false);
+        if ($statusId) {
+            if (!$ticket->setStatus($statusId, false, $errors, false)) {
+                // Tickets _must_ have a status. Forceably set one here
+                $ticket->setStatusId($cfg->getDefaultTicketStatusId());
+            }
+        }
 
         /**********   double check auto-response  ************/
         //Override auto responder if the FROM email is one of the internal emails...loop control.
@@ -3065,12 +3091,12 @@ class Ticket {
         # not have a return 'ping' message
         if (isset($vars['flags']) && $vars['flags']['bounce'])
             $autorespond = false;
-        if ($autorespond && $message->isAutoReply())
+        if ($autorespond && $message instanceof ThreadEntry && $message->isAutoReply())
             $autorespond = false;
 
         //post canned auto-response IF any (disables new ticket auto-response).
         if ($vars['cannedResponseId']
-            && $ticket->postCannedReply($vars['cannedResponseId'], $message->getId(), $autorespond)) {
+            && $ticket->postCannedReply($vars['cannedResponseId'], $message, $autorespond)) {
                 $ticket->markUnAnswered(); //Leave the ticket as unanswred.
                 $autorespond = false;
         }
@@ -3082,7 +3108,7 @@ class Ticket {
 
         //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())
+        if ($alertstaff && $message instanceof ThreadEntry && $message->isBounce())
             $alertstaff = false;
 
         /***** See if we need to send some alerts ****/
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index de9ccf80153ce21876688d343459a1cb08dc6b17..5bda5f6374998dd31bf662c8fe8a37b3e8375eb1 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -466,7 +466,7 @@ $tcount+= $ticket->getNumNotes();
             $msgId = $entry['id'];
        }
     } else {
-        echo '<p>'.__('Error fetching ticket thread - get technical help.').'</p>';
+        echo '<p><em>'.__('No entries have been posted to this ticket.').'</em></p>';
     }?>
 <div class="clear" style="padding-bottom:10px;"></div>
 <?php if($errors['err']) { ?>
diff --git a/scp/css/scp.css b/scp/css/scp.css
index d958edda6e4b31ffbe376d141fc68788e7c8d60e..01dc05cf9506c278ec4b73b0bd552147e6172e01 100644
--- a/scp/css/scp.css
+++ b/scp/css/scp.css
@@ -2133,3 +2133,7 @@ td.indented {
    position: relative;
    top: -1px;
 }
+
+#topic-forms tbody + tbody td.handle {
+  padding-top: 15px;
+}