diff --git a/include/class.search.php b/include/class.search.php
index 616fb9ce0b0e1897f443709dc1758ffd620d8162..2ce10df368bf4700345231dafbe6d28bd176c3b8 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -30,10 +30,10 @@ abstract class SearchBackend {
     const SORT_RECENT = 2;
     const SORT_OLDEST = 3;
 
-    const PERM_AGENTS = 'search.all';
+    const PERM_EVERYTHING = 'search.all';
 
     static protected $perms = array(
-        self::PERM_AGENTS => array(
+        self::PERM_EVERYTHING => array(
             'title' => /* @trans */ 'Search',
             'desc'  => /* @trans */ 'See all tickets in search results, regardless of access'
         ),
diff --git a/include/class.user.php b/include/class.user.php
index 5bf264644c7c5418767eb9c7fa4a1eaf3d07d544..becd978422b7c8509d174acaef2dc4066aa113eb 100644
--- a/include/class.user.php
+++ b/include/class.user.php
@@ -650,8 +650,14 @@ class PersonsName {
         elseif($cfg)
             $this->format = $cfg->getDefaultNameFormat();
 
-        $this->parts = static::splitName($name);
-        $this->name = $name;
+        if (!is_array($name)) {
+            $this->parts = static::splitName($name);
+            $this->name = $name;
+        }
+        else {
+            $this->parts = $name;
+            $this->name = implode(' ', $name);
+        }
     }
 
     function getFirst() {
diff --git a/include/staff/templates/tickets.tmpl.php b/include/staff/templates/tickets.tmpl.php
index e70d3e29cd537338d5feb20b6f5f070acdf60de9..87cc1f9afba2ba7e85e1520e0a18facc9e73bbe4 100644
--- a/include/staff/templates/tickets.tmpl.php
+++ b/include/staff/templates/tickets.tmpl.php
@@ -1,63 +1,42 @@
 <?php
 
-$select ='SELECT ticket.ticket_id,ticket.`number`,ticket.dept_id,ticket.staff_id,ticket.team_id, ticket.user_id '
-        .' ,dept.name as department, status.name as status,ticket.source,ticket.isoverdue,ticket.isanswered,ticket.created '
-        .' ,CAST(GREATEST(IFNULL(ticket.lastmessage, 0), IFNULL(ticket.reopened, 0), ticket.created) as datetime) as effective_date '
-        .' ,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 as priority_id, cdata.subject, user.name, email.address as email';
+$tickets = TicketModel::objects();
 
-$from =' FROM '.TICKET_TABLE.' ticket '
-      .' LEFT JOIN '.TICKET_STATUS_TABLE.' status
-        ON status.id = ticket.status_id '
-      .' LEFT JOIN '.USER_TABLE.' user ON user.id = ticket.user_id '
-      .' LEFT JOIN '.USER_EMAIL_TABLE.' email ON user.id = email.user_id '
-      .' LEFT JOIN '.USER_ACCOUNT_TABLE.' account ON (ticket.user_id=account.user_id) '
-      .' LEFT JOIN '.DEPT_TABLE.' dept ON ticket.dept_id=dept.id '
-      .' LEFT JOIN '.STAFF_TABLE.' staff ON (ticket.staff_id=staff.staff_id) '
-      .' LEFT JOIN '.TEAM_TABLE.' team ON (ticket.team_id=team.team_id) '
-      .' 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 '.PRIORITY_TABLE.' pri ON (pri.priority_id = cdata.priority)';
+if ($user) {
+    $tickets->filter(array('user_id' => $user->getId()));
+}
+elseif ($org) {
+    $tickets->filter(array('user__org' => $org));
+}
+
+if (!$thisstaff->getRole()->hasPerm(SearchBackend::PERM_EVERYTHING)) {
+    // -- Open and assigned to me
+    $visibility = array(
+        new Q(array('status__state'=>'open', 'staff_id' => $thisstaff->getId()))
+    );
+    // -- Routed to a department of mine
+    if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts()))
+        $visibility[] = new Q(array('dept_id__in' => $depts));
+    // -- Open and assigned to a team of mine
+    if (($teams = $thisstaff->getTeams()) && count(array_filter($teams)))
+        $visibility[] = new Q(array(
+            'team_id__in' => array_filter($teams), 'status__state'=>'open'
+        ));
+    $tickets->filter(Q::any($visibility));
+}
 
-if ($user)
-    $where = 'WHERE ticket.user_id = '.db_input($user->getId());
-elseif ($org)
-    $where = 'WHERE user.org_id = '.db_input($org->getId());
+$tickets->annotate(array(
+    'collab_count' => SqlAggregate::COUNT('thread__collaborators'),
+    'attachment_count' => SqlAggregate::COUNT('thread__entries__attachments'),
+    'thread_count' => SqlAggregate::COUNT('thread__entries'),
+));
 
+$tickets->values('staff_id', 'staff__firstname', 'staff__lastname', 'team__name', 'team_id', 'lock_id', 'lock__staff_id', 'isoverdue', 'status_id', 'status__name', 'status__state', 'number', 'cdata__subject', 'ticket_id', 'source', 'dept_id', 'dept__name', 'user_id', 'user__default_email__address', 'user__name');
 
 TicketForm::ensureDynamicDataView();
 
-$query ="$select $from $where ORDER BY ticket.created DESC";
-
 // Fetch the results
-$results = array();
-$res = db_query($query);
-while ($row = db_fetch_array($res))
-    $results[$row['ticket_id']] = $row;
-
-if ($results) {
-    $counts_sql = 'SELECT ticket.ticket_id,
-        count(DISTINCT attach.id) as attachments,
-        count(DISTINCT entry.id) as thread_count,
-        count(DISTINCT collab.id) as collaborators
-        FROM '.TICKET_TABLE.' ticket '
-     .' LEFT JOIN '.THREAD_TABLE.' thread
-            ON (thread.object_id=ticket.ticket_id AND thread.object_type="T") '
-     .' LEFT JOIN '.THREAD_ENTRY_TABLE.' entry ON (entry.thread_id=thread.id) '
-     .' LEFT JOIN '.ATTACHMENT_TABLE.' attach
-            ON (attach.object_id=entry.id AND attach.`type` = "H") '
-     .' LEFT JOIN '.THREAD_COLLABORATOR_TABLE.' collab
-            ON ( thread.id=collab.thread_id) '
-     .' WHERE ticket.ticket_id IN ('.implode(',', db_input(array_keys($results))).')
-        GROUP BY ticket.ticket_id';
-    $ids_res = db_query($counts_sql);
-    while ($row = db_fetch_array($ids_res)) {
-        $results[$row['ticket_id']] += $row;
-    }
-}
+$results = count($tickets);
 ?>
 <div style="width:700px;" class="pull-left">
    <?php
@@ -94,80 +73,91 @@ if ($results) { ?>
             <?php
             } ?>
             <th width="70"><?php echo __('Ticket'); ?></th>
-            <th width="100"><?php echo __('Date'); ?></th>
-            <th width="100"><?php echo __('Status'); ?></th>
-            <th width="300"><?php echo __('Subject'); ?></th>
+            <th width="120"><?php echo __('Date'); ?></th>
+            <th width="70"><?php echo __('Status'); ?></th>
+            <th width="380"><?php echo __('Subject'); ?></th>
             <?php
             if ($user) { ?>
-            <th width="100"><?php echo __('Department'); ?></th>
-            <th width="100"><?php echo __('Assignee'); ?></th>
+            <th width="150"><?php echo __('Department'); ?></th>
+            <th width="150"><?php echo __('Assignee'); ?></th>
             <?php
             } else { ?>
-            <th width="200"><?php echo __('User'); ?></th>
+            <th width="300"><?php echo __('User'); ?></th>
             <?php
             } ?>
         </tr>
     </thead>
     <tbody>
     <?php
-    foreach($results as $row) {
+    $subject_field = TicketForm::objects()->one()->getField('subject');
+    foreach($tickets as $T) {
         $flag=null;
-        if ($row['lock_id'])
+        if ($T['lock_id'] && $T['lock__staff_id'] != $thisstaff->getId())
             $flag='locked';
-        elseif ($row['isoverdue'])
+        elseif ($T['isoverdue'])
             $flag='overdue';
 
         $assigned='';
-        if ($row['staff_id'])
-            $assigned=sprintf('<span class="truncate Icon staffAssigned">%s</span>',$row['staff']);
-        elseif ($row['team_id'])
-            $assigned=sprintf('<span class="truncate Icon teamAssigned">%s</span>',$row['team']);
+        if ($T['staff_id'])
+            $assigned = new PersonsName(array(
+                'first' => $row['staff__firstname'],
+                'last' => $row['staff__lastname']
+            ));
+        elseif ($T['team_id'])
+            $assigned = Team::getLocalById($T['team_id'], 'name', $T['team__name']);
         else
             $assigned=' ';
 
-        $status = ucfirst($row['status']);
-        $tid=$row['number'];
-        $subject = Format::htmlchars($row['subject']);
-        $threadcount=$row['thread_count'];
+        $status = TicketStatus::getLocalById($T['status_id'], 'value', $T['status__name']);
+        $tid = $T['number'];
+        $subject = $subject_field->display($subject_field->to_php($T['cdata__subject']));
+        $threadcount = $T['thread_count'];
         ?>
-        <tr id="<?php echo $row['ticket_id']; ?>">
+        <tr id="<?php echo $T['ticket_id']; ?>">
             <?php
             //Implement mass  action....if need be.
             if (0) { ?>
             <td align="center" class="nohover">
-                <input class="ckb" type="checkbox" name="tids[]" value="<?php echo $row['ticket_id']; ?>" <?php echo $sel?'checked="checked"':''; ?>>
+                <input class="ckb" type="checkbox" name="tids[]" value="<?php echo $T['ticket_id']; ?>" <?php echo $sel?'checked="checked"':''; ?>>
             </td>
             <?php
             } ?>
             <td align="center" nowrap>
               <a class="Icon <?php
-                echo strtolower($row['source']); ?>Ticket preview"
+                echo strtolower($T['source']); ?>Ticket preview"
                 title="<?php echo __('Preview Ticket'); ?>"
-                href="tickets.php?id=<?php echo $row['ticket_id']; ?>"
-                data-preview="#tickets/<?php echo $row['ticket_id']; ?>/preview"><?php echo $tid; ?></a></td>
+                href="tickets.php?id=<?php echo $T['ticket_id']; ?>"
+                data-preview="#tickets/<?php echo $T['ticket_id']; ?>/preview"><?php echo $tid; ?></a></td>
             <td align="center" nowrap><?php echo Format::datetime($row['effective_date']); ?></td>
             <td><?php echo $status; ?></td>
-            <td><a class="truncate <?php if ($flag) { ?> Icon <?php echo $flag; ?>Ticket" title="<?php echo ucfirst($flag); ?> Ticket<?php } ?>"
-                style="max-width: 80%; max-width: calc(100% - 86px);"
-                href="tickets.php?id=<?php echo $row['ticket_id']; ?>"><?php echo $subject; ?></a>
+            <td><a <?php if ($flag) { ?> class="Icon <?php echo $flag; ?>Ticket" title="<?php echo ucfirst($flag); ?> Ticket" <?php } ?>
+                href="tickets.php?id=<?php echo $T['ticket_id']; ?>"><span class="truncate"
+                style="max-width: 290px"><?php echo $subject; ?></span></a>
                  <?php
-                    if ($threadcount>1)
-                        echo "<small>($threadcount)</small>&nbsp;".'<i
-                            class="icon-fixed-width icon-comments-alt"></i>&nbsp;';
-                    if ($row['collaborators'])
-                        echo '<i class="icon-fixed-width icon-group faded"></i>&nbsp;';
+                    if ($threadcount > 1) { ?>
+                        <span class="pull-right faded-more"><i class="icon-comments-alt"></i>
+                        <small><?php echo $threadcount; ?></small>
+<?php               }
                     if ($row['attachments'])
-                        echo '<i class="icon-fixed-width icon-paperclip"></i>&nbsp;';
+                        echo '<i class="small icon-paperclip icon-flip-horizontal"></i>';
+                    if ($row['collaborators'])
+                        echo '<i class="icon-group faded-more"></i>';
                 ?>
             </td>
             <?php
-            if ($user) { ?>
-            <td><span class="truncate"><?php echo $row['department']; ?></td>
-            <td>&nbsp;<?php echo $assigned; ?></td>
+            if ($user) {
+                $dept = Dept::getLocalById($T['dept_id'], 'name', $T['dept__name']); ?>
+            <td><span class="truncate" style="max-wdith:150px"><?php
+                echo Format::htmlchars($dept); ?></span></td>
+            <td><span class="truncate" style="max-width:150px"><?php
+                echo Format::htmlchars($assigned); ?></span></td>
             <?php
             } else { ?>
-            <td>&nbsp;<?php echo sprintf('<a href="users.php?id=%d">%s <em> &lt;%s&gt;</em></a>',
-                    $row['user_id'], $row['name'], $row['email']); ?></td>
+            <td><a class="truncate" style="max-width:250px" href="users.php?id="<?php
+                echo $T['user_id']; ?>><?php echo Format::htmlchars($T['user__name']);
+                    ?> <em>&lt;<?php echo Format::htmlchars($T['user__default_email__address']);
+                    ?>&gt;</em</a>
+            </td>
             <?php
             } ?>
         </tr>
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index f8013df254662376ad4546e6d10d3c0cf115813e..99c52d00e047d6768d9e59c746de86ffab421028 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -93,19 +93,21 @@ if ($status)
 
 // Impose visibility constraints
 // ------------------------------------------------------------
-// -- Open and assigned to me
-$visibility = array(
-    new Q(array('status__state'=>'open', 'staff_id' => $thisstaff->getId()))
-);
-// -- Routed to a department of mine
-if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts()))
-    $visibility[] = new Q(array('dept_id__in' => $depts));
-// -- Open and assigned to a team of mine
-if (($teams = $thisstaff->getTeams()) && count(array_filter($teams)))
-    $visibility[] = new Q(array(
-        'team_id__in' => array_filter($teams), 'status__state'=>'open'
-    ));
-$tickets->filter(Q::any($visibility));
+if (!$thisstaff->getRole()->hasPerm(SearchBackend::PERM_EVERYTHING)) {
+    // -- Open and assigned to me
+    $visibility = array(
+        new Q(array('status__state'=>'open', 'staff_id' => $thisstaff->getId()))
+    );
+    // -- Routed to a department of mine
+    if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts()))
+        $visibility[] = new Q(array('dept_id__in' => $depts));
+    // -- Open and assigned to a team of mine
+    if (($teams = $thisstaff->getTeams()) && count(array_filter($teams)))
+        $visibility[] = new Q(array(
+            'team_id__in' => array_filter($teams), 'status__state'=>'open'
+        ));
+    $tickets->filter(Q::any($visibility));
+}
 
 // Add in annotations
 $tickets->annotate(array(