diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index 6d726f5a189631861aa7986970284563bc52e573..fbb8425bdaab9f65da2b833974ab2f8f62e10bd8 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -405,31 +405,44 @@ class TicketsAjaxAPI extends AjaxController {
     }
 
 
-    function assign($tid, $to=null) {
+    function assign($tid, $target=null) {
         global $thisstaff;
 
         if (!($ticket=Ticket::lookup($tid)))
             Http::response(404, __('No such ticket'));
 
-        if (!$ticket->checkStaffPerm($thisstaff, Ticket::PERM_ASSIGN))
+        if (!$ticket->checkStaffPerm($thisstaff, Ticket::PERM_ASSIGN)
+                || !($form = $ticket->getAssignmentForm($_POST,
+                        array('target' => $target))))
             Http::response(403, __('Permission Denied'));
 
         $errors = array();
         $info = array(
                 ':title' => sprintf(__('Ticket #%s: %s'),
                     $ticket->getNumber(),
-                    $ticket->isAssigned() ? __('Reassign') :  __('Assign')),
+                    sprintf('%s %s',
+                        $ticket->isAssigned() ?
+                            __('Reassign') :  __('Assign'),
+                        !strcasecmp($target, 'agents') ?
+                            __('to an Agent') : __('to a Team')
+                    )),
                 ':action' => sprintf('#tickets/%d/assign%s',
                     $ticket->getId(),
-                    ($to  ? "/$to": '')),
+                    ($target  ? "/$target": '')),
                 );
+
         if ($ticket->isAssigned()) {
-            $info['notice'] = sprintf(__('%s is currently assigned to %s'),
-                    __('Ticket'),
-                    $ticket->getAssigned());
+            if ($ticket->getStaffId() == $thisstaff->getId())
+                $assigned = __('you');
+            else
+                $assigned = $ticket->getAssigned();
+
+            $info['notice'] = sprintf(__('%s is currently assigned to <b>%s</b>'),
+                    __('This ticket'),
+                    Format::htmlchars($assigned)
+                    );
         }
 
