diff --git a/include/ajax.tasks.php b/include/ajax.tasks.php
index d987b56786a9f603ebdd315405bdeca4bb32ba2d..6c4c159244ab892151e2d385742fce5896dd9485 100644
--- a/include/ajax.tasks.php
+++ b/include/ajax.tasks.php
@@ -136,8 +136,8 @@ class TasksAjaxAPI extends AjaxController {
         include STAFFINC_DIR . 'templates/task-edit.tmpl.php';
     }
 
-    function massProcess($action)  {
-        global $thisstaff;
+    function massProcess($action, $w=null)  {
+        global $thisstaff, $cfg;
 
         $actions = array(
                 'transfer' => array(
@@ -146,6 +146,9 @@ class TasksAjaxAPI extends AjaxController {
                 'assign' => array(
                     'verbed' => __('assigned'),
                     ),
+                'claim' => array(
+                    'verbed' => __('claimed'),
+                    ),
                 'delete' => array(
                     'verbed' => __('deleted'),
                     ),
@@ -174,20 +177,112 @@ class TasksAjaxAPI extends AjaxController {
         }
 
         switch ($action) {
+        case 'claim':
+            $w = 'me';
         case 'assign':
             $inc = 'assign.tmpl.php';
-            $info[':action'] = '#tasks/mass/assign';
+            $info[':action'] = "#tasks/mass/assign/$w";
             $info[':title'] = sprintf('Assign %s',
                     _N('selected task', 'selected tasks', $count));
+
             $form = AssignmentForm::instantiate($_POST);
-            if ($_POST && $form->isValid()) {
+
+            $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) {
+                    $tasks = Task::objects()
+                        ->distinct('dept_id')
+                        ->filter(array('id__in' => $tids));
+                    $depts = $tasks->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'] = '#tasks/mass/claim';
+                $info[':title'] = sprintf('Claim %s',
+                        _N('selected task', 'selected tasks', $count));
+                $info['warn'] = sprintf(
+                        __('Are you sure you want to CLAIM %s?'),
+                        _N('selected task', 'selected tasks', $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() && !$errors) {
                 foreach ($_POST['tids'] as $tid) {
                     if (($t=Task::lookup($tid))
                             // Make sure the agent is allowed to
                             // access and assign the task.
                             && $t->checkStaffPerm($thisstaff, Task::PERM_ASSIGN)
-                            // Do the transfer
-                            && $t->assign($form, $e)
+                            // Do the assignment
+                            && $assignCB($t, $form, $e)
                             )
                         $i++;
                 }
@@ -230,19 +325,34 @@ class TasksAjaxAPI extends AjaxController {
             $info['status'] = 'open';
         case 'close':
             $inc = 'task-status.tmpl.php';
+            $info[':action'] = "#tasks/mass/$action";
             $info['status'] = $info['status'] ?: 'closed';
-            $perm = '';
+            $perm = $action = '';
             switch ($info['status']) {
             case 'open':
                 // If an agent can create a task then they're allowed to
                 // reopen closed ones.
                 $perm = Task::PERM_CREATE;
+                $info[':title'] = sprintf('Reopen %s',
+                         _N('selected task', 'selected tasks', $count));
+
+                $info['warn'] = sprintf(__('Are you sure you want to %s?'),
+                        sprintf(__('REOPEN %s'),
+                             _N('selected task', 'selected tasks', $count)
+                             ));
                 break;
             case 'closed':
                 $perm = Task::PERM_CLOSE;
+                $info[':title'] = sprintf('Close %s',
+                         _N('selected task', 'selected tasks', $count));
+
+                $info['warn'] = sprintf(__('Are you sure you want to %s?'),
+                        sprintf(__('CLOSE %s'),
+                             _N('selected task', 'selected tasks', $count)
+                             ));
                 break;
             default:
-                $errors['err'] = __('Unknown action');
+                Http::response(404, __('Unknown action'));
             }
             // Check generic permissions --  department specific permissions
             // will be checked below.
@@ -401,13 +511,15 @@ class TasksAjaxAPI extends AjaxController {
         include STAFFINC_DIR . 'templates/transfer.tmpl.php';
     }
 
-    function assign($tid) {
+    function assign($tid, $target=null) {
         global $thisstaff;
 
         if (!($task=Task::lookup($tid)))
             Http::response(404, __('No such task'));
 
-        if (!$task->checkStaffPerm($thisstaff, Task::PERM_ASSIGN))
+        if (!$task->checkStaffPerm($thisstaff, Task::PERM_ASSIGN)
+                || !($form=$task->getAssignmentForm($_POST, array(
+                            'target' => $target))))
             Http::response(403, __('Permission Denied'));
 
         $errors = array();
@@ -415,8 +527,9 @@ class TasksAjaxAPI extends AjaxController {
                 ':title' => sprintf(__('Task #%s: %s'),
                     $task->getNumber(),
                     $task->isAssigned() ? __('Reassign') :  __('Assign')),
-                ':action' => sprintf('#tasks/%d/assign',
-                    $task->getId()),
+                ':action' => sprintf('#tasks/%d/assign%s',
+                    $task->getId(),
+                    $target ? "/$target" : ''),
                 );
         if ($task->isAssigned()) {
             $info['notice'] = sprintf(__('%s is currently assigned to %s'),
@@ -424,7 +537,6 @@ class TasksAjaxAPI extends AjaxController {
                     $task->getAssigned());
         }
 
-        $form = $task->getAssignmentForm($_POST);
         if ($_POST && $form->isValid()) {
             if ($task->assign($form, $errors)) {
                 $_SESSION['::sysmsgs']['msg'] = sprintf(
@@ -444,6 +556,64 @@ class TasksAjaxAPI extends AjaxController {
         include STAFFINC_DIR . 'templates/assign.tmpl.php';
     }
 
+    function claim($tid) {
+
+        global $thisstaff;
+
+        if (!($task=Task::lookup($tid)))
+            Http::response(404, __('No such task'));
+
+        // Check for premissions and such
+        if (!$task->checkStaffPerm($thisstaff, Task::PERM_ASSIGN)
+                || !($form = $task->getClaimForm($_POST)))
+            Http::response(403, __('Permission Denied'));
+
+        $errors = array();
+        $info = array(
+                ':title' => sprintf(__('Task #%s: %s'),
+                    $task->getNumber(),
+                    __('Claim')),
+                ':action' => sprintf('#tasks/%d/claim',
+                    $task->getId()),
+
+                );
+
+        if ($task->isAssigned()) {
+            if ($task->getStaffId() == $thisstaff->getId())
+                $assigned = __('you');
+            else
+                $assigneed = $task->getAssigned();
+
+            $info['error'] = sprintf(__('%s is currently assigned to <b>%s</b>'),
+                    __('This task'),
+                    $assigned);
+        } else {
+            $info['warn'] = sprintf(__('Are you sure you want to CLAIM %s?'),
+                    __('this task'));
+        }
+
+        if ($_POST && $form->isValid()) {
+            if ($task->claim($form, $errors)) {
+                $_SESSION['::sysmsgs']['msg'] = sprintf(
+                        __('%s successfully'),
+                        sprintf(
+                            __('%s assigned to %s'),
+                            __('Task'),
+                            __('you'))
+                        );
+                Http::response(201, $task->getId());
+            }
+
+            $form->addErrors($errors);
+            $info['error'] = $errors['err'] ?: __('Unable to claim task');
+        }
+
+        $verb = sprintf('%s, %s', __('Yes'), __('Claim'));
+
+        include STAFFINC_DIR . 'templates/assign.tmpl.php';
+
+    }
+
    function delete($tid) {
         global $thisstaff;
 
@@ -487,6 +657,71 @@ class TasksAjaxAPI extends AjaxController {
         include STAFFINC_DIR . 'templates/delete.tmpl.php';
     }
 
+   function changeStatus($tid, $status) {
+        global $thisstaff;
+        $statuses = array(
+                'open' => __('Reopen'),
+                'closed' => __('Close'),
+                );
+
+        if(!($task=Task::lookup($tid)) || !$task->checkStaffPerm($thisstaff))
+            Http::response(404, __('No such task'));
+
+        $perm = null;
+        $info = $errors = array();
+        switch ($status) {
+        case 'open':
+            $perm = Task::PERM_CREATE;
+            $info = array(
+                    ':title' => sprintf(__('Reopen Task #%s'),
+                        $task->getNumber()),
+                    ':action' => sprintf('#tasks/%d/reopen',
+                        $task->getId())
+                    );
+            break;
+        case 'closed':
+            $perm = Task::PERM_CLOSE;
+            $info = array(
+                    ':title' => sprintf(__('Close Task #%s'),
+                        $task->getNumber()),
+                    ':action' => sprintf('#tasks/%d/close',
+                        $task->getId())
+                    );
+
+            if (($m=$task->isCloseable()) !== true)
+                $errors['err'] = $info['error'] = $m;
+            else
+                $info['warn'] = sprintf(__('Are you sure you want to %s?'),
+                        sprintf(__('change status of %s'), __('this task')));
+            break;
+        default:
+            Http::response(404, __('Unknown status'));
+        }
+
+        if (!$errors && (!$perm || !$task->checkStaffPerm($thisstaff, $perm)))
+            $errors['err'] = sprintf(
+                        __('You do not have permission to %s %s'),
+                        $statuses[$status], __('tasks'));
+
+        if ($_POST && !$errors) {
+            if ($task->setStatus($status, $_POST['comments'], $errors))
+                Http::response(201, 0);
+
+            $info['error'] = $errors['err'] ?: __('Unable to change status of the task');
+        }
+
+        $info['status'] = $status;
+
+        include STAFFINC_DIR . 'templates/task-status.tmpl.php';
+   }
+
+   function reopen($tid) {
+       return $this->changeStatus($tid, 'open');
+   }
+
+   function close($tid) {
+       return $this->changeStatus($tid, 'closed');
+   }
 
     function task($tid) {
         global $thisstaff;
diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index fbb8425bdaab9f65da2b833974ab2f8f62e10bd8..95e124a1fcd5dad3c4d008c2b14340a3c7660eba 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -496,7 +496,7 @@ class TicketsAjaxAPI extends AjaxController {
                     __('This ticket'),
                     $assigned);
         } else {
-            $info['warn'] = sprintf(__('Are you sure you want to claim %s?'),
+            $info['warn'] = sprintf(__('Are you sure you want to CLAIM %s?'),
                     __('this ticket'));
         }
 
@@ -639,8 +639,9 @@ class TicketsAjaxAPI extends AjaxController {
                     $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));
+                    $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());
@@ -1084,9 +1085,10 @@ class TicketsAjaxAPI extends AjaxController {
         $count = $_REQUEST['count'] ?:
             ($_REQUEST['tids'] ?  count($_REQUEST['tids']) : 0);
 
-        $info['title'] = sprintf(__('%1$s Tickets &mdash; %2$d selected'),
-                TicketStateField::getVerb($state),
-                 $count);
+        $info['title'] = sprintf(__('Change Status &mdash; %1$d %2$s selected'),
+                 $count,
+                 _N('ticket', 'tickets', $count)
+                 );
 
         if (!strcasecmp($state, 'deleted')) {
 
diff --git a/include/class.forms.php b/include/class.forms.php
index d642209565a79a0cdc468e9e41b8c448608ebd1f..3b6d129643a8baf1b9d992964b1036df898ab10a 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -2215,7 +2215,7 @@ FormField::addFieldTypes(/*@trans*/ 'Dynamic Fields', function() {
 
 
 class AssigneeField extends ChoiceField {
-    var $_choices = array();
+    var $_choices = null;
     var $_criteria = null;
 
     function getWidget() {
diff --git a/include/class.task.php b/include/class.task.php
index c3b23bb694c92aea9da74c3e48ac7d81069929ae..3de800bce36b9322b197c567af6825f74970e6b0 100644
--- a/include/class.task.php
+++ b/include/class.task.php
@@ -433,15 +433,62 @@ class Task extends TaskModel implements RestrictedAccess, Threadable {
         return $this->form;
     }
 
-    function getAssignmentForm($source=null) {
+    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('t%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;
+    }
+
+    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,
-                array('dept' => $this->getDept()));
     }
 
+
     function getTransferForm($source=null) {
 
         if (!$source)
@@ -571,6 +618,55 @@ class Task extends TaskModel implements RestrictedAccess, Threadable {
         $this->getThread()->getEvents()->log($this, $state, $data, $user, $annul);
     }
 
+    function claim(ClaimForm $form, &$errors) {
+        global $thisstaff;
+
+        $dept = $this->getDept();
+        $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($assignee, $form->getComments(), false);
+    }
+
+    function assignToStaff($staff, $note, $alert=true) {
+
+        if(!is_object($staff) && !($staff = Staff::lookup($staff)))
+            return false;
+
+        if (!$staff->isAvailable())
+            return false;
+
+        $this->staff_id = $staff->getId();
+
+        if (!$this->save())
+            return false;
+
+        $this->onAssignment($staff, $note, $alert);
+
+        global $thisstaff;
+        $data = array();
+        if ($thisstaff && $staff->getId() == $thisstaff->getId())
+            $data['claim'] = true;
+        else
+            $data['staff'] = $staff->getId();
+
+        $this->logEvent('assigned', $data);
+
+        return true;
+    }
+
+
     function assign(AssignmentForm $form, &$errors, $alert=true) {
         global $thisstaff;
 
@@ -706,7 +802,7 @@ class Task extends TaskModel implements RestrictedAccess, Threadable {
         else
             $this->dept_id = $dept->getId();
 
-        if ($errors || !$this->save())
+        if ($errors || !$this->save(true))
             return false;
 
         // Log transfer event
@@ -1430,7 +1526,7 @@ extends AbstractForm {
         $mode = @$this->options['mode'];
         if ($mode && $mode == 'edit') {
             unset($fields['dept_id']);
-            unset($fields['staff_id']);
+            unset($fields['assignee']);
         }
 
         return $fields;
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 61da381c5b641bf1895dc4d69e5462bd84eb4f67..f1aeef7e9fe2c39a5586a663e6d4e386ce2747e9 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -885,7 +885,7 @@ implements RestrictedAccess, Threadable {
                         $assignees['t'.$id] = $name;
 
                 if (!$source && $this->isOpen() && $this->team)
-                    $assignee = sprintf('s%d', $this->team->getId());
+                    $assignee = sprintf('t%d', $this->team->getId());
                 $prompt = __('Select a Team');
                 break;
         }
diff --git a/include/staff/tasks.inc.php b/include/staff/tasks.inc.php
index 9c96ad5bb3ac752dfc173482fbf9dfa71bfdc43f..f144ab189819531c524684fbf37f9f30b32d68f4 100644
--- a/include/staff/tasks.inc.php
+++ b/include/staff/tasks.inc.php
@@ -383,7 +383,7 @@ if ($thisstaff->hasPerm(Task::PERM_DELETE, false)) {
     </tfoot>
     </table>
     <?php
-    if ($total>0) { //if we actually had any tickets returned.
+    if ($total>0) { //if we actually had any tasks returned.
         echo '<div>&nbsp;'.__('Page').':'.$pageNav->getPageLinks().'&nbsp;';
         echo sprintf('<a class="export-csv no-pjax" href="?%s">%s</a>',
                 Http::build_query(array(
@@ -400,7 +400,7 @@ if ($thisstaff->hasPerm(Task::PERM_DELETE, false)) {
     <a class="close" href=""><i class="icon-remove-circle"></i></a>
     <hr/>
     <p class="confirm-action" style="display:none;" id="mark_overdue-confirm">
-        <?php echo __('Are you sure want to flag the selected tickets as <font color="red"><b>overdue</b></font>?');?>
+        <?php echo __('Are you sure want to flag the selected tasks as <font color="red"><b>overdue</b></font>?');?>
     </p>
     <div><?php echo __('Please confirm to continue.');?></div>
     <hr style="margin-top:1em"/>
@@ -416,38 +416,21 @@ if ($thisstaff->hasPerm(Task::PERM_DELETE, false)) {
 </div>
 <script type="text/javascript">
 $(function() {
-    $(document).off('.tasks');
-    $(document).on('click.tasks', 'a.tasks-action', function(e) {
-        e.preventDefault();
-        var count = checkbox_checker($('form#tasks'), 1);
-        if (count) {
-            var url = 'ajax.php/'
-            +$(this).attr('href').substr(1)
-            +'?count='+count
-            +'&_uid='+new Date().getTime();
-            var $redirect = $(this).data('redirect');
-            $.dialog(url, [201], function (xhr) {
-                if (!!$redirect)
-                    $.pjax({url: $redirect, container:'#pjax-container'});
-                else
-                    $.pjax.reload('#pjax-container');
-             });
-        }
-        return false;
-    });
-    $(document).off('.task-action');
-    $(document).on('click.task-action', 'a.task-action', function(e) {
+
+    $(document).off('.new-task');
+    $(document).on('click.new-task', 'a.new-task', function(e) {
         e.preventDefault();
         var url = 'ajax.php/'
         +$(this).attr('href').substr(1)
         +'?_uid='+new Date().getTime();
         var $options = $(this).data('dialogConfig');
-        var $redirect = $(this).data('redirect');
         $.dialog(url, [201], function (xhr) {
-            if (!!$redirect)
-                window.location.href = $redirect;
-            else
+            var tid = parseInt(xhr.responseText);
+            if (tid) {
+                 window.location.href = 'tasks.php?id='+tid;
+            } else {
                 $.pjax.reload('#pjax-container');
+            }
         }, $options);
 
         return false;
diff --git a/include/staff/templates/task-status.tmpl.php b/include/staff/templates/task-status.tmpl.php
index 8aba2d100c0fdaa56b4b77d3961e27bb15f231c7..a6cf6594bb6a4abac698f379a987485c9b22b7e0 100644
--- a/include/staff/templates/task-status.tmpl.php
+++ b/include/staff/templates/task-status.tmpl.php
@@ -27,6 +27,7 @@ $action = $info[':action'] ?: ('#tasks/mass/'. $action);
     <form method="post" name="status" id="status"
         action="<?php echo $action; ?>"
         class="mass-action">
+        <input type="hidden" name="status" value="<?php echo $info['status']; ?>" >
         <table width="100%">
             <?php
             if ($info[':extra']) {
@@ -38,36 +39,6 @@ $action = $info[':action'] ?: ('#tasks/mass/'. $action);
             <?php
             }
             ?>
-            <tbody>
-                <tr>
-                    <td colspan=2>
-                        <span>
-                            <strong><?php echo __('Status') ?>:&nbsp;</strong>
-                            <select name="status">
-                            <?php
-                            $statuses = array(
-                                    'open' => __('Open'),
-                                    'closed' => __('Closed'));
-
-                            if (!$info['status'])
-                                echo '<option value=""> '. __('Select One')
-                                .' </option>';
-                            foreach ($statuses as $k => $status) {
-                                echo sprintf('<option value="%s" %s>%s</option>',
-                                        $k,
-                                        ($info['status'] == $k)
-                                         ? 'selected="selected"' : '',
-                                        $status
-                                        );
-                            }
-                            ?>
-                            </select>
-                            <font class="error">*&nbsp;<?php echo
-                            $errors['status']; ?></font>
-                        </span>
-                    </td>
-                </tr>
-            </tbody>
             <tbody>
                 <tr>
                     <td colspan="2">
diff --git a/include/staff/templates/task-view.tmpl.php b/include/staff/templates/task-view.tmpl.php
index a2a95ff4ebd01632f320c40a97fa89d4fbfac89e..f53a410ef722f9928630a6bdce9948a6c644989b 100644
--- a/include/staff/templates/task-view.tmpl.php
+++ b/include/staff/templates/task-view.tmpl.php
@@ -6,33 +6,41 @@ if (!defined('OSTSCPINC')
 
 global $cfg;
 
+$id = $task->getId();
+$dept = $task->getDept();
+$thread = $task->getThread();
+
 $iscloseable = $task->isCloseable();
 $canClose = ($role->hasPerm(TaskModel::PERM_CLOSE) && $iscloseable === true);
 $actions = array();
-$actions += array(
-        'print' => array(
-            'href' => sprintf('tasks.php?id=%d&a=print', $task->getId()),
-            'class' => 'no-pjax',
-            'icon' => 'icon-print',
-            'label' => __('Print')
-        ));
 
-if ($role->hasPerm(Task::PERM_EDIT)) {
+if ($task->isOpen() && $role->hasPerm(Task::PERM_ASSIGN)) {
+
+    if ($task->getStaffId() != $thisstaff->getId()
+            && (!$dept->assignMembersOnly()
+                || $dept->isMember($thisstaff))) {
+        $actions += array(
+                'claim' => array(
+                    'href' => sprintf('#tasks/%d/claim', $task->getId()),
+                    'icon' => 'icon-user',
+                    'label' => __('Claim'),
+                    'redirect' => 'tasks.php'
+                ));
+    }
+
     $actions += array(
-            'edit' => array(
-                'href' => sprintf('#tasks/%d/edit', $task->getId()),
-                'icon' => 'icon-edit',
-                'dialog' => '{"size":"large"}',
-                'label' => __('Edit')
+            'assign/agents' => array(
+                'href' => sprintf('#tasks/%d/assign/agents', $task->getId()),
+                'icon' => 'icon-user',
+                'label' => __('Assign to Agent'),
+                'redirect' => 'tasks.php'
             ));
-}
 
-if ($role->hasPerm(Task::PERM_ASSIGN)) {
     $actions += array(
-            'assign' => array(
-                'href' => sprintf('#tasks/%d/assign', $task->getId()),
+            'assign/teams' => array(
+                'href' => sprintf('#tasks/%d/assign/teams', $task->getId()),
                 'icon' => 'icon-user',
-                'label' => $task->isAssigned() ? __('Reassign') : __('Assign'),
+                'label' => __('Assign to Team'),
                 'redirect' => 'tasks.php'
             ));
 }
@@ -47,13 +55,30 @@ if ($role->hasPerm(Task::PERM_TRANSFER)) {
             ));
 }
 
+$actions += array(
+        'print' => array(
+            'href' => sprintf('tasks.php?id=%d&a=print', $task->getId()),
+            'class' => 'no-pjax',
+            'icon' => 'icon-print',
+            'label' => __('Print')
+        ));
+
+if ($role->hasPerm(Task::PERM_EDIT)) {
+    $actions += array(
+            'edit' => array(
+                'href' => sprintf('#tasks/%d/edit', $task->getId()),
+                'icon' => 'icon-edit',
+                'dialog' => '{"size":"large"}',
+                'label' => __('Edit')
+            ));
+}
 
 if ($role->hasPerm(Task::PERM_DELETE)) {
     $actions += array(
             'delete' => array(
                 'href' => sprintf('#tasks/%d/delete', $task->getId()),
                 'icon' => 'icon-trash',
-                'class' => 'danger',
+                'class' => 'red button',
                 'label' => __('Delete'),
                 'redirect' => 'tasks.php'
             ));
@@ -61,50 +86,40 @@ if ($role->hasPerm(Task::PERM_DELETE)) {
 
 $info=($_POST && $errors)?Format::input($_POST):array();
 
-$id = $task->getId();
-$dept = $task->getDept();
-$thread = $task->getThread();
-
 if ($task->isOverdue())
     $warn.='&nbsp;&nbsp;<span class="Icon overdueTicket">'.__('Marked overdue!').'</span>';
 
 ?>
-
-<div class="has_bottom_border" class="sticky bar stop">
+<div>
     <div class="sticky bar">
        <div class="content">
         <div class="pull-left flush-left">
             <?php
             if ($ticket) { ?>
                 <strong>
-                <a id="all-ticket-tasks" href="#"> All Tasks (<?php echo $ticket->getNumTasks(); ?>)</a>
+                <a id="all-ticket-tasks" href="#">
+                <?php
+                    echo sprintf(__('All Tasks (%s)'),
+                            $ticket->getNumTasks());
+                 ?></a>
                 &nbsp;/&nbsp;
-                <?php echo $task->getTitle(); ?>
-                &nbsp;&mdash;&nbsp;
-                <a
-                    id="reload-task" class="preview"
+                <a id="reload-task" class="preview"
                     <?php
                     echo ' class="preview" ';
                     echo sprintf('data-preview="#tasks/%d/preview" ', $task->getId());
                     echo sprintf('href="#tickets/%s/tasks/%d/view" ',
                             $ticket->getId(), $task->getId()
                             );
-                    ?>
-                ><?php
-                echo sprintf('#%s', $task->getNumber()); ?></a>
+                    ?>><?php echo sprintf(__('Task #%s'), $task->getNumber()); ?></a>
                 </strong>
             <?php
             } else { ?>
                <h2>
-                <a
-                id="reload-task"
-                href="tasks.php?id=<?php echo $task->getId(); ?>"
-                href="tasks.php?id=<?php echo $task->getId(); ?>"
-                ><i class="icon-refresh"></i> <?php
-                echo sprintf(__('Task #%s'), $task->getNumber()); ?></a>
-                   <?php if ($task) { ?> – <small><span class="ltr"><?php echo $task->getTitle(); ?></span></small>
-                <?php } ?>
-            </h2>
+                <a  id="reload-task"
+                    href="tasks.php?id=<?php echo $task->getId(); ?>"><i
+                    class="icon-refresh"></i>&nbsp;<?php
+                    echo sprintf(__('Task #%s'), $task->getNumber()); ?></a>
+                </h2>
             <?php
             } ?>
         </div>
@@ -129,7 +144,28 @@ if ($task->isOverdue())
             <div id="action-dropdown-task-options"
                 class="action-dropdown anchor-right">
                 <ul>
-            <?php foreach ($actions as $a => $action) { ?>
+
+                    <?php
+                    if ($task->isOpen()) { ?>
+                    <li>
+                        <a class="no-pjax task-action"
+                            href="#tasks/<?php echo $task->getId(); ?>/reopen"><i
+                            class="icon-fixed-width icon-undo"></i> <?php
+                            echo __('Reopen');?> </a>
+                    </li>
+                    <?php
+                    } else {
+                    ?>
+                    <li>
+                        <a class="no-pjax task-action"
+                            href="#tasks/<?php echo $task->getId(); ?>/close"><i
+                            class="icon-fixed-width icon-ok-circle"></i> <?php
+                            echo __('Close');?> </a>
+                    </li>
+                    <?php
+                    } ?>
+                    <?php
+                    foreach ($actions as $a => $action) { ?>
                     <li <?php if ($action['class']) echo sprintf("class='%s'", $action['class']); ?> >
                         <a class="no-pjax task-action" <?php
                             if ($action['dialog'])
@@ -152,21 +188,101 @@ if ($task->isOverdue())
                 </ul>
             </div>
             <?php
-           } else {
-                foreach ($actions as $action) {?>
-                <a class="action-button <?php
-                    echo $action['class'] ?: 'task-action'; ?>"
+           } else { ?>
+                <span
+                    class="action-button"
+                    data-dropdown="#action-dropdown-tasks-status">
+                    <i class="icon-caret-down pull-right"></i>
+                    <a class="tasks-status-action"
+                        href="#statuses"
+                        data-placement="bottom"
+                        data-toggle="tooltip"
+                        title="<?php echo __('Change Status'); ?>"><i
+                        class="icon-flag"></i></a>
+                </span>
+                <div id="action-dropdown-tasks-status"
+                    class="action-dropdown anchor-right">
+                    <ul>
+                        <?php
+                        if ($task->isClosed()) { ?>
+                        <li>
+                            <a class="no-pjax task-action"
+                                href="#tasks/<?php echo $task->getId(); ?>/reopen"><i
+                                class="icon-fixed-width icon-undo"></i> <?php
+                                echo __('Reopen');?> </a>
+                        </li>
+                        <?php
+                        } else {
+                        ?>
+                        <li>
+                            <a class="no-pjax task-action"
+                                href="#tasks/<?php echo $task->getId(); ?>/close"><i
+                                class="icon-fixed-width icon-ok-circle"></i> <?php
+                                echo __('Close');?> </a>
+                        </li>
+                        <?php
+                        } ?>
+                    </ul>
+                </div>
+                <?php
+                // Assign
+                unset($actions['claim'], $actions['assign/agents'], $actions['assign/teams']);
+                if ($task->isOpen() && $role->hasPerm(Task::PERM_ASSIGN)) {?>
+                <span class="action-button"
+                    data-dropdown="#action-dropdown-assign"
+                    data-placement="bottom"
+                    data-toggle="tooltip"
+                    title=" <?php echo $task->isAssigned() ? __('Reassign') : __('Assign'); ?>"
+                    >
+                    <i class="icon-caret-down pull-right"></i>
+                    <a class="task-action" id="task-assign"
+                        data-redirect="tasks.php"
+                        href="#tasks/<?php echo $task->getId(); ?>/assign"><i class="icon-user"></i></a>
+                </span>
+                <div id="action-dropdown-assign" class="action-dropdown anchor-right">
+                  <ul>
                     <?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 $action['href']; ?>"><i
-                    class="<?php
-                    echo $action['icon'] ?: 'icon-tag'; ?>"></i> <?php
-                    echo $action['label'];
-                ?></a>
+                    // Agent can claim team assigned ticket
+                    if ($task->getStaffId() != $thisstaff->getId()
+                            && (!$dept->assignMembersOnly()
+                                || $dept->isMember($thisstaff))
+                            ) { ?>
+                     <li><a class="no-pjax task-action"
+                        data-redirect="tasks.php"
+                        href="#tasks/<?php echo $task->getId(); ?>/claim"><i
+                        class="icon-chevron-sign-down"></i> <?php echo __('Claim'); ?></a>
+                    <?php
+                    } ?>
+                     <li><a class="no-pjax task-action"
+                        data-redirect="tasks.php"
+                        href="#tasks/<?php echo $task->getId(); ?>/assign/agents"><i
+                        class="icon-user"></i> <?php echo __('Agent'); ?></a>
+                     <li><a class="no-pjax task-action"
+                        data-redirect="tasks.php"
+                        href="#tasks/<?php echo $task->getId(); ?>/assign/teams"><i
+                        class="icon-group"></i> <?php echo __('Team'); ?></a>
+                  </ul>
+                </div>
+                <?php
+                } ?>
+                <?php
+                foreach ($actions as $action) {?>
+                <span class="action-button <?php echo $action['class'] ?: ''; ?>">
+                    <a class="task-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 $action['href']; ?>"
+                        data-placement="bottom"
+                        data-toggle="tooltip"
+                        title="<?php echo $action['label']; ?>">
+                        <i class="<?php
+                        echo $action['icon'] ?: 'icon-tag'; ?>"></i>
+                    </a>
+                </span>
            <?php
                 }
            } ?>
@@ -175,6 +291,14 @@ if ($task->isOverdue())
    </div>
 </div>
 
+<div class="clear tixTitle has_bottom_border">
+    <h3>
+    <?php
+        $title = TaskForm::getInstance()->getField('title');
+        echo $title->display($task->getTitle());
+    ?>
+    </h3>
+</div>
 <?php
 if (!$ticket) { ?>
     <table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0">
@@ -274,7 +398,8 @@ if (!$ticket) { ?>
     foreach (DynamicFormEntry::forObject($task->getId(),
                 ObjectModel::OBJECT_TYPE_TASK) as $form) {
         $answers = $form->getAnswers()->exclude(Q::any(array(
-            'field__flags__hasbit' => DynamicFormField::FLAG_EXT_STORED
+            'field__flags__hasbit' => DynamicFormField::FLAG_EXT_STORED,
+            'field__name__in' => array('title')
         )));
         if (!$answers || count($answers) == 0)
             continue;
@@ -543,5 +668,10 @@ $(function() {
         .done(function() { })
         .fail(function() { });
      });
+    <?php
+    if ($ticket) { ?>
+    $('#ticket-tasks-count').html(<?php echo $ticket->getNumTasks(); ?>);
+   <?php
+    } ?>
 });
 </script>
diff --git a/include/staff/templates/tasks-actions.tmpl.php b/include/staff/templates/tasks-actions.tmpl.php
index 04696a7714499e87b20aa35f0e3140d79921d17e..dc59eae4fc5827a7231c39dbdbb4a7fc2f9c0d2e 100644
--- a/include/staff/templates/tasks-actions.tmpl.php
+++ b/include/staff/templates/tasks-actions.tmpl.php
@@ -13,9 +13,11 @@ if ($agent->hasPerm(Task::PERM_CLOSE, false)) {
             data-dropdown="#action-dropdown-tasks-status">
             <i class="icon-caret-down pull-right"></i>
             <a class="tasks-status-action"
-                href="#statuses"><i
-                class="icon-flag"></i> <?php
-                echo __('Change Status'); ?></a>
+                href="#statuses"
+                data-placement="bottom"
+                data-toggle="tooltip"
+                title="<?php echo __('Change Status'); ?>"><i
+                class="icon-flag"></i></a>
         </span>
         <div id="action-dropdown-tasks-status"
             class="action-dropdown anchor-right">
@@ -61,9 +63,19 @@ if ($agent->hasPerm(Task::PERM_CLOSE, false)) {
 
 if ($agent->hasPerm(Task::PERM_ASSIGN, false)) {
     $actions += array(
-            'assign' => array(
+            'claim' => array(
                 'icon' => 'icon-user',
-                'action' => __('Assign')
+                'action' => __('Claim')
+            ));
+     $actions += array(
+            'assign/agents' => array(
+                'icon' => 'icon-user',
+                'action' => __('Assign to Agent')
+            ));
+    $actions += array(
+            'assign/teams' => array(
+                'icon' => 'icon-group',
+                'action' => __('Assign to Team')
             ));
 }
 
@@ -71,7 +83,6 @@ if ($agent->hasPerm(Task::PERM_TRANSFER, false)) {
     $actions += array(
             'transfer' => array(
                 'icon' => 'icon-share',
-                'redirect' => 'tickets.php',
                 'action' => __('Transfer')
             ));
 }
@@ -84,7 +95,7 @@ if ($agent->hasPerm(Task::PERM_DELETE, false)) {
                 'action' => __('Delete')
             ));
 }
-if ($actions) {
+if ($actions && !isset($options['status'])) {
     $more = $options['morelabel'] ?: __('More');
     ?>
     <span
@@ -121,20 +132,87 @@ if ($actions) {
         </ul>
     </div>
  <?php
- } ?>
+ } else {
+    // Mass Claim/Assignment
+    if ($agent->hasPerm(Task::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="tasks-action" id="tasks-assign"
+            href="#tasks/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 tasks-action"
+            href="#tasks/mass/claim"><i
+            class="icon-chevron-sign-down"></i> <?php echo __('Claim'); ?></a>
+         <li><a class="no-pjax tasks-action"
+            href="#tasks/mass/assign/agents"><i
+            class="icon-user"></i> <?php echo __('Agent'); ?></a>
+         <li><a class="no-pjax tasks-action"
+            href="#tasks/mass/assign/teams"><i
+            class="icon-group"></i> <?php echo __('Team'); ?></a>
+      </ul>
+    </div>
+    <?php
+    }
+
+    // Mass Transfer
+    if ($agent->hasPerm(Task::PERM_TRANSFER, false)) {?>
+    <span class="action-button">
+     <a class="tasks-action" id="tasks-transfer" data-placement="bottom"
+        data-toggle="tooltip" title="<?php echo __('Transfer'); ?>"
+        href="#tasks/mass/transfer"><i class="icon-share"></i></a>
+    </span>
+    <?php
+    }
+
+
+    // Mass Delete
+    if ($agent->hasPerm(Task::PERM_DELETE, false)) {?>
+    <span class="red button action-button">
+     <a class="tasks-action" id="tasks-delete" data-placement="bottom"
+        data-toggle="tooltip" title="<?php echo __('Delete'); ?>"
+        href="#tasks/mass/delete"><i class="icon-trash"></i></a>
+    </span>
+<?php
+    }
+} ?>
+
+
 <script type="text/javascript">
 $(function() {
     $(document).off('.tasks-actions');
     $(document).on('click.tasks-actions', 'a.tasks-action', function(e) {
         e.preventDefault();
-        var count = checkbox_checker($('form#tasks'), 1);
+        var $form = $('form#tasks');
+        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();
+            var $redirect = $(this).data('redirect');
             $.dialog(url, [201], function (xhr) {
-                $.pjax.reload('#pjax-container');
+                if (!!$redirect)
+                    $.pjax({url: $redirect, container:'#pjax-container'});
+                else
+                  <?php
+                  if (isset($options['callback_url']))
+                    echo sprintf("$.pjax({url: '%s', container: '%s', push: false});",
+                           $options['callback_url'],
+                           @$options['container'] ?: '#pjax-container'
+                           );
+                  else
+                    echo sprintf("$.pjax.reload('%s');",
+                            @$options['container'] ?: '#pjax-container');
+                 ?>
              });
         }
         return false;
diff --git a/include/staff/ticket-tasks.inc.php b/include/staff/ticket-tasks.inc.php
index cf6c7a0c7561f1a11dfd114807a21cf081c5f6db..a260f0f05b07e2427b973ccfd68f44ea9ce0e30c 100644
--- a/include/staff/ticket-tasks.inc.php
+++ b/include/staff/ticket-tasks.inc.php
@@ -41,7 +41,11 @@ $showing = $pageNav->showing().' '._N('task', 'tasks', $count);
     <?php
     }
     if ($count)
-        Task::getAgentActions($thisstaff, array('morelabel' => __('Options')));
+        Task::getAgentActions($thisstaff, array(
+                    'container' => '#tasks_content',
+                    'callback_url' => sprintf('ajax.php/tickets/%d/tasks',
+                        $ticket->getId()),
+                    'morelabel' => __('Options')));
     ?>
 </div>
 <div class="clear"></div>
@@ -177,11 +181,12 @@ $(function() {
             var tid = parseInt(xhr.responseText);
             if (tid) {
                 var url = 'ajax.php/tickets/'+<?php echo $ticket->getId();
-                ?>+'/tasks/'+tid+'/view';
+                ?>+'/tasks';
                 var $container = $('div#task_content');
-                $container.load(url, function () {
+                $container.load(url+'/'+tid+'/view', function () {
                     $('.tip_box').remove();
                     $('div#tasks_content').hide();
+                    $.pjax({url: url, container: '#tasks_content', push: false});
                 }).show();
             } else {
                 window.location.href = $redirect ? $redirect : window.location.href;
@@ -189,5 +194,7 @@ $(function() {
         }, $options);
         return false;
     });
+
+    $('#ticket-tasks-count').html(<?php echo $count; ?>);
 });
 </script>
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index ca3ba69cdbdc3092cd8ded141dd72130f7015ecd..2b39913a5483cc892a0a0ce202e9b63b21fb6e96 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -485,7 +485,7 @@ $tcount = $ticket->getThreadEntries($types)->count();
         echo sprintf('#tickets/%d/tasks', $ticket->getId()); ?>"><?php
         echo __('Tasks');
         if ($ticket->getNumTasks())
-            echo sprintf('&nbsp;(%d)', $ticket->getNumTasks());
+            echo sprintf('&nbsp;(<span id="ticket-tasks-count">%d</span>)', $ticket->getNumTasks());
         ?></a></li>
 </ul>
 
diff --git a/scp/ajax.php b/scp/ajax.php
index 8fcb6146f2f9e6d97bdc2567ac6a22c6259f2e6a..f01cf70b4bb00f0b4b4a6f17bab1c0d5d92e5a2c 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -182,16 +182,17 @@ $dispatcher = patterns('',
         url_post('^(?P<tid>\d+)/edit$', 'edit'),
         url_get('^(?P<tid>\d+)/transfer', 'transfer'),
         url_post('^(?P<tid>\d+)/transfer$', 'transfer'),
-        url_get('^(?P<tid>\d+)/assign', 'assign'),
-        url_post('^(?P<tid>\d+)/assign$', 'assign'),
+        url('^(?P<tid>\d+)/assign(?:/(?P<to>\w+))?$', 'assign'),
+        url('^(?P<tid>\d+)/claim$', 'claim'),
         url_get('^(?P<tid>\d+)/delete', 'delete'),
         url_post('^(?P<tid>\d+)/delete$', 'delete'),
+        url('^(?P<tid>\d+)/close', 'close'),
+        url('^(?P<tid>\d+)/reopen', 'reopen'),
         url_get('^(?P<tid>\d+)/view$', 'task'),
         url_post('^(?P<tid>\d+)$', 'task'),
         url('^add$', 'add'),
         url('^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('^/thread/', patterns('ajax.thread.php:ThreadAjaxAPI',
         url_get('^(?P<tid>\d+)/collaborators/preview$', 'previewCollaborators'),
diff --git a/scp/tasks.php b/scp/tasks.php
index f33018f3252569cd9ace6f0de58115d1e7ee7a26..616a1720adff44c09e86b72c66d6864f4a3c7fb8 100644
--- a/scp/tasks.php
+++ b/scp/tasks.php
@@ -195,7 +195,7 @@ if ($thisstaff->hasPerm(TaskModel::PERM_CREATE, false)) {
     $nav->addSubMenu(array('desc'=>__('New Task'),
                            'title'=> __('Open a New Task'),
                            'href'=>'#tasks/add',
-                           'iconclass'=>'newTicket task-action',
+                           'iconclass'=>'newTicket new-task',
                            'id' => 'new-task',
                            'attr' => array(
                                'data-dialog-config' => '{"size":"large"}'