diff --git a/api/cron.php b/api/cron.php
index f5d47e43e2af43e1d26a1f8a5e9af698bc7e0b8f..787460ee7c3042ee36a46ec39e8060fc73f5beaf 100644
--- a/api/cron.php
+++ b/api/cron.php
@@ -13,7 +13,7 @@
 
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
-@chdir(realpath(dirname(__FILE__)).'/'); //Change dir.
+@chdir(dirname(__FILE__).'/'); //Change dir.
 require('api.inc.php');
 
 if (!osTicket::is_cli())
diff --git a/api/pipe.php b/api/pipe.php
index 7cf1ad1b4f7c5edd88ba75cb5c7c66b683a109dc..249cfc8a79ffef59dee8295b7feb2e8ffd94f4f2 100644
--- a/api/pipe.php
+++ b/api/pipe.php
@@ -15,7 +15,7 @@
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
 ini_set('memory_limit', '256M'); //The concern here is having enough mem for emails with attachments.
-@chdir(realpath(dirname(__FILE__)).'/'); //Change dir.
+@chdir(dirname(__FILE__).'/'); //Change dir.
 require('api.inc.php');
 
 //Only local piping supported via pipe.php
diff --git a/bootstrap.php b/bootstrap.php
index 0de2d5d69bc168948d8c25c7b31f5f3241c98dcc..7d589e33518e1e362210104132a875e6bea6f6f7 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -264,7 +264,11 @@ class Bootstrap {
 }
 
 #Get real path for root dir ---linux and windows
-define('ROOT_DIR',str_replace('\\', '/', realpath(dirname(__FILE__))).'/');
+$here = dirname(__FILE__);
+$here = ($h = realpath($here)) ? $h : $here;
+define('ROOT_DIR',str_replace('\\', '/', $here.'/'));
+unset($here); unset($h);
+
 define('INCLUDE_DIR',ROOT_DIR.'include/'); //Change this if include is moved outside the web path.
 define('PEAR_DIR',INCLUDE_DIR.'pear/');
 define('SETUP_DIR',ROOT_DIR.'setup/');
diff --git a/client.inc.php b/client.inc.php
index 84eeaca1136446c977a6ce5e5ec26093b8244cc6..ee9a9fcae443df2d4c0ade4636270d102b9955e8 100644
--- a/client.inc.php
+++ b/client.inc.php
@@ -15,7 +15,7 @@
 **********************************************************************/
 if(!strcasecmp(basename($_SERVER['SCRIPT_NAME']),basename(__FILE__))) die('kwaheri rafiki!');
 
-$thisdir=str_replace('\\', '/', realpath(dirname(__FILE__))).'/';
+$thisdir=str_replace('\\', '/', dirname(__FILE__)).'/';
 if(!file_exists($thisdir.'main.inc.php')) die('Fatal Error.');
 
 require_once($thisdir.'main.inc.php');
diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index 5137cbaabc670f7e15d0842df05fa127328aab83..b9fad85ad45dd6b97e38a671f062b84fb5290798 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -263,7 +263,7 @@ class TicketsAjaxAPI extends AjaxController {
     function acquireLock($tid) {
         global $cfg,$thisstaff;
 
-        if(!$tid or !is_numeric($tid) or !$thisstaff or !$cfg or !$cfg->getLockTime())
+        if(!$tid || !is_numeric($tid) || !$thisstaff || !$cfg || !$cfg->getLockTime())
             return 0;
 
         if(!($ticket = Ticket::lookup($tid)) || !$ticket->checkStaffAccess($thisstaff))
@@ -290,10 +290,10 @@ class TicketsAjaxAPI extends AjaxController {
     function renewLock($tid, $id) {
         global $thisstaff;
 
-        if(!$id or !is_numeric($id) or !$thisstaff)
+        if(!$tid || !is_numeric($tid) || !$id || !is_numeric($id) || !$thisstaff)
             return $this->json_encode(array('id'=>0, 'retry'=>true));
 
-        $lock= TicketLock::lookup($id);
+        $lock= TicketLock::lookup($id, $tid);
         if(!$lock || !$lock->getStaffId() || $lock->isExpired()) //Said lock doesn't exist or is is expired
             return self::acquireLock($tid); //acquire the lock
 
diff --git a/include/class.forms.php b/include/class.forms.php
index c50c86d462c24f8b462adaa2d2237c5594649f13..538515c760130318403402a9298d7658fc8f09f1 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -230,6 +230,17 @@ class FormField {
         # form
         if ($this->get('required') && !$value && $this->hasData())
             $this->_errors[] = sprintf('%s is a required field', $this->getLabel());
+
+        # Perform declared validators for the field
+        if ($vs = $this->get('validators')) {
+            if (is_array($vs)) {
+                foreach ($vs as $validator)
+                    if (is_callable($validator))
+                        $validator($this, $value);
+            }
+            elseif (is_callable($vs))
+                $vs($this, $value);
+        }
     }
 
     /**
@@ -670,6 +681,16 @@ class ChoiceField extends FormField {
                 entries if the list item names change',
                 'configuration'=>array('html'=>false)
             )),
+            'default' => new TextboxField(array(
+                'id'=>3, 'label'=>'Default', 'required'=>false, 'default'=>'',
+                'hint'=>'(Enter a key). Value selected from the list initially',
+                'configuration'=>array('size'=>20, 'length'=>40),
+            )),
+            'prompt' => new TextboxField(array(
+                'id'=>2, 'label'=>'Prompt', 'required'=>false, 'default'=>'',
+                'hint'=>'Text shown in the drop-down select before a value is selected',
+                'configuration'=>array('size'=>40, 'length'=>40),
+            )),
         );
     }
 
@@ -1006,9 +1027,12 @@ class ChoicesWidget extends Widget {
         // selected)
         $choices = $this->field->getChoices();
         $def_key = $this->field->get('default');
+        if (!$def_key && $config['default'])
+            $def_key = $config['default'];
         $have_def = isset($choices[$def_key]);
         if (!$have_def)
-            $def_val = 'Select '.$this->field->get('label');
+            $def_val = ($config['prompt'])
+               ? $config['prompt'] : 'Select';
         else
             $def_val = $choices[$def_key];
         $value = $this->value;
diff --git a/include/class.i18n.php b/include/class.i18n.php
index b4b2564b7ec96e5983b5fafbf245140ab771fff4..7335495d5bd75ecdc9547a27d5af35f8f5de5076 100644
--- a/include/class.i18n.php
+++ b/include/class.i18n.php
@@ -127,7 +127,7 @@ class Internationalization {
         }
         // This shouldn't be necessary
         $tpl = EmailTemplateGroup::lookup(1);
-        foreach ($tpl->all_names as $name=>$info) {
+        foreach ($tpl::$all_names as $name=>$info) {
             if (($tp = $this->getTemplate("templates/email/$name.yaml"))
                     && ($t = $tp->getData())) {
                 $t['tpl_id'] = $tpl->getId();
@@ -274,7 +274,7 @@ class DataTemplate {
         foreach ($langs as $l) {
             if (file_exists("{$this->base}/$l/$path")) {
                 $this->lang = $l;
-                $this->filepath = realpath("{$this->base}/$l/$path");
+                $this->filepath = Misc::realpath("{$this->base}/$l/$path");
                 break;
             }
             elseif (Phar::isValidPharFilename("{$this->base}/$l.phar")
diff --git a/include/class.misc.php b/include/class.misc.php
index 41edef9f6bd7515e8264db429d0dea3b4fdc3251..e0b9559b93c4470554474ba691ec01daaae5e7ae 100644
--- a/include/class.misc.php
+++ b/include/class.misc.php
@@ -139,5 +139,10 @@ class Misc {
         return $output;
     }
 
+    function realpath($path) {
+        $rp = realpath($path);
+        return $rp ? $rp : $path;
+    }
+
 }
 ?>
diff --git a/include/class.osticket.php b/include/class.osticket.php
index 4108d7f1739cd394720c21de22afadb188556def..98979448ccf100f271caa41670046301ebf55e63 100644
--- a/include/class.osticket.php
+++ b/include/class.osticket.php
@@ -401,7 +401,10 @@ class osTicket {
         $file = str_replace('\\','/', $frame['file']);
         $path = substr($file, strlen(ROOT_DIR));
         if($path && ($pos=strpos($_SERVER['SCRIPT_NAME'], $path))!==false)
-            return substr($_SERVER['SCRIPT_NAME'], 0, $pos);
+            return ($pos) ? substr($_SERVER['SCRIPT_NAME'], 0, $pos) : '/';
+
+        if (self::is_cli())
+            return '/';
 
         return null;
     }
diff --git a/include/class.pdf.php b/include/class.pdf.php
index 1555de7727ec8b70848585470a643538b4ac9343..8346ee3c735a43de303008670fe9e3b6fb101e3d 100644
--- a/include/class.pdf.php
+++ b/include/class.pdf.php
@@ -14,7 +14,7 @@
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
 
-define('THIS_DIR', str_replace('\\', '/', realpath(dirname(__FILE__))) . '/'); //Include path..
+define('THIS_DIR', str_replace('\\', '/', Misc::realpath(dirname(__FILE__))) . '/'); //Include path..
 
 require_once(INCLUDE_DIR.'mpdf/mpdf.php');
 
diff --git a/include/class.template.php b/include/class.template.php
index 70af7fce0d960ce494638398869ecfd34b858add..020a5acc035cad4be6dfe7c62c82a87cbb1355e1 100644
--- a/include/class.template.php
+++ b/include/class.template.php
@@ -21,47 +21,65 @@ class EmailTemplateGroup {
     var $id;
     var $ht;
     var $_templates;
-    var $all_names=array(
+    static $all_groups = array(
+        'sys' => 'System Management Templates',
+        'ticket.user' => 'End-User Ticket Templates',
+        'ticket.staff' => 'Staff Ticket Templates',
+    );
+    static $all_names=array(
         'ticket.autoresp'=>array(
+            'group'=>'ticket.user',
             'name'=>'New Ticket Auto-response',
             'desc'=>'Autoresponse sent to user, if enabled, on new ticket.'),
         'ticket.autoreply'=>array(
+            'group'=>'ticket.user',
             'name'=>'New Ticket Auto-reply',
             'desc'=>'Canned Auto-reply sent to user on new ticket, based on filter matches. Overwrites "normal" auto-response.'),
         'message.autoresp'=>array(
+            'group'=>'ticket.user',
             'name'=>'New Message Auto-response',
             'desc'=>'Confirmation sent to user when a new message is appended to an existing ticket.'),
         'ticket.notice'=>array(
+            'group'=>'ticket.user',
             'name'=>'New Ticket Notice',
             'desc'=>'Notice sent to user, if enabled, on new ticket created by staff on their behalf (e.g phone calls).'),
         'ticket.overlimit'=>array(
+            'group'=>'ticket.user',
             'name'=>'Over Limit Notice',
             'desc'=>'A one-time notice sent, if enabled, when user has reached the maximum allowed open tickets.'),
         'ticket.reply'=>array(
+            'group'=>'ticket.user',
             'name'=>'Response/Reply Template',
             'desc'=>'Template used on ticket response/reply'),
         'ticket.activity.notice'=>array(
             'name'=>'New Activity Notice',
             'desc'=>'Template used to notify collaborators on ticket activity (e.g CC on reply)'),
         'ticket.alert'=>array(
+            'group'=>'ticket.staff',
             'name'=>'New Ticket Alert',
             'desc'=>'Alert sent to staff, if enabled, on new ticket.'),
         'message.alert'=>array(
+            'group'=>'ticket.staff',
             'name'=>'New Message Alert',
             'desc'=>'Alert sent to staff, if enabled, when user replies to an existing ticket.'),
         'note.alert'=>array(
+            'group'=>'ticket.staff',
             'name'=>'Internal Note Alert',
             'desc'=>'Alert sent to selected staff, if enabled, on new internal note.'),
         'assigned.alert'=>array(
+            'group'=>'ticket.staff',
             'name'=>'Ticket Assignment Alert',
             'desc'=>'Alert sent to staff on ticket assignment.'),
         'transfer.alert'=>array(
+            'group'=>'ticket.staff',
             'name'=>'Ticket Transfer Alert',
             'desc'=>'Alert sent to staff on ticket transfer.'),
         'ticket.overdue'=>array(
+            'group'=>'ticket.staff',
             'name'=>'Overdue Ticket Alert',
             'desc'=>'Alert sent to staff on stale or overdue tickets.'),
         'staff.pwreset' => array(
+            'group'=>'sys',
             'name' => 'Staff Password Reset',
             'desc' => 'Notice sent to staff with the password reset link.',
             'default' => 'templates/staff.pwreset.txt'),
@@ -144,7 +162,7 @@ class EmailTemplateGroup {
     }
 
     function getTemplateDescription($name) {
-        return $this->all_names[$name];
+        return static::$all_names[$name];
     }
 
     function getMsgTemplate($name) {
@@ -174,7 +192,7 @@ class EmailTemplateGroup {
     }
 
     function getUndefinedTemplateNames() {
-        $list = $this->all_names;
+        $list = static::$all_names;
         foreach ($this->getTemplates() as $cn=>$tpl)
             unset($list[$cn]);
         return $list;
@@ -421,6 +439,10 @@ class EmailTemplate {
         return $this->ht['code_name'];
     }
 
+    function getLastUpdated() {
+        return $this->ht['updated'];
+    }
+
     function getTplId() {
         return $this->ht['tpl_id'];
     }
diff --git a/include/class.ticket.php b/include/class.ticket.php
index a815cb9328fdb385631407ffa9f09a64c23114e2..bb7f2c83478a3d451cab3b78597835fee2ac3bb3 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -1822,12 +1822,15 @@ class Ticket {
 
     function delete() {
 
+        //delete just orphaned ticket thread & associated attachments.
+        // Fetch thread prior to removing ticket entry
+        $t = $this->getThread();
+
         $sql = 'DELETE FROM '.TICKET_TABLE.' WHERE ticket_id='.$this->getId().' LIMIT 1';
         if(!db_query($sql) || !db_affected_rows())
             return false;
 
-        //delete just orphaned ticket thread & associated attachments.
-        $this->getThread()->delete();
+        $t->delete();
 
         foreach (DynamicFormEntry::forTicket($this->getId()) as $form)
             $form->delete();
@@ -2116,11 +2119,17 @@ class Ticket {
             $vars['field.'.$f->get('id')] = $f->toString($f->getClean());
 
         // Unpack the basic user information
-        $interesting = array('name', 'email');
-        $user_form = UserForm::getUserForm()->getForm($vars);
-        foreach ($user_form->getFields() as $f)
-            if (in_array($f->get('name'), $interesting))
-                $vars[$f->get('name')] = $f->toString($f->getClean());
+        if ($vars['uid'] && ($user = User::lookup($vars['uid']))) {
+            $vars['email'] = $user->getEmail();
+            $vars['name'] = $user->getName();
+        }
+        else {
+            $interesting = array('name', 'email');
+            $user_form = UserForm::getUserForm()->getForm($vars);
+            foreach ($user_form->getFields() as $f)
+                if (in_array($f->get('name'), $interesting))
+                    $vars[$f->get('name')] = $f->toString($f->getClean());
+        }
 
         //Init ticket filters...
         $ticket_filter = new TicketFilter($origin, $vars);
@@ -2173,11 +2182,6 @@ class Ticket {
 
         if (!$errors) {
 
-            if ($vars['uid'] && ($user = User::lookup($vars['uid']))) {
-                $vars['email'] = $user->getEmail();
-                $vars['name'] = $user->getName();
-            }
-
             # Perform ticket filter actions on the new ticket arguments
             if ($ticket_filter) $ticket_filter->apply($vars);
 
diff --git a/include/mysqli.php b/include/mysqli.php
index 7245d9ec20eeab75197500a8b9f5d8f06af8e567..3b535919e88f18fec8465067c7f7b55d7b4e54f2 100644
--- a/include/mysqli.php
+++ b/include/mysqli.php
@@ -160,7 +160,7 @@ function db_result($res, $row=0) {
     return $value;
 }
 
-function db_fetch_array($res, $mode=MYSQL_ASSOC) {
+function db_fetch_array($res, $mode=MYSQLI_ASSOC) {
     return ($res) ? db_output($res->fetch_array($mode)) : NULL;
 }
 
diff --git a/include/staff/template.inc.php b/include/staff/template.inc.php
index 2d05235eecb07d2a20c5d389fc58b1aaf763a022..84e7704cd6799a4c598e57243e1bfecbdbe8563d 100644
--- a/include/staff/template.inc.php
+++ b/include/staff/template.inc.php
@@ -71,39 +71,41 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 echo $info['lang']; ?>
             </td>
         </tr>
-        <tr>
-            <th colspan="2">
-                <em><strong>Template Messages</strong>: Click on the message to edit.&nbsp;
-                    <span class="error">*&nbsp;<?php echo $errors['rules']; ?></span></em>
-            </th>
-        </tr>
         <?php
-         foreach($template->getTemplates() as $tpl){
-             $info = $tpl->getDescription();
+            $current_group = false;
+            $impl = $template->getTemplates();
+            $_tpls = $template::$all_names;
+            $_groups = $template::$all_groups;
+            uasort($_tpls, function($a,$b) {
+                return strcmp($a['group'].$a['name'], $b['group'].$b['name']);
+            });
+         foreach($_tpls as $cn=>$info){
              if (!$info['name'])
                  continue;
-            echo sprintf('<tr><td colspan=2>&nbsp;<strong><a href="templates.php?id=%d&a=manage">%s</a></strong>&nbsp-&nbsp<em>%s</em></td></tr>',
-                    $tpl->getId(),Format::htmlchars($info['name']),
-                    Format::htmlchars($info['desc']));
-         }
-         if (($undef = $template->getUndefinedTemplateNames())) { ?>
+             if (!$current_group || $current_group != $info['group']) {
+                $current_group = $info['group']; ?>
         <tr>
             <th colspan="2">
-                <em><strong>Unimplemented Template Messages</strong>: Click
-                on the message to implement</em>
+            <em><strong><?php echo isset($_groups[$current_group])
+            ? $_groups[$current_group] : $current_group; ?></strong>
+            :: Click on the title to edit.&nbsp;</em>
             </th>
         </tr>
-        <?php
-            foreach($template->getUndefinedTemplateNames() as $cn=>$info){
+<?php } # end if ($current_group)
+            if (isset($impl[$cn])) {
+                echo sprintf('<tr><td colspan="2">&nbsp;<strong><a href="templates.php?id=%d&a=manage">%s</a></strong>, <span class="faded">Updated %s</span><br/>&nbsp;%s</td></tr>',
+                $impl[$cn]->getId(), Format::htmlchars($info['name']),
+                Format::db_datetime($impl[$cn]->getLastUpdated()),
+                Format::htmlchars($info['desc']));
+            } else {
                 echo sprintf('<tr><td colspan=2>&nbsp;<strong><a
                     href="templates.php?tpl_id=%d&a=implement&code_name=%s"
-                    style="color:red;text-decoration:underline"
-                    >%s</a></strong>&nbsp-&nbsp<em>%s</em></td></tr>',
-                    $template->getId(),$cn,Format::htmlchars($info['name']),
-                    Format::htmlchars($info['desc']));
+                    >%s</a></strong><br/>&nbsp%s</td></tr>',
+                    $template->getid(),$cn,format::htmlchars($info['name']),
+                    format::htmlchars($info['desc']));
             }
-        }
-        }else{ ?>
+         } # endfor
+        } else { ?>
         <tr>
             <td width="180" class="required">
                 Language:
diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php
index a1b180aae2c0c8d47a8819d29595c83d2b6a0489..a5e0505304dccc59be810befbc061a15ab28d462 100644
--- a/include/staff/ticket-open.inc.php
+++ b/include/staff/ticket-open.inc.php
@@ -24,32 +24,32 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
     <tbody>
         <tr>
             <th colspan="2">
-                <em><strong>Client Information</strong>: </em>
+                <em><strong>User Information</strong>: </em>
             </th>
         </tr>
         <?php
         if ($user) { ?>
-        <tr><td>Client:</td><td>
-            <div id="client-info">
+        <tr><td>User:</td><td>
+            <div id="user-info">
                 <input type="hidden" name="uid" id="uid" value="<?php echo $user->getId(); ?>" />
             <a href="#" onclick="javascript:
                 $.userLookup('ajax.php/users/<?php echo $user->getId(); ?>/edit',
                         function (user) {
-                            $('#client-name').text(user.name);
-                            $('#client-email').text(user.email);
+                            $('#user-name').text(user.name);
+                            $('#user-email').text(user.email);
                         });
                 return false;
                 "><i class="icon-user"></i>
-                <span id="client-name"><?php echo $user->getName(); ?></span>
-                &lt;<span id="client-email"><?php echo $user->getEmail(); ?></span>&gt;
+                <span id="user-name"><?php echo $user->getName(); ?></span>
+                &lt;<span id="user-email"><?php echo $user->getEmail(); ?></span>&gt;
                 </a>
                 <a class="action-button" style="float:none;overflow:inherit" href="#"
                     onclick="javascript:
                         $.userLookup('ajax.php/users/select/'+$('input#uid').val(),
                             function(user) {
                                 $('input#uid').val(user.id);
-                                $('#client-name').text(user.name);
-                                $('#client-email').text('<'+user.email+'>');
+                                $('#user-name').text(user.name);
+                                $('#user-email').text('<'+user.email+'>');
                         });
                         return false;
                 "><i class="icon-edit"></i> Change</a>
@@ -373,6 +373,15 @@ $(function() {
         property: "/bin/true"
     });
 
+   <?php
+    // Popup user lookup on the initial page load (not post) if we don't have a
+    // user selected
+    if (!$_POST && !$user) {?>
+    $.userLookup('ajax.php/users/lookup/form', function (user) {
+        window.location.href = window.location.href+'&uid='+user.id;
+     });
+    <?php
+    } ?>
 });
 </script>
 
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index 530d6b2d93ec7262370d81fed89c0a7bab14bdfa..853e9e8530a7090da647e3e9010db8320631c5fb 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -73,7 +73,7 @@ $qwhere .= ' )';
 
 //STATUS
 if($status) {
-    $qwhere.=' AND status='.db_input(strtolower($status));
+    $qwhere.=' AND ticket.status='.db_input(strtolower($status));
 }
 
 if (isset($_REQUEST['ownerId'])) {
diff --git a/include/staff/tpl.inc.php b/include/staff/tpl.inc.php
index b4dd330548b8d156205b26334b21fa0d39f0dcbf..7588092c5898e6d1a3e0bba13d24cc8b5c785eb4 100644
--- a/include/staff/tpl.inc.php
+++ b/include/staff/tpl.inc.php
@@ -10,7 +10,8 @@ if (is_a($template, EmailTemplateGroup)) {
     $selected = $_REQUEST['code_name'];
     $action = 'implement';
     $extras = array('code_name'=>$selected, 'tpl_id'=>$tpl_id);
-    $msgtemplates=$template->all_names;
+    $msgtemplates=$template::$all_names;
+    $desc = $msgtemplates[$selected];
     // Attempt to lookup the default data if it is defined
     $default = @$template->getMsgTemplate($selected);
     if ($default) {
@@ -22,11 +23,12 @@ if (is_a($template, EmailTemplateGroup)) {
     $id = $template->getId();
     $tpl_id = $template->getTplId();
     $name = $template->getGroup()->getName();
+    $desc = $template->getDescription();
     $group = $template->getGroup();
     $selected = $template->getCodeName();
     $action = 'updatetpl';
     $extras = array();
-    $msgtemplates=$template->getGroup()->all_names;
+    $msgtemplates=$group::$all_names;
     $info=array_merge(array('subject'=>$template->getSubject(), 'body'=>$template->getBodyWithImages()),$info);
 }
 $tpl=$msgtemplates[$selected];
@@ -34,24 +36,37 @@ $tpl=$msgtemplates[$selected];
 ?>
 <h2>Email Template Message - <span><?php echo $name; ?></span></h2>
 <div style="padding-top:10px;padding-bottom:5px;">
-    <form method="get" action="templates.php">
+    <form method="get" action="templates.php?">
     <input type="hidden" name="a" value="manage">
+    <input type="hidden" name="tpl_id" value="<?php echo $tpl_id; ?>">
     Message Template:
     <select id="tpl_options" name="id" style="width:300px;">
         <option value="">&mdash; Select Setting Group &mdash;</option>
         <?php
-        foreach($group->getTemplates() as $cn=>$t) {
-            $nfo=$t->getDescription();
+        $impl = $group->getTemplates();
+        $current_group = false;
+        $_tpls = $group::$all_names;
+        $_groups = $group::$all_groups;
+        uasort($_tpls, function($a,$b) {
+            return strcmp($a['group'].$a['name'], $b['group'].$b['name']);
+        });
+        foreach($_tpls as $cn=>$nfo) {
             if (!$nfo['name'])
                 continue;
+            if (!$current_group || $current_group != $nfo['group']) {
+                if ($current_group)
+                    echo "</optgroup>";
+                $current_group = $nfo['group']; ?>
+                <optgroup label="<?php echo isset($_groups[$current_group])
+                    ? $_groups[$current_group] : $current_group; ?>">
+            <?php }
             $sel=($selected==$cn)?'selected="selected"':'';
             echo sprintf('<option value="%s" %s>%s</option>',
-                    $t->getId(),$sel,$nfo['name']);
+                isset($impl[$cn]) ? $impl[$cn]->getId() : $cn,
+                $sel,$nfo['name']);
         }
-        if ($id == 0) { ?>
-            <option selected="selected" value="<?php echo $id; ?>"><?php
-            echo $msgtemplates[$selected]['name']; ?></option>
-        <?php }
+        if ($current_group)
+            echo "</optgroup>";
         ?>
     </select>
     <input type="submit" value="Go">
@@ -71,7 +86,7 @@ $tpl=$msgtemplates[$selected];
    <thead>
      <tr>
         <th colspan="2">
-            <h4><?php echo Format::htmlchars($tpl['desc']); ?></h4>
+            <h4><?php echo Format::htmlchars($desc['desc']); ?></h4>
             <em>Subject and body required.  <a class="tip" href="ticket_variables.txt">Supported Variables</a>.</em>
         </th>
      </tr>
diff --git a/pages/index.php b/pages/index.php
index fc65aebc11b59fa80c0cb28860b562ab8f2e4e22..f646858352e9cb8e34b16300f9e6713b6930f392 100644
--- a/pages/index.php
+++ b/pages/index.php
@@ -14,7 +14,7 @@
 
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
-@chdir(realpath(dirname(__file__).'/../'));
+@chdir(dirname(__file__).'/../');
 
 require_once('client.inc.php');
 require_once(INCLUDE_DIR.'class.format.php');
diff --git a/scp/js/scp.js b/scp/js/scp.js
index a70082e1746444a50c1edc814921b88115920e80..2ad14158f8ed3b23877b9260787b20b1465506ae 100644
--- a/scp/js/scp.js
+++ b/scp/js/scp.js
@@ -148,7 +148,12 @@ $(document).ready(function(){
      });
 
     $('select#tpl_options').change(function() {
-        $(this).closest('form').submit();
+        var $this = $(this), form = $this.closest('form');
+        if ($this.val() % 1 !== 0) {
+            $('[name="a"]', form).val('implement');
+            $this.attr('name', 'code_name');
+        }
+        form.submit();
      });
 
     $(".clearrule").live('click',function() {
@@ -414,17 +419,9 @@ $(document).ready(function(){
         $('#advanced-search').show();
     });
 
-
-    $(document).on('click', 'a#new-ticket', function(e) {
-        e.preventDefault();
-        var $elem = $(this);
-        $.userLookup('ajax.php/users/lookup/form', function (user) {
-            window.location.href = $elem.attr('href')+'&uid='+user.id;
-           });
-     });
-
     $.dialog = function (url, code, cb, options) {
         options = options||{};
+
         $('.dialog#popup .body').load(url, function () {
             $('#overlay').show();
             $('.dialog#popup').show({
diff --git a/setup/cli/modules/deploy.php b/setup/cli/modules/deploy.php
index aa123bfcb1de9524ddb3b9bf3d291450eb866d62..d307e51f2616e34ab378689b1993111b3b81eaa5 100644
--- a/setup/cli/modules/deploy.php
+++ b/setup/cli/modules/deploy.php
@@ -35,7 +35,7 @@ class Deployment extends Unpacker {
             if (is_file($start . '/main.inc.php')) break;
             $start .= '/..';
         }
-        return realpath($start);
+        return self::realpath($start);
     }
 
     /**
@@ -92,7 +92,7 @@ class Deployment extends Unpacker {
         if (!is_dir($this->destination))
             if (!@mkdir($this->destination, 0751, true))
                 die("Destination path does not exist and cannot be created");
-        $this->destination = realpath($this->destination).'/';
+        $this->destination = self::realpath($this->destination).'/';
 
         # Determine if this is an upgrade, and if so, where the include/
         # folder is currently located
diff --git a/setup/cli/modules/unpack.php b/setup/cli/modules/unpack.php
index 55fe6ab5a35299bd4e1c3017a40b7aab8342823f..af5cfd6247079facfcbf6215819475f0417be120 100644
--- a/setup/cli/modules/unpack.php
+++ b/setup/cli/modules/unpack.php
@@ -34,6 +34,10 @@ class Unpacker extends Module {
              main installation path.",
     );
 
+    function realpath($path) {
+        return ($p = realpath($path)) ? $p : $path;
+    }
+
     function find_upload_folder() {
         # Hop up to the root folder
         $start = dirname(__file__);
@@ -41,7 +45,7 @@ class Unpacker extends Module {
             if (is_dir($start . '/upload')) break;
             $start .= '/..';
         }
-        return realpath($start.'/upload');
+        return self::realpath($start.'/upload');
     }
 
     function change_include_dir($include_path) {