-        $form = $ticket->getAssignmentForm($_POST);
         if ($_POST && $form->isValid()) {
             if ($ticket->assign($form, $errors)) {
                 $_SESSION['::sysmsgs']['msg'] = sprintf(
@@ -449,9 +462,69 @@ class TicketsAjaxAPI extends AjaxController {
         include STAFFINC_DIR . 'templates/assign.tmpl.php';
     }
 
-    function massProcess($action)  {
+    function claim($tid) {
+
         global $thisstaff;
 
+        if (!($ticket=Ticket::lookup($tid)))
+            Http::response(404, __('No such ticket'));
+
+        // Check for premissions and such
+        if (!$ticket->checkStaffPerm($thisstaff, Ticket::PERM_ASSIGN)
+                || !$ticket->isOpen() // Claim only open
+                || $ticket->getStaff() // cannot claim assigned ticket
+                || !($form = $ticket->getClaimForm($_POST)))
+            Http::response(403, __('Permission Denied'));
+
+        $errors = array();
+        $info = array(
+                ':title' => sprintf(__('Ticket #%s: %s'),
+                    $ticket->getNumber(),
+                    __('Claim')),
+                ':action' => sprintf('#tickets/%d/claim',
+                    $ticket->getId()),
+
+                );
+
+        if ($ticket->isAssigned()) {
+            if ($ticket->getStaffId() == $thisstaff->getId())
+                $assigned = __('you');
+            else
+                $assigneed = $ticket->getAssigned();
+
+            $info['error'] = sprintf(__('%s is currently assigned to <b>%s</b>'),
+                    __('This ticket'),
+                    $assigned);
+        } else {
+            $info['warn'] = sprintf(__('Are you sure you want to claim %s?'),
+                    __('this ticket'));
+        }
+
+        if ($_POST && $form->isValid()) {
+            if ($ticket->claim($form, $errors)) {
+                $_SESSION['::sysmsgs']['msg'] = sprintf(
+                        __('%s successfully'),
+                        sprintf(
+                            __('%s assigned to %s'),
+                            __('Ticket'),
+                            __('you'))
+                        );
+                Http::response(201, $ticket->getId());
+            }
+
+            $form->addErrors($errors);
+            $info['error'] = $errors['err'] ?: __('Unable to claim ticket');
+        }
+
+        $verb = sprintf('%s, %s', __('Yes'), __('Claim'));
+
+        include STAFFINC_DIR . 'templates/assign.tmpl.php';
+
+    }
+
+    function massProcess($action, $w=null)  {
+        global $thisstaff, $cfg;
+
         $actions = array(
                 'transfer' => array(
                     'verbed' => __('transferred'),
@@ -459,6 +532,9 @@ class TicketsAjaxAPI extends AjaxController {
                 'assign' => array(
                     'verbed' => __('assigned'),
                     ),
+                'claim' => array(
+                    'verbed' => __('assigned'),
+                    ),
                 'delete' => array(
                     'verbed' => __('deleted'),
                     ),
@@ -486,12 +562,102 @@ class TicketsAjaxAPI extends AjaxController {
             $count  =  $_REQUEST['count'];
         }
         switch ($action) {
+        case 'claim':
+            $w = 'me';
         case 'assign':
             $inc = 'assign.tmpl.php';
-            $info[':action'] = '#tickets/mass/assign';
+            $info[':action'] = "#tickets/mass/assign/$w";
             $info[':title'] = sprintf('Assign %s',
                     _N('selected ticket', 'selected tickets', $count));
+
             $form = AssignmentForm::instantiate($_POST);
+
+            $assignCB = function($t, $f, $e) {
+                return $t->assign($f, $e);
+            };
+
+            $assignees = null;
+            switch ($w) {
+                case 'agents':
+                    $depts = array();
+                    $tids = $_POST['tids'] ?: array_filter(explode(',', $_REQUEST['tids']));
+                    if ($tids) {
+                        $tickets = TicketModel::objects()
+                            ->distinct('dept_id')
+                            ->filter(array('ticket_id__in' => $tids));
+
+                        $depts = $tickets->values_flat('dept_id');
+                    }
+                    $members = Staff::objects()
+                        ->distinct('staff_id')
+                        ->filter(array(
+                                    'onvacation' => 0,
+                                    'isactive' => 1,
+                                    )
+                                );
+
+                    if ($depts) {
+                        $members->filter(Q::any( array(
+                                        'dept_id__in' => $depts,
+                                        Q::all(array(
+                                            'dept_access__dept__id__in' => $depts,
+                                            Q::not(array('dept_access__dept__flags__hasbit'
+                                                => Dept::FLAG_ASSIGN_MEMBERS_ONLY))
+                                            ))
+                                        )));
+                    }
+
+                    switch ($cfg->getAgentNameFormat()) {
+                    case 'last':
+                    case 'lastfirst':
+                    case 'legal':
+                        $members->order_by('lastname', 'firstname');
+                        break;
+
+                    default:
+                        $members->order_by('firstname', 'lastname');
+                    }
+
+                    $prompt  = __('Select an Agent');
+                    $assignees = array();
+                    foreach ($members as $member)
+                         $assignees['s'.$member->getId()] = $member->getName();
+
+                    if (!$assignees)
+                        $info['warn'] =  __('No agents available for assignment');
+                    break;
+                case 'teams':
+                    $assignees = array();
+                    $prompt = __('Select a Team');
+                    foreach (Team::getActiveTeams() as $id => $name)
+                        $assignees['t'.$id] = $name;
+
+                    if (!$assignees)
+                        $info['warn'] =  __('No teams available for assignment');
+                    break;
+                case 'me':
+                    $info[':action'] = '#tickets/mass/claim';
+                    $info[':title'] = sprintf('Claim %s',
+                            _N('selected ticket', 'selected tickets', $count));
+                    $info['warn'] = sprintf(__('Are you sure you want to claim %s?'),
+                                _N('selected ticket', 'selected tickets', $count));
+                    $verb = sprintf('%s, %s', __('Yes'), __('Claim'));
+                    $id = sprintf('s%s', $thisstaff->getId());
+                    $assignees = array($id => $thisstaff->getName());
+                    $vars = $_POST ?: array('assignee' => array($id));
+                    $form = ClaimForm::instantiate($vars);
+                    $assignCB = function($t, $f, $e) {
+                        return $t->claim($f, $e);
+                    };
+                    break;
+            }
+
+            if ($assignees != null)
+                $form->setAssignees($assignees);
+
+            if ($prompt && ($f=$form->getField('assignee')))
+                $f->configure('prompt', $prompt);
+
             if ($_POST && $form->isValid()) {
                 foreach ($_POST['tids'] as $tid) {
                     if (($t=Ticket::lookup($tid))
@@ -499,7 +665,7 @@ class TicketsAjaxAPI extends AjaxController {
                             // access and assign the task.
                             && $t->checkStaffPerm($thisstaff, Ticket::PERM_ASSIGN)
                             // Do the assignment
-                            && $t->assign($form, $e)
+                            && $assignCB($t, $form, $e)
                             )
                         $i++;
                 }
diff --git a/include/class.dept.php b/include/class.dept.php
index 0f74f4cf8e0f02f1fcff3491ba4455ab7a0e0b7c..5e916a8167cafdf8e8a7c8e8e4bbe273bd5d2bfc 100644
--- a/include/class.dept.php
+++ b/include/class.dept.php
@@ -205,6 +205,17 @@ implements TemplateVariable {
         return $this->getMembers(array('available'=>1));
     }
 
+    // Get members  eligible members only
+    function getAssignees() {
+
+        $members = clone $this->getAvailableMembers();
+        // If restricted then filter to primary members ONLY!
+        if ($this->assignMembersOnly())
+            $members->filter(array('dept_id' => $this->getId()));
+
+        return $members;
+    }
+
     function getMembersForAlerts() {
         if ($this->isGroupMembershipEnabled() == self::ALERTS_DISABLED) {
             // Disabled for this department
diff --git a/include/class.forms.php b/include/class.forms.php
index 7e092ad9a65c028d17f0e1da2abac5785074d14b..bacd0dd799683209bcb890780cf29d923b7cd919 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -2233,10 +2233,14 @@ class AssigneeField extends ChoiceField {
         return true;
     }
 
+    function setChoices($choices) {
+        $this->_choices = $choices;
+    }
+
     function getChoices() {
         global $cfg;
 
-        if (!$this->_choices) {
+        if (!isset($this->_choices)) {
             $config = $this->getConfiguration();
             $choices = array(
                     __('Agents') => new ArrayObject(),
@@ -2257,7 +2261,7 @@ class AssigneeField extends ChoiceField {
 
             next($choices);
             $T = current($choices);
-            if (($teams = Team::getTeams()))
+            if (($teams = Team::getActiveTeams()))
                 foreach ($teams as $id => $name)
                     $T['t'.$id] = $name;
 
@@ -3239,7 +3243,9 @@ class ChoicesWidget extends Widget {
     }
 
     function emitComplexChoices($choices, $values=array(), $have_def=false, $def_key=null) {
-        foreach ($choices as $label => $group) { ?>
+        foreach ($choices as $label => $group) {
+            if (!count($group)) continue;
+            ?>
             <optgroup label="<?php echo $label; ?>"><?php
             foreach ($group as $key => $name) {
                 if (!$have_def && $key == $def_key)
@@ -3810,6 +3816,10 @@ class VisibilityConstraint {
     }
 
     function emitJavascript($field) {
+
+        if (!$this->constraint->constraints)
+            return;
+
         $func = 'recheck';
         $form = $field->getForm();
 ?>
@@ -3851,6 +3861,12 @@ class VisibilityConstraint {
      * Determines if the field was visible when the form was submitted
      */
     function isVisible($field) {
+
+        // Assume initial visibility if constraint is not provided.
+        if (!$this->constraint->constraints)
+            return $this->initial == self::VISIBLE;
+
+
         return $this->compileQPhp($this->constraint, $field);
     }
 
@@ -3942,14 +3958,8 @@ class AssignmentForm extends Form {
 
     static $id = 'assign';
     var $_assignee = null;
-    var $_dept = null;
+    var $_assignees = null;
 
-    function __construct($source=null, $options=array()) {
-        parent::__construct($source, $options);
-        // Department of the object -- if necessary to limit assinees
-        if (isset($options['dept']))
-            $this->_dept = $options['dept'];
-    }
 
     function getFields() {
 
@@ -3967,7 +3977,6 @@ class AssignmentForm extends Form {
                         'criteria' => array(
                             'available' => true,
                             ),
-                        'dept' => $this->_dept ?: null,
                        ),
                     )
                 ),
@@ -3985,26 +3994,41 @@ class AssignmentForm extends Form {
                 ),
             );
 
+
+        if (isset($this->_assignees))
+            $fields['assignee']->setChoices($this->_assignees);
+
+
         $this->setFields($fields);
 
         return $this->fields;
     }
 
+    function getField($name) {
+
+        if (($fields = $this->getFields())
+                && isset($fields[$name]))
+            return $fields[$name];
+    }
+
     function isValid() {
 
-        if (!parent::isValid())
+        if (!parent::isValid() || !($f=$this->getField('assignee')))
             return false;
 
         // Do additional assignment validation
         if (!($assignee = $this->getAssignee())) {
-            $this->getField('assignee')->addError(
-                    __('Unknown assignee'));
+            $f->addError(__('Unknown assignee'));
         } elseif ($assignee instanceof Staff) {
             // Make sure the agent is available
             if (!$assignee->isAvailable())
-                $this->getField('assignee')->addError(
-                        __('Agent is unavailable for assignment')
-                        );
+                $f->addError(__('Agent is unavailable for assignment'));
+        } elseif ($assignee instanceof Team) {
+            // Make sure the team is active and has members
+            if (!$assignee->isActive())
+                $f->addError(__('Team is disabled'));
+            elseif (!$assignee->getNumMembers())
+                $f->addError(__('Team does not have members'));
         }
 
         return !$this->errors();
@@ -4025,6 +4049,15 @@ class AssignmentForm extends Form {
         include $inc;
     }
 
+    function setAssignees($assignees) {
+        $this->_assignees = $assignees;
+        $this->_fields = array();
+    }
+
+    function getAssignees() {
+        return $this->_assignees;
+    }
+
     function getAssignee() {
 
         if (!isset($this->_assignee))
@@ -4033,11 +4066,45 @@ class AssignmentForm extends Form {
         return $this->_assignee;
     }
 
-    function assigneeCriteria() {
-        $dept = $this->id;
-        return function () use($dept) {
-            return array('dept_id' =>$dept);
-        };
+    function getComments() {
+        return $this->getField('comments')->getClean();
+    }
+}
+
+class ClaimForm extends AssignmentForm {
+
+    var $_fields;
+
+    function setFields($fields) {
+        $this->_fields = $fields;
+        parent::setFields($fields);
+    }
+
+    function getFields() {
+
+        if ($this->_fields)
+            return $this->_fields;
+
+        $fields = parent::getFields();
+
+        // Disable && hide assignee field selection
+        if (isset($fields['assignee'])) {
+            $visibility = new VisibilityConstraint(
+                    new Q(array()), VisibilityConstraint::HIDDEN);
+
+            $fields['assignee']->set('visibility', $visibility);
+        }
+
+        // Change coments placeholder to reflect claim
+        if (isset($fields['comments'])) {
+            $fields['comments']->configure('placeholder',
+                    __('Optional reason for the claim'));
+        }
+
+
+        $this->setFields($fields);
+
+        return $this->fields;
     }
 
 }
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 3fe355de2a1e8f807e59d3d447e5513626c526c3..b8e6b55828ccc48744fd19a67688b57a40c64d5c 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -852,12 +852,58 @@ implements RestrictedAccess, Threadable {
 
     function getAssignmentForm($source=null, $options=array()) {
 
+        $prompt = $assignee = '';
+        // Possible assignees
+        $assignees = array();
+        switch (strtolower($options['target'])) {
+            case 'agents':
+                $dept = $this->getDept();
+                foreach ($dept->getAssignees() as $member)
+                    $assignees['s'.$member->getId()] = $member;
+
+                if (!$source && $this->isOpen() && $this->staff)
+                    $assignee = sprintf('s%d', $this->staff->getId());
+                $prompt = __('Select an Agent');
+                break;
+            case 'teams':
+                if (($teams = Team::getActiveTeams()))
+                    foreach ($teams as $id => $name)
+                        $assignees['t'.$id] = $name;
+
+                if (!$source && $this->isOpen() && $this->team)
+                    $assignee = sprintf('s%d', $this->team->getId());
+                $prompt = __('Select a Team');
+                break;
+        }
+
+        // Default to current assignee if source is not set
         if (!$source)
-            $source = array('assignee' => array($this->getAssigneeId()));
+            $source = array('assignee' => array($assignee));
+
+        $form = AssignmentForm::instantiate($source, $options);
+
+        if ($assignees)
+            $form->setAssignees($assignees);
+
+        if ($prompt && ($f=$form->getField('assignee')))
+            $f->configure('prompt', $prompt);
+
+
+        return $form;
+    }
 
-        $options += array('dept' => $this->getDept());
+    function getClaimForm($source=null, $options=array()) {
+        global $thisstaff;
+
+        $id = sprintf('s%d', $thisstaff->getId());
+        if(!$source)
+            $source = array('assignee' => array($id));
+
+        $form = ClaimForm::instantiate($source, $options);
+        $form->setAssignees(array($id => $thisstaff->getName()));
+
+        return $form;
 
-        return AssignmentForm::instantiate($source, $options);
     }
 
     function getTransferForm($source=null) {
@@ -2025,17 +2071,25 @@ implements RestrictedAccess, Threadable {
          return true;
     }
 
-    function claim() {
+    function claim(ClaimForm $form, &$errors) {
         global $thisstaff;
 
-        if (!$thisstaff || !$this->isOpen() || $this->isAssigned())
-            return false;
-
         $dept = $this->getDept();
-        if ($dept->assignMembersOnly() && !$dept->isMember($thisstaff))
+        $assignee = $form->getAssignee();
+        if (!($assignee instanceof Staff)
+                || !$thisstaff
+                || $thisstaff->getId() != $assignee->getId()) {
+            $errors['err'] = __('Unknown assignee');
+        } elseif (!$assignee->isAvailable()) {
+            $errors['err'] = __('Agent is unavailable for assignment');
+        } elseif ($dept->assignMembersOnly() && !$dept->isMember($assignee)) {
+            $errors['err'] = __('Permission denied');
+        }
+
+        if ($errors)
             return false;
 
-        return $this->assignToStaff($thisstaff->getId(), null, false);
+        return $this->assignToStaff($assignee, $form->getComments(), false);
     }
 
     function assignToStaff($staff, $note, $alert=true) {
@@ -2085,6 +2139,7 @@ implements RestrictedAccess, Threadable {
         $evd = array();
         $assignee = $form->getAssignee();
         if ($assignee instanceof Staff) {
+            $dept = $this->getDept();
             if ($this->getStaffId() == $assignee->getId()) {
                 $errors['assignee'] = sprintf(__('%s already assigned to %s'),
                         __('Ticket'),
@@ -2092,6 +2147,8 @@ implements RestrictedAccess, Threadable {
                         );
             } elseif(!$assignee->isAvailable()) {
                 $errors['assignee'] = __('Agent is unavailable for assignment');
+            } elseif ($dept->assignMembersOnly() && !$dept->isMember($assignee)) {
+                $errors['err'] = __('Permission denied');
             } else {
                 $this->staff_id = $assignee->getId();
                 if ($thisstaff && $thisstaff->getId() == $assignee->getId())
@@ -2118,9 +2175,7 @@ implements RestrictedAccess, Threadable {
 
         $this->logEvent('assigned', $evd);
 
-        $this->onAssign($assignee,
-                $form->getField('comments')->getClean(),
-                $alert);
+        $this->onAssign($assignee, $form->getComments(), $alert);
 
         return true;
     }
@@ -3303,7 +3358,7 @@ implements RestrictedAccess, Threadable {
 
         // Assign ticket to staff or team (new ticket by staff)
         if ($vars['assignId']) {
-            $asnform = new AssignmentForm(array('assignee' => $vars['assignId']));
+            $asnform = $ticket->AssignmentForm(array('assignee' => $vars['assignId']));
             $ticket->assign($asnform, $vars['note']);
         }
         else {
diff --git a/include/staff/templates/status-options.tmpl.php b/include/staff/templates/status-options.tmpl.php
index 1f9918f26ca44c70df7cd72e2af925d598cc84fe..3b493f37927b9cbf608f0a698fa06a8ca5c6e469 100644
--- a/include/staff/templates/status-options.tmpl.php
+++ b/include/staff/templates/status-options.tmpl.php
@@ -34,12 +34,11 @@ if (!$nextStatuses)
 
 <span
     class="action-button"
-    data-dropdown="#action-dropdown-statuses">
+    data-dropdown="#action-dropdown-statuses" data-placement="bottom" data-toggle="tooltip" title="<?php echo __('Change Status'); ?>">
     <i class="icon-caret-down pull-right"></i>
     <a class="tickets-action"
         href="#statuses"><i
-        class="icon-flag"></i> <?php
-        echo __('Change Status'); ?></a>
+        class="icon-flag"></i></a>
 </span>
 <div id="action-dropdown-statuses"
     class="action-dropdown anchor-right">
diff --git a/include/staff/templates/tickets-actions.tmpl.php b/include/staff/templates/tickets-actions.tmpl.php
index cdc741db90d6adcc8eee43e76b137bc783d264ef..0535a5af2832a7da0354b6fa53dc88373ff6f6ca 100644
--- a/include/staff/templates/tickets-actions.tmpl.php
+++ b/include/staff/templates/tickets-actions.tmpl.php
@@ -1,83 +1,77 @@
 <?php
 // Tickets mass actions based on logged in agent
 
+// Status change
 if ($agent->canManageTickets())
     echo TicketStatus::status_options();
 
-$actions = array();
-if ($agent->hasPerm(Ticket::PERM_ASSIGN, false)) {
-    $actions += array(
-            'assign' => array(
-                'icon' => 'icon-user',
-                'action' => __('Assign')
-            ));
+
+// Mass Claim/Assignment
+if ($agent->hasPerm(Ticket::PERM_ASSIGN, false)) {?>
+<span
+    class="action-button" data-placement="bottom"
+    data-dropdown="#action-dropdown-assign" data-toggle="tooltip" title=" <?php
+    echo __('Assign'); ?>">
+    <i class="icon-caret-down pull-right"></i>
+    <a class="tickets-action" id="tickets-assign"
+        href="#tickets/mass/assign"><i class="icon-user"></i></a>
+</span>
+<div id="action-dropdown-assign" class="action-dropdown anchor-right">
+  <ul>
+     <li><a class="no-pjax tickets-action"
+        href="#tickets/mass/claim"><i
+        class="icon-chevron-sign-down"></i> <?php echo __('Claim'); ?></a>
+     <li><a class="no-pjax tickets-action"
+        href="#tickets/mass/assign/agents"><i
+        class="icon-user"></i> <?php echo __('Agent'); ?></a>
+     <li><a class="no-pjax tickets-action"
+        href="#tickets/mass/assign/teams"><i
+        class="icon-group"></i> <?php echo __('Team'); ?></a>
+  </ul>
+</div>
+<?php
 }
 
-if ($agent->hasPerm(Ticket::PERM_TRANSFER, false)) {
-    $actions += array(
-            'transfer' => array(
-                'icon' => 'icon-share',
-                'action' => __('Transfer')
-            ));
+// Mass Transfer
+if ($agent->hasPerm(Ticket::PERM_TRANSFER, false)) {?>
+<span class="action-button">
+ <a class="tickets-action" id="tickets-transfer" data-placement="bottom"
+    data-toggle="tooltip" title="<?php echo __('Transfer'); ?>"
+    href="#tickets/mass/transfer"><i class="icon-share"></i></a>
+</span>
+<?php
 }
 
-if ($agent->hasPerm(Ticket::PERM_DELETE, false)) {
-    $actions += array(
-            'delete' => array(
-                'class' => 'danger',
-                'icon' => 'icon-trash',
-                'action' => __('Delete')
-            ));
+
+// Mass Delete
+if ($agent->hasPerm(Ticket::PERM_DELETE, false)) {?>
+<span class="red button action-button">
+ <a class="tickets-action" id="tickets-delete" data-placement="bottom"
+    data-toggle="tooltip" title="<?php echo __('Delete'); ?>"
+    href="#tickets/mass/delete"><i class="icon-trash"></i></a>
+</span>
+<?php
 }
-if ($actions) {
-    $more = $options['morelabel'] ?: __('More');
-    ?>
-    <span
-        class="action-button"
-        data-dropdown="#action-dropdown-moreoptions">
-        <i class="icon-caret-down pull-right"></i>
-        <a class="tickets-action"
-            href="#moreoptions"><i
-            class="icon-reorder"></i> <?php
-            echo $more; ?></a>
-    </span>
-    <div id="action-dropdown-moreoptions"
-        class="action-dropdown anchor-right">
-        <ul>
-    <?php foreach ($actions as $a => $action) { ?>
-            <li <?php
-                if ($action['class'])
-                    echo sprintf("class='%s'", $action['class']); ?> >
-                <a class="no-pjax tickets-action"
-                    <?php
-                    if ($action['dialog'])
-                        echo sprintf("data-dialog-config='%s'", $action['dialog']);
-                    if ($action['redirect'])
-                        echo sprintf("data-redirect='%s'", $action['redirect']);
-                    ?>
-                    href="<?php
-                    echo sprintf('#tickets/mass/%s', $a); ?>"
-                    ><i class="icon-fixed-width <?php
-                    echo $action['icon'] ?: 'icon-tag'; ?>"></i> <?php
-                    echo $action['action']; ?></a>
-            </li>
-        <?php
-        } ?>
-        </ul>
-    </div>
- <?php
- } ?>
+
+?>
 <script type="text/javascript">
 $(function() {
-    $(document).off('.tickets-actions');
-    $(document).on('click.tickets-actions', 'a.tickets-action', function(e) {
+
+    $(document).off('.tickets');
+    $(document).on('click.tickets', 'a.tickets-action', function(e) {
         e.preventDefault();
-        var count = checkbox_checker($('form#tickets'), 1);
+        var $form = $('form#tickets');
+        var count = checkbox_checker($form, 1);
         if (count) {
+            var tids = $('.ckb:checked', $form).map(function() {
+                    return this.value;
+                }).get();
             var url = 'ajax.php/'
             +$(this).attr('href').substr(1)
             +'?count='+count
+            +'&tids='+tids.join(',')
             +'&_uid='+new Date().getTime();
+            console.log(tids);
             $.dialog(url, [201], function (xhr) {
                 $.pjax.reload('#pjax-container');
              });
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index 156b2c323556a57f4de5771baae88a64eb123fc0..29a2d1fc1e490e094a7bfe27dd9fb4559ff0dc3d 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -60,46 +60,68 @@ if($ticket->isOverdue())
             if ($thisstaff->hasPerm(Email::PERM_BANLIST)
                     || $role->hasPerm(TicketModel::PERM_EDIT)
                     || ($dept && $dept->isManager($thisstaff))) { ?>
-            <span class="action-button pull-right" data-dropdown="#action-dropdown-more">
+            <span class="action-button pull-right" data-placement="bottom" data-dropdown="#action-dropdown-more" data-toggle="tooltip" title="<?php echo __('More');?>">
                 <i class="icon-caret-down pull-right"></i>
-                <span ><i class="icon-cog"></i> <?php echo __('More');?></span>
+                <span ><i class="icon-cog"></i></span>
             </span>
             <?php
             }
-            // Status change options
-            echo TicketStatus::status_options();
 
             if ($role->hasPerm(TicketModel::PERM_EDIT)) { ?>
-                <a class="action-button pull-right" href="tickets.php?id=<?php echo $ticket->getId(); ?>&a=edit"><i class="icon-edit"></i> <?php
-                    echo __('Edit'); ?></a>
+                <span class="action-button pull-right"><a data-placement="bottom" data-toggle="tooltip" title="<?php echo __('Edit'); ?>" href="tickets.php?id=<?php echo $ticket->getId(); ?>&a=edit"><i class="icon-edit"></i></a></span>
             <?php
             } ?>
+            <span class="action-button pull-right" data-placement="bottom" data-dropdown="#action-dropdown-print" data-toggle="tooltip" title="<?php echo __('Print'); ?>">
+                <i class="icon-caret-down pull-right"></i>
+                <a id="ticket-print" href="tickets.php?id=<?php echo $ticket->getId(); ?>&a=print"><i class="icon-print"></i></a>
+            </span>
+            <div id="action-dropdown-print" class="action-dropdown anchor-right">
+              <ul>
+                 <li><a class="no-pjax" target="_blank" href="tickets.php?id=<?php echo $ticket->getId(); ?>&a=print&notes=0"><i
+                 class="icon-file-alt"></i> <?php echo __('Ticket Thread'); ?></a>
+                 <li><a class="no-pjax" target="_blank" href="tickets.php?id=<?php echo $ticket->getId(); ?>&a=print&notes=1"><i
+                 class="icon-file-text-alt"></i> <?php echo __('Thread + Internal Notes'); ?></a>
+              </ul>
+            </div>
             <?php
             // Transfer
             if ($role->hasPerm(TicketModel::PERM_TRANSFER)) {?>
-            <a class="ticket-action action-button pull-right" id="ticket-transfer"
+            <span class="action-button pull-right">
+            <a class="ticket-action" id="ticket-transfer" data-placement="bottom" data-toggle="tooltip" title="<?php echo __('Transfer'); ?>"
                 data-redirect="tickets.php"
-                href="#tickets/<?php echo $ticket->getId(); ?>/transfer"><i class="icon-share"></i> <?php
-                echo __('Transfer'); ?></a>
+                href="#tickets/<?php echo $ticket->getId(); ?>/transfer"><i class="icon-share"></i></a>
+            </span>
             <?php
             } ?>
 
             <?php
             // Assign
-            if ($role->hasPerm(TicketModel::PERM_ASSIGN)) {?>
-            <span class="action-button pull-right" data-dropdown="#action-dropdown-assign">
+            if ($ticket->isOpen() && $role->hasPerm(TicketModel::PERM_ASSIGN)) {?>
+            <span class="action-button pull-right"
+                data-dropdown="#action-dropdown-assign"
+                data-placement="bottom"
+                data-toggle="tooltip"
+                title=" <?php echo $ticket->isAssigned() ? __('Assign') : __('Reassign'); ?>"
+                >
                 <i class="icon-caret-down pull-right"></i>
                 <a class="ticket-action" id="ticket-assign"
                     data-redirect="tickets.php"
-                    href="#tickets/<?php echo $ticket->getId(); ?>/assign"><i class="icon-user"></i> <?php
-                    echo $ticket->isAssigned() ? __('Assign') :  __('Reassign'); ?></a>
+                    href="#tickets/<?php echo $ticket->getId(); ?>/assign"><i class="icon-user"></i></a>
             </span>
             <div id="action-dropdown-assign" class="action-dropdown anchor-right">
               <ul>
+                <?php
+                // Agent can claim team assigned ticket
+                if (!$ticket->getStaff()
+                        && (!$dept->assignMembersOnly()
+                            || $dept->isMember($thisstaff))
+                        ) { ?>
                  <li><a class="no-pjax ticket-action"
                     data-redirect="tickets.php"
-                    href="#tickets/<?php echo $ticket->getId(); ?>/assign/<?php echo $thisstaff->getId(); ?>"><i
+                    href="#tickets/<?php echo $ticket->getId(); ?>/claim"><i
                     class="icon-chevron-sign-down"></i> <?php echo __('Claim'); ?></a>
+                <?php
+                } ?>
                  <li><a class="no-pjax ticket-action"
                     data-redirect="tickets.php"
                     href="#tickets/<?php echo $ticket->getId(); ?>/assign/agents"><i
@@ -112,19 +134,6 @@ if($ticket->isOverdue())
             </div>
             <?php
             } ?>
-            <span class="action-button pull-right" data-dropdown="#action-dropdown-print">
-                <i class="icon-caret-down pull-right"></i>
-                <a id="ticket-print" href="tickets.php?id=<?php echo $ticket->getId(); ?>&a=print"><i class="icon-print"></i> <?php
-                    echo __('Print'); ?></a>
-            </span>
-            <div id="action-dropdown-print" class="action-dropdown anchor-right">
-              <ul>
-                 <li><a class="no-pjax" target="_blank" href="tickets.php?id=<?php echo $ticket->getId(); ?>&a=print&notes=0"><i
-                 class="icon-file-alt"></i> <?php echo __('Ticket Thread'); ?></a>
-                 <li><a class="no-pjax" target="_blank" href="tickets.php?id=<?php echo $ticket->getId(); ?>&a=print&notes=1"><i
-                 class="icon-file-text-alt"></i> <?php echo __('Thread + Internal Notes'); ?></a>
-              </ul>
-            </div>
             <div id="action-dropdown-more" class="action-dropdown anchor-right">
               <ul>
                 <?php
@@ -191,7 +200,20 @@ if($ticket->isOverdue())
                 ?>
               </ul>
             </div>
-        </div>
+                <?php
+                if ($role->hasPerm(TicketModel::PERM_REPLY)) { ?>
+                <a href="#post-reply" class="post-response action-button"
+                data-placement="bottom" data-toggle="tooltip"
+                title="<?php echo __('Post Reply'); ?>"><i class="icon-mail-reply"></i></a>
+                <?php
+                } ?>
+                <a href="#post-note" id="post-note" class="post-response action-button"
+                data-placement="bottom" data-toggle="tooltip"
+                title="<?php echo __('Post Internal Note'); ?>"><i class="icon-file-text"></i></a>
+                <?php // Status change options
+                echo TicketStatus::status_options();
+                ?>
+           </div>
         <div class="flush-left">
              <h2><a href="tickets.php?id=<?php echo $ticket->getId(); ?>"
              title="<?php echo __('Reload'); ?>"><i class="icon-refresh"></i>
@@ -456,7 +478,8 @@ echo $v;
 $tcount = $ticket->getThreadEntries($types)->count();
 ?>
 <ul  class="tabs clean threads" id="ticket_tabs" >
-    <li class="active"><a href="#ticket_thread"><?php echo sprintf(__('Ticket Thread (%d)'), $tcount); ?></a></li>
+    <li class="active"><a id="ticket-thread-tab" href="#ticket_thread"><?php
+        echo sprintf(__('Ticket Thread (%d)'), $tcount); ?></a></li>
     <li><a id="ticket-tasks-tab" href="#tasks"
             data-url="<?php
         echo sprintf('#tickets/%d/tasks', $ticket->getId()); ?>"><?php
@@ -468,6 +491,7 @@ $tcount = $ticket->getThreadEntries($types)->count();
 
 <div id="ticket_tabs_container">
 <div id="ticket_thread" class="tab_content">
+
 <?php
     // Render ticket thread
     $ticket->getThread()->render(
@@ -478,23 +502,31 @@ $tcount = $ticket->getThreadEntries($types)->count();
             );
 ?>
 <div class="clear"></div>
-<?php if($errors['err']) { ?>
-    <div id="msg_error"><?php echo $errors['err']; ?></div>
-<?php }elseif($msg) { ?>
+<?php
+if ($errors['err'] && isset($_POST['a'])) {
+    // Reflect errors back to the tab.
+    $errors[$_POST['a']] = $errors['err'];
+} elseif($msg) { ?>
     <div id="msg_notice"><?php echo $msg; ?></div>
-<?php }elseif($warn) { ?>
+<?php
+} elseif($warn) { ?>
     <div id="msg_warning"><?php echo $warn; ?></div>
-<?php } ?>
+<?php
+} ?>
 
 <div class="sticky bar stop actions" id="response_options"
 >
-    <ul class="tabs">
+    <ul class="tabs" id="response-tabs">
         <?php
         if ($role->hasPerm(TicketModel::PERM_REPLY)) { ?>
-        <li class="active"><a href="#reply"><?php echo __('Post Reply');?></a></li>
+        <li class="active <?php
+            echo isset($errors['reply']) ? 'error' : ''; ?>"><a
+            href="#reply" id="post-reply-tab"><?php echo __('Post Reply');?></a></li>
         <?php
         } ?>
-        <li><a href="#note"><?php echo __('Post Internal Note');?></a></li>
+        <li><a href="#note" <?php
+            echo isset($errors['postnote']) ?  'class="error"' : ''; ?>
+            id="post-note-tab"><?php echo __('Post Internal Note');?></a></li>
     </ul>
     <?php
     if ($role->hasPerm(TicketModel::PERM_REPLY)) { ?>
@@ -508,8 +540,12 @@ $tcount = $ticket->getThreadEntries($types)->count();
         <input type="hidden" name="msgId" value="<?php echo $msgId; ?>">
         <input type="hidden" name="a" value="reply">
         <input type="hidden" name="lockCode" value="<?php echo $mylock ? $mylock->getCode() : ''; ?>">
-        <span class="error"></span>
         <table style="width:100%" border="0" cellspacing="0" cellpadding="3">
+            <?php
+            if ($errors['reply']) {?>
+            <tr><td width="120">&nbsp;</td><td class="error"><?php echo $errors['reply']; ?>&nbsp;</td></tr>
+            <?php
+            }?>
            <tbody id="to_sec">
             <tr>
                 <td width="120">
@@ -896,5 +932,30 @@ $(function() {
             }
         });
     });
+
+    // Post Reply or Note action buttons.
+    $('a.post-response').click(function (e) {
+        var $r = $('ul.tabs > li > a'+$(this).attr('href')+'-tab');
+        if ($r.length) {
+            // Make sure ticket thread tab is visiable.
+            var $t = $('ul#ticket_tabs > li > a#ticket-thread-tab');
+            if ($t.length && !$t.hasClass('active'))
+                $t.trigger('click');
+            // Make the target response tab active.
+            if (!$r.hasClass('active'))
+                $r.trigger('click');
+
+            // Scroll to the response section.
+            var $stop = $(document).height();
+            var $s = $('div#response_options');
+            if ($s.length)
+                $stop = $s.offset().top-125
+
+            $('html, body').animate({scrollTop: $stop}, 'fast');
+        }
+
+        return false;
+    });
+
 });
 </script>
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index 690f6c2066fefa03c4b2e78b7e39a6919b08f610..d015d1cfad8bbf536fb74291209f3eb01d34a602 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -586,21 +586,6 @@ return false;">
 </div>
 <script type="text/javascript">
 $(function() {
-    $(document).off('.tickets');
-    $(document).on('click.tickets', 'a.tickets-action', function(e) {
-        e.preventDefault();
-        var count = checkbox_checker($('form#tickets'), 1);
-        if (count) {
-            var url = 'ajax.php/'
-            +$(this).attr('href').substr(1)
-            +'?count='+count
-            +'&_uid='+new Date().getTime();
-            $.dialog(url, [201], function (xhr) {
-                $.pjax({url: 'tickets.php', container: '#pjax-container'});
-             });
-        }
-        return false;
-    });
     $('[data-toggle=tooltip]').tooltip();
 });
 </script>
diff --git a/scp/ajax.php b/scp/ajax.php
index 78682a36315846be8c87295a22d80d1ef521def6..8fcb6146f2f9e6d97bdc2567ac6a22c6259f2e6a 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -161,10 +161,10 @@ $dispatcher = patterns('',
         url_get('^(?P<tid>\d+)/tasks/(?P<id>\d+)/view$', 'task'),
         url_post('^(?P<tid>\d+)/tasks/(?P<id>\d+)$', 'task'),
         url_get('^lookup', 'lookup'),
-        url_get('^mass/(?P<action>[\w.]+)', 'massProcess'),
-        url_post('^mass/(?P<action>[\w.]+)', 'massProcess'),
+        url('^mass/(?P<action>\w+)(?:/(?P<what>\w+))?', 'massProcess'),
         url('^(?P<tid>\d+)/transfer$', 'transfer'),
         url('^(?P<tid>\d+)/assign(?:/(?P<to>\w+))?$', 'assign'),
+        url('^(?P<tid>\d+)/claim$', 'claim'),
         url('^search', patterns('ajax.search.php:SearchAjaxAPI',
             url_get('^$', 'getAdvancedSearchDialog'),
             url_post('^$', 'doSearch'),
diff --git a/scp/css/dropdown.css b/scp/css/dropdown.css
index c0b90c83a9fc3b080df495c16e74c18380b88770..1106463645a48208b3526afe37ee08423e7db3ff 100644
--- a/scp/css/dropdown.css
+++ b/scp/css/dropdown.css
@@ -5,7 +5,7 @@
 
 .action-dropdown {
   position: absolute;
-  z-index: 9999999;
+  z-index: 9999998;
   display: none;
   margin-top: 8px;
 }
diff --git a/scp/css/scp.css b/scp/css/scp.css
index 5b3141cb176ffa6c468c89c6a4bea4a58ef8a2fd..73c0e0029ce6eee6905006512fd2b9abf8ca2ba9 100644
--- a/scp/css/scp.css
+++ b/scp/css/scp.css
@@ -904,6 +904,12 @@ h2 .reload {
     border-bottom:none;
     margin:0;
 }
+/***** top page ticket response buttons *****/
+a#post-note:hover {
+    background-color:#fff9e2;
+    color:#555!IMPORTANT;
+}
+
 .thread-entry {
     margin-bottom: 15px;
     z-index: 0;
diff --git a/scp/css/tooltip.css b/scp/css/tooltip.css
index ae54e90fc6b05e52e73828a6a4fa8492244023bc..daecf02bccdecc1d1477b834066b8771723610b9 100644
--- a/scp/css/tooltip.css
+++ b/scp/css/tooltip.css
@@ -1,6 +1,6 @@
 .tooltip {
   position: absolute;
-  z-index: 1070;
+  z-index: 9999999;
   display: block;
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
   font-style: normal;
diff --git a/scp/js/scp.js b/scp/js/scp.js
index 94b3b699371c1208ddb25932dbeeef6bdfb25c5e..28162de01b9a026a35a573f8089a35658c98ebda 100644
--- a/scp/js/scp.js
+++ b/scp/js/scp.js
@@ -464,6 +464,10 @@ var scp_prep = function() {
 
   $('[data-toggle="tooltip"]').tooltip()
 
+  $('[data-toggle="tooltip"]').on('click', function() {
+        $(this).tooltip('hide');
+  });
+
   $('.attached.input input[autofocus]').parent().addClass('focus')
   $('.attached.input input')
     .on('focus', function() { $(this).parent().addClass('focus'); })