diff --git a/include/class.queue.php b/include/class.queue.php
index 4180162d566ee09abf694bd9d3982f983c6edda8..92ad23ae55f88659acdb2865a3ee57db2dbe3b79 100644
--- a/include/class.queue.php
+++ b/include/class.queue.php
@@ -1245,10 +1245,10 @@ extends QueueColumnAnnotation {
 
         return $query
             ->annotate(array(
-                '_locked' => new SqlExpr(array(new Q(array(
+                '_locked' => new SqlExpr(new Q(array(
                     'lock__expire__gt' => SqlFunction::NOW(),
                     Q::not(array('lock__staff_id' => $thisstaff->getId())),
-                ))))
+                )))
             ));
     }
 
@@ -1262,6 +1262,65 @@ extends QueueColumnAnnotation {
     }
 }
 
+class AssigneeAvatarDecoration
+extends QueueColumnAnnotation {
+    static $icon = "user";
+    static $desc = /* @trans */ 'Assignee Avatar';
+
+    function annotate($query) {
+        return $query->values('staff_id', 'team_id');
+    }
+
+    function getDecoration($row, $text) {
+        if ($row['staff_id'] && ($staff = Staff::lookup($row['staff_id'])))
+            return sprintf('<span class="avatar">%s</span>',
+                $staff->getAvatar(16));
+        elseif ($row['team_id'] && ($team = Team::lookup($row['team_id']))) {
+            $avatars = [];
+            foreach ($team->getMembers() as $T)
+                $avatars[] = $T->getAvatar(16);
+            return sprintf('<span class="avatar group %s">%s</span>',
+                count($avatars), implode('', $avatars));
+        }
+    }
+
+    function isVisible($row) {
+        return $row['staff_id'] + $row['team_id'] > 0;
+    }
+
+    function getWidth($row) {
+        if (!$this->isVisible($row))
+            return 0;
+
+        // If assigned to a team with no members, return 0 width
+        $width = 10;
+        if ($row['team_id'] && ($team = Team::lookup($row['team_id'])))
+            $width += (count($team->getMembers()) - 1) * 10;
+
+        return $width ? $width + 10 : $width;
+    }
+}
+
+class UserAvatarDecoration
+extends QueueColumnAnnotation {
+    static $icon = "user";
+    static $desc = /* @trans */ 'User Avatar';
+
+    function annotate($query) {
+        return $query->values('user_id');
+    }
+
+    function getDecoration($row, $text) {
+        if ($row['user_id'] && ($user = User::lookup($row['user_id'])))
+            return sprintf('<span class="avatar">%s</span>',
+                $user->getAvatar(16));
+    }
+
+    function isVisible($row) {
+        return $row['user_id'] > 0;
+    }
+}
+
 class DataSourceField
 extends ChoiceField {
     function getChoices($verbose=false) {
@@ -1548,8 +1607,9 @@ extends VerySimpleModel {
     }
 
     function getFilter() {
-         if ($this->filter)
-             return QueueColumnFilter::getInstance($this->filter);
+         if ($this->filter
+                && ($F = QueueColumnFilter::getInstance($this->filter)))
+            return $F;
      }
 
     function getName() {
@@ -2095,8 +2155,9 @@ abstract class QueueColumnFilter {
 
     static function getInstance($id) {
         if (isset(static::$registry[$id])) {
-            list(, $class) = static::$registry[$id];
-            return new $class();
+            list(, $class) = @static::$registry[$id];
+            if ($class && class_exists($class))
+                return new $class();
         }
     }
 
diff --git a/include/class.user.php b/include/class.user.php
index e4cadc37fb7eb51bebf45a9d1c6a8fbb0f37ea78..a24efed69de28ec41cb2b289edf3be086c086264 100644
--- a/include/class.user.php
+++ b/include/class.user.php
@@ -269,10 +269,13 @@ implements TemplateVariable, Searchable {
         return new EmailAddress($this->default_email->address);
     }
 
-    function getAvatar() {
+    function getAvatar($size=null) {
         global $cfg;
         $source = $cfg->getClientAvatarSource();
-        return $source->getAvatar($this);
+        $avatar = $source->getAvatar($this);
+        if (isset($size))
+            $avatar->setSize($size);
+        return $avatar;
     }
 
     function getFullName() {
diff --git a/scp/css/scp.css b/scp/css/scp.css
index c9e2f4d192e295530bc1f3ba77b3f81dbe908be7..725c169b9866d9be8827bbd6872d6a1352dfce17 100644
--- a/scp/css/scp.css
+++ b/scp/css/scp.css
@@ -1532,6 +1532,7 @@ a#post-note:hover {
     margin-left: -60px;
     display:inline-block;
     width:48px;
+    max-height:48px;
     height:auto;
 }
 .avatar {
@@ -1547,7 +1548,9 @@ img.avatar {
     margin-right: 5px;
 }
 .avatar > img.avatar {
-    width: 100%;
+    width: auto;
+    max-width: 100%;
+    max-height: 100%;
     height: auto;
 }
 .thread-entry .header {
@@ -3598,6 +3601,28 @@ a.attachment {
 .conditions .condition + .condition {
     margin-top: 10px;
 }
+img.avatar + img.avatar {
+    margin-left: -14px;
+    z-index: 1;
+    transition: margin-left 0.1s linear;
+}
+.avatar.group:hover > img.avatar + img.avatar {
+    margin-left: -4px;
+}
+.avatar.group {
+    position: relative;
+    z-index: 1;
+    transition: margin-right 0.1s linear;
+}
+
+.avatar.group.\32:hover { margin-right: -10px; }
+.avatar.group.\33:hover { margin-right: -20px; }
+.avatar.group.\34:hover { margin-right: -30px; }
+.avatar.group.\35:hover { margin-right: -40px; }
+.avatar.group.\36:hover { margin-right: -50px; }
+.avatar.group.\37:hover { margin-right: -60px; }
+.avatar.group.\38:hover { margin-right: -70px; }
+.avatar.group.\39:hover { margin-right: -80px; }
 
 /* FIXME: Drop this with select2 4.0.1
  * Fixes a rendering issue on Safari