diff --git a/bootstrap.php b/bootstrap.php
index 8a68c184342105d0bb5d3583a8a842d389de3426..ff09b15b66be4a7433d2f46b4dd8c07431eabe46 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -98,6 +98,7 @@ class Bootstrap {
         define('TICKET_TABLE',$prefix.'ticket');
         define('TICKET_CDATA_TABLE', $prefix.'ticket__cdata');
         define('THREAD_EVENT_TABLE',$prefix.'thread_event');
+        define('THREAD_REFERRAL_TABLE',$prefix.'thread_referral');
         define('THREAD_COLLABORATOR_TABLE', $prefix.'thread_collaborator');
         define('TICKET_STATUS_TABLE', $prefix.'ticket_status');
         define('TICKET_PRIORITY_TABLE',$prefix.'ticket_priority');
diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index 57df9e01333c5465944d1cb166b04b7f1ba436e9..e89ceead6b9175c76dafcfd1547d845b81214d56 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -418,6 +418,88 @@ class TicketsAjaxAPI extends AjaxController {
     }
 
 
+  function referrals($tid) {
+
+      return $this->refer($tid);
+
+  }
+
+function refer($tid, $target=null) {
+    global $thisstaff;
+
+    if (!($ticket=Ticket::lookup($tid)))
+        Http::response(404, __('No such ticket'));
+
+    if (!$ticket->checkStaffPerm($thisstaff, Ticket::PERM_ASSIGN)
+            || !($form = $ticket->getReferralForm($_POST,
+                    array('target' => $target))))
+        Http::response(403, __('Permission denied'));
+
+    $errors = array();
+    $info = array(
+            ':title' => sprintf(__('Ticket #%s: %s'),
+                $ticket->getNumber(),
+                __('Refer')
+                ),
+            ':action' => sprintf('#tickets/%d/refer%s',
+                $ticket->getId(),
+                ($target  ? "/$target": '')),
+            );
+
+    if ($_POST) {
+
+        switch ($_POST['do']) {
+        case 'refer':
+            if ($form->isValid() && $ticket->refer($form, $errors)) {
+                $_SESSION['::sysmsgs']['msg'] = sprintf(
+                        __('%s successfully'),
+                        sprintf(
+                            __('%s referred to %s'),
+                            sprintf(__('Ticket #%s'),
+                                 sprintf('<a href="tickets.php?id=%d"><b>%s</b></a>',
+                                     $ticket->getId(),
+                                     $ticket->getNumber()))
+                            ,
+                            $form->getTarget())
+                        );
+                Http::response(201, $ticket->getId());
+            }
+
+            $form->addErrors($errors);
+            $info['error'] = $errors['err'] ?: __('Unable to refer ticket');
+            break;
+        case 'manage':
+            $remove = array();
+            if (is_array($_POST['referrals'])) {
+                $remove = array();
+                foreach ($_POST['referrals'] as $k => $v)
+                    if ($v[0] == '-')
+                        $remove[] = substr($v, 1);
+                if (count($remove)) {
+                    $num = $ticket->thread->referrals
+                        ->filter(array('id__in' => $remove))
+                        ->delete();
+                    if ($num) {
+                        $info['msg'] = sprintf(
+                                __('%s successfully'),
+                                sprintf(__('Removed %d referrals'),
+                                    $num
+                                    )
+                                );
+                    }
+                    //TODO: log removal
+                }
+            }
+            break;
+        default:
+             $errors['err'] = __('Unknown Action');
+        }
+    }
+
+    $thread = $ticket->getThread();
+    include STAFFINC_DIR . 'templates/refer.tmpl.php';
+}
+
     function assign($tid, $target=null) {
         global $thisstaff;
 
@@ -545,6 +627,9 @@ class TicketsAjaxAPI extends AjaxController {
                 'assign' => array(
                     'verbed' => __('assigned'),
                     ),
+                'refer' => array(
+                    'verbed' => __('referred'),
+                    ),
                 'claim' => array(
                     'verbed' => __('assigned'),
                     ),
diff --git a/include/class.forms.php b/include/class.forms.php
index eaf5dbd255476418222d5f9e945a14d75964a14e..6f13a4a0ce0ef68fb6fd0ce1443e13f8c6dcd06e 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -2671,17 +2671,24 @@ class AssigneeField extends ChoiceField {
     }
 
     function to_php($value, $id=false) {
+        $type = '';
         if (is_array($id)) {
             reset($id);
             $id = key($id);
+            $type = $id[0];
+            $id = substr($id, 1);
         }
 
-        if ($id[0] == 's')
-            return Staff::lookup(substr($id, 1));
-        elseif ($id[0] == 't')
-            return Team::lookup(substr($id, 1));
-
-        return $id;
+        switch ($type) {
+        case 's':
+            return Staff::lookup($id);
+        case 't':
+            return Team::lookup($id);
+        case 'd':
+            return Dept::lookup($id);
+        default:
+            return $id;
+        }
     }
 
 
@@ -4613,6 +4620,128 @@ class ClaimForm extends AssignmentForm {
 
 }
 
+class ReferralForm extends Form {
+
+    static $id = 'refer';
+    var $_target = null;
+    var $_choices = null;
+    var $_prompt = '';
+
+    function getFields() {
+
+        if ($this->fields)
+            return $this->fields;
+
+        $fields = array(
+            'target' => new AssigneeField(array(
+                    'id'=>1,
+                    'label' => __('Referee'),
+                    'flags' => hexdec(0X450F3),
+                    'required' => true,
+                    'validator-error' => __('Selection required'),
+                    'configuration' => array(
+                        'criteria' => array(
+                            'available' => true,
+                            ),
+                        'prompt' => $this->_prompt,
+                       ),
+                    )
+                ),
+            'comments' => new TextareaField(array(
+                    'id' => 2,
+                    'label'=> '',
+                    'required'=>false,
+                    'default'=>'',
+                    'configuration' => array(
+                        'html' => true,
+                        'size' => 'small',
+                        'placeholder' => __('Optional reason for the referral'),
+                        ),
+                    )
+                ),
+            );
+
+
+        if (isset($this->_choices))
+            $fields['target']->setChoices($this->_choices);
+
+
+        $this->setFields($fields);
+
+        return $this->fields;
+    }
+
+    function getField($name) {
+
+        if (($fields = $this->getFields())
+                && isset($fields[$name]))
+            return $fields[$name];
+    }
+
+    function isValid($include=false) {
+
+        if (!parent::isValid($include) || !($f=$this->getField('target')))
+            return false;
+
+        // Do additional assignment validation
+        $choice = $this->getTarget();
+        switch (true) {
+        case $choice instanceof Staff:
+            // Make sure the agent is available
+            if (!$choice->isAvailable())
+                $f->addError(__('Agent is unavailable for assignment'));
+        break;
+        case $choice instanceof Team:
+            // Make sure the team is active and has members
+            if (!$choice->isActive())
+                $f->addError(__('Team is disabled'));
+            elseif (!$choice->getNumMembers())
+                $f->addError(__('Team does not have members'));
+        break;
+        case $choice instanceof Dept:
+        break;
+        default:
+            $f->addError(__('Unknown selection'));
+        }
+
+        return !$this->errors();
+    }
+
+    function render($options) {
+
+        switch(strtolower($options['template'])) {
+        case 'simple':
+            $inc = STAFFINC_DIR . 'templates/dynamic-form-simple.tmpl.php';
+            break;
+        default:
+            throw new Exception(sprintf(__('%s: Unknown template style %s'),
+                        'FormUtils', $options['template']));
+        }
+
+        $form = $this;
+        include $inc;
+    }
+
+    function setChoices($choices, $prompt='') {
+        $this->_choices = $choices;
+        $this->_prompt = $prompt;
+        $this->_fields = array();
+    }
+
+    function getTarget() {
+
+        if (!isset($this->_target))
+            $this->_target = $this->getField('target')->getClean();
+
+        return $this->_target;
+    }
+
+    function getComments() {
+        return $this->getField('comments')->getClean();
+    }
+}
+
+
 class TransferForm extends Form {
 
     static $id = 'transfer';
diff --git a/include/class.model.php b/include/class.model.php
index 5d41a05d099684b943c9ad754f2b8653b443324d..c9158a2e8d3801139b909c946012fb043dd71fad 100644
--- a/include/class.model.php
+++ b/include/class.model.php
@@ -22,6 +22,9 @@ class ObjectModel {
     const OBJECT_TYPE_FAQ    = 'K';
     const OBJECT_TYPE_FILE   = 'F';
     const OBJECT_TYPE_TASK   = 'A';
+    const OBJECT_TYPE_TEAM   = 'E';
+    const OBJECT_TYPE_DEPT   = 'D';
+    const OBJECT_TYPE_STAFF  = 'S';
 
     private function objects() {
         static $objects = false;
@@ -34,6 +37,9 @@ class ObjectModel {
                     self::OBJECT_TYPE_FAQ     => 'FAQ',
                     self::OBJECT_TYPE_FILE    => 'AttachmentFile',
                     self::OBJECT_TYPE_TASK    => 'Task',
+                    self::OBJECT_TYPE_TEAM    => 'Team',
+                    self::OBJECT_TYPE_DEPT    => 'Dept',
+                    self::OBJECT_TYPE_STAFF   => 'Staff',
                     );
         }
 
diff --git a/include/class.staff.php b/include/class.staff.php
index c2c1b67670ca05575a370763fa134ea43ad14522..bbe66e4626d97a641ab1f75257594154b59ad0fa 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -540,8 +540,34 @@ implements AuthenticatedUser, EmailContact, TemplateVariable, Searchable {
 
         return $this->_teams;
     }
-    /* stats */
 
+    function getTicketsVisibility() {
+
+        // -- Open and assigned to me
+        $assigned = Q::any(array(
+            'staff_id' => $this->getId(),
+        ));
+
+        $assigned->add(array('thread__referrals__agent__staff_id' => $this->getId()));
+
+        // -- Open and assigned to a team of mine
+        if ($teams = array_filter($this->getTeams())) {
+            $assigned->add(array('team_id__in' => $teams));
+            $assigned->add(array('thread__referrals__team__team_id__in' => $teams));
+        }
+
+        $visibility = Q::any(new Q(array('status__state'=>'open', $assigned)));
+
+        // -- Routed to a department of mine
+        if (!$this->showAssignedOnly() && ($depts=$this->getDepts())) {
+            $visibility->add(array('dept_id__in' => $depts));
+            $visibility->add(array('thread__referrals__dept__id__in' => $depts));
+        }
+
+        return $visibility;
+    }
+
+    /* stats */
     function resetStats() {
         $this->stats = array();
     }
diff --git a/include/class.thread.php b/include/class.thread.php
index eab798690b60242706a19e0bd9563f823e0e463f..bbb0d100b7feb758ecf39c74c14d533de313714e 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -40,6 +40,10 @@ implements Searchable {
             'collaborators' => array(
                 'reverse' => 'Collaborator.thread',
             ),
+
+            'referrals' => array(
+                'reverse' => 'ThreadReferral.thread',
+            ),
             'entries' => array(
                 'reverse' => 'ThreadEntry.thread',
             ),
@@ -104,6 +108,15 @@ implements Searchable {
         return $this->_entries;
     }
 
+    // Referrals
+    function getNumReferrals() {
+        return $this->referrals->count();
+    }
+
+    function getReferrals() {
+        return $this->referrals;
+    }
+
     // Collaborators
     function getNumCollaborators() {
         return $this->collaborators->count();
@@ -262,6 +275,30 @@ implements Searchable {
         return $this->_participants;
     }
 
+    function refer($to) {
+
+        $vars = array('thread_id' => $this->getId());
+        switch (true) {
+        case $to instanceof Staff:
+            $vars['object_id'] = $to->getId();
+            $vars['object_type'] = ObjectModel::OBJECT_TYPE_STAFF;
+            break;
+        case $to instanceof Team:
+            $vars['object_id'] = $to->getId();
+            $vars['object_type'] = ObjectModel::OBJECT_TYPE_TEAM;
+            break;
+        case $to instanceof Dept:
+            $vars['object_id'] = $to->getId();
+            $vars['object_type'] = ObjectModel::OBJECT_TYPE_DEPT;
+            break;
+        default:
+            return false;
+        }
+
+        var_dump($vars);
+
+        return ThreadReferral::create($vars);
+    }
 
     // Render thread
     function render($type=false, $options=array()) {
@@ -1636,6 +1673,79 @@ implements TemplateVariable {
 
 RolePermission::register(/* @trans */ 'Tickets', ThreadEntry::getPermissions());
 
+
+class ThreadReferral extends VerySimpleModel {
+    static $meta = array(
+        'table' => THREAD_REFERRAL_TABLE,
+        'pk' => array('id'),
+        'joins' => array(
+            'thread' => array(
+                'constraint' => array('thread_id' => 'Thread.id'),
+            ),
+            'agent' => array(
+                'constraint' => array(
+                    'object_type' => "'S'",
+                    'object_id' => 'Staff.staff_id',
+                ),
+            ),
+            'team' => array(
+                'constraint' => array(
+                    'object_type' => "'E'",
+                    'object_id' => 'Team.team_id',
+                ),
+            ),
+            'dept' => array(
+                'constraint' => array(
+                    'object_type' => "'D'",
+                    'object_id' => 'Dept.id',
+                ),
+            ),
+          )
+        );
+
+    var $icons = array(
+            'E' => 'group',
+            'D' => 'sitemap',
+            'S' => 'user'
+            );
+
+    var $_object = null;
+
+    function getId() {
+        return $this->id;
+    }
+
+    function getName() {
+        return (string) $this->getObject();
+    }
+
+    function getObject() {
+
+        if (!isset($this->_object)) {
+            $this->_object = ObjectModel::lookup(
+                    $this->object_id, $this->object_type);
+        }
+
+        return $this->_object;
+    }
+
+    function getIcon() {
+        return $this->icons[$this->object_type];
+    }
+
+    function display() {
+        return sprintf('<i class="icon-%s"></i> %s',
+                $this->getIcon(), $this->getName());
+    }
+
+    static function create($vars) {
+
+        $new = new self($vars);
+        $new->created = SqlFunction::NOW();
+        return $new->save();
+    }
+}
+
 class ThreadEvent extends VerySimpleModel {
     static $meta = array(
         'table' => THREAD_EVENT_TABLE,
@@ -1690,6 +1800,7 @@ class ThreadEvent extends VerySimpleModel {
     const REOPENED  = 'reopened';
     const STATUS    = 'status';
     const TRANSFERRED = 'transferred';
+    const REFERRED = 'referred';
     const VIEWED    = 'viewed';
 
     const MODE_STAFF = 1;
@@ -1719,6 +1830,7 @@ class ThreadEvent extends VerySimpleModel {
             'created'   => 'magic',
             'overdue'   => 'time',
             'transferred' => 'share-alt',
+            'referred' => 'exchange',
             'edited'    => 'pencil',
             'closed'    => 'thumbs-up-alt',
             'reopened'  => 'rotate-right',
@@ -1963,6 +2075,27 @@ class AssignmentEvent extends ThreadEvent {
     }
 }
 
+class ReferralEvent extends ThreadEvent {
+    static $icon = 'exchange';
+    static $state = 'referred';
+
+    function getDescription($mode=self::MODE_STAFF) {
+        $data = $this->getData();
+        switch (true) {
+        case isset($data['staff']):
+            $desc = __('<b>{somebody}</b> referred this to <strong>{<Staff>data.staff}</strong> {timestamp}');
+            break;
+        case isset($data['team']):
+            $desc = __('<b>{somebody}</b> referred this to <strong>{<Team>data.team}</strong> {timestamp}');
+            break;
+        case isset($data['dept']):
+            $desc = __('<b>{somebody}</b> referred this to <strong>{<Dept>data.dept}</strong> {timestamp}');
+            break;
+        }
+        return $this->template($desc);
+    }
+}
+
 class CloseEvent extends ThreadEvent {
     static $icon = 'thumbs-up-alt';
     static $state = 'closed';
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 332f10c125736d786c7cbd9f3ec569eb0ba258c0..f91ab94bfdca21792200e98615d050ecab633dd6 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -852,6 +852,36 @@ implements RestrictedAccess, Threadable, Searchable {
         return $form;
     }
 
+    function getReferralForm($source=null, $options=array()) {
+
+        $prompt = '';
+        $choices = array();
+        switch (strtolower($options['target'])) {
+        case 'agents':
+            $dept = $this->getDept();
+            foreach ($dept->getAssignees() as $member)
+                $choices['s'.$member->getId()] = $member;
+            $prompt = sprintf('%s %s', __('Select an'), __('Agent'));
+            break;
+        case 'teams':
+            if (($teams = Team::getActiveTeams()))
+                foreach ($teams as $id => $name)
+                    $choices['t'.$id] = $name;
+            $prompt = sprintf('%s %s', __('Select a'), __('Team'));
+            break;
+        case 'departments':
+            foreach (Dept::getDepartments() as $k => $v)
+                $choices["d$k"] = $v;
+            $prompt = sprintf('%s %s', __('Select a'), __('Department'));
+            break;
+        }
+
+        $form = ReferralForm::instantiate($source, $options);
+        $form->setChoices($choices, $prompt);
+
+        return $form;
+    }
+
     function getClaimForm($source=null, $options=array()) {
         global $thisstaff;
 
@@ -2283,6 +2313,65 @@ implements RestrictedAccess, Threadable, Searchable {
         return $this->unassign();
     }
 
+    function refer(ReferralForm $form, &$errors, $alert=true) {
+        global $thisstaff;
+
+        $evd = array();
+        $choice = $form->getTarget();
+        switch (true) {
+        case $choice instanceof Staff:
+            $dept = $this->getDept();
+            if ($this->getStaffId() == $choice->getId()) {
+                $errors['target'] = sprintf(__('%s is assigned to %s'),
+                        __('Ticket'),
+                        __('the agent')
+                        );
+            } elseif(!$choice->isAvailable()) {
+                $errors['assignee'] = sprintf(__('Agent is unavailable for %s'),
+                        __('referral'));
+            } elseif ($dept->assignMembersOnly() && !$dept->isMember($choice)) {
+                $errors['err'] = __('Permission denied');
+            } else {
+                $evd['staff'] = array($choice->getId(), (string) $choice->getName()->getOriginal());
+            }
+            break;
+        case $choice instanceof Team:
+            if ($this->getTeamId() == $choice->getId()) {
+                $errors['assignee'] = sprintf(__('%s is assigned to %s'),
+                        __('Ticket'),
+                        __('the team')
+                        );
+            } else {
+                //TODO::
+                $evd = array('team' => $choice->getId());
+            }
+            break;
+        case $choice instanceof Dept:
+            if ($this->getTeamId() == $choice->getId()) {
+                $errors['target'] = sprintf(__('%s is already in %s'),
+                        __('Ticket'),
+                        __('the department')
+                        );
+            } else {
+                //TODO::
+                $evd = array('dept' => $choice->getId());
+            }
+            break;
+        default:
+            $errors['target'] = __('Unknown referral');
+        }
+
+        if (!$errors && !$this->thread->refer($choice))
+            $errors['err'] = __('Unable to reffer ticket');
+
+        if ($errors)
+            return false;
+
+        $this->logEvent('referred', $evd);
+
+        return true;
+    }
+
     //Change ownership
     function changeOwner($user) {
         global $thisstaff;
@@ -3073,19 +3162,7 @@ implements RestrictedAccess, Threadable, Searchable {
         if(!$staff || (!is_object($staff) && !($staff=Staff::lookup($staff))) || !$staff->isStaff())
             return null;
 
-        // -- Open and assigned to me
-        $assigned = Q::any(array(
-            'staff_id' => $staff->getId(),
-        ));
-        // -- Open and assigned to a team of mine
-        if ($teams = array_filter($staff->getTeams()))
-            $assigned->add(array('team_id__in' => $teams));
-
-        $visibility = Q::any(new Q(array('status__state'=>'open', $assigned)));
-
-        // -- Routed to a department of mine
-        if (!$staff->showAssignedOnly() && ($depts = $staff->getDepts()))
-            $visibility->add(array('dept_id__in' => $depts));
+        $visibility = $staff->getTicketsVisibility();
 
         $blocks = Ticket::objects()
             ->filter(Q::any($visibility))
diff --git a/include/staff/templates/refer.tmpl.php b/include/staff/templates/refer.tmpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..b1c850f8a779871c6d34de2dec19049c15748a2e
--- /dev/null
+++ b/include/staff/templates/refer.tmpl.php
@@ -0,0 +1,129 @@
+<?php
+global $cfg;
+
+if (!$thread) return;
+
+$form = $form ?: ReferralForm::instantiate($info);
+
+?>
+<h3 class="drag-handle"><?php echo $info[':title'] ?:  __('Refer'); ?></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'] ?: ('#');
+$manage = (!$target);
+?>
+<ul class="tabs" id="referral">
+    <li <?php echo !$manage ? 'class="active"' : ''; ?>><a href="#refer"
+        ><i class="icon-exchange"></i>&nbsp;<?php echo __('Refer'); ?></a></li>
+    <li <?php echo $manage ? 'class="active"' : ''; ?>><a href="#referrals"
+        ><i class="icon-list"></i>&nbsp;<?php
+        echo sprintf('%s (%d)', __('Referrals'), $thread->getNumReferrals()); ?></a></li>
+</ul>
+<div id="referral_container">
+   <div class="tab_content <?php echo $manage ? 'hidden' : ''; ?>" id="refer" style="margin:5px;">
+    <form class="mass-action" method="post"
+        name="assign"
+        id="<?php echo $form->getId(); ?>"
+        action="<?php echo $action; ?>">
+      <input type='hidden' name='do' value='refer'>
+    <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
+             $options = array('template' => 'simple', 'form_id' => 'refer');
+             $form->render($options);
+             ?>
+            </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 __('Refer'); ?>">
+        </span>
+     </p>
+    </form>
+    </div>
+   <div class="tab_content <?php echo !$manage ? 'hidden' : ''; ?>" id="referrals" style="margin:5px;">
+   <form class="mass-action" method="post"
+    name="referrals"
+    id="rf"
+    action="<?php echo sprintf('#/tickets/%d/referrals', $ticket->getId()); ?>">
+     <input type='hidden' name='do' value='manage'>
+    <table width="100%">
+        <tbody>
+           <?php
+           if ($thread->referrals->count()) {
+            foreach ($thread->referrals as $r) {
+            ?>
+            <tr>
+                <td style="border-top: 1px solid #ddd;"> <?php echo  $r->display(); ?></td>
+                <td style="border-top: 1px solid #ddd;">
+                    <div style="position:relative">
+                    <input type="hidden" name="referrals[]" value="<?php echo $r->getId(); ?>"/>
+                    <div class="pull-right" style="right:2px;">
+                        <a href="#" title="<?php echo __('clear'); ?>" onclick="javascript:
+                            if (!confirm(__('You sure?')))
+                            return false;
+                            $(this).closest('td').find('input[name=\'referrals[]\']')
+                                .val(function(i,v) { return '-'+ v; });
+                            $(this).closest('tr').fadeOut(400, function() { $(this).hide(); });
+                            $('input[type=submit], button[type=submit]',
+                                    $(this).closest('form')).addClass('save pending');
+                            return false;"><i class="icon-trash"></i></a>
+                        </div>
+                    </div>
+                </td>
+            </tr>
+            <?php }
+            } ?>
+        </tbody>
+    </table>
+    <hr>
+    <?php
+    if ($thread->getNumReferrals()) {?>
+    <p class="full-width">
+        <span class="buttons pull-left">
+            <input type="button" name="cancel" class="close"
+            value="<?php echo __('Cancel'); ?>">
+        </span>
+        <span class="buttons pull-right">
+            <input type="submit" value="<?php
+            echo __('Save Changes'); ?>">
+        </span>
+     </p>
+     <?php
+    } ?>
+    </form>
+  </div>
+</div>
+<div class="clear"></div>
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index a977ab2c6cc1fa387b996011e0c9d1167c552630..81965fbcef6a6f8ca021d1cae63e8f296c654dd8 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -92,6 +92,33 @@ if($ticket->isOverdue())
                 data-redirect="tickets.php"
                 href="#tickets/<?php echo $ticket->getId(); ?>/transfer"><i class="icon-share"></i></a>
             </span>
+            <span class="action-button pull-right"
+                data-dropdown="#action-dropdown-refer"
+                data-placement="bottom"
+                data-toggle="tooltip"
+                title=" <?php echo __('Refer'); ?>"
+                >
+                <i class="icon-caret-down pull-right"></i>
+                <a class="ticket-action" id="ticket-refer"
+                    data-redirect="tickets.php"
+                    href="#tickets/<?php echo $ticket->getId(); ?>/refer"><i class="icon-exchange"></i></a>
+            </span>
+            <div id="action-dropdown-refer" class="action-dropdown anchor-right">
+              <ul>
+                 <li><a class="no-pjax ticket-action"
+                    data-redirect="tickets.php"
+                    href="#tickets/<?php echo $ticket->getId(); ?>/refer/agents"><i
+                    class="icon-user"></i> <?php echo __('Agent'); ?></a>
+                 <li><a class="no-pjax ticket-action"
+                    data-redirect="tickets.php"
+                    href="#tickets/<?php echo $ticket->getId(); ?>/refer/teams"><i
+                    class="icon-group"></i> <?php echo __('Team'); ?></a>
+                 <li><a class="no-pjax ticket-action"
+                    data-redirect="tickets.php"
+                    href="#tickets/<?php echo $ticket->getId(); ?>/refer/departments"><i
+                    class="icon-sitemap"></i> <?php echo __('Department'); ?></a>
+              </ul>
+            </div>
             <?php
             } ?>
 
diff --git a/scp/ajax.php b/scp/ajax.php
index 215079e18c80f65ef5d1b9776fc5f6d586df7a3d..b935414c1de4544a0c448b7b448770b17f05db2e 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -165,6 +165,8 @@ $dispatcher = patterns('',
         url('^mass/(?P<action>\w+)(?:/(?P<what>\w+))?', 'massProcess'),
         url('^(?P<tid>\d+)/transfer$', 'transfer'),
         url('^(?P<tid>\d+)/assign(?:/(?P<to>\w+))?$', 'assign'),
+        url('^(?P<tid>\d+)/refer(?:/(?P<to>\w+))?$', 'refer'),
+        url('^(?P<tid>\d+)/referrals$', 'referrals'),
         url('^(?P<tid>\d+)/claim$', 'claim'),
         url('^search', patterns('ajax.search.php:SearchAjaxAPI',
             url_get('^$', 'getAdvancedSearchDialog'),