diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index b9fad85ad45dd6b97e38a671f062b84fb5290798..81c367065a05f0adc3c4f16a21e832a3f71fd8a4 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -213,9 +213,10 @@ class TicketsAjaxAPI extends AjaxController {
                     && ($val = $req[$f->getFormName()])) {
                 $name = $f->get('name') ? $f->get('name')
                     : 'field_'.$f->get('id');
-                $cwhere = "cdata.`$name` LIKE '%".db_real_escape($val)."%'";
                 if ($f->getImpl()->hasIdValue() && is_numeric($val))
-                    $cwhere .= " OR cdata.`{$name}_id` = ".db_input($val);
+                    $cwhere = "cdata.`{$name}_id` = ".db_input($val);
+                else
+                    $cwhere = "cdata.`$name` LIKE '%".db_real_escape($val)."%'";
                 $where .= ' AND ('.$cwhere.')';
                 $cdata_search = true;
             }
@@ -232,7 +233,8 @@ class TicketsAjaxAPI extends AjaxController {
             $sections[] = "$select $from $where";
 
         $sql=implode(' union ', $sections);
-        $res = db_query($sql);
+        if (!($res = db_query($sql)))
+            return TicketForm::dropDynamicDataView();
 
         $tickets = array();
         while ($row = db_fetch_row($res))
diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index 118805882148d03fb084b753e0e18aaf55c67a09..27e4a0afe186e550db4ae74051f9fea50fa40b09 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -878,13 +878,20 @@ class SelectionField extends FormField {
     }
 
     function parse($value) {
-        return $this->to_php($value);
+        $config = $this->getConfiguration();
+        if (is_int($value))
+            return $this->to_php($this->getWidget()->getEnteredValue(), (int) $value);
+        elseif (!$config['typeahead'])
+            return $this->to_php(null, (int) $value);
+        else
+            return $this->to_php($value);
     }
 
     function to_php($value, $id=false) {
-        $item = DynamicListItem::lookup($id ? $id : $value);
+        if ($id && is_int($id))
+            $item = DynamicListItem::lookup($id);
         # Attempt item lookup by name too
-        if (!$item) {
+        if (!$item || ($value !== null && $value != $item->get('value'))) {
             $item = DynamicListItem::lookup(array(
                 'value'=>$value,
                 'list_id'=>$this->getListId()));
@@ -903,13 +910,18 @@ class SelectionField extends FormField {
     }
 
     function toString($item) {
-        return ($item instanceof DynamicListItem) ? $item->toString() : $item;
+        return ($item instanceof DynamicListItem)
+            ? $item->toString() : (string) $item;
     }
 
     function validateEntry($item) {
+        $config = $this->getConfiguration();
         parent::validateEntry($item);
         if ($item && !$item instanceof DynamicListItem)
             $this->_errors[] = 'Select a value from the list';
+        elseif ($item && $config['typeahead']
+                && $this->getWidget()->getEnteredValue() != $item->get('value'))
+            $this->_errors[] = 'Select a value from the list';
     }
 
     function getConfigurationOptions() {
@@ -943,10 +955,8 @@ class SelectionWidget extends ChoicesWidget {
         } elseif ($this->value) {
             // Loaded from POST
             $value = $this->value;
-            $name = DynamicListItem::lookup($value);
-            $name = ($name) ? $name->get('value') : $value;
+            $name = $this->getEnteredValue();
         }
-
         if (!$config['typeahead']) {
             $this->value = $value;
             return parent::render();
@@ -955,7 +965,7 @@ class SelectionWidget extends ChoicesWidget {
         $source = array();
         foreach ($this->field->getList()->getItems() as $i)
             $source[] = array(
-                'value' => $i->get('value'),
+                'value' => $i->get('value'), 'id' => $i->get('id'),
                 'info' => $i->get('value')." -- ".$i->get('extra'),
             );
         ?>
@@ -963,6 +973,8 @@ class SelectionWidget extends ChoicesWidget {
         <input type="text" size="30" name="<?php echo $this->name; ?>"
             id="<?php echo $this->name; ?>" value="<?php echo $name; ?>"
             autocomplete="off" />
+        <input type="hidden" name="<?php echo $this->name;
+            ?>_id" id="<?php echo $this->name; ?>_id" value="<?php echo $value; ?>"/>
         <script type="text/javascript">
         $(function() {
             $('input#<?php echo $this->name; ?>').typeahead({
@@ -970,6 +982,7 @@ class SelectionWidget extends ChoicesWidget {
                 property: 'info',
                 onselect: function(item) {
                     $('input#<?php echo $this->name; ?>').val(item['value'])
+                    $('input#<?php echo $this->name; ?>_id').val(item['id'])
                 }
             });
         });
@@ -977,5 +990,18 @@ class SelectionWidget extends ChoicesWidget {
         </span>
         <?php
     }
+
+    function getValue() {
+        $data = $this->field->getSource();
+        // Search for HTML form name first
+        if (isset($data[$this->name.'_id']))
+            return (int) $data[$this->name.'_id'];
+        return parent::getValue();
+    }
+
+    function getEnteredValue() {
+        // Used to verify typeahead fields
+        return parent::getValue();
+    }
 }
 ?>
diff --git a/include/class.staff.php b/include/class.staff.php
index e353c5cd908c6ce9a1e316f03b3098fe3cc94556..a3a571b54086a448fded6e83c5f284238f22d990 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -53,8 +53,10 @@ class Staff extends AuthenticatedUser {
             $sql .= 'staff_id='.db_input($var);
         elseif (Validator::is_email($var))
             $sql .= 'email='.db_input($var);
-        else
+        elseif (is_string($var))
             $sql .= 'username='.db_input($var);
+        else
+            return null;
 
         if(!($res=db_query($sql)) || !db_num_rows($res))
             return NULL;
@@ -748,9 +750,23 @@ class Staff extends AuthenticatedUser {
         if(!($email=$cfg->getAlertEmail()))
             $email = $cfg->getDefaultEmail();
 
-        $info = array('email' => $email, 'vars' => &$vars);
+        $info = array('email' => $email, 'vars' => &$vars, 'log'=>true);
         Signal::send('auth.pwreset.email', $this, $info);
 
+        if ($info['log'])
+            $ost->logWarning('Staff Password Reset', sprintf(
+               'Password reset was attempted for staff member: %s<br><br>
+                Requested-User-Id: %s<br>
+                Source-Ip: %s<br>
+                Email-Sent-To: %s<br>
+                Email-Sent-Via: %s',
+                $this->getName(),
+                $_POST['userid'],
+                $_SERVER['REMOTE_ADDR'],
+                $this->getEmail(),
+                $email->getEmail()
+            ), false);
+
         $msg = $ost->replaceTemplateVariables($template->asArray(), $vars);
 
         $_config = new Config('pwreset');
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index d1484a68db311e81febb35bf23876fd7420b1bcb..d72982411337e76705d4d66d3601c7f1869162f3 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -145,7 +145,7 @@ if ($_REQUEST['advsid'] && isset($_SESSION['adv_'.$_REQUEST['advsid']])) {
 }
 
 $sortOptions=array('date'=>'effective_date','ID'=>'`number`',
-    'pri'=>'priority_id','name'=>'user.name','subj'=>'subject',
+    'pri'=>'priority_urgency','name'=>'user.name','subj'=>'subject',
     'status'=>'ticket.status','assignee'=>'assigned','staff'=>'staff',
     'dept'=>'dept_name');
 
@@ -180,16 +180,16 @@ if(!$order_by ) {
     elseif(!strcasecmp($status,'closed'))
         $order_by='ticket.closed, ticket.created'; //No priority sorting for closed tickets.
     elseif($showoverdue) //priority> duedate > age in ASC order.
-        $order_by='priority_id, ISNULL(duedate) ASC, duedate ASC, effective_date ASC, ticket.created';
+        $order_by='priority_urgency ASC, ISNULL(duedate) ASC, duedate ASC, effective_date ASC, ticket.created';
     else //XXX: Add due date here?? No -
-        $order_by='priority_id, effective_date DESC, ticket.created';
+        $order_by='priority_urgency ASC, effective_date DESC, ticket.created';
 }
 
 $order=$order?$order:'DESC';
 if($order_by && strpos($order_by,',') && $order)
     $order_by=preg_replace('/(?<!ASC|DESC),/', " $order,", $order_by);
 
-$sort=$_REQUEST['sort']?strtolower($_REQUEST['sort']):'priority_id'; //Urgency is not on display table.
+$sort=$_REQUEST['sort']?strtolower($_REQUEST['sort']):'priority_urgency'; //Urgency is not on display table.
 $x=$sort.'_sort';
 $$x=' class="'.strtolower($order).'" ';
 
@@ -231,7 +231,7 @@ $qselect.=' ,IF(ticket.duedate IS NULL,IF(sla.id IS NULL, NULL, DATE_ADD(ticket.
          .' ,CONCAT_WS(" ", staff.firstname, staff.lastname) as staff, team.name as team '
          .' ,IF(staff.staff_id IS NULL,team.name,CONCAT_WS(" ", staff.lastname, staff.firstname)) as assigned '
          .' ,IF(ptopic.topic_pid IS NULL, topic.topic, CONCAT_WS(" / ", ptopic.topic, topic.topic)) as helptopic '
-         .' ,cdata.priority_id, cdata.subject';
+         .' ,cdata.priority_id, cdata.subject, pri.priority_desc, pri.priority_color';
 
 $qfrom.=' LEFT JOIN '.TICKET_LOCK_TABLE.' tlock ON (ticket.ticket_id=tlock.ticket_id AND tlock.expire>NOW()
                AND tlock.staff_id!='.db_input($thisstaff->getId()).') '
@@ -240,16 +240,11 @@ $qfrom.=' LEFT JOIN '.TICKET_LOCK_TABLE.' tlock ON (ticket.ticket_id=tlock.ticke
        .' LEFT JOIN '.SLA_TABLE.' sla ON (ticket.sla_id=sla.id AND sla.isactive=1) '
        .' LEFT JOIN '.TOPIC_TABLE.' topic ON (ticket.topic_id=topic.topic_id) '
        .' LEFT JOIN '.TOPIC_TABLE.' ptopic ON (ptopic.topic_id=topic.topic_pid) '
-       .' LEFT JOIN '.TABLE_PREFIX.'ticket__cdata cdata ON (cdata.ticket_id = ticket.ticket_id) ';
+       .' LEFT JOIN '.TABLE_PREFIX.'ticket__cdata cdata ON (cdata.ticket_id = ticket.ticket_id) '
+       .' LEFT JOIN '.PRIORITY_TABLE.' pri ON (pri.priority_id = cdata.priority_id)';
 
 TicketForm::ensureDynamicDataView();
 
-// Fetch priority information
-$res = db_query('select * from '.PRIORITY_TABLE);
-$prios = array();
-while ($row = db_fetch_array($res))
-    $prios[$row['priority_id']] = $row;
-
 $query="$qselect $qfrom $qwhere ORDER BY $order_by $order LIMIT ".$pageNav->getStart().",".$pageNav->getLimit();
 //echo $query;
 $hash = md5($query);
@@ -435,8 +430,8 @@ if ($results) {
                         $displaystatus="<b>$displaystatus</b>";
                     echo "<td>$displaystatus</td>";
                 } else { ?>
-                <td class="nohover" align="center" style="background-color:<?php echo $prios[$row['priority_id']]['priority_color']; ?>;">
-                    <?php echo $prios[$row['priority_id']]['priority_desc']; ?></td>
+                <td class="nohover" align="center" style="background-color:<?php echo $row['priority_color']; ?>;">
+                    <?php echo $row['priority_desc']; ?></td>
                 <?php
                 }
                 ?>
diff --git a/setup/doc/signals.md b/setup/doc/signals.md
index 68c5e1513305ae8b615ece591c2fb8364099b9a8..a7f0656c56625f7187340341e7f23b712b3a0406 100644
--- a/setup/doc/signals.md
+++ b/setup/doc/signals.md
@@ -56,7 +56,25 @@ the signal handler should be called.
 
 Signals in osTicket
 -------------------
-**auth.login.succeeded**
+#### ajax.client
+Sent before an AJAX request is processed for the client interface
+
+Context:
+Object<Dispatcher> - Dispatcher used to resolve and service the request
+
+Parameters:
+(none)
+
+#### ajax.scp
+Sent before an AJAX request is processed for the staff interface
+
+Context:
+Object<Dispatcher> - Dispatcher used to resolve and service the request
+
+Parameters:
+(none)
+
+#### auth.login.succeeded
 Sent after a successful login is process for a user
 
 Context:
@@ -65,7 +83,7 @@ Object<StaffSession> - Staff object retrieved from the login credentials
 Parameters:
 (none)
 
-**auth.login.failed**
+#### auth.login.failed
 Sent after an unsuccessful login is attempted by a user.
 
 Context:
@@ -75,7 +93,7 @@ Arguments:
   * **username**: *read-only* username submitted to the login form
   * **passowrd**: *read-only* password submitted to the login form
 
-**auth.pwreset.email**
+#### auth.pwreset.email
 Sent just before an email is sent to the user with the password reset token
 
 Context:
@@ -85,8 +103,10 @@ Parameters:
   * **email**: *read-only* email object used to send the email
   * **vars**: (array) template variables used to render the password-reset
         email template
+  * **log**: (bool) TRUE if a log should be appended to the system log
+        concerning the password reset attempt
 
-**auth.pwreset.login**
+#### auth.pwreset.login
 Sent just before processing the automatic login for the staff from the link
 and token provided in the password-reset email. This signal is only sent if
 the token presented is considered completely valid and the password for the
@@ -99,7 +119,7 @@ Parameters:
   * **page**: Page / URL sent in the redirect to the user. In other words,
         the next page the staff will see.
 
-**auth.pwchange**
+#### auth.pwchange
 Sent when the password for a user is changed
 
 Context:
@@ -107,3 +127,9 @@ Object<Staff> - Staff whose password is being changed
 
 Parameters:
   * **password**: New password (clear-text) for the user
+
+#### cron
+Sent at the end of a cron run
+
+Context:
+null