diff --git a/include/ajax.forms.php b/include/ajax.forms.php
index 1d4dc14236ad922978c8cefd7e8020bc1a6d14da..f99870a9770d436cc36c028c068a5d25ba9061d9 100644
--- a/include/ajax.forms.php
+++ b/include/ajax.forms.php
@@ -358,7 +358,7 @@ class DynamicFormsAjaxAPI extends AjaxController {
     function attach() {
         $field = new FileUploadField();
         return JsonDataEncoder::encode(
-            array('id'=>$field->ajaxUpload(true))
+            array('id'=>$field->ajaxUpload())
         );
     }
 
diff --git a/include/ajax.orgs.php b/include/ajax.orgs.php
index f7be2b2d130e5672e71a88669b102cb2b96f74ee..1a1c8d19ca060a22e139135cae4d5af4965510f4 100644
--- a/include/ajax.orgs.php
+++ b/include/ajax.orgs.php
@@ -24,7 +24,10 @@ class OrgsAjaxAPI extends AjaxController {
 
         if(!isset($_REQUEST['q'])) {
             Http::response(400, 'Query argument is required');
-        }
+        } 
+        
+        if (!$_REQUEST['q'])
+            return $this->json_encode(array());
 
         $q = $_REQUEST['q'];
         $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit']:25;
diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index 6acae0719f35404ed9b43e871a238b53d92c6a22..c20abba7ec0120fbaceffca81f762c5e5eb0c650 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -26,14 +26,17 @@ class TicketsAjaxAPI extends AjaxController {
     function lookup() {
         global $thisstaff;
 
-
         $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit']:25;
         $tickets=array();
+        // Bail out of query is empty
+        if (!$_REQUEST['q'])
+            return $this->json_encode($tickets);
 
         $visibility = Q::any(array(
             'staff_id' => $thisstaff->getId(),
             'team_id__in' => $thisstaff->teams->values_flat('team_id'),
         ));
+
         if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts())) {
             $visibility->add(array('dept_id__in' => $depts));
         }
diff --git a/include/ajax.users.php b/include/ajax.users.php
index 22257675d152e6eed6e4916f5de17b0f7f5acb05..f8b9b78b4ea8a8d7dfc3c3d0a3c67352067e214b 100644
--- a/include/ajax.users.php
+++ b/include/ajax.users.php
@@ -29,6 +29,10 @@ class UsersAjaxAPI extends AjaxController {
             Http::response(400, __('Query argument is required'));
         }
 
+        $matches = array();
+        if (!$_REQUEST['q'])
+            return $this->json_encode($matches);
+
         $q = $_REQUEST['q'];
         $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit']:25;
         $users=array();
diff --git a/include/class.auth.php b/include/class.auth.php
index 9619a389f0af1b32cca214132205155d915f8d6f..a106d6a4c9fa89dce87115dfa7c460b4f19a0903 100644
--- a/include/class.auth.php
+++ b/include/class.auth.php
@@ -1006,8 +1006,9 @@ class PasswordResetTokenBackend extends StaffAuthenticationBackend {
             return false;
         elseif (!($_config = new Config('pwreset')))
             return false;
-        elseif (($staff = StaffSession::lookup($_POST['userid'])) &&
-                !$staff->getId())
+
+        $staff = StaffSession::lookup($_POST['userid']);
+        if (!$staff || !$staff->getId())
             $errors['msg'] = __('Invalid user-id given');
         elseif (!($id = $_config->get($_POST['token']))
                 || $id != $staff->getId())
diff --git a/include/class.client.php b/include/class.client.php
index 932a5bde686bea6071c23d413368c39dc1fde5b7..9a624e13c545934b7bd864551152ec05b5525c8e 100644
--- a/include/class.client.php
+++ b/include/class.client.php
@@ -53,6 +53,8 @@ implements EmailContact, ITicketUser, TemplateVariable {
     }
 
     function getVar($tag) {
+        global $cfg;
+
         switch (strtolower($tag)) {
         case 'ticket_link':
             $qstr = array();
diff --git a/include/class.config.php b/include/class.config.php
index 8b7dde5d8542e1e59f35bffd6a7c8021041579cc..61b5012dfb1b6309fec706a0f457a917e6297185 100644
--- a/include/class.config.php
+++ b/include/class.config.php
@@ -150,8 +150,19 @@ extends VerySimpleModel {
     );
 
     static function items($namespace, $column='namespace') {
-        return static::objects()
+
+        $items = static::objects()
             ->filter([$column => $namespace]);
+
+        try {
+            count($items);
+        }
+        catch (InconsistentModelException $ex) {
+            // Pending upgrade ??
+            $items = array();
+        }
+
+        return $items;
     }
 
     function save($refetch=false) {
diff --git a/include/class.export.php b/include/class.export.php
index bcf509299946398a188bbcafa9a1552eca7ef883..72b66967adde73f9d2e912017292d0b85dd6d151 100644
--- a/include/class.export.php
+++ b/include/class.export.php
@@ -59,7 +59,7 @@ class Export {
         // Reset the $sql query
         $tickets = $sql->models()
             ->select_related('user', 'user__default_email', 'dept', 'staff',
-                'team', 'staff', 'cdata', 'topic', 'status', 'cdata.priority')
+                'team', 'staff', 'cdata', 'topic', 'status', 'cdata__:priority')
             ->annotate(array(
                 'collab_count' => TicketThread::objects()
                     ->filter(array('ticket__ticket_id' => new SqlField('ticket_id', 1)))
@@ -81,7 +81,7 @@ class Export {
                 'cdata.subject' =>  __('Subject'),
                 'user.name' =>      __('From'),
                 'user.default_email.address' => __('From Email'),
-                'cdata.priority.priority_desc' => __('Priority'),
+                'cdata.:priority.priority_desc' => __('Priority'),
                 'dept::getLocalName' => __('Department'),
                 'topic::getName' => __('Help Topic'),
                 'source' =>         __('Source'),
diff --git a/include/class.filter_action.php b/include/class.filter_action.php
index 98d71d85ec55fc407dd3db3dd208c00eacc1d27a..6c687cc6faee238d1adb0f007560eb6941404d12 100644
--- a/include/class.filter_action.php
+++ b/include/class.filter_action.php
@@ -541,12 +541,14 @@ class FA_SendEmail extends TriggerAction {
                 }
             )),
             'subject' => new TextboxField(array(
+                'required' => true,
                 'configuration' => array(
                     'size' => 80,
                     'placeholder' => __('Subject')
                 ),
             )),
             'message' => new TextareaField(array(
+                'required' => true,
                 'configuration' => array(
                     'placeholder' => __('Message'),
                     'html' => true,
diff --git a/include/class.format.php b/include/class.format.php
index 70b06a8a37c09f05f0e27017f9d520c08f99cd29..dda04156936c4046bc1d677470257cb46062f2ea 100644
--- a/include/class.format.php
+++ b/include/class.format.php
@@ -194,6 +194,9 @@ class Format {
 
     function html2text($html, $width=74, $tidy=true) {
 
+        if (!$html)
+            return $html;
+
 
         # Tidy html: decode, balance, sanitize tags
         if($tidy)
@@ -201,8 +204,9 @@ class Format {
 
         # See if advanced html2text is available (requires xml extension)
         if (function_exists('convert_html_to_text')
-                && extension_loaded('dom'))
-            return convert_html_to_text($html, $width);
+                && extension_loaded('dom')
+                && ($text = convert_html_to_text($html, $width)))
+                return $text;
 
         # Try simple html2text  - insert line breaks after new line tags.
         $html = preg_replace(
@@ -518,7 +522,9 @@ class Format {
 
         $format = self::getStrftimeFormat($format);
         // Properly convert to user local time
-        $time = DateTime::createFromFormat('U', $timestamp, new DateTimeZone('UTC'));
+        if (!($time = DateTime::createFromFormat('U', $timestamp, new DateTimeZone('UTC'))))
+           return '';
+
         $offset = $user_timezone->getOffset($time);
         $timestamp = $time->getTimestamp() + $offset;
         return strftime($format ?: $strftimeFallback, $timestamp);
diff --git a/include/class.i18n.php b/include/class.i18n.php
index 9163f6cf0d4bfdd4c687f3d54f9faa015b5d0087..c290821194ddacee624ef6a4400da4f170db2857 100644
--- a/include/class.i18n.php
+++ b/include/class.i18n.php
@@ -260,6 +260,7 @@ class Internationalization {
             return self::availableLanguages();
 
         if (!isset($langs)) {
+            $langs = array();
             $pri = $cfg->getPrimaryLanguage();
             if ($info = self::getLanguageInfo($pri))
                 $langs = array($pri => $info);
diff --git a/include/class.orm.php b/include/class.orm.php
index 1638d8b97de68423fd079d3ee8733705e3582aa0..f816265e326e1014eac1ec9407713784d7534577 100644
--- a/include/class.orm.php
+++ b/include/class.orm.php
@@ -1029,7 +1029,7 @@ class QuerySet implements IteratorAggregate, ArrayAccess, Serializable, Countabl
     }
 
     function isWindowed() {
-        return $this->limit || $this->offset;
+        return $this->limit || $this->offset || (count($this->values) + count($this->annotations) + @count($this->extra['select'])) > 1;
     }
 
     function select_related() {
diff --git a/include/class.thread.php b/include/class.thread.php
index 06ad342f583a99f3b1b0574393c267cda861c39d..0a1162487feece9b9d247574657b2287a75afa24 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -604,6 +604,8 @@ implements TemplateVariable {
     var $_headers;
     var $_thread;
     var $_actions;
+    var $is_autoreply;
+    var $is_bounce;
 
     static protected $perms = array(
         self::PERM_EDIT => array(
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 43e74d1756d63ce47869d026d32f39cef608626f..8e0871df0160a787dbe1c8d26550d25d9c199f5e 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -224,7 +224,7 @@ class TicketCData extends VerySimpleModel {
             'ticket' => array(
                 'constraint' => array('ticket_id' => 'TicketModel.ticket_id'),
             ),
-            'priority' => array(
+            ':priority' => array(
                 'constraint' => array('priority' => 'Priority.priority_id'),
                 'null' => true,
             ),
@@ -1351,8 +1351,8 @@ implements RestrictedAccess, Threadable {
 
             // Only alerts dept members if the ticket is NOT assigned.
             if ($cfg->alertDeptMembersONNewTicket() && !$this->isAssigned()) {
-                if ($members = $dept->getMembersForAlerts()->all())
-                    $recipients = array_merge($recipients, $members);
+                if (($members = $dept->getMembersForAlerts()))
+                    $recipients = array_merge($recipients, $members->all());
             }
 
             if ($cfg->alertDeptManagerONNewTicket() && $dept &&
@@ -1542,6 +1542,9 @@ implements RestrictedAccess, Threadable {
                 $this->setStaffId(0); // Clear assignment
         }
 
+        if (!$autorespond)
+            return;
+
         // Figure out the user
         if ($this->getOwnerId() == $message->getUserId())
             $user = new TicketOwner(
@@ -1553,11 +1556,11 @@ implements RestrictedAccess, Threadable {
 
         /**********   double check auto-response  ************/
         if (!$user)
-            $autorespond=false;
-        elseif ($autorespond && (Email::getIdByEmail($user->getEmail())))
-            $autorespond=false;
-        elseif ($autorespond && ($dept=$this->getDept()))
-            $autorespond=$dept->autoRespONNewMessage();
+            $autorespond = false;
+        elseif ((Email::getIdByEmail($user->getEmail())))
+            $autorespond = false;
+        elseif (($dept=$this->getDept()))
+            $autorespond = $dept->autoRespONNewMessage();
 
         if (!$autorespond
             || !$cfg->autoRespONNewMessage()
@@ -2293,28 +2296,18 @@ implements RestrictedAccess, Threadable {
         }
 
         // Do not auto-respond to bounces and other auto-replies
-        if ($alerts)
-            $alerts = isset($vars['mailflags'])
+        $autorespond = isset($vars['mailflags'])
                 ? !$vars['mailflags']['bounce'] && !$vars['mailflags']['auto-reply']
                 : true;
-        if ($alerts && $message->isBounceOrAutoReply())
-            $alerts = false;
-
-        if ($alerts && $this->getThread()->getLastEmailMessage(array(
-            'user_id' => $message->user_id,
-            'id__lt' => $message->id,
-            'created__gt' => SqlFunction::NOW()->minus(SqlInterval::MINUTE(5)),
-        ))) {
-            // One message already from this user in the last five minutes
-            $alerts = false;
-        }
+        if ($autorespond && $message->isBounceOrAutoReply())
+            $autorespond = false;
 
-        $this->onMessage($message, $alerts); //must be called b4 sending alerts to staff.
+        $this->onMessage($message, $autorespond); //must be called b4 sending alerts to staff.
 
-        if ($alerts && $cfg && $cfg->notifyCollabsONNewMessage())
+        if ($autorespond && $cfg && $cfg->notifyCollabsONNewMessage())
             $this->notifyCollaborators($message, array('signature' => ''));
 
-        if (!$alerts)
+        if (!($alerts && $autorespond))
             return $message; //Our work is done...
 
         $dept = $this->getDept();
@@ -2388,8 +2381,10 @@ implements RestrictedAccess, Threadable {
             return false;
         }
         $files = array();
-        foreach ($canned->attachments->getAll() as $file)
+        foreach ($canned->attachments->getAll() as $file) {
             $files[] = $file->file_id;
+            $_SESSION[':cannedFiles'][$file->file_id] = 1;
+        }
 
         if ($cfg->isRichTextEnabled())
             $response = new HtmlThreadEntryBody(
diff --git a/include/class.topic.php b/include/class.topic.php
index d448ea7ec10279dfef915674ee253d50e785efa5..731ea0e1c55acbc5844a064867b9c2ece1743088 100644
--- a/include/class.topic.php
+++ b/include/class.topic.php
@@ -418,7 +418,6 @@ implements TemplateVariable {
         $this->priority_id = $vars['priority_id'] ?: 0;
         $this->status_id = $vars['status_id'] ?: 0;
         $this->sla_id = $vars['sla_id'] ?: 0;
-        $this->form_id = $vars['form_id'] ?: 0;
         $this->page_id = $vars['page_id'] ?: 0;
         $this->isactive = !!$vars['isactive'];
         $this->ispublic = !!$vars['ispublic'];
diff --git a/include/class.user.php b/include/class.user.php
index 165eebb100afe5c47ecf9b056d65f35f19f0cee5..cc64e736298c436b6398ece1700380728fb469d1 100644
--- a/include/class.user.php
+++ b/include/class.user.php
@@ -31,7 +31,7 @@ class UserEmailModel extends VerySimpleModel {
     );
 
     function __toString() {
-        return $this->address;
+        return (string) $this->address;
     }
 }
 
@@ -616,7 +616,7 @@ implements TemplateVariable {
     }
 
     function __toString() {
-        return $this->address;
+        return (string) $this->address;
     }
 
     function getVar($what) {
diff --git a/include/html2text.php b/include/html2text.php
index 2863e10524cac3e7d500ad5e6b9710c5eb0db21e..d8ef77c5e77c51284a0fa9e304c6989754873f58 100644
--- a/include/html2text.php
+++ b/include/html2text.php
@@ -181,7 +181,7 @@ class HtmlInlineElement {
     }
 
     function traverse($node) {
-        if ($node->hasChildNodes()) {
+        if ($node && $node->hasChildNodes()) {
             for ($i = 0; $i < $node->childNodes->length; $i++) {
                 $n = $node->childNodes->item($i);
                 $this->children[] = identify_node($n, $this);
@@ -194,7 +194,9 @@ class HtmlInlineElement {
         $after_block = false;
         $this->ws = $this->getStyle('white-space', 'normal');
         // Direction
-        $dir = $this->node->getAttribute('dir');
+        if ($this->node)
+            $dir = $this->node->getAttribute('dir');
+
         // Ensure we have a value, but don't emit a control char unless
         // direction is declared
         $this->dir = $dir ?: 'ltr';
@@ -287,10 +289,11 @@ class HtmlInlineElement {
         if ($this->style && $this->style->has($property))
             return $this->style->get($property, $default);
 
-        if ($tag === false)
+        if ($this->node && $tag === false)
             $tag = $this->node->nodeName;
+
         if ($classes === false) {
-            if ($c = $this->node->getAttribute('class'))
+            if ($this->node && ($c = $this->node->getAttribute('class')))
                 $classes = explode(' ', $c);
             else
                 $classes = array();
diff --git a/include/staff/plugin.inc.php b/include/staff/plugin.inc.php
index 58d4a0313d852d26a59ac040b8be6b536870f2ba..6ab5b3c284d7c1eedf88a477a17cc931c9f05a70 100644
--- a/include/staff/plugin.inc.php
+++ b/include/staff/plugin.inc.php
@@ -1,9 +1,9 @@
 <?php
-
-$info=array();
+$info = array();
+$page = null;
 if($plugin && $_REQUEST['a']!='add') {
     $config = $plugin->getConfig();
-    if (!($page = $config->hasCustomConfig())) {
+    if ($config && !($page = $config->hasCustomConfig())) {
         if ($config)
             $form = $config->getForm();
         if ($form && $_POST)
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index 9a3c5e18a0ebaf92c3c300f8c28e719a8ac237c2..99bfb2381c0efd0b717b705181edf92379051284 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -189,6 +189,7 @@ case 'search':
     // Fall-through and show open tickets
 case 'open':
     $status='open';
+    $queue_name = $queue_name ?: 'open';
     $results_type=__('Open Tickets');
     if (!$cfg->showAnsweredTickets())
         $tickets->filter(array('isanswered'=>0));
@@ -273,7 +274,7 @@ case 'number':
     break;
 
 case 'priority,created':
-    $tickets->order_by(($sort_dir ? '-' : '') . 'cdata__priority__priority_urgency');
+    $tickets->order_by(($sort_dir ? '-' : '') . 'cdata__:priority__priority_urgency');
     // Fall through to columns for `created`
 case 'created':
     $queue_columns['date']['heading'] = __('Date Created');
@@ -283,7 +284,7 @@ case 'created':
     break;
 
 case 'priority,due':
-    $tickets->order_by('cdata__priority__priority_urgency', $orm_dir_r);
+    $tickets->order_by('cdata__:priority__priority_urgency', $orm_dir_r);
     // Fall through to add in due date filter
 case 'due':
     $queue_columns['date']['heading'] = __('Due Date');
@@ -340,7 +341,7 @@ default:
     }
 
 case 'priority,updated':
-    $tickets->order_by('cdata__priority__priority_urgency', $orm_dir_r);
+    $tickets->order_by('cdata__:priority__priority_urgency', $orm_dir_r);
     // Fall through for columns defined for `updated`
 case 'updated':
     $queue_columns['date']['heading'] = __('Last Updated');
@@ -371,7 +372,9 @@ TicketForm::ensureDynamicDataView();
 
 // Select pertinent columns
 // ------------------------------------------------------------
-$tickets->values('lock__staff_id', 'staff_id', 'isoverdue', 'team_id', 'ticket_id', 'number', 'cdata__subject', 'user__default_email__address', 'source', 'cdata__priority__priority_color', 'cdata__priority__priority_desc', 'status_id', 'status__name', 'status__state', 'dept_id', 'dept__name', 'user__name', 'lastupdate', 'isanswered', 'staff__firstname', 'staff__lastname', 'team__name');
+$tickets->values('lock__staff_id', 'staff_id', 'isoverdue', 'team_id',
+'ticket_id', 'number', 'cdata__subject', 'user__default_email__address',
+'source', 'cdata__:priority__priority_color', 'cdata__:priority__priority_desc', 'status_id', 'status__name', 'status__state', 'dept_id', 'dept__name', 'user__name', 'lastupdate', 'isanswered', 'staff__firstname', 'staff__lastname', 'team__name');
 
 // Add in annotations
 $tickets->annotate(array(
@@ -546,7 +549,7 @@ return false;">
                     ><?php echo $tid; ?></a></td>
                 <td align="center" nowrap><?php echo Format::datetime($T[$date_col ?: 'lastupdate']) ?: $date_fallback; ?></td>
                 <td><div style="max-width: <?php
-                    $base = 280;
+                    $base = 279;
                     // Make room for the paperclip and some extra
                     if ($T['attachment_count']) $base -= 18;
                     // Assume about 8px per digit character
@@ -582,8 +585,9 @@ return false;">
                         $displaystatus="<b>$displaystatus</b>";
                     echo "<td>$displaystatus</td>";
                 } else { ?>
-                <td class="nohover" align="center" style="background-color:<?php echo $T['cdata__priority__priority_color']; ?>;">
-                    <?php echo $T['cdata__priority__priority_desc']; ?></td>
+                <td class="nohover" align="center"
+                    style="background-color:<?php echo $T['cdata__:priority__priority_color']; ?>;">
+                    <?php echo $T['cdata__:priority__priority_desc']; ?></td>
                 <?php
                 }
                 ?>
diff --git a/scp/css/scp.css b/scp/css/scp.css
index 1aa6361639c51abee2bff81811197a7d4fb31669..8050c819b3f12c5f4bdaddce27ab7c41c1534bbe 100644
--- a/scp/css/scp.css
+++ b/scp/css/scp.css
@@ -2835,6 +2835,16 @@ input[type=checkbox] {
   margin-top: 3px;
 }
 
+input, textarea {
+    padding: 3px 5px;
+    font-size: 0.95em;
+    font-family: inherit;
+    border-radius:4px;
+   -webkit-border-radius: 4px;
+   -moz-border-radius: 4px;
+    border: 1px solid #bbb;
+}
+
 small {
     font-weight: normal;
     letter-spacing: 0.01px;
diff --git a/setup/test/tests/stubs.php b/setup/test/tests/stubs.php
index 49ef4baa1d721e7f1e28783d8228e754a73a9f43..6bcbf3110d835657c99f9383807a3b6aa7b0a3a3 100644
--- a/setup/test/tests/stubs.php
+++ b/setup/test/tests/stubs.php
@@ -127,6 +127,7 @@ class IntlBreakIterator {
 
 class SqlFunction {
     static function NOW() {}
+    static function LENGTH() {}
     static function COALESCE() {}
     static function DATEDIFF() {}
 }