diff --git a/include/ajax.tasks.php b/include/ajax.tasks.php
index e58507401e859115a20cc05458781227982f7454..ab8bce914e6b87629fc43d12ff14deaaaf137cc5 100644
--- a/include/ajax.tasks.php
+++ b/include/ajax.tasks.php
@@ -32,6 +32,98 @@ class TasksAjaxAPI extends AjaxController {
         include STAFFINC_DIR . 'templates/task-preview.tmpl.php';
     }
 
+    function edit($tid) {
+        global $thisstaff;
+
+        // TODO: check staff's access.
+        if(!$thisstaff || !($task=Task::lookup($tid)))
+            Http::response(404, __('No such task'));
+
+        $info = $errors = array();
+        $forms = DynamicFormEntry::forObject($task->getId(),
+                ObjectModel::OBJECT_TYPE_TASK);
+
+        if ($_POST) {
+            $info = Format::htmlchars($_POST);
+            $info['error'] = $errors['err'] ?: __('Coming soon!');
+        }
+
+        include STAFFINC_DIR . 'templates/task-edit.tmpl.php';
+    }
+
+    function transfer($tid) {
+        global $thisstaff;
+
+        // TODO: check staff's access.
+        if(!$thisstaff || !($task=Task::lookup($tid)))
+            Http::response(404, __('No such task'));
+
+        $info = $errors = array();
+        if ($_POST) {
+            if ($task->transfer($_POST,  $errors)) {
+                Http::response(201, $task->getId());
+
+            }
+
+            $info = Format::htmlchars($_POST);
+            $info['error'] = $errors['err'] ?: __('Unable to transfer task');
+        }
+
+        include STAFFINC_DIR . 'templates/task-transfer.tmpl.php';
+    }
+
+    function assign($tid) {
+        global $thisstaff;
+
+        // TODO: check staff's access.
+        if(!$thisstaff || !($task=Task::lookup($tid)))
+            Http::response(404, __('No such task'));
+
+        $info = $errors = array();
+        if ($_POST) {
+            if ($task->assign($_POST,  $errors)) {
+                Http::response(201, $task->getId());
+
+            }
+
+            $info = Format::htmlchars($_POST);
+            $info['error'] = $errors['err'] ?: __('Unable to assign task');
+        }
+
+        include STAFFINC_DIR . 'templates/task-assign.tmpl.php';
+    }
+
+   function delete($tid) {
+        global $thisstaff;
+
+        // TODO: check staff's access.
+        if(!$thisstaff || !($task=Task::lookup($tid)))
+            Http::response(404, __('No such task'));
+
+        $info = $errors = array();
+        if ($_POST) {
+            if ($task->delete($_POST,  $errors)) {
+                Http::response(201, 0);
+
+            }
+
+            $info = Format::htmlchars($_POST);
+            $info['error'] = $errors['err'] ?: __('Unable to delete task');
+        }
+        $info['placeholder'] = sprintf(__(
+                    'Optional reason for deleting %s'),
+                __('this task'));
+        $info['warn'] = sprintf(__(
+                    'Are you sure you want to DELETE %s?'),
+                    __('this task'));
+        $info['extra'] = sprintf('<strong>%s</strong>',
+                    __('Deleted tasks CANNOT be recovered, including any associated attachments.')
+                    );
+
+        include STAFFINC_DIR . 'templates/task-delete.tmpl.php';
+    }
+
+
     function task($tid) {
         global $thisstaff;
 
@@ -54,7 +146,6 @@ class TasksAjaxAPI extends AjaxController {
                 $attachments = $task_note_form->getField('attachments')->getClean();
                 $vars['cannedattachments'] = array_merge(
                     $vars['cannedattachments'] ?: array(), $attachments);
-
                 if(($note=$task->postNote($vars, $errors, $thisstaff))) {
                     $msg=__('Note posted successfully');
                     // Clear attachment list
diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index 28c97eaf8c777348649cce147f44c9bc3d14e65c..6cd63e98ad71c3603754b88e25cc78ee61d1bf4b 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -872,17 +872,39 @@ class TicketsAjaxAPI extends AjaxController {
                 || !$ticket->checkStaffAccess($thisstaff))
             Http::response(404, 'Unknown ticket');
 
-        $info = array();
+        $info=$errors=array();
 
         if ($_POST) {
-            /*
             Draft::deleteForNamespace(
                     sprintf('ticket.%d.task', $ticket->getId()),
                     $thisstaff->getId());
-            */
+            // Default form
             $form = TaskForm::getDefaultForm()->getForm($_POST);
-            if ($form && ($task = Task::create($form, $ticket)))
-                Http::response(201, $task->to_json());
+            // Internal form
+            $iform = TaskForm::getInternalForm($_POST);
+            $isvalid = true;
+            if (!$iform->isValid())
+                $isvalid = false;
+            if (!$form->isValid())
+                $isvalid = false;
+
+            if ($isvalid) {
+                $vars = $_POST;
+                $vars['object_id'] = $ticket->getId();
+                $vars['object_type'] = ObjectModel::OBJECT_TYPE_TICKET;
+                $vars['default_formdata'] = $form->getClean();
+                $vars['internal_formdata'] = $iform->getClean();
+                $desc = $form->getField('description');
+                if ($desc
+                        && $desc->isAttachmentsEnabled()
+                        && ($attachments=$desc->getWidget()->getAttachments()))
+                    $vars['cannedattachments'] = $attachments->getClean();
+                $vars['staffId'] = $thisstaff->getId();
+                $vars['poster'] = $thisstaff;
+                $vars['ip_address'] = $_SERVER['REMOTE_ADDR'];
+                if (($task=Task::create($vars, $errors)))
+                    Http::response(201, $task->getId());
+            }
 
             $info['error'] = __('Error adding task - try again!');
         }
diff --git a/include/class.forms.php b/include/class.forms.php
index 25ee52ce1a427caa6f514abf57dcd65daf710362..4188797bddf25a7496b4e6a382224c1651b8e296 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -1547,6 +1547,139 @@ FormField::addFieldTypes(/*@trans*/ 'Dynamic Fields', function() {
 });
 
 
+class DepartmentField extends ChoiceField {
+    function getWidget() {
+        $widget = parent::getWidget();
+        if ($widget->value instanceof Dept)
+            $widget->value = $widget->value->getId();
+        return $widget;
+    }
+
+    function hasIdValue() {
+        return true;
+    }
+
+    function getChoices() {
+        global $cfg;
+
+        $choices = array();
+        if (($depts = Dept::getDepartments()))
+            foreach ($depts as $id => $name)
+                $choices[$id] = $name;
+
+        return $choices;
+    }
+
+    function parse($id) {
+        return $this->to_php(null, $id);
+    }
+
+    function to_php($value, $id=false) {
+        if (is_array($id)) {
+            reset($id);
+            $id = key($id);
+        }
+        return $id;
+    }
+
+    function to_database($dept) {
+        return ($dept instanceof Dept)
+            ? array($dept->getName(), $dept->getId())
+            : $dept;
+    }
+
+    function toString($value) {
+        return (string) $value;
+    }
+
+    function searchable($value) {
+        return null;
+    }
+
+    function getConfigurationOptions() {
+        return array(
+            'prompt' => new TextboxField(array(
+                'id'=>2, 'label'=>__('Prompt'), 'required'=>false, 'default'=>'',
+                'hint'=>__('Leading text shown before a value is selected'),
+                'configuration'=>array('size'=>40, 'length'=>40),
+            )),
+        );
+    }
+}
+FormField::addFieldTypes(/*@trans*/ 'Dynamic Fields', function() {
+    return array(
+        'department' => array(__('Department'), DepartmentField),
+    );
+});
+
+
+class AssigneeField extends ChoiceField {
+    function getWidget() {
+        $widget = parent::getWidget();
+        if (is_object($widget->value))
+            $widget->value = $widget->value->getId();
+        return $widget;
+    }
+
+    function hasIdValue() {
+        return true;
+    }
+
+    function getChoices() {
+        global $cfg;
+        $choices = array();
+        if (($agents = Staff::getAvailableStaffMembers()))
+            foreach ($agents as $id => $name)
+                $choices[$id] = $name;
+
+        return $choices;
+    }
+
+    function parse($id) {
+        return $this->to_php(null, $id);
+    }
+
+    function to_php($value, $id=false) {
+        if (is_array($id)) {
+            reset($id);
+            $id = key($id);
+        }
+
+        return $id;
+    }
+
+
+    function to_database($value) {
+        return (is_object($value))
+            ? array($value->getName(), $value->getId())
+            : $value;
+    }
+
+    function toString($value) {
+        return (string) $value;
+    }
+
+    function searchable($value) {
+        return null;
+    }
+
+    function getConfigurationOptions() {
+        return array(
+            'prompt' => new TextboxField(array(
+                'id'=>2, 'label'=>__('Prompt'), 'required'=>false, 'default'=>'',
+                'hint'=>__('Leading text shown before a value is selected'),
+                'configuration'=>array('size'=>40, 'length'=>40),
+            )),
+        );
+    }
+}
+FormField::addFieldTypes(/*@trans*/ 'Dynamic Fields', function() {
+    return array(
+        'assignee' => array(__('Assignee'), AssigneeField),
+    );
+});
+
+
 class TicketStateField extends ChoiceField {
 
     static $_states = array(
diff --git a/include/class.role.php b/include/class.role.php
index 1f2ab4d8cda60f1f16130a1a1dba505e0823cc34..38fbc68a93465250611c7165a9c7e842ca5b207e 100644
--- a/include/class.role.php
+++ b/include/class.role.php
@@ -297,7 +297,7 @@ class RolePermission {
                 'task.close'   => array(
                     /* @trans */ 'Close',
                     /* @trans */ 'Ability to close tasks'),
-                'tasks.delete'   => array(
+                'task.delete'   => array(
                     /* @trans */ 'Delete',
                     /* @trans */ 'Ability to delete tasks'),
                 ),
@@ -373,7 +373,7 @@ class RolePermission {
         return ($this->has('ticket.transfer'));
     }
 
-    function canPostReply() {
+    function canPostTicketReply() {
         return ($this->has('ticket.reply'));
     }
 
@@ -385,6 +385,35 @@ class RolePermission {
         return ($this->has('ticket.delete'));
     }
 
+    /* tasks */
+    function canCreateTasks() {
+        return ($this->get('task.create'));
+    }
+
+    function canEditTasks() {
+        return ($this->get('task.edit'));
+    }
+
+    function canAssignTasks() {
+        return ($this->get('task.assign'));
+    }
+
+    function canTransferTasks() {
+        return ($this->get('task.transfer'));
+    }
+
+    function canPostTaskReply() {
+        return ($this->get('task.reply'));
+    }
+
+    function canCloseTasks() {
+        return ($this->get('task.close'));
+    }
+
+    function canDeleteTasks() {
+        return ($this->get('task.delete'));
+    }
+
     /* Knowledge base */
     function canManagePremade() {
         return ($this->has('kb.premade'));
diff --git a/include/class.task.php b/include/class.task.php
index 57767a41f1d17db7922446c8b056ad1dccdd25a8..9b155e249a94b9b20ebf89295b76b23e26d05485 100644
--- a/include/class.task.php
+++ b/include/class.task.php
@@ -5,10 +5,14 @@ class TaskModel extends VerySimpleModel {
         'table' => TASK_TABLE,
         'pk' => array('id'),
         'joins' => array(
-            'thread' => array(
-                'reverse' => 'ThreadModel.object',
+            'dept' => array(
+                'constraint' => array('dept_id' => 'Dept.id'),
             ),
-        )
+            'staff' => array(
+                'constraint' => array('staff_id' => 'Staff.staff_id'),
+                'null' => true,
+            ),
+        ),
     );
 
     const ISOPEN    = 0x0001;
@@ -86,6 +90,8 @@ class Task extends TaskModel {
     var $entry;
     var $thread;
 
+    var $_entries;
+
 
     function getStatus() {
         return $this->isOpen() ? _('Open') : _('Closed');
@@ -95,9 +101,23 @@ class Task extends TaskModel {
         return $this->__cdata('title', ObjectModel::OBJECT_TYPE_TASK);
     }
 
+    function getAssignees() {
+
+        $assignees=array();
+        if ($this->staff)
+            $assignees[] = $this->staff->getName();
+
+        //Add team assignment
+        if (isset($this->team))
+            $assignees[] = $this->team->getName();
+
+        return $assignees;
+    }
+
+    function getAssigned($glue='/') {
+        $assignees = $this->getAssignees();
 
-    function getDept() {
-        return "Dept Object";
+        return $assignees ? implode($glue, $assignees):'';
     }
 
     function getThread() {
@@ -199,6 +219,68 @@ class Task extends TaskModel {
     }
 
     /* util routines */
+    function assign($vars, &$errors) {
+        global $thisstaff;
+
+        if (!isset($vars['staff_id']) || !($staff=Staff::lookup($vars['staff_id'])))
+            $errors['staff_id'] = __('Agent selection required');
+        elseif ($staff->getid() == $this->getStaffId())
+            $errors['dept_id'] = __('Task already assigned to agent');
+        else
+            $this->staff_id = $staff->getId();
+
+        if ($errors || !$this->save())
+            return false;
+
+        // Transfer completed... post internal note.
+        $title = sprintf(__('Task assigned to %s'),
+                $staff->getName());
+        if ($vars['comments']) {
+            $note = $vars['comments'];
+        } else {
+            $note = $title;
+            $title = '';
+        }
+
+        $this->postNote(
+                array('note' => $note, 'title' => $title),
+                $errors,
+                $thisstaff);
+
+        return true;
+    }
+
+    function transfer($vars, &$errors) {
+        global $thisstaff;
+
+        if (!isset($vars['dept_id']) || !($dept=Dept::lookup($vars['dept_id'])))
+            $errors['dept_id'] = __('Department selection required');
+        elseif ($dept->getid() == $this->getDeptId())
+            $errors['dept_id'] = __('Task already in the department');
+        else
+            $this->dept_id = $dept->getId();
+
+        if ($errors || !$this->save())
+            return false;
+
+        // Transfer completed... post internal note.
+        $title = sprintf(__('Task transfered to %s department'),
+                $dept->getName());
+        if ($vars['comments']) {
+            $note = $vars['comments'];
+        } else {
+            $note = $title;
+            $title = '';
+        }
+
+        $this->postNote(
+                array('note' => $note, 'title' => $title),
+                $errors,
+                $thisstaff);
+
+        return true;
+    }
+
     function postNote($vars, &$errors, $poster='', $alert=true) {
         global $cfg, $thisstaff;
 
@@ -216,7 +298,7 @@ class Task extends TaskModel {
 
         if (isset($vars['task_status'])) {
             if ($vars['task_status'])
-                $this->open();
+                $this->reopen();
             else
                 $this->close();
 
@@ -238,55 +320,69 @@ class Task extends TaskModel {
         return !self::lookupIdByNumber($number);
     }
 
-    static function create($form, $object) {
-        global $cfg, $thisstaff;
+    static function create($vars) {
+        global $cfg;
 
-        if (!$thisstaff
-                || !$form
-                // TODO: Make sure it's an instance of ORM Model
-                || !$object)
-            return null;
+        $task = parent::create(array(
+            'flags' => self::ISOPEN,
+            'object_id' => $vars['object_id'],
+            'object_type' => $vars['object_type'],
+            'number' => $cfg->getNewTaskNumber(),
+            'created' => new SqlFunction('NOW'),
+            'updated' => new SqlFunction('NOW'),
+        ));
+        // Save internal fields.
+        if ($vars['internal_formdata']['staff_id'])
+            $task->staff_id = $vars['internal_formdata']['staff_id'];
+        if ($vars['internal_formdata']['dept_id'])
+            $task->dept_id = $vars['internal_formdata']['dept_id'];
+        if ($vars['internal_formdata']['duedate'])
+            $task->duedate = $vars['internal_formdata']['duedate'];
 
-        if (!$form->isValid())
-            return false;
+        $task->save(true);
 
-        try {
-
-            $task = parent::create(array(
-                'flags' => 1,
-                'object_id' => $object->getId(),
-                'object_type' => $object->getObjectType(),
-                'number' => $cfg->getNewTaskNumber(),
-                'created' => new SqlFunction('NOW'),
-                'updated' => new SqlFunction('NOW'),
-            ));
-            $task->save(true);
-        } catch(OrmException $e) {
-            return null;
-        }
+        // Add dynamic data
+        $task->addDynamicData($vars['default_formdata']);
 
-        $vars = $form->getClean();
-        $task->addDynamicData($vars);
         // Create a thread + message.
         $thread = TaskThread::create($task);
-        $desc = $form->getField('description');
-        if ($desc
-                && $desc->isAttachmentsEnabled()
-                && ($attachments=$desc->getWidget()->getAttachments()))
-            $vars['cannedattachments'] = $attachments->getClean();
-
-        $vars['staffId'] = $thisstaff->getId();
-        $vars['poster'] = $thisstaff;
-        if (!$vars['ip_address'] && $_SERVER['REMOTE_ADDR'])
-            $vars['ip_address'] = $_SERVER['REMOTE_ADDR'];
-
         $thread->addDescription($vars);
-
         Signal::send('model.created', $task);
 
         return $task;
     }
 
+    function delete($comments='') {
+        global $ost, $thisstaff;
+
+        $thread = $this->getThread();
+
+        if (!parent::delete())
+            return false;
+
+        $thread->delete();
+
+        Draft::deleteForNamespace('task.%.' . $this->getId());
+
+        foreach (DynamicFormEntry::forObject($this->getId(), ObjectModel::OBJECT_TYPE_TASK) as $form)
+            $form->delete();
+
+        // Log delete
+        $log = sprintf(__('Task #%1$s deleted by %2$s'),
+                $this->getNumber(),
+                $thisstaff ? $thisstaff->getName() : __('SYSTEM'));
+
+        if ($comments)
+            $log .= sprintf('<hr>%s', $comments);
+
+        $ost->logDebug(
+                sprintf( __('Task #%s deleted'), $this->getNumber()),
+                $log);
+
+        return true;
+
+    }
+
     static function __loadDefaultForm() {
 
         require_once INCLUDE_DIR.'class.i18n.php';
@@ -305,7 +401,10 @@ class Task extends TaskModel {
 
 class TaskForm extends DynamicForm {
     static $instance;
-    static $form;
+    static $defaultForm;
+    static $internalForm;
+
+    static $forms;
 
     static function objects() {
         $os = parent::objects();
@@ -313,12 +412,12 @@ class TaskForm extends DynamicForm {
     }
 
     static function getDefaultForm() {
-        if (!isset(static::$form)) {
+        if (!isset(static::$defaultForm)) {
             if (($o = static::objects()) && $o[0])
-                static::$form = $o[0];
+                static::$defaultForm = $o[0];
         }
 
-        return static::$form;
+        return static::$defaultForm;
     }
 
     static function getInstance($object_id=0, $new=false) {
@@ -332,6 +431,43 @@ class TaskForm extends DynamicForm {
 
         return static::$instance;
     }
+
+    static function getInternalForm($source=null) {
+        if (!isset(static::$internalForm))
+            static::$internalForm = new Form(self::getInternalFields(), $source);
+
+        return static::$internalForm;
+    }
+
+    static function getInternalFields() {
+        return array(
+                'dept_id' => new DepartmentField(array(
+                    'id'=>1,
+                    'label' => __('Department'),
+                    'flags' => hexdec(0X450F3),
+                    'required' => true,
+                    )),
+                'staff_id' => new AssigneeField(array(
+                    'id'=>2,
+                    'label' => __('Assignee'),
+                    'flags' => hexdec(0X450F3),
+                    'required' => false,
+                    )),
+                'duedate'  =>  new DatetimeField(array(
+                    'id' => 3,
+                    'label' => __('Due Date'),
+                    'flags' => hexdec(0X450B3),
+                    'required' => false,
+                    'configuration' => array(
+                        'min' => Misc::gmtime(),
+                        'time' => true,
+                        'gmt' => true,
+                        'future' => true,
+                        ),
+                    )),
+
+            );
+    }
 }
 
 // Task thread class
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 64fb7dcb00cae7542ec497b54281e405951bd2fd..eb46e86c4278659806e2f54349063885b08c7964 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -3031,7 +3031,7 @@ class Ticket {
 
         // post response - if any
         $response = null;
-        if($vars['response'] && $role->canPostReply()) {
+        if($vars['response'] && $role->canPostTicketReply()) {
 
             $vars['response'] = $ticket->replaceVars($vars['response']);
             // $vars['cannedatachments'] contains the attachments placed on
diff --git a/include/i18n/en_US/form.yaml b/include/i18n/en_US/form.yaml
index 6e3d4c9e99e0df2309f129af394b292a11eb1f2c..7d1eb9aa2f5303d1c35b2c04c9a9b15102b1e9de 100644
--- a/include/i18n/en_US/form.yaml
+++ b/include/i18n/en_US/form.yaml
@@ -185,35 +185,20 @@
   title: Task Details
   instructions: Please Describe The Issue
   notes: |
-      This form is used to create tasks.
+      This form is used to create a task.
   deletable: false
   fields:
     - type: text # notrans
       name: title # notrans
-      label: Title
-      required: true
-      edit_mask: 15
-      flags: 1
+      flags: 0x470B1
       sort: 1
+      label: Title
       configuration:
         size: 40
         length: 50
     - type: thread # notrans
       name: description # notrans
+      flags: 0x450B3
+      sort: 2
       label: Description
       hint: Details on the reason(s) for creating the task.
-      required: true
-      edit_mask: 15
-      flags: 3
-      sort: 2
-    - type: datetime # notrans
-      name: duedate # notrans
-      label: Due Date
-      required: false
-      edit_mask: 15
-      flags: 3
-      sort: 3
-      configuration:
-        time: true
-        gmt: true
-        future: true
diff --git a/include/staff/templates/task-assign.tmpl.php b/include/staff/templates/task-assign.tmpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c5dd7a5eac411e9f78ab99e0096a0dd671187a8
--- /dev/null
+++ b/include/staff/templates/task-assign.tmpl.php
@@ -0,0 +1,95 @@
+<?php
+global $cfg;
+
+if (!$info['title'])
+    $info['title'] = sprintf(__('%s Tasks #%s'),
+            $task->isAssigned() ? __('Reassign') :  __('Assign'),
+            $task->getNumber()
+            );
+
+?>
+<h3><?php echo $info['title']; ?></h3>
+<b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
+<div class="clear"></div>
+<hr/>
+<?php
+if ($info['error']) {
+    echo sprintf('<p id="msg_error">%s</p>', $info['error']);
+} elseif ($info['warn']) {
+    echo sprintf('<p id="msg_warning">%s</p>', $info['warn']);
+} elseif ($info['msg']) {
+    echo sprintf('<p id="msg_notice">%s</p>', $info['msg']);
+} elseif ($info['notice']) {
+   echo sprintf('<p id="msg_info"><i class="icon-info-sign"></i> %s</p>',
+           $info['notice']);
+}
+
+
+$action = $info['action'] ?: ('#tasks/'.$task->getId().'/assign');
+?>
+<div id="ticket-status" style="display:block; margin:5px;">
+<form method="post" name="transfer" id="transfer"
+    action="<?php echo $action; ?>">
+    <table width="100%">
+        <?php
+        if ($info['extra']) {
+            ?>
+        <tbody>
+            <tr><td colspan="2"><strong><?php echo $info['extra'];
+            ?></strong></td> </tr>
+        </tbody>
+        <?php
+        }
+       ?>
+        <tbody>
+            <tr><td colspan=2>
+                <span>
+                <strong><?php echo __('Agent') ?>:&nbsp;</strong>
+                <select name="staff_id">
+                <?php
+                foreach (Staff::getAvailableStaffMembers() as $id => $name) {
+                    echo sprintf('<option value="%d" %s>%s</option>',
+                            $id,
+                            ($info['staff_id'] == $id)
+                             ? 'selected="selected"' : '',
+                            $name
+                            );
+                }
+                ?>
+                </select>
+                <font class="error">*&nbsp;<?php echo
+                $errors['dept_id']; ?></font>
+                </span>
+            </td> </tr>
+        </tbody>
+        <tbody>
+            <tr>
+                <td colspan="2">
+                <?php
+                $placeholder = $info['placeholder'] ?: __('Optional reason for the assignment');
+                ?>
+                <textarea name="comments" id="comments"
+                    cols="50" rows="3" wrap="soft" style="width:100%"
+                    class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                    ?> no-bar"
+                    placeholder="<?php echo $placeholder; ?>"><?php
+                    echo $info['comments']; ?></textarea>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+    <hr>
+    <p class="full-width">
+        <span class="buttons pull-left">
+            <input type="reset" value="<?php echo __('Reset'); ?>">
+            <input type="button" name="cancel" class="close"
+            value="<?php echo __('Cancel'); ?>">
+        </span>
+        <span class="buttons pull-right">
+            <input type="submit" value="<?php
+            echo $verb ?: __('Submit'); ?>">
+        </span>
+     </p>
+</form>
+</div>
+<div class="clear"></div>
diff --git a/include/staff/templates/task-delete.tmpl.php b/include/staff/templates/task-delete.tmpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..6014bd88aa6be37d1027d01cbb083ba6b4d03b1b
--- /dev/null
+++ b/include/staff/templates/task-delete.tmpl.php
@@ -0,0 +1,74 @@
+<?php
+global $cfg;
+
+if (!$info['title'])
+    $info['title'] = sprintf(__('%s Tasks #%s'),
+            __('Delete'),
+            $task->getNumber()
+            );
+
+?>
+<h3><?php echo $info['title']; ?></h3>
+<b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
+<div class="clear"></div>
+<hr/>
+<?php
+if ($info['error']) {
+    echo sprintf('<p id="msg_error">%s</p>', $info['error']);
+} elseif ($info['warn']) {
+    echo sprintf('<p id="msg_warning">%s</p>', $info['warn']);
+} elseif ($info['msg']) {
+    echo sprintf('<p id="msg_notice">%s</p>', $info['msg']);
+} elseif ($info['notice']) {
+   echo sprintf('<p id="msg_info"><i class="icon-info-sign"></i> %s</p>',
+           $info['notice']);
+}
+
+
+$action = $info['action'] ?: ('#tasks/'.$task->getId().'/delete');
+?>
+<div id="ticket-status" style="display:block; margin:5px;">
+<form method="post" name="delete" id="delete"
+    action="<?php echo $action; ?>">
+    <table width="100%">
+        <?php
+        if ($info['extra']) {
+            ?>
+        <tbody>
+            <tr><td colspan="2"><strong><?php echo $info['extra'];
+            ?></strong></td> </tr>
+        </tbody>
+        <?php
+        }
+       ?>
+        <tbody>
+            <tr>
+                <td colspan="2">
+                <?php
+                $placeholder = $info['placeholder'] ?: __('Optional reason for the deletion');
+                ?>
+                <textarea name="comments" id="comments"
+                    cols="50" rows="3" wrap="soft" style="width:100%"
+                    class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                    ?> no-bar"
+                    placeholder="<?php echo $placeholder; ?>"><?php
+                    echo $info['comments']; ?></textarea>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+    <hr>
+    <p class="full-width">
+        <span class="buttons pull-left">
+            <input type="reset" value="<?php echo __('Reset'); ?>">
+            <input type="button" name="cancel" class="close"
+            value="<?php echo __('Cancel'); ?>">
+        </span>
+        <span class="buttons pull-right">
+            <input type="submit" value="<?php
+            echo $verb ?: __('Submit'); ?>">
+        </span>
+     </p>
+</form>
+</div>
+<div class="clear"></div>
diff --git a/include/staff/templates/task-edit.tmpl.php b/include/staff/templates/task-edit.tmpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..a77079e251be82ab85d584083a05a540fe2eb977
--- /dev/null
+++ b/include/staff/templates/task-edit.tmpl.php
@@ -0,0 +1,96 @@
+<?php
+global $cfg;
+
+if (!$info['title'])
+    $info['title'] = sprintf(__('%s Tasks #%s'),
+            __('Edit'), $task->getNumber()
+            );
+
+$action = $info['action'] ?: ('#tasks/'.$task->getId().'/edit');
+
+?>
+<div id="task-form">
+<h3><?php echo $info['title']; ?></h3>
+<b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
+<hr/>
+<?php
+
+if ($info['error']) {
+    echo sprintf('<p id="msg_error">%s</p>', $info['error']);
+} elseif ($info['warning']) {
+    echo sprintf('<p id="msg_warning">%s</p>', $info['warning']);
+} elseif ($info['msg']) {
+    echo sprintf('<p id="msg_notice">%s</p>', $info['msg']);
+} ?>
+<div id="edit-task-form" style="display:block;">
+<form method="post" class="task" action="<?php echo $action; ?>">
+
+    <table class="form_table dynamic-forms" width="100%" border="0" cellspacing="0" cellpadding="2">
+            <?php if ($forms)
+                foreach ($forms as $form) {
+                    $form->render(true, false, array('mode'=>'edit','width'=>160,'entry'=>$form));
+                    print $form->getForm()->getMedia();
+            } ?>
+    </table>
+    <table class="form_table dynamic-forms" width="100%" border="0" cellspacing="0" cellpadding="2">
+        <tr><th colspan=2><em><?php
+             echo __('Task Visibility & Assignment'); ?></em></th></tr>
+    <?php
+        $iform = $iform ?: TaskForm::getInternalForm();
+        foreach ($iform->getFields()  as $name=>$field) {
+            if (!$field->isEditable()) continue;
+         ?>
+        <tr>
+            <td class="multi-line <?php if ($field->get('required')) echo 'required';
+            ?>" style="min-width:120px;" width="160">
+            <?php echo Format::htmlchars($field->get('label')); ?>:</td>
+            <td>
+            <fieldset id="field<?php echo $field->getWidget()->id;
+                ?>" <?php if (!$field->isVisible()) echo 'style="display:none;"'; ?>>
+                <?php echo $field->render(); ?>
+                <?php if ($field->get('required')) { ?>
+                <span class="error">*</span>
+                <?php
+                }
+                foreach ($field->errors() as $E) {
+                    ?><div class="error"><?php echo $E; ?></div><?php
+                } ?>
+            </fieldset>
+          </td>
+        </tr>
+        <?php
+        }
+       ?>
+    </table>
+    <table class="form_table" width="100%" border="0" cellspacing="0" cellpadding="2">
+        <tbody>
+            <tr>
+                <th colspan="2">
+                    <em><strong><?php echo __('Internal Note');?></strong>: <?php
+                     echo __('Reason for editing the task (optional');?> <font class="error">&nbsp;<?php echo $errors['note'];?></font></em>
+                </th>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <textarea class="richtext no-bar" name="note" cols="21"
+                        rows="6" style="width:80%;"><?php echo $info['note'];
+                        ?></textarea>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+    <hr>
+    <p class="full-width">
+        <span class="buttons pull-left">
+            <input type="reset" value="<?php echo __('Reset'); ?>">
+            <input type="button" name="cancel" class="close"
+                value="<?php echo __('Cancel'); ?>">
+        </span>
+        <span class="buttons pull-right">
+            <input type="submit" value="<?php echo __('Update'); ?>">
+        </span>
+     </p>
+</form>
+</div>
+<div class="clear"></div>
+</div>
diff --git a/include/staff/templates/task-preview.tmpl.php b/include/staff/templates/task-preview.tmpl.php
index ab2b9f90cac48499b6dd01bfe20c07ee66d13d26..d6968f49a42da80daa6ccc8f730d548edbd519b0 100644
--- a/include/staff/templates/task-preview.tmpl.php
+++ b/include/staff/templates/task-preview.tmpl.php
@@ -1,10 +1,7 @@
 <?php
 $error=$msg=$warn=null;
 
-if($lock && $lock->getStaffId()==$thisstaff->getId())
-    $warn.='&nbsp;<span class="Icon lockedTicket">'
-    .sprintf(__('Ticket is locked by %s'), $lock->getStaffName()).'</span>';
-elseif($task->isOverdue())
+if($task->isOverdue())
     $warn.='&nbsp;<span class="Icon overdueTicket">'.__('Marked overdue!').'</span>';
 
 echo sprintf(
@@ -21,21 +18,14 @@ elseif($msg)
 elseif($warn)
     echo sprintf('<div id="msg_warning">%s</div>',$warn);
 
-echo '<ul class="tabs" id="ticket-preview">';
+echo '<ul class="tabs" id="task-preview">';
 
 echo '
-        <li><a id="preview_tab" href="#preview" class="active"
+        <li class="active"><a href="#summary"
             ><i class="icon-list-alt"></i>&nbsp;'.__('Task Summary').'</a></li>';
-if (0 && $task->getNumCollaborators()) {
-echo sprintf('
-        <li><a id="collab_tab" href="#collab"
-            ><i class="icon-fixed-width icon-group
-            faded"></i>&nbsp;'.__('Collaborators (%d)').'</a></li>',
-            $task->getNumCollaborators());
-}
 echo '</ul>';
-echo '<div id="ticket-preview_container">';
-echo '<div class="tab_content" id="preview_tab_content">';
+echo '<div id="task-preview_container">';
+echo '<div class="tab_content" id="summary">';
 echo '<table border="0" cellspacing="" cellpadding="1" width="100%" class="ticket_info">';
 $status=sprintf('<span>%s</span>',ucfirst($task->getStatus()));
 echo sprintf('
@@ -47,27 +37,27 @@ echo sprintf('
             <th>'.__('Created').':</th>
             <td>%s</td>
         </tr>',$status,
-        Format::db_datetime($task->getCreateDate()));
+        Format::datetime($task->getCreateDate()));
 
-if (0 && $task->isOpen() && $task->getEstDueDate()) {
+if ($task->isOpen() && $task->duedate) {
     echo sprintf('
             <tr>
                 <th>'.__('Due Date').':</th>
                 <td>%s</td>
             </tr>',
-            Format::db_datetime($task->getEstDueDate()));
+            Format::datetime($task->duedate));
 }
 echo '</table>';
 
 
 echo '<hr>
     <table border="0" cellspacing="" cellpadding="1" width="100%" class="ticket_info">';
-if(0 && $ticket->isOpen()) {
+if ($task->isOpen()) {
     echo sprintf('
             <tr>
                 <th width="100">'.__('Assigned To').':</th>
                 <td>%s</td>
-            </tr>',$ticket->isAssigned()?implode('/', $ticket->getAssignees()):' <span class="faded">&mdash; '.__('Unassigned').' &mdash;</span>');
+            </tr>', $task->getAssigned() ?: ' <span class="faded">&mdash; '.__('Unassigned').' &mdash;</span>');
 }
 echo sprintf(
     '
@@ -75,63 +65,16 @@ echo sprintf(
             <th width="100">'.__('Department').':</th>
             <td>%s</td>
         </tr>',
-    Format::htmlchars('Dept. HERE')
+    Format::htmlchars($task->dept->getName())
     );
 
 echo '
     </table>';
 echo '</div>';
 ?>
-<div class="tab_content" id="collab_tab_content" style="display:none;">
-    <table border="0" cellspacing="" cellpadding="1">
-        <colgroup><col style="min-width: 250px;"></col></colgroup>
-        <?php
-        if (0 && ($collabs=$task->getCollaborators())) {?>
-        <?php
-            foreach($collabs as $collab) {
-                echo sprintf('<tr><td %s><i class="icon-%s"></i>
-                        <a href="users.php?id=%d" class="no-pjax">%s</a> <em>&lt;%s&gt;</em></td></tr>',
-                        ($collab->isActive()? '' : 'class="faded"'),
-                        ($collab->isActive()? 'comments' :  'comment-alt'),
-                        $collab->getUserId(),
-                        $collab->getName(),
-                        $collab->getEmail());
-            }
-        }  else {
-            echo __("Task doesn't have any collaborators.");
-        }?>
-    </table>
-    <br>
-    <?php
-    echo sprintf('<span><a class="collaborators"
-                            href="#tasks/%d/collaborators">%s</a></span>',
-                            $task->getId(),
-                            0
-                                ? __('Manage Collaborators') : __('Add Collaborator')
-                                );
-    ?>
-</div>
 </div>
 <?php
-$options = array();
-$options[]=array('action'=>sprintf(__('Thread (%d)'),
-            $task->getThread()->getNumEntries()),
-        'url'=>"tickets.php?id=$tid");
-if ($thisstaff->canAssignTickets())
-    $options[]=array('action'=>($task->isAssigned()?__('Reassign'):__('Assign')),'url'=>"tickets.php?id=$tid#assign");
-
-if ($thisstaff->canTransferTickets())
-    $options[]=array('action'=>'Transfer','url'=>"tickets.php?id=$tid#transfer");
-
-if ($thisstaff->canEditTickets())
-    $options[]=array('action'=>'Edit Task','url'=>"tickets.php?id=$tid&a=edit");
-
-if ($options) {
-    echo '<ul class="tip_menu">';
-    foreach($options as $option)
-        echo sprintf('<li><a href="%s">%s</a></li>',$option['url'],$option['action']);
-    echo '</ul>';
-}
+//TODO: add link to view if the user has permission
 
 echo '</div>';
 ?>
diff --git a/include/staff/templates/task-transfer.tmpl.php b/include/staff/templates/task-transfer.tmpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..8a872f43845ec328c92554f32125e10682173b89
--- /dev/null
+++ b/include/staff/templates/task-transfer.tmpl.php
@@ -0,0 +1,93 @@
+<?php
+global $cfg;
+
+if (!$info['title'])
+    $info['title'] = sprintf(__('%s Tasks #%s'),
+            __('Tranfer'), $task->getNumber());
+
+?>
+<h3><?php echo $info['title']; ?></h3>
+<b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
+<div class="clear"></div>
+<hr/>
+<?php
+if ($info['error']) {
+    echo sprintf('<p id="msg_error">%s</p>', $info['error']);
+} elseif ($info['warn']) {
+    echo sprintf('<p id="msg_warning">%s</p>', $info['warn']);
+} elseif ($info['msg']) {
+    echo sprintf('<p id="msg_notice">%s</p>', $info['msg']);
+} elseif ($info['notice']) {
+   echo sprintf('<p id="msg_info"><i class="icon-info-sign"></i> %s</p>',
+           $info['notice']);
+}
+
+
+$action = $info['action'] ?: ('#tasks/'.$task->getId().'/transfer');
+?>
+<div style="display:block; margin:5px;">
+<form method="post" name="transfer" id="transfer"
+    action="<?php echo $action; ?>">
+    <table width="100%">
+        <?php
+        if ($info['extra']) {
+            ?>
+        <tbody>
+            <tr><td colspan="2"><strong><?php echo $info['extra'];
+            ?></strong></td> </tr>
+        </tbody>
+        <?php
+        }
+       ?>
+        <tbody>
+            <tr><td colspan=2>
+                <span>
+                <strong><?php echo __('Department') ?>:&nbsp;</strong>
+                <select name="dept_id">
+                <?php
+                foreach (Dept::getDepartments() as $id => $name) {
+                    echo sprintf('<option value="%d" %s>%s</option>',
+                            $id,
+                            ($info['dept_id'] == $id)
+                             ? 'selected="selected"' : '',
+                            $name
+                            );
+                }
+                ?>
+                </select>
+                <font class="error">*&nbsp;<?php echo
+                $errors['dept_id']; ?></font>
+                </span>
+            </td> </tr>
+        </tbody>
+        <tbody>
+            <tr>
+                <td colspan="2">
+                <?php
+                $placeholder = $info['placeholder'] ?: __('Optional reason for the transfer');
+                ?>
+                <textarea name="comments" id="comments"
+                    cols="50" rows="3" wrap="soft" style="width:100%"
+                    class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                    ?> no-bar"
+                    placeholder="<?php echo $placeholder; ?>"><?php
+                    echo $info['comments']; ?></textarea>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+    <hr>
+    <p class="full-width">
+        <span class="buttons pull-left">
+            <input type="reset" value="<?php echo __('Reset'); ?>">
+            <input type="button" name="cancel" class="close"
+            value="<?php echo __('Cancel'); ?>">
+        </span>
+        <span class="buttons pull-right">
+            <input type="submit" value="<?php
+            echo $verb ?: __('Submit'); ?>">
+        </span>
+     </p>
+</form>
+</div>
+<div class="clear"></div>
diff --git a/include/staff/templates/task-view.tmpl.php b/include/staff/templates/task-view.tmpl.php
index 686ffa6fe3f4ee3fcca96629e220843ec36e22de..217afdc8c20edd5e7652d7d1b5f9be75fd2db96d 100644
--- a/include/staff/templates/task-view.tmpl.php
+++ b/include/staff/templates/task-view.tmpl.php
@@ -8,14 +8,32 @@ if (!defined('OSTSCPINC') || !$thisstaff || !is_object($task))
     die('Access Denied');
 */
 
-//Re-use the post info on error...savekeyboards.org (Why keyboard? -> some people care about objects than users!!)
+$actions = array();
+$actions += array(
+        'edit' => array(
+            'icon' => 'icon-edit',
+            'dialog' => '{"size":"large"}',
+            'action' => __('Edit')
+        ));
+$actions += array(
+        'assign' => array(
+            'icon' => 'icon-user',
+            'action' => $task->isAssigned() ? __('Reassign') : __('Assign')
+        ));
+$actions += array(
+        'transfer' => array(
+            'icon' => 'icon-share',
+            'action' => __('Transfer')
+        ));
+$actions += array(
+        'delete' => array(
+            'icon' => 'icon-trash',
+            'action' => __('Delete')
+        ));
+
+
 $info=($_POST && $errors)?Format::input($_POST):array();
 
-/*
-$dept  = $task->getDept();  //Dept
-$staff = $task->getStaff(); //Assigned or closed by..
-$team  = $task->getTeam();  //Assigned team.
-*/
 $id    = $task->getId();    //Ticket ID.
 if ($task->isOverdue())
     $warn.='&nbsp;&nbsp;<span class="Icon overdueTicket">'.__('Marked overdue!').'</span>';
@@ -30,14 +48,39 @@ if ($task->isOverdue())
             </h3>
         </td>
         <td width="auto" class="flush-right has_bottom_border">
-            <span>
-                <i class="icon-list"></i>
-                <select name="task-action">
-                    <option value="" selected="selected">
-                    <?php echo _('Task Options'); ?>
-                    </option>
-                </select>
+        <?php
+           if ($actions) { ?>
+            <span
+                class="action-button"
+                data-dropdown="#action-dropdown-taskoptions">
+                <i class="icon-caret-down pull-right"></i>
+                <a class="task-action"
+                    href="#taskoptions"><i
+                    class="icon-reorder"></i> <?php
+                    echo __('Task Options'); ?></a>
             </span>
+            <div id="action-dropdown-taskoptions"
+                class="action-dropdown anchor-right">
+                <ul>
+            <?php foreach ($actions as $a => $action) { ?>
+                    <li>
+                        <a class="no-pjax task-action"
+                            <?php
+                            if ($action['dialog'])
+                                echo sprintf("data-dialog='%s'", $action['dialog']);
+                            ?>
+                            href="<?php
+                            echo sprintf('#tasks/%d/%s', $task->getId(), $a); ?>"
+                            ><i class="<?php
+                            echo $action['icon'] ?: 'icon-tag'; ?>"></i> <?php
+                            echo $action['action']; ?></a>
+                    </li>
+                <?php
+                } ?>
+                </ul>
+            </div>
+            <?php
+           } ?>
         </td>
     </tr>
 </table>
@@ -51,11 +94,11 @@ if ($task->isOverdue())
                 </tr>
                 <tr>
                     <th><?php echo __('Department');?>:</th>
-                    <td><?php echo Format::htmlchars( (string) $task->getDept()); ?></td>
+                    <td><?php echo Format::htmlchars($task->dept->getName()); ?></td>
                 </tr>
                 <tr>
                     <th><?php echo __('Create Date');?>:</th>
-                    <td><?php echo Format::db_datetime($task->getCreateDate()); ?></td>
+                    <td><?php echo Format::datetime($task->getCreateDate()); ?></td>
                 </tr>
             </table>
         </td>
@@ -67,8 +110,8 @@ if ($task->isOverdue())
                     <th width="100"><?php echo __('Assigned To');?>:</th>
                     <td>
                         <?php
-                        if ( 0 && $ticket->isAssigned())
-                            echo Format::htmlchars(implode('/', $ticket->getAssignees()));
+                        if ($assigned=$task->getAssigned())
+                            echo Format::htmlchars($assigned);
                         else
                             echo '<span class="faded">&mdash; '.__('Unassigned').' &mdash;</span>';
                         ?>
@@ -97,14 +140,16 @@ if ($task->isOverdue())
                 if($task->isOpen()){ ?>
                 <tr>
                     <th><?php echo __('Due Date');?>:</th>
-                    <td><?php echo 'here'; //Format::db_datetime($ticket->getEstDueDate()); ?></td>
+                    <td><?php echo $task->duedate ?
+                    Format::datetime($task->duedate) : '<span
+                    class="faded">&mdash; '.__('None').' &mdash;</span>'; ?></td>
                 </tr>
                 <?php
                 }else { ?>
                 <tr>
                     <th><?php echo __('Close Date');?>:</th>
                     <td><?php echo 0 ?
-                    Format::db_datetime($task->getCloseDate()) : ' recently! '; ?></td>
+                    Format::datetime($task->getCloseDate()) : ''; ?></td>
                 </tr>
                 <?php
                 }
@@ -163,7 +208,7 @@ foreach (DynamicFormEntry::forObject($task->getId(),
                 <div>
                     <span class="pull-left">
                     <span style="display:inline-block"><?php
-                        echo Format::db_datetime($entry['created']);?></span>
+                        echo Format::datetime($entry['created']);?></span>
                     <span style="display:inline-block;padding:0 1em" class="faded title"><?php
                         echo Format::truncate($entry['title'], 100); ?></span>
                     </span>
@@ -219,7 +264,7 @@ foreach (DynamicFormEntry::forObject($task->getId(),
 <div id="response_options">
     <ul class="tabs"></ul>
     <form id="task_note"
-        action="#tasks/<? echo $task->getId(); ?>"
+        action="#tasks/<?php echo $task->getId(); ?>"
         name="task_note"
         method="post" enctype="multipart/form-data">
         <?php csrf_token(); ?>
@@ -281,7 +326,7 @@ foreach (DynamicFormEntry::forObject($task->getId(),
  </div>
 <script type="text/javascript">
 $(function() {
-    $(document).on('click', 'a.active#ticket_tasks', function(e) {
+    $(document).on('click', 'li.active a#ticket_tasks', function(e) {
         e.preventDefault();
         $('div#task_content').hide().empty();
         $('div#tasks_content').show();
diff --git a/include/staff/templates/task.tmpl.php b/include/staff/templates/task.tmpl.php
index 959a80c73a8d52055b8954b9cbf9f6f96a973ba9..bf1355bc0ac77b94c672f322eee7e1389674ccf4 100644
--- a/include/staff/templates/task.tmpl.php
+++ b/include/staff/templates/task.tmpl.php
@@ -21,13 +21,40 @@ if ($info['error']) {
 <form method="post" class="org" action="<?php echo $info['action'] ?: '#tasks/add'; ?>">
     <table width="100%" class="fixed">
     <?php
-        if (!$form) $form = TaskForm::getInstance();
+        $form = $form ?: TaskForm::getInstance();
         $form->render(true,
                 __('Create New Task'),
                 array(
                     'draft-namespace' => sprintf('ticket.%d.task',
                         $ticket->getId()))
-                ); ?>
+                );
+    ?>
+        <tr><th colspan=2><em><?php
+             echo __('Task Visibility & Assignment'); ?></em></th></tr>
+    <?php
+        $iform = $iform ?: TaskForm::getInternalForm();
+        foreach ($iform->getFields()  as $name=>$field) { ?>
+        <tr>
+            <td class="multi-line <?php if ($field->get('required')) echo 'required';
+            ?>" style="min-width:120px;" >
+            <?php echo Format::htmlchars($field->get('label')); ?>:</td>
+            <td>
+            <fieldset id="field<?php echo $field->getWidget()->id;
+                ?>" <?php if (!$field->isVisible()) echo 'style="display:none;"'; ?>>
+                <?php echo $field->render(); ?>
+                <?php if ($field->get('required')) { ?>
+                <span class="error">*</span>
+                <?php
+                }
+                foreach ($field->errors() as $E) {
+                    ?><div class="error"><?php echo $E; ?></div><?php
+                } ?>
+            </fieldset>
+          </td>
+        </tr>
+        <?php
+        }
+       ?>
     </table>
     <hr>
     <p class="full-width">
diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php
index 7ec099aff6b315bbc6180c6f2f88b5f8841e0b40..642808356b95b644a5a0b9a99921c601cd57f714 100644
--- a/include/staff/ticket-open.inc.php
+++ b/include/staff/ticket-open.inc.php
@@ -272,7 +272,7 @@ if ($_POST)
         <tbody>
         <?php
         //is the user allowed to post replies??
-        if($thisstaff->getRole()->canPostReply()) { ?>
+        if($thisstaff->getRole()->canPostTicketReply()) { ?>
         <tr>
             <th colspan="2">
                 <em><strong><?php echo __('Response');?></strong>: <?php echo __('Optional response to the above issue.');?></em>
diff --git a/include/staff/ticket-tasks.inc.php b/include/staff/ticket-tasks.inc.php
index 24f111be56f2e238d055182b4e4ec2e092352b2e..d4cf59e5f133cd06dc5d243872752fa6e61c6429 100644
--- a/include/staff/ticket-tasks.inc.php
+++ b/include/staff/ticket-tasks.inc.php
@@ -1,36 +1,22 @@
 <?php
 
-//TODO: Make it ORM based once we marge other models.
-$select ='SELECT task.*, dept.dept_name '
-        .' ,CONCAT_WS(" ", staff.firstname, staff.lastname) as staff, team.name as team '
-        .' ,IF(staff.staff_id IS NULL,team.name,CONCAT_WS(" ", staff.lastname, staff.firstname)) as assigned ';
+$tasks = Task::objects()
+    ->select_related('dept', 'staff')
+    ->order_by('-created');
 
-$from =' FROM '.TASK_TABLE.' task '
-      .' LEFT JOIN '.DEPT_TABLE.' dept ON task.dept_id=dept.dept_id '
-      .' LEFT JOIN '.STAFF_TABLE.' staff ON (task.staff_id=staff.staff_id) '
-      .' LEFT JOIN '.TEAM_TABLE.' team ON (task.team_id=team.team_id) ';
 
-if ($ticket)
-    $where = 'WHERE task.object_type="T" AND task.object_id = '.db_input($ticket->getId());
-
-$query ="$select $from $where ORDER BY task.created DESC";
-
-// Fetch the results
-$results = array();
-$res = db_query($query);
-while ($row = db_fetch_array($res))
-    $results[$row['id']] = $row;
+$count = $tasks->count();
+$pageNav = new Pagenate($count,1, 100000); //TODO: support ajax based pages
+$showing = $pageNav->showing().' '._N('task', 'tasks', $count);
 
 ?>
-
 <div id="tasks_content" style="display:block;">
 <div style="width:700px; float:left;">
    <?php
-    if ($results) {
-        echo '<strong>'.sprintf(_N('Showing %d Task', 'Showing %d Tasks',
-            count($results)), count($results)).'</strong>';
+    if ($count) {
+        echo '<strong>'.$showing.'</strong>';
     } else {
-        echo sprintf(__('%s does not have any tasks'), $ticket? 'Ticket' :
+        echo sprintf(__('%s does not have any tasks'), $ticket? 'This ticket' :
                 'System');
     }
    ?>
@@ -39,7 +25,8 @@ while ($row = db_fetch_array($res))
     <?php
     if ($ticket) { ?>
         <a
-        class="Icon newTicket ticket-action"
+        class="Icon newTicket task-action"
+        data-url="tickets.php?id=<?php echo $ticket->getId(); ?>#tasks"
         data-dialog='{"size":"large"}'
         href="#tickets/<?php
             echo $ticket->getId(); ?>/add-task"> <?php
@@ -50,8 +37,8 @@ while ($row = db_fetch_array($res))
 <br/>
 <div>
 <?php
-if ($results) { ?>
-<form action="tickets.php?id=<?php echo $ticket->getId(); ?>" method="POST" name='tasks' style="padding-top:10px;">
+if ($count) { ?>
+<form action="#tickets/<?php echo $ticket->getId(); ?>/tasks" method="POST" name='tasks' style="padding-top:10px;">
 <?php csrf_token(); ?>
  <input type="hidden" name="a" value="mass_process" >
  <input type="hidden" name="do" id="action" value="" >
@@ -59,6 +46,7 @@ if ($results) { ?>
     <thead>
         <tr>
             <?php
+            //TODO: support mass actions.
             if (0) {?>
             <th width="8px">&nbsp;</th>
             <?php
@@ -73,52 +61,41 @@ if ($results) { ?>
     </thead>
     <tbody class="tasks">
     <?php
-    foreach($results as $row) {
-        if (!($task = Task::lookup($row['id'])))
-            continue;
-
-        $flag=null;
-        if ($row['lock_id'])
-            $flag='locked';
-        elseif ($row['isoverdue'])
-            $flag='overdue';
-
+    foreach($tasks as $task) {
+        $id = $task->getId();
         $assigned='';
-        if ($row['staff_id'])
-            $assigned=sprintf('<span class="Icon staffAssigned">%s</span>',Format::truncate($row['staff'],40));
-        elseif ($row['team_id'])
-            $assigned=sprintf('<span class="Icon teamAssigned">%s</span>',Format::truncate($row['team'],40));
-        else
-            $assigned=' ';
+        if ($task->staff)
+            $assigned=sprintf('<span class="Icon staffAssigned">%s</span>',
+                    Format::truncate($task->staff->getName(),40));
 
         $status = $task->isOpen() ? '<strong>open</strong>': 'closed';
 
-        $tid=$row['number'];
         $title = Format::htmlchars(Format::truncate($task->getTitle(),40));
-        $threadcount= $task->getThread()->getNumEntries();
+        $threadcount = $task->getThread() ?
+            $task->getThread()->getNumEntries() : 0;
         ?>
-        <tr id="<?php echo $row['id']; ?>">
+        <tr id="<?php echo $id; ?>">
             <?php
             //Implement mass  action....if need be.
             if (0) { ?>
             <td align="center" class="nohover">
                 <input class="ckb" type="checkbox" name="tids[]"
-                value="<?php echo $row['id']; ?>" <?php echo $sel?'checked="checked"':''; ?>>
+                value="<?php echo $id; ?>" <?php echo $sel?'checked="checked"':''; ?>>
             </td>
             <?php
             } ?>
             <td align="center" nowrap>
               <a class="Icon no-pjax preview"
                 title="<?php echo __('Preview Task'); ?>"
-                href="#tasks/<?php echo $task->getId(); ?>/view"
-                data-preview="#tasks/<?php echo $task->getId(); ?>/preview"
+                href="#tasks/<?php echo $id; ?>/view"
+                data-preview="#tasks/<?php echo $id; ?>/preview"
                 ><?php echo $task->getNumber(); ?></a></td>
             <td align="center" nowrap><?php echo
-            Format::db_datetime($row['created']); ?></td>
+            Format::datetime($task->created); ?></td>
             <td><?php echo $status; ?></td>
             <td><a <?php if ($flag) { ?> class="no-pjax"
                     title="<?php echo ucfirst($flag); ?> Task" <?php } ?>
-                    href="#tasks/<?php echo $task->getId(); ?>/view"><?php
+                    href="#tasks/<?php echo $id; ?>/view"><?php
                 echo $title; ?></a>
                  <?php
                     if ($threadcount>1)
@@ -130,7 +107,7 @@ if ($results) { ?>
                         echo '<i class="icon-fixed-width icon-paperclip"></i>&nbsp;';
                 ?>
             </td>
-            <td><?php echo Format::truncate($row['dept_name'], 40); ?></td>
+            <td><?php echo Format::truncate($task->dept->getName(), 40); ?></td>
             <td>&nbsp;<?php echo $assigned; ?></td>
         </tr>
    <?php
@@ -157,5 +134,30 @@ $(function() {
         }).show();
         return false;
      });
+    $(document).off('.task-action');
+    $(document).on('click.task-action', 'a.task-action', function(e) {
+        e.preventDefault();
+        var url = 'ajax.php/'
+        +$(this).attr('href').substr(1)
+        +'?_uid='+new Date().getTime();
+        var $redirect = $(this).data('href');
+        var $options = $(this).data('dialog');
+        $.dialog(url, [201], function (xhr) {
+            var tid = parseInt(xhr.responseText);
+            if (tid) {
+                var url = 'ajax.php/tasks/'+tid+'/view';
+                var $container = $('div#task_content');
+                $container.load(url, function () {
+                    $('.tip_box').remove();
+                    $('div#tasks_content').hide();
+                }).show();
+            } else {
+                window.location.href = $redirect ? $redirect : window.location.href;
+            }
+        }, $options);
+        return false;
+    });
+
+
 });
 </script>
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index d8d0e5b43b180dcb604540424e698344848c8daa..e6522e7dee47fbb44e6a87aeb10e35379828b5e3 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -377,8 +377,9 @@ $tcount = $ticket->getThreadCount();
 $tcount+= $ticket->getNumNotes();
 ?>
 <ul  class="tabs threads" id="ticket_tabs" >
-    <li><a class="active" href="#ticket_thread"><?php echo sprintf(__('Ticket Thread (%d)'), $tcount); ?></a></li>
-    <li><a id="ticket_tasks" href="<?php
+    <li class="active"><a href="#ticket_thread"><?php echo sprintf(__('Ticket Thread (%d)'), $tcount); ?></a></li>
+    <li><a id="ticket_tasks" href="#tasks"
+            data-url="<?php
         echo sprintf('#tickets/%d/tasks', $ticket->getId()); ?>"><?php
         echo __('Tasks');
         if ($ticket->getNumTasks())
@@ -454,7 +455,7 @@ $tcount+= $ticket->getNumNotes();
 <div id="response_options">
     <ul class="tabs">
         <?php
-        if ($role->canPostReply()) { ?>
+        if ($role->canPostTicketReply()) { ?>
         <li class="active"><a href="#reply"><?php echo __('Post Reply');?></a></li>
         <?php
         } ?>
@@ -472,7 +473,7 @@ $tcount+= $ticket->getNumNotes();
         } ?>
     </ul>
     <?php
-    if ($role->canPostReply()) { ?>
+    if ($role->canPostTicketReply()) { ?>
     <form id="reply" class="tab_content" action="tickets.php?id=<?php
         echo $ticket->getId(); ?>" name="reply" method="post" enctype="multipart/form-data">
         <?php csrf_token(); ?>
diff --git a/scp/ajax.php b/scp/ajax.php
index d0d6f409f4628e114db3833635b848e993dd570a..1c313c18c4afab80c58cbb3579de2cf254a34c76 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -160,6 +160,14 @@ $dispatcher = patterns('',
     )),
     url('^/tasks/', patterns('ajax.tasks.php:TasksAjaxAPI',
         url_get('^(?P<tid>\d+)/preview$', 'preview'),
+        url_get('^(?P<tid>\d+)/edit', 'edit'),
+        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_get('^(?P<tid>\d+)/delete', 'delete'),
+        url_post('^(?P<tid>\d+)/delete$', 'delete'),
         url_get('^(?P<tid>\d+)/view$', 'task'),
         url_post('^(?P<tid>\d+)$', 'task')
     )),