diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index e89ceead6b9175c76dafcfd1547d845b81214d56..0338545a6d4935489c8cb31613b6154bfc712db8 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -460,7 +460,7 @@ function refer($tid, $target=null) {
                                      $ticket->getId(),
                                      $ticket->getNumber()))
                             ,
-                            $form->getTarget())
+                            $form->getReferee())
                         );
                 Http::response(201, $ticket->getId());
             }
diff --git a/include/class.forms.php b/include/class.forms.php
index 6f13a4a0ce0ef68fb6fd0ce1443e13f8c6dcd06e..c834309b4c65ea7b8daa15c4b6265af35d3fea2c 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -3896,7 +3896,7 @@ class CheckboxWidget extends Widget {
         $data = $this->field->getSource();
         if (count($data)) {
             if (!isset($data[$this->name]))
-                return false;
+                return null;
             return @in_array($this->field->get('id'), $data[$this->name]);
         }
         return parent::getValue();
@@ -4479,10 +4479,8 @@ class AssignmentForm extends Form {
 
         $fields = array(
             'assignee' => new AssigneeField(array(
-                    'id'=>1,
-                    'label' => __('Assignee'),
-                    'flags' => hexdec(0X450F3),
-                    'required' => true,
+                    'id'=>1, 'label' => __('Assignee'),
+                    'flags' => hexdec(0X450F3), 'required' => true,
                     'validator-error' => __('Assignee selection required'),
                     'configuration' => array(
                         'criteria' => array(
@@ -4491,11 +4489,15 @@ class AssignmentForm extends Form {
                        ),
                     )
                 ),
+            'refer' => new BooleanField(array(
+                    'id'=>2, 'label'=>'', 'required'=>false,
+                    'default'=>false,
+                    'configuration'=>array(
+                        'desc' => 'Maintain referral access to current assignees')
+                    )
+                ),
             'comments' => new TextareaField(array(
-                    'id' => 2,
-                    'label'=> '',
-                    'required'=>false,
-                    'default'=>'',
+                    'id' => 3, 'label'=> '', 'required'=>false, 'default'=>'',
                     'configuration' => array(
                         'html' => true,
                         'size' => 'small',
@@ -4580,6 +4582,10 @@ class AssignmentForm extends Form {
     function getComments() {
         return $this->getField('comments')->getClean();
     }
+
+    function refer() {
+        return $this->getField('refer')->getClean();
+    }
 }
 
 class ClaimForm extends AssignmentForm {
@@ -4633,22 +4639,60 @@ class ReferralForm extends Form {
             return $this->fields;
 
         $fields = array(
-            'target' => new AssigneeField(array(
+            'target' => new ChoiceField(array(
                     'id'=>1,
                     'label' => __('Referee'),
                     'flags' => hexdec(0X450F3),
                     'required' => true,
                     'validator-error' => __('Selection required'),
-                    'configuration' => array(
-                        'criteria' => array(
-                            'available' => true,
-                            ),
-                        'prompt' => $this->_prompt,
-                       ),
-                    )
+                    'choices' => array(
+                    'agent' => __('Agent'),
+                    'team'  => __('Team'),
+                                'dept'  => __('Department'),
+                               ),
+                            )
+                ),
+            'agent' => new ChoiceField(array(
+                    'id'=>2,
+                    'label' => '',
+                    'flags' => hexdec(0X450F3),
+                    'required' => true,
+                    'configuration'=>array('prompt'=>__('Select Agent')),
+                            'validator-error' => __('Agent selection required'),
+                    'visibility' => new VisibilityConstraint(
+                        new Q(array('target__eq'=>'agent')),
+                        VisibilityConstraint::HIDDEN
+                      ),
+                            )
+                ),
+            'team' => new ChoiceField(array(
+                    'id'=>3,
+                    'label' => '',
+                    'flags' => hexdec(0X450F3),
+                    'required' => true,
+                    'validator-error' => __('Team selection required'),
+                    'configuration'=>array('prompt'=>__('Select Team')),
+                            'visibility' => new VisibilityConstraint(
+                                    new Q(array('target__eq'=>'team')),
+                                    VisibilityConstraint::HIDDEN
+                              ),
+                            )
+                ),
+            'dept' => new ChoiceField(array(
+                    'id'=>4,
+                    'label' => '',
+                    'flags' => hexdec(0X450F3),
+                    'required' => true,
+                    'validator-error' => __('Dept. selection required'),
+                    'configuration'=>array('prompt'=>__('Select Department')),
+                            'visibility' => new VisibilityConstraint(
+                                    new Q(array('target__eq'=>'dept')),
+                                    VisibilityConstraint::HIDDEN
+                              ),
+                            )
                 ),
             'comments' => new TextareaField(array(
-                    'id' => 2,
+                    'id' => 5,
                     'label'=> '',
                     'required'=>false,
                     'default'=>'',
@@ -4661,11 +4705,6 @@ class ReferralForm extends Form {
                 ),
             );
 
-
-        if (isset($this->_choices))
-            $fields['target']->setChoices($this->_choices);
-
-
         $this->setFields($fields);
 
         return $this->fields;
@@ -4678,27 +4717,29 @@ class ReferralForm extends Form {
             return $fields[$name];
     }
 
+
+
     function isValid($include=false) {
 
         if (!parent::isValid($include) || !($f=$this->getField('target')))
             return false;
 
         // Do additional assignment validation
-        $choice = $this->getTarget();
+        $referee = $this->getReferee();
         switch (true) {
-        case $choice instanceof Staff:
+        case $referee instanceof Staff:
             // Make sure the agent is available
-            if (!$choice->isAvailable())
+            if (!$referee->isAvailable())
                 $f->addError(__('Agent is unavailable for assignment'));
         break;
-        case $choice instanceof Team:
+        case $referee instanceof Team:
             // Make sure the team is active and has members
-            if (!$choice->isActive())
+            if (!$referee->isActive())
                 $f->addError(__('Team is disabled'));
-            elseif (!$choice->getNumMembers())
+            elseif (!$referee->getNumMembers())
                 $f->addError(__('Team does not have members'));
         break;
-        case $choice instanceof Dept:
+        case $referee instanceof Dept:
         break;
         default:
             $f->addError(__('Unknown selection'));
@@ -4722,18 +4763,31 @@ class ReferralForm extends Form {
         include $inc;
     }
 
-    function setChoices($choices, $prompt='') {
-        $this->_choices = $choices;
-        $this->_prompt = $prompt;
-        $this->_fields = array();
+    function setChoices($field, $choices, $prompt='') {
+
+        if (!($f= $this->getField($field)))
+           return;
+
+        $f->set('choices', $choices);
+
+        return $f;
     }
 
-    function getTarget() {
+    function getReferee() {
 
-        if (!isset($this->_target))
-            $this->_target = $this->getField('target')->getClean();
+        $target = $this->getField('target')->getClean();
+        if (!$target || !($f=$this->getField($target)))
+            return null;
 
-        return $this->_target;
+        $id = $f->getClean();
+        switch($target) {
+        case 'agent':
+            return Staff::lookup($id);
+        case 'team':
+            return Team::lookup($id);
+        case 'dept':
+            return Dept::lookup($id);
+        }
     }
 
     function getComments() {
@@ -4765,8 +4819,13 @@ class TransferForm extends Form {
                     'validator-error' => __('Department selection is required'),
                     )
                 ),
+            'refer' => new BooleanField(array(
+                'id'=>2, 'label'=>'', 'required'=>false, 'default'=>false,
+                'configuration'=>array(
+                    'desc' => 'Maintain referral access to current department')
+            )),
             'comments' => new TextareaField(array(
-                    'id' => 2,
+                    'id' => 3,
                     'label'=> '',
                     'required'=>false,
                     'default'=>'',
@@ -4813,6 +4872,10 @@ class TransferForm extends Form {
 
     }
 
+    function refer() {
+        return $this->getField('refer')->getClean();
+    }
+
     function getDept() {
 
         if (!isset($this->_dept)) {
diff --git a/include/class.staff.php b/include/class.staff.php
index bbe66e4626d97a641ab1f75257594154b59ad0fa..5a20d35b5b24e7618143a540f9b4883cc986de71 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -449,7 +449,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable, Searchable {
         return isset($this->locale) ? $this->locale : 0;
     }
 
-    function getRole($dept=null) {
+    function getRole($dept=null, $useDefault=true) {
         $deptId = is_object($dept) ? $dept->getId() : $dept;
         if ($deptId && $deptId != $this->dept_id) {
             if (isset($this->_roles[$deptId]))
@@ -458,7 +458,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable, Searchable {
             if ($access = $this->dept_access->findFirst(array('dept_id' => $deptId)))
                 return $this->_roles[$deptId] = $access->role;
 
-            if (!$this->usePrimaryRoleOnAssignment())
+            if (!$useDefault || !$this->usePrimaryRoleOnAssignment())
                 // View only access
                 return new Role(array());
 
diff --git a/include/class.thread.php b/include/class.thread.php
index bbb0d100b7feb758ecf39c74c14d533de313714e..f6dffd7a88b3fd9436c6bc9b530563ac6186547a 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -275,6 +275,13 @@ implements Searchable {
         return $this->_participants;
     }
 
+    function getReferral($id, $type) {
+
+        return $this->referrals->findFirst(array(
+                    'object_id' => $id,
+                    'object_type' => $type));
+    }
+
     function refer($to) {
 
         $vars = array('thread_id' => $this->getId());
@@ -295,8 +302,6 @@ implements Searchable {
             return false;
         }
 
-        var_dump($vars);
-
         return ThreadReferral::create($vars);
     }
 
diff --git a/include/class.ticket.php b/include/class.ticket.php
index f91ab94bfdca21792200e98615d050ecab633dd6..c1ad3d6c2bdffc96e7d17410cd758c9d8425656b 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -241,8 +241,25 @@ implements RestrictedAccess, Threadable, Searchable {
          return $this->hasState('deleted');
     }
 
-    function isAssigned() {
-        return $this->isOpen() && ($this->getStaffId() || $this->getTeamId());
+    function isAssigned($to=null) {
+
+        if ($this->isOpen())
+            return false;
+
+        if (!$to)
+            return ($this->getStaffId() || $this->getTeamId());
+
+        switch (true) {
+        case $to instanceof Staff:
+            return ($to->getId() == $this->getStaffId() ||
+                    $to->isTeamMember($this->getTeamId()));
+            break;
+        case $to instanceof Team:
+            return ($to->getId() == $this->getTeamId());
+            break;
+        }
+
+        return false;
     }
 
     function isOverdue() {
@@ -269,6 +286,8 @@ implements RestrictedAccess, Threadable, Searchable {
             && $this->isOpen()
             && $staff->getId() != $this->getStaffId()
             && !$staff->isTeamMember($this->getTeamId())
+            && !$this->thread->getReferral($staff->getId(),
+                ObjectModel::OBJECT_TYPE_STAFF)
         ) {
             return false;
         }
@@ -841,10 +860,21 @@ implements RestrictedAccess, Threadable, Searchable {
             $source = array('assignee' => array($assignee));
 
         $form = AssignmentForm::instantiate($source, $options);
-
         if ($assignees)
             $form->setAssignees($assignees);
 
+        if (($refer = $form->getField('refer'))) {
+            if ($assignee) {
+                $visibility = new VisibilityConstraint(
+                        new Q(array()), VisibilityConstraint::HIDDEN);
+                $refer->set('visibility', $visibility);
+            } else {
+                $refer->configure('desc', sprintf(__('Maintain referral access to %s'),
+                        $this->getAssigned()));
+            }
+        }
+
+
         if ($prompt && ($f=$form->getField('assignee')))
             $f->configure('prompt', $prompt);
 
@@ -854,30 +884,22 @@ implements RestrictedAccess, Threadable, Searchable {
 
     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);
+        $dept = $this->getDept();
+        // Agents
+        $staff = Staff::objects()->filter(array(
+         'isactive' => 1,
+         ))
+         ->filter(Q::not(array('dept_id' => $dept->getId())));
+        $staff = Staff::nsort($staff);
+        $agents = array();
+        foreach ($staff as $s)
+          $agents[$s->getId()] = $s;
+        $form->setChoices('agent', $agents);
+        // Teams
+        $form->setChoices('team', Team::getActiveTeams());
+        // Depts
+        $form->setChoices('dept', Dept::getDepartments());
 
         return $form;
     }
@@ -899,7 +921,8 @@ implements RestrictedAccess, Threadable, Searchable {
     function getTransferForm($source=null) {
 
         if (!$source)
-            $source = array('dept' => array($this->getDeptId()));
+            $source = array('dept' => array($this->getDeptId()),
+                    'refer' => false);
 
         return TransferForm::instantiate($source);
     }
@@ -2121,6 +2144,9 @@ implements RestrictedAccess, Threadable, Searchable {
                     $_errors, $thisstaff, false);
         }
 
+        if ($form->refer() && $cdept)
+            $this->thread->refer($cdept);
+
         //Send out alerts if enabled AND requested
         if (!$alert || !$cfg->alertONTransfer())
             return true; //no alerts!!
@@ -2243,6 +2269,7 @@ implements RestrictedAccess, Threadable, Searchable {
         global $thisstaff;
 
         $evd = array();
+        $refer = null;
         $assignee = $form->getAssignee();
         if ($assignee instanceof Staff) {
             $dept = $this->getDept();
@@ -2257,6 +2284,7 @@ implements RestrictedAccess, Threadable, Searchable {
                 $errors['err'] = __('Permission denied');
             } else {
                 $this->staff_id = $assignee->getId();
+                $refer = $this->staff ?: null;
                 if ($thisstaff && $thisstaff->getId() == $assignee->getId()) {
                     $alert = false;
                     $evd['claim'] = true;
@@ -2271,6 +2299,7 @@ implements RestrictedAccess, Threadable, Searchable {
                         __('the team')
                         );
             } else {
+                $refer = $this->team ?: null;
                 $this->team_id = $assignee->getId();
                 $evd = array('team' => $assignee->getId());
             }
@@ -2285,6 +2314,9 @@ implements RestrictedAccess, Threadable, Searchable {
 
         $this->onAssign($assignee, $form->getComments(), $alert);
 
+        if ($refer && $form->refer())
+            $this->thread->refer($refer);
+
         return true;
     }
 
@@ -2317,52 +2349,50 @@ implements RestrictedAccess, Threadable, Searchable {
         global $thisstaff;
 
         $evd = array();
-        $choice = $form->getTarget();
+        $referee = $form->getReferee();
         switch (true) {
-        case $choice instanceof Staff:
+        case $referee instanceof Staff:
             $dept = $this->getDept();
-            if ($this->getStaffId() == $choice->getId()) {
-                $errors['target'] = sprintf(__('%s is assigned to %s'),
+            if ($this->getStaffId() == $referee->getId()) {
+                $errors['agent'] = sprintf(__('%s is assigned to %s'),
                         __('Ticket'),
                         __('the agent')
                         );
-            } elseif(!$choice->isAvailable()) {
-                $errors['assignee'] = sprintf(__('Agent is unavailable for %s'),
+            } elseif(!$referee->isAvailable()) {
+                $errors['agent'] = 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());
+                $evd['staff'] = array($referee->getId(), (string) $referee->getName()->getOriginal());
             }
             break;
-        case $choice instanceof Team:
-            if ($this->getTeamId() == $choice->getId()) {
-                $errors['assignee'] = sprintf(__('%s is assigned to %s'),
+        case $referee instanceof Team:
+            if ($this->getTeamId() == $referee->getId()) {
+                $errors['team'] = sprintf(__('%s is assigned to %s'),
                         __('Ticket'),
                         __('the team')
                         );
             } else {
                 //TODO::
-                $evd = array('team' => $choice->getId());
+                $evd = array('team' => $referee->getId());
             }
             break;
-        case $choice instanceof Dept:
-            if ($this->getTeamId() == $choice->getId()) {
-                $errors['target'] = sprintf(__('%s is already in %s'),
+        case $referee instanceof Dept:
+            if ($this->getTeamId() == $referee->getId()) {
+                $errors['dept'] = sprintf(__('%s is already in %s'),
                         __('Ticket'),
                         __('the department')
                         );
             } else {
                 //TODO::
-                $evd = array('dept' => $choice->getId());
+                $evd = array('dept' => $referee->getId());
             }
             break;
         default:
             $errors['target'] = __('Unknown referral');
         }
 
-        if (!$errors && !$this->thread->refer($choice))
-            $errors['err'] = __('Unable to reffer ticket');
+        if (!$errors && !$this->thread->refer($referee))
+            $errors['err'] = __('Unable to refer ticket');
 
         if ($errors)
             return false;
diff --git a/include/staff/templates/refer.tmpl.php b/include/staff/templates/refer.tmpl.php
index b1c850f8a779871c6d34de2dec19049c15748a2e..6a2d991e5b7b4edf6e0d1b80e323f69aef2d34d6 100644
--- a/include/staff/templates/refer.tmpl.php
+++ b/include/staff/templates/refer.tmpl.php
@@ -26,17 +26,17 @@ $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>
+    <li <?php echo !$manage ? 'class="active"' : ''; ?>><a href="#refer"
+        ><i class="icon-exchange"></i>&nbsp;<?php echo __('Refer'); ?></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(); ?>"
+        id="<?php echo $form->getFormId(); ?>"
         action="<?php echo $action; ?>">
       <input type='hidden' name='do' value='refer'>
     <table width="100%">
diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php
index 81965fbcef6a6f8ca021d1cae63e8f296c654dd8..258dd9985fd2ed08ae0a1db1f3534ae95a631324 100644
--- a/include/staff/ticket-view.inc.php
+++ b/include/staff/ticket-view.inc.php
@@ -10,7 +10,7 @@ $info=($_POST && $errors)?Format::input($_POST):array();
 
 //Get the goodies.
 $dept  = $ticket->getDept();  //Dept
-$role  = $thisstaff->getRole($dept);
+$role  = $thisstaff->getRole($dept, $ticket->isAssigned($thisstaff));
 $staff = $ticket->getStaff(); //Assigned or closed by..
 $user  = $ticket->getOwner(); //Ticket User (EndUser)
 $team  = $ticket->getTeam();  //Assigned team.
@@ -92,33 +92,6 @@ 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
             } ?>
 
@@ -196,6 +169,15 @@ if($ticket->isOverdue())
                     <?php
                     }
                 } ?>
+
+                <?php
+                if ($role->hasPerm(Ticket::PERM_TRANSFER)) { ?>
+                <li><a href="#tickets/<?php echo $ticket->getId();
+                    ?>/referrals" class="ticket-action"
+                     data-redirect="tickets.php?id=<?php echo $ticket->getId(); ?>" >
+                       <i class="icon-exchange"></i> <?php echo __('Manage Referrals'); ?></a></li>
+                <?php
+                } ?>
                 <?php
                 if ($role->hasPerm(Ticket::PERM_EDIT)) { ?>
                 <li><a href="#ajax.php/tickets/<?php echo $ticket->getId();