diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index c9c98b04001d05cf428c14c6600de8df2952ddae..93e90758c2963eebcefa43518b757e5c473d8eef 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -457,23 +457,34 @@ class TicketsAjaxAPI extends AjaxController {
                 || !$ticket->checkStaffAccess($thisstaff))
             Http::response(404, 'No such ticket');
 
-        $errors = $info = array();
-        $user = null;
-        $form = UserForm::getInstance();
-        if ($form->isValid())
-            $user = User::fromForm($form->getClean());
+        //If not a post then assume new collaborator form
+        if(!$_POST)
+            return self::_addcollaborator($ticket);
+
+        $user = $form = null;
+        if (isset($_POST['id']) && $_POST['id']) { //Existing user/
+            $user =  User::lookup($_POST['id']);
+        } else { //We're creating a new user!
+            $form = UserForm::getUserForm()->getForm($_POST);
+            $user = User::fromForm($form);
+        }
 
+        $errors = $info = array();
         if ($user && ($c=$ticket->addCollaborator($user, $errors))) {
-            $info +=array('msg' => sprintf('%s added as a collaborator',
+            $info =array('msg' => sprintf('%s added as a collaborator',
                         $c->getName()));
-            $form = null;
-        } elseif($errors && $errors['err']) {
-            $info +=array('add_error' => $errors['err']);
+
+            return self::_collaborators($ticket, $info);
+        }
+
+        if($errors && $errors['err']) {
+            $info +=array('error' => $errors['err']);
         } else {
-            $info +=array('add_error' =>'Errors occurred - try again');
+            $info +=array('error' =>'Unable to add collaborator - try again');
         }
 
-        return self::_collaborators($ticket, $form, $info);
+
+        return self::_addcollaborator($ticket, $user, $form, $info);
     }
 
     function updateCollaborator($cid) {
@@ -493,7 +504,7 @@ class TicketsAjaxAPI extends AjaxController {
         $info = array('msg' => sprintf('%s updated successfully',
                     $c->getName()));
 
-        return self::_collaborators($ticket, null, $info);
+        return self::_collaborators($ticket, $info);
     }
 
     function viewCollaborator($cid) {
@@ -514,7 +525,22 @@ class TicketsAjaxAPI extends AjaxController {
                 || !$ticket->checkStaffAccess($thisstaff))
             Http::response(404, 'No such ticket');
 
-        return self::_collaborators($ticket);
+        if($ticket->getCollaborators())
+            return self::_collaborators($ticket);
+
+        return self::_addcollaborator($ticket);
+    }
+
+
+
+    function _addcollaborator($ticket, $user=null, $form=null, $info=array()) {
+
+        $info += array(
+                    'title' => sprintf('Ticket #%s: Add a collaborator', $ticket->getNumber()),
+                    'action' => sprintf('#tickets/%d/add-collaborator', $ticket->getId())
+                    );
+
+        return self::_userlookup($user, $form, $info);
     }
 
 
@@ -532,22 +558,26 @@ class TicketsAjaxAPI extends AjaxController {
             $info +=array('error' => $errors['err']);
         }
 
-        return self::_collaborators($ticket, null, $info);
+        return self::_collaborators($ticket, $info);
     }
 
 
 
-    function _collaborator($collaborator, $form=null, $errors=array()) {
+    function _collaborator($collaborator, $form=null, $info=array()) {
+
+        $info += array('action' => '#collaborators/'.$collaborator->getId());
+
+        $user = $collaborator->getUser();
 
         ob_start();
-        include(STAFFINC_DIR . 'templates/collaborator.tmpl.php');
+        include(STAFFINC_DIR . 'templates/user.tmpl.php');
         $resp = ob_get_contents();
         ob_end_clean();
 
         return $resp;
     }
 
-    function _collaborators($ticket, $form=null, $info=array()) {
+    function _collaborators($ticket, $info=array()) {
 
         ob_start();
         include(STAFFINC_DIR . 'templates/collaborators.tmpl.php');
@@ -556,5 +586,86 @@ class TicketsAjaxAPI extends AjaxController {
 
         return $resp;
     }
+
+    function viewUser($tid) {
+        global $thisstaff;
+
+        if(!$thisstaff
+                || !($ticket=Ticket::lookup($tid))
+                || !$ticket->checkStaffAccess($thisstaff))
+            Http::response(404, 'No such ticket');
+
+
+        if(!($user = $ticket->getOwner()))
+            Http::response(404, 'Unknown user');
+
+
+        $info = array(
+                'title' => sprintf('Ticket #%s: %s', $ticket->getNumber(), $user->getName())
+                );
+
+        ob_start();
+        include(STAFFINC_DIR . 'templates/user.tmpl.php');
+        $resp = ob_get_contents();
+        ob_end_clean();
+        return $resp;
+
+    }
+
+    function updateUser($tid) {
+
+        global $thisstaff;
+
+        if(!$thisstaff
+                || !($ticket=Ticket::lookup($tid))
+                || !$ticket->checkStaffAccess($thisstaff)
+                || ! ($user = $ticket->getOwner()))
+            Http::response(404, 'No such ticket/user');
+
+        $errors = array();
+        if($user->updateInfo($_POST, $errors))
+             Http::response(201, $user->to_json());
+
+        $forms = $user->getForms();
+
+        $info = array(
+                'title' => sprintf('Ticket #%s: %s', $ticket->getNumber(), $user->getName())
+                );
+
+        ob_start();
+        include(STAFFINC_DIR . 'templates/user.tmpl.php');
+        $resp = ob_get_contents();
+        ob_end_clean();
+        return $resp;
+    }
+
+    function changeUserForm($tid) {
+        global $thisstaff;
+
+        if(!$thisstaff
+                || !($ticket=Ticket::lookup($tid))
+                || !$ticket->checkStaffAccess($thisstaff))
+            Http::response(404, 'No such ticket');
+
+
+        $user = $ticket->getOwner();
+
+        $info = array(
+                'title' => sprintf('Change user for ticket #%s', $ticket->getNumber())
+                );
+
+        return self::_userlookup($user, $info);
+    }
+
+    function _userlookup($user, $form, $info) {
+
+        ob_start();
+        include(STAFFINC_DIR . 'templates/user-lookup.tmpl.php');
+        $resp = ob_get_contents();
+        ob_end_clean();
+        return $resp;
+
+    }
+
 }
 ?>
diff --git a/include/staff/templates/collaborator.tmpl.php b/include/staff/templates/collaborator.tmpl.php
deleted file mode 100644
index 03f7dce6ddfee8a5b7811859126dd6ad0e132e2a..0000000000000000000000000000000000000000
--- a/include/staff/templates/collaborator.tmpl.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<h3>Update Collaborator: <?php echo $collaborator->getName(); ?></h3>
-<b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b>
-<?php
-if($errors && $errors['err']) {
-    echo sprintf('<div><p id="msg_error">%s</p></div>', $errors['err']);
-} ?>
-<hr/>
-<div>
-<div><p id="msg_info"><i class="icon-info-sign"></i> Please note that updates will be reflected system-wide.</p></div>
-<form method="post" class="collaborators" action="#collaborators/<?php echo $collaborator->getId(); ?>">
-    <table width="100%">
-    <?php
-        if(!$forms) $forms =  $collaborator->getForms();
-        foreach($forms as$form)
-            $form->render(); ?>
-    </table>
-    <hr style="margin-top:1em"/>
-    <p class="full-width">
-        <span class="buttons" style="float:left">
-            <input type="reset" value="Reset">
-            <input type="button" name="cancel" class="cancel"
-                data-href="#tickets/<?php echo $collaborator->getTicketId(); ?>/collaborators/manage" value="Cancel">
-        </span>
-        <span class="buttons" style="float:right">
-            <input type="submit" value="Update">
-        </span>
-     </p>
-</form>
-<div class="clear"></div>
-</div>
diff --git a/scp/ajax.php b/scp/ajax.php
index eaca914dbcc67c9834839fd74ab98265339d315b..0ea64116e77289b22e9c5aba5a7efac971f8b6ee 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -77,8 +77,7 @@ $dispatcher = patterns('',
         url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/release', 'releaseLock'),
         url_get('^(?P<tid>\d+)/collaborators/manage$', 'showCollaborators'),
         url_post('^(?P<tid>\d+)/collaborators$', 'updateCollaborators'),
-        url_post('^(?P<tid>\d+)/add-collaborator$', 'addCollaborator'),
-        url_get('^(?P<tid>\d+)/add-collaborator$', 'addCollaborator'),
+        url('^(?P<tid>\d+)/add-collaborator$', 'addCollaborator'),
         url_get('^lookup', 'lookup'),
         url_get('^search', 'search')
     )),
diff --git a/scp/js/scp.js b/scp/js/scp.js
index 1c124f42c30744517c18b910f29e781273ff9678..b80cb1a3b83f41f7825ff3e0b6aad8019c7af002 100644
--- a/scp/js/scp.js
+++ b/scp/js/scp.js
@@ -400,7 +400,7 @@ $(document).ready(function(){
      });
 
     $.dialog = function (url, code, cb) {
-        console.log(url);
+
         $('.dialog#popup .body').load(url, function () {
             $('#overlay').show();
             $('.dialog#popup').show();
@@ -435,9 +435,9 @@ $(document).ready(function(){
 
     $.userLookup = function (url, cb) {
         $.dialog(url, 201, function (resp) {
-                var user = $.parseJSON(resp);
-                if(cb) cb(user);
-                });
+            var user = $.parseJSON(resp);
+            if(cb) cb(user);
+        });
     };
 
     $('#advanced-search').delegate('#status', 'change', function() {
diff --git a/scp/js/tips.js b/scp/js/tips.js
index 44c924711c1b73bc012674acefce634f007b2eca..205eb6fc9d2df8edbbd17d3ad43dbfab76145d36 100644
--- a/scp/js/tips.js
+++ b/scp/js/tips.js
@@ -93,7 +93,6 @@ jQuery(function() {
             tip_timer = setTimeout(function() {
                 $('.tip_box').remove();
                 $('body').append(the_tip.hide().fadeIn());
-                console.log($(window).width(), tip_content.width(), the_tip.position())
                 if ($(window).width() < tip_content.outerWidth() + the_tip.position().left) {
                     the_tip.css({'left':x_pos-tip_content.outerWidth()-40+'px'});
                     tip_box.addClass('right');