diff --git a/include/ajax.content.php b/include/ajax.content.php
index e97e96a5c3d1d894f5d7cacfad702c97ced25cf6..e93030a9ed9734c586ce3df32979b4163a80be36 100644
--- a/include/ajax.content.php
+++ b/include/ajax.content.php
@@ -37,42 +37,46 @@ class ContentAjaxAPI extends AjaxController {
     function ticket_variables() {
 
         $content='
-<div style="width:600px;">
+<div style="width:680px;">
     <h2>Ticket Variables</h2>
-    Please note that non-base variables depends on the context of use.
+    Please note that non-base variables depends on the context of use. Visit osTicket Wiki for up to date documentation.
     <br/>
     <table width="100%" border="0" cellspacing=1 cellpadding=2>
-        <tr><td width="50%" valign="top"><b>Base Variables</b></td><td><b>Other Variables</b></td></tr>
+        <tr><td width="55%" valign="top"><b>Base Variables</b></td><td><b>Other Variables</b></td></tr>
         <tr>
-            <td width="50%" valign="top">
+            <td width="55%" valign="top">
                 <table width="100%" border="0" cellspacing=1 cellpadding=1>
-                    <tr><td width="100">%id</td><td>Ticket ID (internal ID)</td></tr>
-                    <tr><td>%ticket</td><td>Ticket number (external ID)</td></tr>
-                    <tr><td>%email</td><td>Email address</td></tr>
-                    <tr><td>%name</td><td>Full name</td></tr>
-                    <tr><td>%subject</td><td>Subject</td></tr>
-                    <tr><td>%topic</td><td>Help topic (web only)</td></tr>
-                    <tr><td>%phone</td><td>Phone number | ext</td></tr>
-                    <tr><td>%status</td><td>Status</td></tr>
-                    <tr><td>%priority</td><td>Priority</td></tr>
-                    <tr><td>%dept</td><td>Department</td></tr>
-                    <tr><td>%assigned</td><td>Assigned staff or team (if any)</td></tr>
-                    <tr><td>%createdate</td><td>Date created</td></tr>
-                    <tr><td>%duedate</td><td>Due date</td></tr>
-                    <tr><td>%closedate</td><td>Date closed</td></tr>
+                    <tr><td width="130">%{ticket.id}</td><td>Ticket ID (internal ID)</td></tr>
+                    <tr><td>%{ticket.number}</td><td>Ticket number (external ID)</td></tr>
+                    <tr><td>%{ticket.email}</td><td>Email address</td></tr>
+                    <tr><td>%{ticket.name}</td><td>Full name</td></tr>
+                    <tr><td>%{ticket.subject}</td><td>Subject</td></tr>
+                    <tr><td>%{ticket.phone}</td><td>Phone number | ext</td></tr>
+                    <tr><td>%{ticket.status}</td><td>Status</td></tr>
+                    <tr><td>%{ticket.priority}</td><td>Priority</td></tr>
+                    <tr><td>%{ticket.assigned}</td><td>Assigned staff and/or team</td></tr>
+                    <tr><td>%{ticket.create_date}</td><td>Date created</td></tr>
+                    <tr><td>%{ticket.due_date}</td><td>Due date</td></tr>
+                    <tr><td>%{ticket.close_date}</td><td>Date closed</td></tr>
+                    <tr><td>%{ticket.auth_token}</td><td>Auth. token used for auto-login</td></tr>
+                    <tr><td>%{ticket.client_link}</td><td>Client\'s ticket view link</td></tr>
+                    <tr><td>%{ticket.staff_link}</td><td>Staff\'s ticket view link</td></tr>
+                    <tr><td colspan="2" style="padding:5px 0 5px 0;"><em>Expandable Variables (See Wiki)</em></td></tr>
+                    <tr><td>%{ticket.<b>topic</b>}</td><td>Help topic</td></tr>
+                    <tr><td>%{ticket.<b>dept</b>}</td><td>Department</td></tr>
+                    <tr><td>%{ticket.<b>staff</b>}</td><td>Assigned/closing staff</td></tr>
+                    <tr><td>%{ticket.<b>team</b>}</td><td>Assigned/closing team</td></tr>
                 </table>
             </td>
             <td valign="top">
                 <table width="100%" border="0" cellspacing=1 cellpadding=1>
-                    <tr><td width="100">%message</td><td>Message (incoming)</td></tr>
-                    <tr><td>%response</td><td>Response (outgoing)</td></tr>
-                    <tr><td>%note</td><td>Internal/transfer note</td></tr>
-                    <tr><td>%staff</td><td>Staff\'s name (alert/notices)</td></tr>
-                    <tr><td>%assignee</td><td>Assigned staff</td></tr>
-                    <tr><td>%assigner</td><td>Staff assigning the ticket</td></tr>
-                    <tr><td>%url</td><td>osTicket\'s base url (FQDN)</td></tr>
-                    <tr><td>%auth</td><td>Client authentication token</td></tr>
-                    <tr><td>%clientlink</td><td>Client auto-login link</td></tr>
+                    <tr><td width="100">%{message}</td><td>Incoming message</td></tr>
+                    <tr><td>%{response}</td><td>Outgoing response</td></tr>
+                    <tr><td>%{comments}</td><td>Assign/transfer comments</td></tr>
+                    <tr><td>%{note}</td><td>Internal note <em>(expandable)</em></td></tr>
+                    <tr><td>%{assignee}</td><td>Assigned staff/team</td></tr>
+                    <tr><td>%{assigner}</td><td>Staff assigning the ticket</td></tr>
+                    <tr><td>%{url}</td><td>osTicket\'s base url (FQDN)</td></tr>
                 </table>
             </td>
         </tr>
diff --git a/include/ajax.kbase.php b/include/ajax.kbase.php
index b51d8781dff46f94409c7b797e59973862d222a9..576b50585a0da4e8006a87b92026286bd9ce2219 100644
--- a/include/ajax.kbase.php
+++ b/include/ajax.kbase.php
@@ -36,7 +36,7 @@ class KbaseAjaxAPI extends AjaxController {
             case 'json':
                 $resp['id'] = $canned->getId();
                 $resp['ticket'] = $canned->getTitle();
-                $resp['response'] = $ticket?$ticket->replaceTemplateVars($canned->getResponse()):$canned->getResponse();
+                $resp['response'] = $ticket?$ticket->replaceVars($canned->getResponse()):$canned->getResponse();
                 $resp['files'] = $canned->getAttachments();
 
 
@@ -44,7 +44,7 @@ class KbaseAjaxAPI extends AjaxController {
                 break;
             case 'txt':
             default:
-                $response =$ticket?$ticket->replaceTemplateVars($canned->getResponse()):$canned->getResponse();
+                $response =$ticket?$ticket->replaceVars($canned->getResponse()):$canned->getResponse();
         }
 
 
diff --git a/include/class.dept.php b/include/class.dept.php
index 5516646129b348de5eba208d005c8ab87d2f4145..0eae779c9eb13f19c225f0c2ff6e15d366fb28b2 100644
--- a/include/class.dept.php
+++ b/include/class.dept.php
@@ -24,7 +24,7 @@ class Dept {
 
     var $ht;
   
-    function Dept($id){
+    function Dept($id) {
         $this->id=0;
         $this->load($id);
     }
@@ -55,24 +55,28 @@ class Dept {
         return true;
     }
 
-    function reload(){
+    function reload() {
         return $this->load();
     }
 
-    function getId(){
+    function asVar() {
+        return $this->getName();
+    }
+
+    function getId() {
         return $this->id;
     }
     
-    function getName(){
+    function getName() {
         return $this->ht['name'];
     }
 
         
-    function getEmailId(){
+    function getEmailId() {
         return $this->ht['email_id'];
     }
 
-    function getEmail(){
+    function getEmail() {
         
         if(!$this->email && $this->getEmailId())
             $this->email=Email::lookup($this->getEmailId());
@@ -80,16 +84,16 @@ class Dept {
         return $this->email;
     }
 
-    function getNumStaff(){
+    function getNumStaff() {
         return $this->ht['users'];
     }
 
      
-    function getNumUsers(){
+    function getNumUsers() {
         return $this->getNumStaff();
     }
 
-    function getNumMembers(){
+    function getNumMembers() {
         return count($this->getMembers());
     }
 
@@ -117,11 +121,11 @@ class Dept {
     }
 
 
-    function getSLAId(){
+    function getSLAId() {
         return $this->ht['sla_id'];
     }
 
-    function getSLA(){
+    function getSLA() {
 
         if(!$this->sla && $this->getSLAId())
             $this->sla=SLA::lookup($this->getSLAId());
@@ -164,11 +168,11 @@ class Dept {
         return ($this->getSignature() && $this->isPublic());
     }
     
-    function getManagerId(){
+    function getManagerId() {
         return $this->ht['manager_id'];
     }
 
-    function getManager(){
+    function getManager() {
      
         if(!$this->manager && $this->getManagerId())
             $this->manager=Staff::lookup($this->getManagerId());
@@ -176,19 +180,19 @@ class Dept {
         return $this->manager;
     }
 
-    function isPublic(){
+    function isPublic() {
          return ($this->ht['ispublic']);
     }
     
-    function autoRespONNewTicket(){
+    function autoRespONNewTicket() {
         return ($this->ht['ticket_auto_response']);
     }
         
-    function autoRespONNewMessage(){
+    function autoRespONNewMessage() {
         return ($this->ht['message_auto_response']);
     }
 
-    function noreplyAutoResp(){
+    function noreplyAutoResp() {
          return ($this->ht['noreply_autoresp']);
     }
 
@@ -201,7 +205,7 @@ class Dept {
         return $this->ht;
     }
 
-    function getInfo(){
+    function getInfo() {
         return $this->getHashtable();
     }
 
@@ -243,9 +247,9 @@ class Dept {
 
     }
 
-    function update($vars,&$errors){
+    function update($vars, &$errors) {
 
-        if(!$this->save($this->getId(),$vars,$errors))
+        if(!$this->save($this->getId(), $vars, $errors))
             return false;
 
         $this->updateAllowedGroups($vars['groups']);
@@ -262,7 +266,7 @@ class Dept {
 
         $id=$this->getId();
         $sql='DELETE FROM '.DEPT_TABLE.' WHERE dept_id='.db_input($id).' LIMIT 1';
-        if(db_query($sql) && ($num=db_affected_rows())){
+        if(db_query($sql) && ($num=db_affected_rows())) {
             // DO SOME HOUSE CLEANING
             //Move tickets to default Dept. TODO: Move one ticket at a time and send alerts + log notes.
             db_query('UPDATE '.TICKET_TABLE.' SET dept_id='.db_input($cfg->getDefaultDeptId()).' WHERE dept_id='.db_input($id));
@@ -287,7 +291,7 @@ class Dept {
         return $id;
     }
 
-    function lookup($id){
+    function lookup($id) {
         return ($id && is_numeric($id) && ($dept = new Dept($id)) && $dept->getId()==$id)?$dept:null;
     }
 
@@ -323,14 +327,14 @@ class Dept {
         return self::getDepartments(true);
     }
 
-    function create($vars,&$errors) {
+    function create($vars, &$errors) {
         if(($id=self::save(0, $vars, $errors)) && ($dept=self::lookup($id)))
             $dept->updateAllowedGroups($vars['groups']);
 
         return $id;
     }
 
-    function save($id,$vars,&$errors) {
+    function save($id, $vars, &$errors) {
         global $cfg;
                 
         if($id && $id!=$vars['id'])
@@ -342,11 +346,11 @@ class Dept {
         if(!is_numeric($vars['tpl_id']))
             $errors['tpl_id']='Template selection required';
 
-        if(!$vars['name']){
+        if(!$vars['name']) {
             $errors['name']='Name required';
-        }elseif(strlen($vars['name'])<4) {
+        } elseif(strlen($vars['name'])<4) {
             $errors['name']='Name is too short.';
-        }elseif(($did=Dept::getIdByName($vars['name'])) && $did!=$id){
+        } elseif(($did=Dept::getIdByName($vars['name'])) && $did!=$id) {
             $errors['name']='Department already exist';
         }
         
@@ -377,7 +381,7 @@ class Dept {
             
             $errors['err']='Unable to update '.Format::htmlchars($vars['name']).' Dept. Error occurred';
            
-        }else{
+        } else {
             $sql='INSERT INTO '.DEPT_TABLE.' '.$sql.',created=NOW()';
             if(db_query($sql) && ($id=db_insert_id()))
                 return $id;
diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php
index 5a4e7e0f73e2edbe006f485f9dbe50b6d69809ce..aa43ce89e960231bdf2e25bf0f622a24d2b44741 100644
--- a/include/class.mailfetch.php
+++ b/include/class.mailfetch.php
@@ -442,7 +442,7 @@ class MailFetcher {
                     //This should be really a comment on message - NoT an internal note.
                     //TODO: support comments on Messages and Responses.
                     $error = sprintf('Attachment %s [%s] rejected because of file type', $a['name'], $a['mime']);
-                    $ticket->postNote('Email Attachment Rejected', $error, false);
+                    $ticket->postNote('Email Attachment Rejected', $error, 'SYSTEM', false);
                     $ost->logDebug('Email Attachment Rejected (Ticket #'.$ticket->getExtId().')', $error);
                 }
             }
diff --git a/include/class.osticket.php b/include/class.osticket.php
index 033ec0f82accf22a97b855b39c12c4166fe580af..44f4143672b9e4b427fbace7e3ce4d1e71867f91 100644
--- a/include/class.osticket.php
+++ b/include/class.osticket.php
@@ -149,6 +149,17 @@ class osTicket {
         return (!$errors);
     }
 
+    /* Replace Template Variables */
+    function replaceTemplateVariables($input, $vars=array()) {
+        
+        $replacer = new VariableReplacer();
+        $replacer->assign(array_merge($vars, 
+                    array('url' => $this->getConfig()->getBaseUrl())
+                    ));
+
+        return $replacer->replaceVars($input);
+    }
+
     function addExtraHeader($header) {
         $this->headers[md5($header)] = $header;
     }
diff --git a/include/class.staff.php b/include/class.staff.php
index 83c9ce2e58da2905c4716a28ff159dfb870074b1..ace8f2a0b785c2b31d6fc0d490d0f21113fad9a4 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -73,6 +73,10 @@ class Staff {
         return $this->load();
     }
 
+    function asVar() {
+        return $this->getName();
+    }
+
     function getHastable() {
         return $this->ht;
     }
@@ -503,7 +507,6 @@ class Staff {
     }
 
     /**** Static functions ********/
-
     function getStaffMembers($availableonly=false) {
 
         $sql='SELECT s.staff_id,CONCAT_WS(", ",s.lastname, s.firstname) as name '
diff --git a/include/class.team.php b/include/class.team.php
index cdf4cffcd3148fab082b2dd69f24733481aaeca0..367815b9637d7ab24d9e295379d11a1f6601df74 100644
--- a/include/class.team.php
+++ b/include/class.team.php
@@ -21,7 +21,7 @@ class Team {
 
     var $members;
 
-    function Team($id){
+    function Team($id) {
 
         return $this->load($id);
     }
@@ -47,30 +47,34 @@ class Team {
         return $this->id;
     }
 
-    function reload(){
+    function reload() {
         return $this->load($this->getId());
     }
 
-    function getId(){
+    function asVar() {
+        return $this->getName();
+    }
+
+    function getId() {
         return $this->id;
     }
 
-    function getName(){
+    function getName() {
         return $this->ht['name'];
     }
 
-    function getNumMembers(){
+    function getNumMembers() {
         return $this->ht['members'];
     }
 
-    function getMembers(){
+    function getMembers() {
 
-        if(!$this->members && $this->getNumMembers()){
+        if(!$this->members && $this->getNumMembers()) {
             $sql='SELECT m.staff_id FROM '.TEAM_MEMBER_TABLE.' m '
                 .'LEFT JOIN '.STAFF_TABLE.' s USING(staff_id) '
                 .'WHERE m.team_id='.db_input($this->getId()).' AND s.staff_id IS NOT NULL '
                 .'ORDER BY s.lastname, s.firstname';
-            if(($res=db_query($sql)) && db_num_rows($res)){
+            if(($res=db_query($sql)) && db_num_rows($res)) {
                 while(list($id)=db_fetch_row($res))
                     if(($staff= Staff::lookup($id)))
                         $this->members[]= $staff;
@@ -87,18 +91,18 @@ class Team {
             .'   AND staff_id='.db_input($staff->getId())) !== 0;
     }
 
-    function getLeadId(){
+    function getLeadId() {
         return $this->ht['lead_id'];
     }
 
-    function getTeamLead(){
+    function getTeamLead() {
         if(!$this->lead && $this->getLeadId())
             $this->lead=Staff::lookup($this->getLeadId());
 
         return $this->lead;
     }
 
-    function getLead(){
+    function getLead() {
         return $this->getTeamLead();
     }
 
@@ -106,27 +110,27 @@ class Team {
         return $this->ht;
     }
 
-    function getInfo(){
+    function getInfo() {
         return  $this->getHashtable();
     }
 
-    function isEnabled(){
+    function isEnabled() {
         return ($this->ht['isenabled']);
     }
 
-    function isActive(){
+    function isActive() {
         return $this->isEnabled();
     }
 
-    function update($vars,&$errors) {
+    function update($vars, &$errors) {
 
         //reset team lead if they're being deleted
         if($this->getLeadId()==$vars['lead_id'] 
-                && $vars['remove'] && in_array($this->getLeadId(),$vars['remove']))
+                && $vars['remove'] && in_array($this->getLeadId(), $vars['remove']))
             $vars['lead_id']=0;
 
         //Save the changes...
-        if(!Team::save($this->getId(),$vars,$errors))
+        if(!Team::save($this->getId(), $vars, $errors))
             return false;
 
         //Delete staff marked for removal...
@@ -170,12 +174,12 @@ class Team {
     }
 
     /* ----------- Static function ------------------*/
-    function lookup($id){
+    function lookup($id) {
         return ($id && is_numeric($id) && ($team= new Team($id)) && $team->getId()==$id)?$team:null;
     }
 
 
-    function getIdbyName($name){
+    function getIdbyName($name) {
 
         $sql='SELECT team_id FROM '.TEAM_TABLE.' WHERE name='.db_input($name);
         if(($res=db_query($sql)) && db_num_rows($res))
@@ -201,7 +205,7 @@ class Team {
                 .' ORDER by t.name ';
         }
         if(($res=db_query($sql)) && db_num_rows($res)) {
-            while(list($id,$name)=db_fetch_row($res))
+            while(list($id, $name)=db_fetch_row($res))
                 $teams[$id] = $name;
         }
 
@@ -212,20 +216,20 @@ class Team {
         return self::getTeams(true);
     }
 
-    function create($vars,&$errors) { 
-        return self::save(0,$vars,$errors);
+    function create($vars, &$errors) { 
+        return self::save(0, $vars, $errors);
     }
 
-    function save($id,$vars,&$errors) {
+    function save($id, $vars, &$errors) {
 
         if($id && $vars['id']!=$id)
             $errors['err']='Missing or invalid team';
             
         if(!$vars['name']) {
             $errors['name']='Team name required';
-        }elseif(strlen($vars['name'])<3) {
+        } elseif(strlen($vars['name'])<3) {
             $errors['name']='Team name must be at least 3 chars.';
-        }elseif(($tid=Team::getIdByName($vars['name'])) && $tid!=$id){
+        } elseif(($tid=Team::getIdByName($vars['name'])) && $tid!=$id) {
             $errors['name']='Team name already exists';
         }
         
@@ -242,7 +246,7 @@ class Team {
                 return true;
                     
             $errors['err']='Unable to update the team. Internal error';
-        }else{
+        } else {
             $sql='INSERT INTO '.TEAM_TABLE.' '.$sql.',created=NOW()';
             if(db_query($sql) && ($id=db_insert_id()))
                 return $id;
diff --git a/include/class.template.php b/include/class.template.php
index fa8d070d544c4bf5eda0da758fed814f106c529d..92cb61b54af382fad2fe5412f6d0feeb97bc66b1 100644
--- a/include/class.template.php
+++ b/include/class.template.php
@@ -375,6 +375,8 @@ class Template {
                 .' ,message_alert_body='.db_input($info['message_alert_body'])
                 .' ,note_alert_subj='.db_input($info['note_alert_subj'])
                 .' ,note_alert_body='.db_input($info['note_alert_body'])
+                .' ,transfer_alert_subj='.db_input($info['transfer_alert_subj'])
+                .' ,transfer_alert_body='.db_input($info['transfer_alert_body'])
                 .' ,assigned_alert_subj='.db_input($info['assigned_alert_subj'])
                 .' ,assigned_alert_body='.db_input($info['assigned_alert_body'])
                 .' ,ticket_overdue_subj='.db_input($info['ticket_overdue_subj'])
diff --git a/include/class.thread.php b/include/class.thread.php
new file mode 100644
index 0000000000000000000000000000000000000000..f830cd98ead00f6a553d8a0d5b77126b2ccfa80e
--- /dev/null
+++ b/include/class.thread.php
@@ -0,0 +1,222 @@
+<?php
+/*********************************************************************
+    class.thread.php
+
+    Ticket thread
+    TODO: move thread related logic here from class.ticket.php
+
+    Peter Rotich <peter@osticket.com>
+    Copyright (c)  2006-2012 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+**********************************************************************/
+include_once(INCLUDE_DIR.'class.ticket.php');
+
+Class ThreadEntry {
+
+    var $id;
+    var $ht;
+
+    var $staff;
+    var $ticket;
+    
+    function ThreadEntry($id, $type='', $ticketId=0) {
+        $this->load($id, $type, $ticketId);
+    }
+
+    function load($id=0, $type='', $ticketId=0) {
+
+        if(!$id && !($id=$this->getId()))
+            return false;
+
+        $sql='SELECT thread.* '
+            .' ,count(DISTINCT attach.attach_id) as attachments '
+            .' FROM '.TICKET_THREAD_TABLE.' thread '
+            .' LEFT JOIN '.TICKET_ATTACHMENT_TABLE.' attach 
+                ON (thread.ticket_id=attach.ticket_id 
+                        AND thread.id=attach.ref_id 
+                        AND thread.thread_type=attach.ref_type) '
+            .' WHERE  thread.id='.db_input($id);
+
+        if($type)
+            $sql.=' AND thread.thread_type='.db_input($type);
+
+        if($ticketId)
+            $sql.=' AND thread.ticket_id='.db_input($ticketId);
+
+        $sql.=' GROUP BY thread.id ';
+        
+        if(!($res=db_query($sql)) || !db_num_rows($res))
+            return false;
+
+        $this->ht = db_fetch_array($res);
+        $this->id = $this->ht['id'];
+
+        $this->staff = $this->ticket = null;
+
+        return true;
+    }
+
+    function reload() {
+        return $this->load();
+    }
+
+    function getId() {
+        return $this->id;
+    }
+
+    function getPid() {
+        return $this->ht['pid'];
+    }
+
+    function getType() {
+        return $this->ht['thread_type'];
+    }
+
+    function getSource() {
+        return $this->ht['source'];
+    }
+
+    function getPoster() {
+        return $this->ht['poster'];
+    }
+
+    function getTitle() {
+        return $this->ht['title'];
+    }
+
+    function getBody() {
+        return $this->ht['body'];
+    }
+
+    function getCreateDate() {
+        return $this->ht['created'];
+    }
+
+    function getUpdateDate() {
+        return $this->ht['updated'];
+    }
+
+    function getNumAttachments() {
+        return $this->ht['attachments'];
+    }
+
+    function getTicketId() {
+        return $this->ht['ticket_id'];
+    }
+
+    function getTicket() {
+
+        if(!$this->ticket && $this->getTicketId())
+            $this->ticket = Ticket::lookup($this->getTicketId());
+
+        return $this->ticket;
+    }
+
+    function getStaffId() {
+        return $this->ht['staff_id'];
+    }
+
+    function getStaff() {
+      
+        if(!$this->staff && $this->getStaffId())
+            $this->staff = Staff::lookup($this->getStaffId());
+
+        return $this->staff;
+    }
+
+    /* variables */
+
+    function asVar() {
+        return $this->getBody();
+    }
+
+    function getVar($tag) {
+        global $cfg;
+
+        if($tag && is_callable(array($this, 'get'.ucfirst($tag))))
+            return call_user_func(array($this, 'get'.ucfirst($tag)));
+
+        switch(strtolower($tag)) {
+            case 'create_date':
+                return Format::date(
+                        $cfg->getDateTimeFormat(),
+                        Misc::db2gmtime($this->getCreateDate()),
+                        $cfg->getTZOffset(),
+                        $cfg->observeDaylightSaving());
+                break;
+            case 'update_date':
+                return Format::date(
+                        $cfg->getDateTimeFormat(),
+                        Misc::db2gmtime($this->getUpdateDate()),
+                        $cfg->getTZOffset(),
+                        $cfg->observeDaylightSaving());
+                break;
+        }
+
+        return false;
+    }
+
+    /* static calls */
+
+    function _lookup($id, $type='', $tid=0) {
+        return ($id && is_numeric($id) 
+                && ($e = new ThreadEntry($id, $type, $tid)) && $e->getId()==$id)?$e:null;
+    }
+}
+
+/* Message - Ticket thread entry of type message */
+class Message extends ThreadEntry {
+
+    function Message($id, $ticketId=0) {
+        parent::ThreadEntry($id, 'M', $ticketId);
+    }
+
+    function getSubject() {
+        return $this->getTitle();
+    }
+
+    function lookup($id, $tid) {
+        return parent::_lookup($id, 'M', $tid);
+    }
+}
+
+/* Response - Ticket thread entry of type response */
+class Response extends ThreadEntry {
+
+    function Response($id, $ticketId=0) {
+        parent::ThreadEntry($id, 'R', $ticketId);
+    }
+
+    function getSubject() {
+        return $this->getTitle();
+    }
+
+    function getRespondent() {
+        return $this->getStaff();
+    }
+
+    function lookup($id, $tid) {
+        return parent::_lookup($id, 'R', $tid);
+    }
+}
+
+/* Note - Ticket thread entry of type note (Internal Note) */
+class Note extends ThreadEntry {
+
+    function Note($id, $ticketId=0) {
+        parent::ThreadEntry($id, 'N', $ticketId);
+    }
+
+    function getMessage() {
+        return $this->getBody();
+    }
+
+    function lookup($id, $tid) {
+        return parent::_lookup($id, 'N', $tid);
+    }
+}
diff --git a/include/class.ticket.php b/include/class.ticket.php
index bfa23d491f127552e2895c33464eb6d8d9d72995..ec3dcdd1e54e6e075e071b5cc94e2092417bfb92 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -13,6 +13,7 @@
 
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
+include_once(INCLUDE_DIR.'class.thread.php');
 include_once(INCLUDE_DIR.'class.staff.php');
 include_once(INCLUDE_DIR.'class.client.php');
 include_once(INCLUDE_DIR.'class.team.php');
@@ -25,10 +26,11 @@ include_once(INCLUDE_DIR.'class.attachment.php');
 include_once(INCLUDE_DIR.'class.pdf.php');
 include_once(INCLUDE_DIR.'class.banlist.php');
 include_once(INCLUDE_DIR.'class.template.php');
+include_once(INCLUDE_DIR.'class.variable.php');
 include_once(INCLUDE_DIR.'class.priority.php');
 include_once(INCLUDE_DIR.'class.sla.php');
 
-class Ticket{
+class Ticket {
 
     var $id;
     var $extid;
@@ -198,13 +200,17 @@ class Ticket{
     }
 
     //Getters
-    function getId(){
+    function getId() {
         return  $this->id;
     }
 
-    function getExtId(){
+    function getExtId() {
         return  $this->extid;
     }
+
+    function getNumber() {
+        return $this->getExtId();
+    }
    
     function getEmail(){
         return $this->email;
@@ -419,6 +425,11 @@ class Ticket{
         return $assignees;
     }
 
+    function getAssigned($glue='/') {
+        $assignees = $this->getAssignees();
+        return $assignees?implode($glue, $assignees):'';
+    }
+
     function getTopicId() {
         return $this->topic_id;
     }
@@ -535,7 +546,7 @@ class Ticket{
     }
 
     function getResponses($msgId=0) {
-        return $this->getThreadByType('R', $msgID);
+        return $this->getThreadByType('R', $msgId);
     }
 
     function getNotes() {
@@ -656,9 +667,9 @@ class Ticket{
 
     //DeptId can NOT be 0. No orphans please!
     function setDeptId($deptId){
-        
+       
         //Make sure it's a valid department//
-        if(!($dept=Dept::lookup($deptId)))
+        if(!($dept=Dept::lookup($deptId)) || $dept->getId()==$this->getDeptId())
             return false;
 
       
@@ -832,17 +843,17 @@ class Ticket{
         if($autorespond && $email && $cfg->autoRespONNewTicket() 
                 && $dept->autoRespONNewTicket() 
                 &&  ($msg=$tpl->getAutoRespMsgTemplate())) {
-              
-            $body=$this->replaceTemplateVars($msg['body']);
-            $subj=$this->replaceTemplateVars($msg['subj']);
-            $body = str_replace('%message', $message, $body);
-            $body = str_replace('%signature',($dept && $dept->isPublic())?$dept->getSignature():'',$body);
             
+            $msg = $this->replaceVars($msg, 
+                    array('message' => $message,
+                          'signature' => ($dept && $dept->isPublic())?$dept->getSignature():'')
+                    );
+
             if($cfg->stripQuotedReply() && ($tag=$cfg->getReplySeparator()))
-                $body ="\n$tag\n\n".$body;
+                $msg['body'] ="\n$tag\n\n".$msg['body'];
             
             //TODO: add auto flags....be nice to mail servers and sysadmins!!
-            $email->send($this->getEmail(),$subj,$body);
+            $email->send($this->getEmail(), $msg['subj'], $msg['body']);
         }
         
         if(!($email=$cfg->getAlertEmail()))
@@ -852,17 +863,14 @@ class Ticket{
         if($alertstaff && $email
                 && $cfg->alertONNewTicket() 
                 && ($msg=$tpl->getNewTicketAlertMsgTemplate())) {
-              
-            $body=$this->replaceTemplateVars($msg['body']);
-            $subj=$this->replaceTemplateVars($msg['subj']);
-            $body = str_replace('%message', $message, $body);
-            
+                    
+            $msg = $this->replaceVars($msg, array('message' => $message));
+
             $recipients=$sentlist=array();
-            
             //Alert admin??
             if($cfg->alertAdminONNewTicket()) {
-                $alert = str_replace("%staff",'Admin',$body);
-                $email->send($cfg->getAdminEmail(),$subj,$alert);
+                $alert = str_replace('%{recipient}', 'Admin', $msg['body']);
+                $email->send($cfg->getAdminEmail(), $msg['subj'], $alert);
                 $sentlist[]=$cfg->getAdminEmail();
             }
               
@@ -877,8 +885,8 @@ class Ticket{
                
             foreach( $recipients as $k=>$staff){
                 if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue;
-                $alert = str_replace("%staff",$staff->getFirstName(),$body);
-                $email->send($staff->getEmail(),$subj,$alert);
+                $alert = str_replace('%{recipient}', $staff->getFirstName(), $msg['body']);
+                $email->send($staff->getEmail(), $msg['subj'], $alert);
                 $sentlist[] = $staff->getEmail();
             }
            
@@ -907,20 +915,21 @@ class Ticket{
             $email=$cfg->getDefaultEmail();
 
         if($tpl && ($msg=$tpl->getOverlimitMsgTemplate()) && $email) {
-            $body=$this->replaceTemplateVars($msg['body']);
-            $subj=$this->replaceTemplateVars($msg['subj']);
-            $body = str_replace('%signature',($dept && $dept->isPublic())?$dept->getSignature():'',$body);
-            $email->send($this->getEmail(), $subj, $body);
+            
+            $msg = $this->replaceVars($msg, 
+                        array('signature' => ($dept && $dept->isPublic())?$dept->getSignature():''));
+            
+            $email->send($this->getEmail(), $msg['subj'], $msg['body']);
         }
 
         $client= $this->getClient();
         
         //Alert admin...this might be spammy (no option to disable)...but it is helpful..I think.
-        $msg='Max. open tickets reached for '.$this->getEmail()."\n"
-            .'Open ticket: '.$client->getNumOpenTickets()."\n"
-            .'Max Allowed: '.$cfg->getMaxOpenTickets()."\n\nNotice sent to the user.";
+        $alert='Max. open tickets reached for '.$this->getEmail()."\n"
+              .'Open ticket: '.$client->getNumOpenTickets()."\n"
+              .'Max Allowed: '.$cfg->getMaxOpenTickets()."\n\nNotice sent to the user.";
             
-        $ost->alertAdmin('Overlimit Notice', $msg);
+        $ost->alertAdmin('Overlimit Notice', $alert);
        
         return true;
     }
@@ -958,38 +967,40 @@ class Ticket{
 
 
         if(!$dept || !($tpl = $dept->getTemplate()))
-            $tpl= $cfg->getDefaultTemplate();
-       
+            $tpl = $cfg->getDefaultTemplate();
+
+        if(!$dept || !($email = $dept->getAutoRespEmail()))
+            $email = $cfg->getDefaultEmail();
+      
         //If enabled...send confirmation to user. ( New Message AutoResponse)
-        if($tpl && ($msg=$tpl->getNewMessageAutorepMsgTemplate())) {
-                        
-            $body=$this->replaceTemplateVars($msg['body']);
-            $subj=$this->replaceTemplateVars($msg['subj']);
-            $body = str_replace('%signature',($dept && $dept->isPublic())?$dept->getSignature():'',$body);
+        if($email && $tpl && ($msg=$tpl->getNewMessageAutorepMsgTemplate())) {
+
+            $msg = $this->replaceVars($msg,
+                            array('signature' => ($dept && $dept->isPublic())?$dept->getSignature():''));
 
             //Reply separator tag.
             if($cfg->stripQuotedReply() && ($tag=$cfg->getReplySeparator()))
-                $body ="\n$tag\n\n".$body;
-            
-            if(!$dept || !($email=$dept->getAutoRespEmail()))
-                $email=$cfg->getDefaultEmail();
-            
-            if($email) {
-                $email->send($this->getEmail(),$subj,$body);
-            }
+                $msg['body'] ="\n$tag\n\n".$msg['body'];
+        
+            $email->send($this->getEmail(), $msg['subj'], $msg['body']);
         }
     }
 
-    function onAssign($note, $alert=true) {
+    function onAssign($assignee, $comments, $alert=true) {
         global $cfg, $thisstaff;
 
         if($this->isClosed()) $this->reopen(); //Assigned tickets must be open - otherwise why assign?
 
+        //Assignee must be an object of type Staff or Team
+        if(!$assignee || !is_object($assignee)) return false;
+
         $this->reload();
 
-        //Log an internal note - no alerts on the internal note.
         $note=$note?$note:'Ticket assignment';
-        $this->postNote('Ticket Assigned to '.$this->getAssignee(),$note,false);
+        $assigner =$thisstaff?$thisstaff:'SYSTEM (Auto Assignment)';
+        
+        //Log an internal note - no alerts on the internal note.
+        $this->postNote('Ticket Assigned to '.$assignee->getName(), $comments, $assigner, false);
 
         //See if we need to send alerts
         if(!$alert || !$cfg->alertONAssignment()) return true; //No alerts!
@@ -998,39 +1009,39 @@ class Ticket{
 
         //Get template.
         if(!$dept || !($tpl = $dept->getTemplate()))
-            $tpl= $cfg->getDefaultTemplate();
+            $tpl = $cfg->getDefaultTemplate();
 
         //Email to use!
         if(!($email=$cfg->getAlertEmail()))
-            $email =$cfg->getDefaultEmail();
+            $email = $cfg->getDefaultEmail();
+
+        //recipients
+        $recipients=array();
+        if(!strcasecmp(get_class($assignee), 'Staff')) {
+            if($cfg->alertStaffONAssignment())
+                $recipients[] = $assignee;
+        } elseif(!strcasecmp(get_class($assignee), 'Team')) {
+            if($cfg->alertTeamMembersONAssignment() && ($members=$assignee->getMembers()))
+                $recipients+=$members;
+            elseif($cfg->alertTeamLeadONAssignment() && ($lead=$assignee->getTeamLead()))
+                $recipients[] = $lead;
+        }
 
         //Get the message template
-        if($tpl && ($msg=$tpl->getAssignedAlertMsgTemplate()) && $email) {
-
-            $body=$this->replaceTemplateVars($msg['body']);
-            $subj=$this->replaceTemplateVars($msg['subj']);
-            $body = str_replace('%note', $note, $body);
-            $body = str_replace('%message', $note, $body); //Previous versions used message.
-            $body = str_replace('%assignee', $this->getAssignee(), $body);
-            $body = str_replace('%assigner', ($thisstaff)?$thisstaff->getName():'System',$body);
-            //recipients
-            $recipients=array();
-            //Assigned staff or team... if any
-            // Assigning a ticket to a team when already assigned to staff disables alerts to the team (!))
-            if($cfg->alertStaffONAssignment() && $this->getStaffId())
-                $recipients[]=$this->getStaff();
-            elseif($this->getTeamId() && ($team=$this->getTeam())) {
-                if($cfg->alertTeamMembersONAssignment() && ($members=$team->getMembers()))
-                    $recipients+=$members;
-                elseif($cfg->alertTeamLeadONAssignment() && ($lead=$team->getTeamLead()))
-                    $recipients[]=$lead;
-            }
+        if($email && $recipients && $tpl && ($msg=$tpl->getAssignedAlertMsgTemplate())) {
+
+            $msg = $this->replaceVars($msg, 
+                        array('comments' => $comments,
+                              'assignee' => $assignee,
+                              'assigner' => $assigner
+                              ));
+
             //Send the alerts.
             $sentlist=array();
-            foreach( $recipients as $k=>$staff){
+            foreach( $recipients as $k=>$staff) {
                 if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue;
-                $alert = str_replace('%staff', $staff->getFirstName(), $body);
-                $email->send($staff->getEmail(), $subj, $alert);
+                $alert = str_replace('%{recipient}', $staff->getFirstName(), $msg['body']);
+                $email->send($staff->getEmail(), $msg['subj'], $alert);
                 $sentlist[] = $staff->getEmail();
             }
         }
@@ -1059,10 +1070,8 @@ class Ticket{
 
         //Get the message template
         if($tpl && ($msg=$tpl->getOverdueAlertMsgTemplate()) && $email) {
-
-            $body=$this->replaceTemplateVars($msg['body']);
-            $subj=$this->replaceTemplateVars($msg['subj']);
-            $body = str_replace('%comments', $comments, $body); //Planned support.
+            
+            $msg = $this->replaceVars($msg, array('comments' => $comments));
 
             //recipients
             $recipients=array();
@@ -1084,51 +1093,83 @@ class Ticket{
             $sentlist=array();
             foreach( $recipients as $k=>$staff){
                 if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue;
-                $alert = str_replace("%staff",$staff->getFirstName(),$body);
-                $email->send($staff->getEmail(),$subj,$alert);
+                $alert = str_replace("%{recipient}", $staff->getFirstName(), $msg['body']);
+                $email->send($staff->getEmail(), $msg['subj'], $alert);
                 $sentlist[] = $staff->getEmail();
             }
 
         }
 
         return true;
+    
+    }
+   
+    //ticket obj as variable = ticket number.
+    function asVar() {
+       return $this->getNumber();
     }
 
-    //Replace base variables.
-    function replaceTemplateVars($text){
+    function getVar($tag) {
         global $cfg;
 
-        $dept = $this->getDept();
-        $staff= $this->getStaff();
-        $team = $this->getTeam();
-
-        //TODO: add new vars (team, sla...etc)
-
-
-        $search = array('/%id/','/%ticket/','/%email/','/%name/','/%subject/','/%topic/','/%phone/','/%status/','/%priority/',
-                        '/%dept/','/%assigned_staff/','/%createdate/','/%duedate/','/%closedate/','/%url/',
-                        '/%auth/', '/%clientlink/');
-        $replace = array($this->getId(),
-                         $this->getExtId(),
-                         $this->getEmail(),
-                         $this->getName(),
-                         $this->getSubject(),
-                         $this->getHelpTopic(),
-                         $this->getPhoneNumber(),
-                         $this->getStatus(),
-                         $this->getPriority(),
-                         ($dept?$dept->getName():''),
-                         ($staff?$staff->getName():''),
-                         Format::db_daydatetime($this->getCreateDate()),
-                         Format::db_daydatetime($this->getDueDate()),
-                         Format::db_daydatetime($this->getCloseDate()),
-                         $cfg->getBaseUrl(),
-                         $this->getAuthToken(),
-                         '%url/view.php?t=%ticket&e=%email&a=%auth');
-        while ($text != ($T = preg_replace($search,$replace,$text))) {
-            $text = $T;
+        if($tag && is_callable(array($this, 'get'.ucfirst($tag))))
+            return call_user_func(array($this, 'get'.ucfirst($tag)));
+
+        switch(strtolower($tag)) {
+            case 'phone_number':
+                return $this->getPhoneNumber();
+                break;
+            case 'auth_token':
+                return $this->getAuthToken();
+                break;
+            case 'client_link':
+                return sprintf('%s/view.php?t=%s&e=%s&a=%s',
+                        $cfg->getBaseUrl(), $this->getNumber(), $this->getEmail(), $this->getAuthToken());
+                break;
+            case 'staff_link':
+                return sprintf('%s/scp/tickets.php?id=%d', $cfg->getBaseUrl(), $this->getId());
+                break;
+            case 'create_date':
+                return Format::date(
+                        $cfg->getDateTimeFormat(), 
+                        Misc::db2gmtime($this->getCreateDate()),
+                        $cfg->getTZOffset(),
+                        $cfg->observeDaylightSaving());
+                break;
+             case 'due_date':
+                $duedate ='';
+                if($this->getDueDate())
+                    $duedate = Format::date(
+                            $cfg->getDateTimeFormat(),
+                            Misc::db2gmtime($this->getDueDate()),
+                            $cfg->getTZOffset(),
+                            $cfg->observeDaylightSaving());
+
+                return $duedate;
+                break;
+            case 'close_date';
+                $closedate ='';
+                if($this->isClosed())
+                    $duedate = Format::date(
+                            $cfg->getDateTimeFormat(),
+                            Misc::db2gmtime($this->getCloseDate()),
+                            $cfg->getTZOffset(),
+                            $cfg->observeDaylightSaving());
+
+                return $closedate;
+                break;
         }
-        return $text;
+
+        return false;
+    }
+
+    //Replace base variables.
+    function replaceVars($input, $vars = array()) {
+        global $ost;
+
+        $vars = array_merge($vars, array('ticket' => $this));
+
+        return $ost->replaceTemplateVariables($input, $vars);
     }
 
     function markUnAnswered() {
@@ -1160,24 +1201,33 @@ class Ticket{
 
     //Dept Tranfer...with alert.. done by staff 
     function transfer($deptId, $comments, $alert = true) {
+        
         global $cfg, $thisstaff;
       
-        if(!$this->setDeptId($deptId))
+        if(!$thisstaff || !$thisstaff->canTransferTickets())
             return false;
-         
+
+        $currentDept = $this->getDeptName(); //Current department
+
+        if(!$deptId || !$this->setDeptId($deptId))
+            return false;
+       
+        // Reopen ticket if closed 
+        if($this->isClosed()) $this->reopen();
+
+        $this->reload();
         // Change to SLA of the new department
         $this->selectSLAId();
-         $currentDept = $this->getDeptName(); //XXX: add to olddept to tpl vars??
+                  
+        /*** log the transfer comments as internal note - with alerts disabled - ***/
+        $title='Dept. Transfer from '.$currentDept.' to '.$this->getDeptName();
+        $comments=$comments?$comments:$title; 
+        $this->postNote($title, $comments, $thisstaff, false);
 
-         // Reopen ticket if closed 
-         if($this->isClosed())
-             $this->reopen();
+        $this->logEvent('transferred');
         
-         $this->reload(); //reload - new dept!!
-         $this->logEvent('transferred');
-
-         //Send out alerts if enabled AND requested
-         if(!$alert || !$cfg->alertONTransfer() || !($dept=$this->getDept())) return true; //no alerts!!
+        //Send out alerts if enabled AND requested
+        if(!$alert || !$cfg->alertONTransfer() || !($dept=$this->getDept())) return true; //no alerts!!
 
 
          //Get template.
@@ -1191,10 +1241,7 @@ class Ticket{
          //Get the message template 
          if($tpl && ($msg=$tpl->getTransferAlertMsgTemplate()) && $email) {
             
-             $body=$this->replaceTemplateVars($msg['body']);
-             $subj=$this->replaceTemplateVars($msg['subj']);
-             $body = str_replace('%note', $comments, $body);
-                        
+             $msg = $this->replaceVars($msg, array('comments' => $comments, 'staff' => $thisstaff));
             //recipients            
             $recipients=array();
             //Assigned staff or team... if any
@@ -1216,8 +1263,8 @@ class Ticket{
             $sentlist=array();
             foreach( $recipients as $k=>$staff){
                 if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue;
-                $alert = str_replace("%staff",$staff->getFirstName(),$body);
-                $email->send($staff->getEmail(),$subj,$alert);
+                $alert = str_replace('%{recipient}',$staff->getFirstName(), $msg['body']);
+                $email->send($staff->getEmail(), $msg['subj'], $alert);
                 $sentlist[] = $staff->getEmail();
             }
          }
@@ -1233,7 +1280,7 @@ class Ticket{
         if(!$this->setStaffId($staff->getId()))
             return false;
 
-        $this->onAssign($note, $alert);
+        $this->onAssign($staff, $note, $alert);
         $this->logEvent('assigned');
 
         return true;
@@ -1252,7 +1299,7 @@ class Ticket{
         if($this->isClosed())
             $this->setStaffId(0);
 
-        $this->onAssign($note, $alert);
+        $this->onAssign($team, $note, $alert);
         $this->logEvent('assigned');
 
         return true;
@@ -1347,9 +1394,7 @@ class Ticket{
         //If enabled...send alert to staff (New Message Alert)
         if($cfg->alertONNewMessage() && $tpl && $email && ($msg=$tpl->getNewMessageAlertMsgTemplate())) {
 
-            $body=$this->replaceTemplateVars($msg['body']);
-            $subj=$this->replaceTemplateVars($msg['subj']);
-            $body = str_replace("%message", $message,$body);
+            $msg = $this->replaceVars($msg, array('message' => $message));
 
             //Build list of recipients and fire the alerts.
             $recipients=array();
@@ -1369,8 +1414,8 @@ class Ticket{
             $sentlist=array(); //I know it sucks...but..it works.
             foreach( $recipients as $k=>$staff){
                 if(!$staff || !$staff->getEmail() || !$staff->isAvailable() && in_array($staff->getEmail(),$sentlist)) continue;
-                $alert = str_replace("%staff",$staff->getFirstName(),$body);
-                $email->send($staff->getEmail(),$subj,$alert);
+                $alert = str_replace('%{recipient}', $staff->getFirstName(), $msg['body']);
+                $email->send($staff->getEmail(), $msg['subj'], $alert);
                 $sentlist[] = $staff->getEmail();
             }
         }
@@ -1380,9 +1425,7 @@ class Ticket{
 
     /* public */ 
     function postReply($vars, $errors, $alert = true) {
-        global $thisstaff,$cfg;
-
-        if(!$thisstaff || !$thisstaff->isStaff() || !$cfg) return 0;
+        global $thisstaff, $cfg;
 
         if(!$vars['msgId'])
             $errors['msgId'] ='Missing messageId - internal error';
@@ -1391,14 +1434,16 @@ class Ticket{
 
         if($errors) return 0;
 
+        $poster = $thisstaff?$thisstaff->getName():'SYSTEM (Canned Response)';
+
         $sql='INSERT INTO '.TICKET_THREAD_TABLE.' SET created=NOW() '
             .' ,thread_type="R"'
             .' ,ticket_id='.db_input($this->getId())
             .' ,pid='.db_input($vars['msgId'])
             .' ,body='.db_input(Format::striptags($vars['response']))
-            .' ,staff_id='.db_input($thisstaff->getId())
-            .' ,poster='.db_input($thisstaff->getName())
-            .' ,ip_address='.db_input($thisstaff->getIP());
+            .' ,staff_id='.db_input($thisstaff?$thisstaff->getId():0)
+            .' ,poster='.db_input($poster)
+            .' ,ip_address='.db_input($thisstaff?$thisstaff->getIP():'');
 
         if(!db_query($sql) || !($respId=db_insert_id()))
             return false;
@@ -1435,26 +1480,24 @@ class Ticket{
             $email = $cfg->getDefaultEmail();
 
         if($tpl && ($msg=$tpl->getReplyMsgTemplate()) && $email) {
-            $body=$this->replaceTemplateVars($msg['body']);
-            $subj=$this->replaceTemplateVars($msg['subj']);
-            $body = str_replace('%response',$vars['response'],$body);
 
-            if($vars['signature']=='mine')
+            if($thisstaff && $vars['signature']=='mine')
                 $signature=$thisstaff->getSignature();
             elseif($vars['signature']=='dept' && $dept && $dept->isPublic())
                 $signature=$dept->getSignature();
             else
                 $signature='';
-
-            $body = str_replace("%signature",$signature,$body);
+            
+            $msg = $this->replaceVars($msg, 
+                    array('response' => $vars['response'], 'signature' => $signature, 'staff' => $thisstaff));
 
             if($cfg->stripQuotedReply() && ($tag=$cfg->getReplySeparator()))
-                $body ="\n$tag\n\n".$body;
+                $msg['body'] ="\n$tag\n\n".$msg['body'];
 
             //Set attachments if emailing.
             $attachments =($cfg->emailAttachments() && $attachments)?$this->getAttachments($respId,'R'):array();
             //TODO: setup  5 param (options... e.g mid trackable on replies)
-            $email->send($this->getEmail(), $subj, $body, $attachments);
+            $email->send($this->getEmail(), $msg['subj'], $msg['body'], $attachments);
         }
 
         return $respId;
@@ -1467,7 +1510,7 @@ class Ticket{
         if(!$cfg || !$cfg->logTicketActivity())
             return 0;
 
-        return $this->postNote($title,$note,false,'System');
+        return $this->postNote($title, $note, 'SYSTEM', false);
     }
 
     // History log -- used for statistics generation (pretty reports)
@@ -1499,22 +1542,30 @@ class Ticket{
     }
 
     //Insert Internal Notes 
-    function postNote($title,$note,$alert=true,$poster='') {        
-        global $thisstaff,$cfg;
-		
-        $poster=($poster || !$thisstaff)?$poster:$thisstaff->getName();
+    function postNote($title, $body, $poster, $alert=true) {        
+        global $cfg;
 		
+        $staffId = 0;
+        if($poster && is_object($poster)) {
+            $staffId = $poster->getId();
+            $poster = $poster->getName();
+        }
+
+        //TODO: move to class.thread.php
+
         $sql= 'INSERT INTO '.TICKET_THREAD_TABLE.' SET created=NOW() '.
                 ',thread_type="N"'.
                 ',ticket_id='.db_input($this->getId()).
                 ',title='.db_input(Format::striptags($title)).
-                ',body='.db_input(Format::striptags($note)).
-                ',staff_id='.db_input($thisstaff?$thisstaff->getId():0).
+                ',body='.db_input(Format::striptags($body)).
+                ',staff_id='.db_input($staffId).
                 ',poster='.db_input($poster);
         //echo $sql;
         if(!db_query($sql) || !($id=db_insert_id()))
             return false;
 
+        $note = Note::lookup($id, $this->getId());
+
         // If alerts are not enabled then return a success.
         if(!$alert || !$cfg->alertONNewNote() || !($dept=$this->getDept()))
             return $id;
@@ -1527,12 +1578,8 @@ class Ticket{
 
 
         if($tpl && ($msg=$tpl->getNoteAlertMsgTemplate()) && $email) {
-                    
-            $body=$this->replaceTemplateVars($msg['body']);
-            $subj=$this->replaceTemplateVars($msg['subj']);
-            $body = str_replace('%note',"$title\n\n$note",$body);
-            # TODO: Support a variable replacement of the staff writing the
-            #       note
+                   
+            $msg = $this->replaceVars($msg, array('note' => $note));
 
             // Alert recipients    
             $recipients=array();
@@ -1552,9 +1599,9 @@ class Ticket{
             $sentlist=array();
             foreach( $recipients as $k=>$staff) {
                 if(!$staff || !is_object($staff) || !$staff->getEmail() || !$staff->isAvailable()) continue;
-                if(in_array($staff->getEmail(),$sentlist) || ($thisstaff && $thisstaff->getId()==$staff->getId())) continue; 
-                $alert = str_replace('%staff',$staff->getFirstName(),$body);
-                $email->send($staff->getEmail(),$subj,$alert);
+                if(in_array($staff->getEmail(),$sentlist) || ($staffId && $staffId==$staff->getId())) continue; 
+                $alert = str_replace('%{recipient}',$staff->getFirstName(), $msg['body']);
+                $email->send($staff->getEmail(), $msg['subj'], $alert);
                 $sentlist[] = $staff->getEmail();
             }
         }
@@ -1590,7 +1637,7 @@ class Ticket{
                 else
                     $error ='Error #'.$file['error'];
 
-                $this->postNote('File Upload Error', $error, false);
+                $this->postNote('File Upload Error', $error, 'SYSTEM', false);
                
                 $ost->logDebug('File Upload Error (Ticket #'.$this->getExtId().')', $error);
             }
@@ -1711,7 +1758,7 @@ class Ticket{
         if(!$vars['note'])
             $vars['note']=sprintf('Ticket Updated by %s', $thisstaff->getName());
 
-        $this->postNote('Ticket Updated', $vars['note']);
+        $this->postNote('Ticket Updated', $vars['note'], $thisstaff);
         $this->reload();
         
         return true;
@@ -2043,7 +2090,7 @@ class Ticket{
                     array(
                         'msgId'     => $msgid,
                         'response'  =>
-                            $ticket->replaceTemplateVars($canned->getResponse()),
+                            $ticket->replaceVars($canned->getResponse()),
                         'cannedattachments' => $files
                     ),$errors, true);
                     
@@ -2091,7 +2138,7 @@ class Ticket{
         
         // post response - if any
         if($vars['response']) {
-            $vars['response']=$ticket->replaceTemplateVars($vars['response']);
+            $vars['response'] = $ticket->replaceVars($vars['response']);
             if(($respId=$ticket->postReply($vars, $errors, false))) {
                 //Only state supported is closed on response
                 if(isset($vars['ticket_state']) && $thisstaff->canCloseTickets())
@@ -2100,16 +2147,16 @@ class Ticket{
         }
         //Post Internal note
         if($vars['assignId'] && $thisstaff->canAssignTickets()) { //Assign ticket to staff or team.
-            $ticket->assign($vars['assignId'],$vars['note']);
+            $ticket->assign($vars['assignId'], $vars['note']);
         } elseif($vars['note']) { //Not assigned...save optional note if any
-            $ticket->postNote('New Ticket',$vars['note'],false);
+            $ticket->postNote('New Ticket', $vars['note'], $thisstaff, false);
         } else { //Not assignment and no internal note - log activity
             $ticket->logActivity('New Ticket by Staff','Ticket created by staff -'.$thisstaff->getName());
         }
 
         $ticket->reload();
         
-        if(!$cfg->notifyONNewStaffTicket() || !isset($var['alertuser']))
+        if(!$cfg->notifyONNewStaffTicket() || !isset($vars['alertuser']))
             return $ticket; //No alerts.
 
         //Send Notice to user --- if requested AND enabled!!
@@ -2123,10 +2170,9 @@ class Ticket{
 
         if($tpl && ($msg=$tpl->getNewTicketNoticeMsgTemplate()) && $email) {
                         
-            $message =$vars['issue']."\n\n".$vars['response'];
-            $body=$ticket->replaceTemplateVars($msg['body']);
-            $subj=$ticket->replaceTemplateVars($msg['subj']);
-            $body = str_replace('%message',$message,$body);
+            $message = $vars['issue'];
+            if($vars['response'])
+                $message.="\n\n".$vars['response'];
 
             if($vars['signature']=='mine')
                 $signature=$thisstaff->getSignature();
@@ -2134,14 +2180,15 @@ class Ticket{
                 $signature=$dept->getSignature();
             else
                 $signature='';
-
-            $body = str_replace('%signature',$signature,$body);
+            
+            $msg = $ticket->replaceVars($msg, 
+                    array('message' => $message, 'signature' => $signature));
 
             if($cfg->stripQuotedReply() && ($tag=trim($cfg->getReplySeparator())))
-                $body ="\n$tag\n\n".$body;
+                $msg['body'] ="\n$tag\n\n".$msg['body'];
 
-            $attachments =($cfg->emailAttachments() && $respId)?$this->getAttachments($respId,'R'):array();
-            $email->send($ticket->getEmail(), $subj, $body, $attachments);
+            $attachments =($cfg->emailAttachments() && $respId)?$ticket->getAttachments($respId,'R'):array();
+            $email->send($ticket->getEmail(), $msg['subj'], $msg['body'], $attachments);
         }
 
         return $ticket;
diff --git a/include/class.topic.php b/include/class.topic.php
index c8e6a9e72b9a8d26da82e97f48cfc9f25e97d51c..900ff76168363c47e9b4763fee6cf2f00334a0fd 100644
--- a/include/class.topic.php
+++ b/include/class.topic.php
@@ -48,6 +48,10 @@ class Topic {
     function reload() {
         return $this->load();
     }
+
+    function asVar() {
+        return $this->getName();
+    }
     
     function getId() {
         return $this->id;
diff --git a/include/class.variable.php b/include/class.variable.php
new file mode 100644
index 0000000000000000000000000000000000000000..f83ba61be9063d385943b4fe4f4fdc751a58f422
--- /dev/null
+++ b/include/class.variable.php
@@ -0,0 +1,147 @@
+<?php
+/*********************************************************************
+    class.variable.php
+
+    Variable replacer 
+    
+    Used to parse, resolve and replace variables.
+
+    Peter Rotich <peter@osticket.com>
+    Copyright (c)  2006-2012 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+**********************************************************************/
+
+class VariableReplacer {
+
+    var $start_delim;
+    var $end_delim;
+
+    var $objects;
+    var $variables;
+
+    var $errors;
+
+    function VariableReplacer($start_delim='%{', $end_delim='}') {
+
+        $this->start_delim = $start_delim;
+        $this->end_delim = $end_delim;
+
+        $this->objects = array();
+        $this->variables = array();
+    }
+
+    function setError($error) {
+        $this->errors[] = $error;
+    }
+
+    function getErrors() {
+        return $this->errors;
+    }
+    
+    function getObj($tag) {
+        return @$this->objects[$tag];
+    }
+
+    function assign($var, $val='') {
+        
+        if($val && is_object($val)) {
+            $this->objects[$var] = $val;
+        } elseif($var && is_array($var)) {
+            foreach($var as $k => $v) 
+                $this->assign($k, $v);
+        } elseif($var) {
+            $this->variables[$var] = $val;
+        }
+    }
+
+    function getVar($obj, $var) {
+
+        if(!$obj) return "";
+
+        if(!$var && is_callable(array($obj, 'asVar')))
+            return call_user_func(array($obj, 'asVar'));
+
+        list($v, $part) = explode('.', $var, 2);
+        if($v && is_callable(array($obj, 'get'.ucfirst($v)))) {
+            $rv = call_user_func(array($obj, 'get'.ucfirst($v)));
+            if(!$rv || !is_object($rv))
+                return $rv;
+
+            return $this->getVar($rv, $part);
+        }
+       
+        if(!$var || !is_callable(array($obj, 'getVar')))
+            return "";
+
+        $parts = explode('.', $var);
+        if(($rv = call_user_func(array($obj, 'getVar'), $parts[0]))===false)
+            return "";
+
+        if(!is_object($rv))
+            return $rv;
+            
+        list(, $part) = explode('.', $var, 2);
+        
+        return $this->getVar($rv, $part);
+    }
+
+    function replaceVars($input) {
+
+        if($input && is_array($input))
+            return array_map(array($this, 'replaceVars'), $input);
+
+        if(!($vars=$this->_parse($input)))
+            return $input;
+
+        return preg_replace($this->_delimit(array_keys($vars)), array_values($vars), $input);
+    }
+
+    function _resolveVar($var) {
+
+        //Variable already memoized?
+        if($var && @isset($this->variables[$var]))
+            return $this->variables[$var];
+
+        $parts = explode('.', $var, 2);
+        if($parts && ($obj=$this->getObj($parts[0])))
+            return $this->getVar($obj, $parts[1]);
+        elseif($parts[0] && @isset($this->variables[$parts[0]])) //root overwrite
+            return $this->variables[$parts[0]];
+
+        //Unknown object or variable - leavig it alone.
+        $this->setError('Unknown obj for "'.$var.'" tag ');
+        return false;
+    }
+
+    function _parse($text) {
+
+        $input = $text;
+        if(!preg_match_all('/'.$this->start_delim.'([A-Za-z_][\w._]+)'.$this->end_delim.'/', $input, $result))
+            return null;
+
+        $vars = array();
+        foreach($result[0] as $k => $v) {
+            if(isset($vars[$v])) continue;
+            $val=$this->_resolveVar($result[1][$k]);
+            if($val!==false)
+                $vars[$v] = $val;
+        }
+
+        return $vars;
+    }
+
+    //Helper function - will be replaced by a lambda function (PHP 5.3+)
+    function _delimit($val, $d='/') {
+
+        if($val && is_array($val))
+            return array_map(array($this, '_delimit'), $val);
+
+        return $d.$val.$d;
+    }
+}
+?>
diff --git a/include/upgrader/sql/15719536-dd0022fb.patch.sql b/include/upgrader/sql/15719536-dd0022fb.patch.sql
new file mode 100644
index 0000000000000000000000000000000000000000..5a44aa898bb9e88ca5c6cda017910f05bbb0e206
--- /dev/null
+++ b/include/upgrader/sql/15719536-dd0022fb.patch.sql
@@ -0,0 +1,11 @@
+
+/**
+ * @version v1.7 RC2+
+ * @signature dd0022fb14892c0bb6a9700392df2de7
+ *
+ * Transitional patch - dev branch installations
+ *  
+ */
+
+UPDATE `%TABLE_PREFIX%config`
+    SET `schema_signature`='dd0022fb14892c0bb6a9700392df2de7';
diff --git a/include/upgrader/sql/dd0022fb-f4da0c9b.patch.sql b/include/upgrader/sql/dd0022fb-f4da0c9b.patch.sql
new file mode 100644
index 0000000000000000000000000000000000000000..c0f10cfa52ec2a8767109d12cfcdec38d9d13136
--- /dev/null
+++ b/include/upgrader/sql/dd0022fb-f4da0c9b.patch.sql
@@ -0,0 +1,445 @@
+/*
+ * @version=1.7RC2+
+ * 
+ * change variable names
+ */
+
+-- Canned Responses (with variables)
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%id', '%{ticket.id}');
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%ticket', '%{ticket.number}');
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%name', '%{ticket.name}');
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%email', '%{ticket.email}');
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%subject', '%{ticket.subject}');
+
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%status', '%{ticket.status}');
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%priority', '%{ticket.priority}');
+
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%auth', '%{ticket.auth_token}');
+
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%phone', '%{ticket.phone_number}');
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%createdate', '%{ticket.create_date}');
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%duedate', '%{ticket.due_date}');
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%closedate', '%{ticket.close_date}');
+
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%topic', '%{ticket.topic.name}');
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%dept', '%{ticket.dept.name}');
+UPDATE `%TABLE_PREFIX%canned_response` SET `response` = REPLACE(`response`, '%team', '%{ticket.team.name}');
+
+-- %id
+UPDATE `%TABLE_PREFIX%email_template` 
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%id', '%{ticket.id}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%id', '%{ticket.id}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%id', '%{ticket.id}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%id', '%{ticket.id}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%id', '%{ticket.id}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%id', '%{ticket.id}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%id', '%{ticket.id}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%id', '%{ticket.id}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%id', '%{ticket.id}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%id', '%{ticket.id}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%id', '%{ticket.id}');
+
+-- %ticket
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_subj` = REPLACE(`ticket_autoresp_subj`, '%ticket', '%{ticket.number}'),
+        `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%ticket', '%{ticket.number}'),
+        `message_autoresp_subj` = REPLACE(`message_autoresp_subj`, '%ticket', '%{ticket.number}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%ticket', '%{ticket.number}'),
+        `ticket_notice_subj` = REPLACE(`ticket_notice_subj`, '%ticket', '%{ticket.number}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%ticket', '%{ticket.number}'),
+        `ticket_overlimit_subj` = REPLACE(`ticket_overlimit_subj`, '%ticket', '%{ticket.number}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%ticket', '%{ticket.number}'),
+        `ticket_reply_subj` = REPLACE(`ticket_reply_subj`, '%ticket', '%{ticket.number}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%ticket', '%{ticket.number}'),
+        `ticket_alert_subj` = REPLACE(`ticket_alert_subj`, '%ticket', '%{ticket.number}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%ticket', '%{ticket.number}'),
+        `message_alert_subj` = REPLACE(`message_alert_subj`, '%ticket', '%{ticket.number}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%ticket', '%{ticket.number}'),
+        `note_alert_subj` = REPLACE(`note_alert_subj`, '%ticket', '%{ticket.number}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%ticket', '%{ticket.number}'),
+        `assigned_alert_subj` = REPLACE(`assigned_alert_subj`, '%ticket', '%{ticket.number}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%ticket', '%{ticket.number}'),
+        `transfer_alert_subj` = REPLACE(`transfer_alert_subj`, '%ticket', '%{ticket.number}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%ticket', '%{ticket.number}'),
+        `ticket_overdue_subj` = REPLACE(`ticket_overdue_subj`, '%ticket', '%{ticket.number}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%ticket', '%{ticket.number}');
+
+-- %subject
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_subj` = REPLACE(`ticket_autoresp_subj`, '%subject', '%{ticket.subject}'),
+        `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%subject', '%{ticket.subject}'),
+        `message_autoresp_subj` = REPLACE(`message_autoresp_subj`, '%subject', '%{ticket.subject}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%subject', '%{ticket.subject}'),
+        `ticket_notice_subj` = REPLACE(`ticket_notice_subj`, '%subject', '%{ticket.subject}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%subject', '%{ticket.subject}'),
+        `ticket_overlimit_subj` = REPLACE(`ticket_overlimit_subj`, '%subject', '%{ticket.subject}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%subject', '%{ticket.subject}'),
+        `ticket_reply_subj` = REPLACE(`ticket_reply_subj`, '%subject', '%{ticket.subject}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%subject', '%{ticket.subject}'),
+        `ticket_alert_subj` = REPLACE(`ticket_alert_subj`, '%subject', '%{ticket.subject}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%subject', '%{ticket.subject}'),
+        `message_alert_subj` = REPLACE(`message_alert_subj`, '%subject', '%{ticket.subject}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%subject', '%{ticket.subject}'),
+        `note_alert_subj` = REPLACE(`note_alert_subj`, '%subject', '%{ticket.subject}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%subject', '%{ticket.subject}'),
+        `assigned_alert_subj` = REPLACE(`assigned_alert_subj`, '%subject', '%{ticket.subject}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%subject', '%{ticket.subject}'),
+        `transfer_alert_subj` = REPLACE(`transfer_alert_subj`, '%subject', '%{ticket.subject}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%subject', '%{ticket.subject}'),
+        `ticket_overdue_subj` = REPLACE(`ticket_overdue_subj`, '%subject', '%{ticket.subject}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%subject', '%{ticket.subject}');
+
+-- %name
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_subj` = REPLACE(`ticket_autoresp_subj`, '%name', '%{ticket.name}'),
+        `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%name', '%{ticket.name}'),
+        `message_autoresp_subj` = REPLACE(`message_autoresp_subj`, '%name', '%{ticket.name}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%name', '%{ticket.name}'),
+        `ticket_notice_subj` = REPLACE(`ticket_notice_subj`, '%name', '%{ticket.name}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%name', '%{ticket.name}'),
+        `ticket_overlimit_subj` = REPLACE(`ticket_overlimit_subj`, '%name', '%{ticket.name}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%name', '%{ticket.name}'),
+        `ticket_reply_subj` = REPLACE(`ticket_reply_subj`, '%name', '%{ticket.name}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%name', '%{ticket.name}'),
+        `ticket_alert_subj` = REPLACE(`ticket_alert_subj`, '%name', '%{ticket.name}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%name', '%{ticket.name}'),
+        `message_alert_subj` = REPLACE(`message_alert_subj`, '%name', '%{ticket.name}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%name', '%{ticket.name}'),
+        `note_alert_subj` = REPLACE(`note_alert_subj`, '%name', '%{ticket.name}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%name', '%{ticket.name}'),
+        `assigned_alert_subj` = REPLACE(`assigned_alert_subj`, '%name', '%{ticket.name}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%name', '%{ticket.name}'),
+        `transfer_alert_subj` = REPLACE(`transfer_alert_subj`, '%name', '%{ticket.name}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%name', '%{ticket.name}'),
+        `ticket_overdue_subj` = REPLACE(`ticket_overdue_subj`, '%name', '%{ticket.name}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%name', '%{ticket.name}');
+
+-- %email
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_subj` = REPLACE(`ticket_autoresp_subj`, '%email', '%{ticket.email}'),
+        `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%email', '%{ticket.email}'),
+        `message_autoresp_subj` = REPLACE(`message_autoresp_subj`, '%email', '%{ticket.email}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%email', '%{ticket.email}'),
+        `ticket_notice_subj` = REPLACE(`ticket_notice_subj`, '%email', '%{ticket.email}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%email', '%{ticket.email}'),
+        `ticket_overlimit_subj` = REPLACE(`ticket_overlimit_subj`, '%email', '%{ticket.email}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%email', '%{ticket.email}'),
+        `ticket_reply_subj` = REPLACE(`ticket_reply_subj`, '%email', '%{ticket.email}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%email', '%{ticket.email}'),
+        `ticket_alert_subj` = REPLACE(`ticket_alert_subj`, '%email', '%{ticket.email}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%email', '%{ticket.email}'),
+        `message_alert_subj` = REPLACE(`message_alert_subj`, '%email', '%{ticket.email}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%email', '%{ticket.email}'),
+        `note_alert_subj` = REPLACE(`note_alert_subj`, '%email', '%{ticket.email}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%email', '%{ticket.email}'),
+        `assigned_alert_subj` = REPLACE(`assigned_alert_subj`, '%email', '%{ticket.email}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%email', '%{ticket.email}'),
+        `transfer_alert_subj` = REPLACE(`transfer_alert_subj`, '%email', '%{ticket.email}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%email', '%{ticket.email}'),
+        `ticket_overdue_subj` = REPLACE(`ticket_overdue_subj`, '%email', '%{ticket.email}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%email', '%{ticket.email}');
+
+-- %status
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_subj` = REPLACE(`ticket_autoresp_subj`, '%status', '%{ticket.status}'),
+        `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%status', '%{ticket.status}'),
+        `message_autoresp_subj` = REPLACE(`message_autoresp_subj`, '%status', '%{ticket.status}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%status', '%{ticket.status}'),
+        `ticket_notice_subj` = REPLACE(`ticket_notice_subj`, '%status', '%{ticket.status}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%status', '%{ticket.status}'),
+        `ticket_overlimit_subj` = REPLACE(`ticket_overlimit_subj`, '%status', '%{ticket.status}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%status', '%{ticket.status}'),
+        `ticket_reply_subj` = REPLACE(`ticket_reply_subj`, '%status', '%{ticket.status}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%status', '%{ticket.status}'),
+        `ticket_alert_subj` = REPLACE(`ticket_alert_subj`, '%status', '%{ticket.status}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%status', '%{ticket.status}'),
+        `message_alert_subj` = REPLACE(`message_alert_subj`, '%status', '%{ticket.status}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%status', '%{ticket.status}'),
+        `note_alert_subj` = REPLACE(`note_alert_subj`, '%status', '%{ticket.status}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%status', '%{ticket.status}'),
+        `assigned_alert_subj` = REPLACE(`assigned_alert_subj`, '%status', '%{ticket.status}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%status', '%{ticket.status}'),
+        `transfer_alert_subj` = REPLACE(`transfer_alert_subj`, '%status', '%{ticket.status}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%status', '%{ticket.status}'),
+        `ticket_overdue_subj` = REPLACE(`ticket_overdue_subj`, '%status', '%{ticket.status}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%status', '%{ticket.status}');
+
+-- %priority
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_subj` = REPLACE(`ticket_autoresp_subj`, '%priority', '%{ticket.priority}'),
+        `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%priority', '%{ticket.priority}'),
+        `message_autoresp_subj` = REPLACE(`message_autoresp_subj`, '%priority', '%{ticket.priority}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%priority', '%{ticket.priority}'),
+        `ticket_notice_subj` = REPLACE(`ticket_notice_subj`, '%priority', '%{ticket.priority}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%priority', '%{ticket.priority}'),
+        `ticket_overlimit_subj` = REPLACE(`ticket_overlimit_subj`, '%priority', '%{ticket.priority}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%priority', '%{ticket.priority}'),
+        `ticket_reply_subj` = REPLACE(`ticket_reply_subj`, '%priority', '%{ticket.priority}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%priority', '%{ticket.priority}'),
+        `ticket_alert_subj` = REPLACE(`ticket_alert_subj`, '%priority', '%{ticket.priority}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%priority', '%{ticket.priority}'),
+        `message_alert_subj` = REPLACE(`message_alert_subj`, '%priority', '%{ticket.priority}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%priority', '%{ticket.priority}'),
+        `note_alert_subj` = REPLACE(`note_alert_subj`, '%priority', '%{ticket.priority}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%priority', '%{ticket.priority}'),
+        `assigned_alert_subj` = REPLACE(`assigned_alert_subj`, '%priority', '%{ticket.priority}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%priority', '%{ticket.priority}'),
+        `transfer_alert_subj` = REPLACE(`transfer_alert_subj`, '%priority', '%{ticket.priority}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%priority', '%{ticket.priority}'),
+        `ticket_overdue_subj` = REPLACE(`ticket_overdue_subj`, '%priority', '%{ticket.priority}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%priority', '%{ticket.priority}');
+
+-- %auth
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%auth', '%{ticket.auth_code}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%auth', '%{ticket.auth_code}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%auth', '%{ticket.auth_code}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%auth', '%{ticket.auth_code}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%auth', '%{ticket.auth_code}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%auth', '%{ticket.auth_code}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%auth', '%{ticket.auth_code}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%auth', '%{ticket.auth_code}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%auth', '%{ticket.auth_code}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%auth', '%{ticket.auth_code}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%auth', '%{ticket.auth_code}');
+
+-- %phone
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%phone', '%{ticket.phone_number}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%phone', '%{ticket.phone_number}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%phone', '%{ticket.phone_number}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%phone', '%{ticket.phone_number}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%phone', '%{ticket.phone_number}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%phone', '%{ticket.phone_number}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%phone', '%{ticket.phone_number}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%phone', '%{ticket.phone_number}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%phone', '%{ticket.phone_number}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%phone', '%{ticket.phone_number}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%phone', '%{ticket.phone_number}');
+
+-- %createdate
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%createdate', '%{ticket.create_date}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%createdate', '%{ticket.create_date}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%createdate', '%{ticket.create_date}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%createdate', '%{ticket.create_date}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%createdate', '%{ticket.create_date}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%createdate', '%{ticket.create_date}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%createdate', '%{ticket.create_date}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%createdate', '%{ticket.create_date}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%createdate', '%{ticket.create_date}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%createdate', '%{ticket.create_date}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%createdate', '%{ticket.create_date}');
+
+-- %duedate
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%duedate', '%{ticket.due_date}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%duedate', '%{ticket.due_date}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%duedate', '%{ticket.due_date}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%duedate', '%{ticket.due_date}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%duedate', '%{ticket.due_date}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%duedate', '%{ticket.due_date}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%duedate', '%{ticket.due_date}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%duedate', '%{ticket.due_date}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%duedate', '%{ticket.due_date}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%duedate', '%{ticket.due_date}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%duedate', '%{ticket.due_date}');
+
+-- %closedate
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%closedate', '%{ticket.close_date}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%closedate', '%{ticket.close_date}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%closedate', '%{ticket.close_date}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%closedate', '%{ticket.close_date}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%closedate', '%{ticket.close_date}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%closedate', '%{ticket.close_date}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%closedate', '%{ticket.close_date}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%closedate', '%{ticket.close_date}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%closedate', '%{ticket.close_date}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%closedate', '%{ticket.close_date}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%closedate', '%{ticket.close_date}');
+
+-- %topic
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%topic', '%{ticket.topic.name}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%topic', '%{ticket.topic.name}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%topic', '%{ticket.topic.name}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%topic', '%{ticket.topic.name}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%topic', '%{ticket.topic.name}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%topic', '%{ticket.topic.name}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%topic', '%{ticket.topic.name}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%topic', '%{ticket.topic.name}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%topic', '%{ticket.topic.name}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%topic', '%{ticket.topic.name}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%topic', '%{ticket.topic.name}');
+
+-- %dept
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%dept', '%{ticket.dept.name}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%dept', '%{ticket.dept.name}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%dept', '%{ticket.dept.name}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%dept', '%{ticket.dept.name}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%dept', '%{ticket.dept.name}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%dept', '%{ticket.dept.name}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%dept', '%{ticket.dept.name}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%dept', '%{ticket.dept.name}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%dept', '%{ticket.dept.name}'),
+        `transfer_alert_subj` = REPLACE(`transfer_alert_subj`, '%dept', '%{ticket.dept.name}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%dept', '%{ticket.dept.name}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%dept', '%{ticket.dept.name}');
+
+-- %team
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%team', '%{ticket.team.name}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%team', '%{ticket.team.name}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%team', '%{ticket.team.name}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%team', '%{ticket.team.name}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%team', '%{ticket.team.name}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%team', '%{ticket.team.name}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%team', '%{ticket.team.name}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%team', '%{ticket.team.name}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%team', '%{ticket.team.name}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%team', '%{ticket.team.name}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%team', '%{ticket.team.name}');
+
+-- %clientlink
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%clientlink', '%{ticket.client_link}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%clientlink', '%{ticket.client_link}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%clientlink', '%{ticket.client_link}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%clientlink', '%{ticket.client_link}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%clientlink', '%{ticket.client_link}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%clientlink', '%{ticket.client_link}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%clientlink', '%{ticket.client_link}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%clientlink', '%{ticket.client_link}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%clientlink', '%{ticket.client_link}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%clientlink', '%{ticket.client_link}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%clientlink', '%{ticket.client_link}');
+
+-- %staff (recipient of the alert)
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%staff', '%{recipient}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%staff', '%{recipient}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%staff', '%{recipient}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%staff', '%{recipient}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%staff', '%{recipient}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%staff', '%{recipient}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%staff', '%{recipient}');
+
+-- %message 
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%message', '%{message}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%message', '%{message}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%message', '%{message}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%message', '%{message}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%message', '%{message}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%message', '%{message}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%message', '%{message}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%message', '%{message}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%message', '%{message}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%message', '%{message}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%message', '%{message}');
+
+-- %response
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%response', '%{response}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%response', '%{response}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%response', '%{response}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%response', '%{response}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%response', '%{response}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%response', '%{response}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%response', '%{response}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%response', '%{response}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%response', '%{response}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%response', '%{response}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%response', '%{response}');
+
+-- %note 
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `note_alert_body` = REPLACE(`note_alert_body`, '%note', '* %{note.title} *\r\n\r\n%{note.message}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%note', '%{comments}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%note', '%{comments}');
+
+-- %{note} (dev branch installations)
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `note_alert_body` = REPLACE(`note_alert_body`, '%{note}', '%{note.message}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%{note}', '%{comments}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%{note}', '%{comments}');
+
+-- %{title} (dev branch installations)
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `note_alert_body` = REPLACE(`note_alert_body`, '%{title}', '* %{note.title} *\r\n');
+
+-- %url
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%url', '%{url}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%url', '%{url}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%url', '%{url}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%url', '%{url}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%url', '%{url}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%url', '%{url}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%url', '%{url}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%url', '%{url}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%url', '%{url}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%url', '%{url}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%url', '%{url}');
+
+-- %signature
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%signature', '%{signature}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%signature', '%{signature}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%signature', '%{signature}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%signature', '%{signature}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%signature', '%{signature}'),
+        `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%signature', '%{signature}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%signature', '%{signature}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%signature', '%{signature}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%signature', '%{signature}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%signature', '%{signature}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%signature', '%{signature}');
+
+-- %assignee
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `assigned_alert_subj` = REPLACE(`assigned_alert_subj`, '%assignee', '%{assignee}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%assignee', '%{assignee}');
+
+-- %assigner
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `assigned_alert_subj` = REPLACE(`assigned_alert_subj`, '%assigner', '%{assigner}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%assigner', '%{assigner}');
+
+/* Change links */
+
+-- Client URL -> %{url}/view.php?e=%{ticket.email}&t=%{ticket.number}
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_autoresp_body` = REPLACE(`ticket_autoresp_body`, '%{url}/view.php?e=%{ticket.email}&t=%{ticket.number}', '%{ticket.client_link}'),
+        `message_autoresp_body` = REPLACE(`message_autoresp_body`, '%{url}/view.php?e=%{ticket.email}&t=%{ticket.number}', '%{ticket.client_link}'),
+        `ticket_notice_body` = REPLACE(`ticket_notice_body`, '%{url}/view.php?e=%{ticket.email}&t=%{ticket.number}', '%{ticket.client_link}'),
+        `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%{url}/view.php?e=%{ticket.email}&t=%{ticket.number}', '%{ticket.client_link}'),
+        `ticket_reply_body` = REPLACE(`ticket_reply_body`, '%{url}/view.php?e=%{ticket.email}&t=%{ticket.number}', '%{ticket.client_link}');
+
+-- Client URL -> %{url}/view.php?e=%{ticket.email} (overlimit template)
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_overlimit_body` = REPLACE(`ticket_overlimit_body`, '%{url}/view.php?e=%{ticket.email}', '%{url}/tickets.php?e=%{ticket.email}');
+
+-- Staff URL -> %{url}/scp/ticket.php?id=%{ticket.id} (should be tickets.php)
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%{url}/scp/ticket.php?id=%{ticket.id}', '%{ticket.staff_link}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%{url}/scp/ticket.php?id=%{ticket.id}', '%{ticket.staff_link}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%{url}/scp/ticket.php?id=%{ticket.id}', '%{ticket.staff_link}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%{url}/scp/ticket.php?id=%{ticket.id}', '%{ticket.staff_link}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%{url}/scp/ticket.php?id=%{ticket.id}', '%{ticket.staff_link}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%{url}/scp/ticket.php?id=%{ticket.id}', '%{ticket.staff_link}');
+
+-- Staff URL 2 -> %{url}/scp/tickets.php?id=%{ticket.id}
+UPDATE `%TABLE_PREFIX%email_template`
+    SET `ticket_alert_body` = REPLACE(`ticket_alert_body`, '%{url}/scp/tickets.php?id=%{ticket.id}', '%{ticket.staff_link}'),
+        `message_alert_body` = REPLACE(`message_alert_body`, '%{url}/scp/tickets.php?id=%{ticket.id}', '%{ticket.staff_link}'),
+        `note_alert_body` = REPLACE(`note_alert_body`, '%{url}/scp/tickets.php?id=%{ticket.id}', '%{ticket.staff_link}'),
+        `assigned_alert_body` = REPLACE(`assigned_alert_body`, '%{url}/scp/tickets.php?id=%{ticket.id}', '%{ticket.staff_link}'),
+        `transfer_alert_body` = REPLACE(`transfer_alert_body`, '%{url}/scp/tickets.php?id=%{ticket.id}', '%{ticket.staff_link}'),
+        `ticket_overdue_body` = REPLACE(`ticket_overdue_body`, '%{url}/scp/tickets.php?id=%{ticket.id}', '%{ticket.staff_link}');
+
+ -- update schema signature
+UPDATE `%TABLE_PREFIX%config`
+    SET `schema_signature`='f4da0c9befa257b5a20a923d4e9c0e91';
diff --git a/main.inc.php b/main.inc.php
index 235a6341a2db15e7be7b5c1e313e6b85e9b678f3..872f56758854a2d84ba78251dcce13c25cc00a42 100644
--- a/main.inc.php
+++ b/main.inc.php
@@ -63,7 +63,7 @@
 
     #Current version && schema signature (Changes from version to version)
     define('THIS_VERSION','1.7-RC2+'); //Shown on admin panel
-    define('SCHEMA_SIGNATURE','dd0022fb14892c0bb6a9700392df2de7'); //MD5 signature of the db schema. (used to trigger upgrades)
+    define('SCHEMA_SIGNATURE','f4da0c9befa257b5a20a923d4e9c0e91'); //MD5 signature of the db schema. (used to trigger upgrades)
     #load config info
     $configfile='';
     if(file_exists(ROOT_DIR.'ostconfig.php')) //Old installs prior to v 1.6 RC5
diff --git a/scp/autocron.php b/scp/autocron.php
index 08b65ba3481e65f99e6bb06567c3be46efb60631..4a3b00678539f628908743800177efc4097e54e1 100644
--- a/scp/autocron.php
+++ b/scp/autocron.php
@@ -30,13 +30,17 @@ ob_start(); //Keep the image output clean. Hide our dirt.
 //TODO: Make cron DB based to allow for better time limits. Direct calls for now sucks big time.
 //We DON'T want to spawn cron on every page load...we record the lastcroncall on the session per user
 $sec=time()-$_SESSION['lastcroncall'];
+$caller = $thisstaff->getUserName();
+
 if($sec>180): //user can call cron once every 3 minutes.
-require_once(INCLUDE_DIR.'class.cron.php');    
+require_once(INCLUDE_DIR.'class.cron.php');
+
+$thisstaff = null; //Clear staff obj to avoid false credit internal notes & auto-assignment
 Cron::TicketMonitor(); //Age tickets: We're going to age tickets regardless of cron settings. 
 if($cfg && $cfg->isAutoCronEnabled()) { //ONLY fetch tickets if autocron is enabled!
     Cron::MailFetcher();  //Fetch mail.
-    $ost->logDebug('Auto Cron', 'Mail fetcher cron call ['.$thisstaff->getUserName().']');
-} 
+    $ost->logDebug('Auto Cron', 'Mail fetcher cron call ['.$caller.']');
+}
 
 $_SESSION['lastcroncall']=time();
 endif;
diff --git a/scp/tickets.php b/scp/tickets.php
index 77eec14eab39caed7e1c235ffa079bdeaa658ace..9cc247cc68cf8aeed4530dfff6333ce5bf105921 100644
--- a/scp/tickets.php
+++ b/scp/tickets.php
@@ -81,13 +81,8 @@ if($_POST && !$errors):
                 elseif(strlen($_POST['transfer_message'])<5)
                     $errors['transfer_message'] = 'Transfer comments too short!';
 
-                $currentDept = $ticket->getDeptName(); //save current dept name.
                 if(!$errors && $ticket->transfer($_POST['deptId'], $_POST['transfer_message'])) {
                     $msg = 'Ticket transferred successfully to '.$ticket->getDeptName();
-                    //ticket->transfer does a reload...new dept at this point.
-                    $title='Dept. Transfer from '.$currentDept.' to '.$ticket->getDeptName();
-                    /*** log the message as internal note - with alerts disabled - ***/
-                    $ticket->postNote($title, $_POST['transfer_message'], false);
                     //Check to make sure the staff still has access to the ticket
                     if(!$ticket->checkStaffAccess($thisstaff))
                         $ticket=null;
@@ -140,7 +135,7 @@ if($_POST && !$errors):
             if(!Validator::process($fields, $_POST, $errors) && !$errors['err'])
                 $errors['err']=$errors['note']='Missing or invalid data. Correct the error(s) below and try again!';
             
-            if(!$errors && ($noteId=$ticket->postNote($_POST['title'], $_POST['internal_note']))) {
+            if(!$errors && ($noteId=$ticket->postNote($_POST['title'], $_POST['internal_note'], $thisstaff))) {
                 $msg='Internal note posted successfully';
                 //Upload attachments IF ANY - TODO: validate attachment types??
                 if($_FILES['attachments'] && ($files=Format::files($_FILES['attachments'])))
diff --git a/setup/inc/sql/osTicket-mysql.sql b/setup/inc/sql/osTicket-mysql.sql
index 53e3c551999567641bd33c71b7056f45de546c6c..ec886a23169af1a12164e6c78e58d8bde6f6af10 100644
--- a/setup/inc/sql/osTicket-mysql.sql
+++ b/setup/inc/sql/osTicket-mysql.sql
@@ -318,7 +318,7 @@ CREATE TABLE `%TABLE_PREFIX%email_template` (
 
 -- TODO: Dump revised copy before release!!!
 INSERT INTO `%TABLE_PREFIX%email_template` (`tpl_id`, `cfg_id`, `isactive`, `name`, `notes`, `ticket_autoresp_subj`, `ticket_autoresp_body`, `ticket_notice_subj`, `ticket_notice_body`, `ticket_alert_subj`, `ticket_alert_body`, `message_autoresp_subj`, `message_autoresp_body`, `message_alert_subj`, `message_alert_body`, `note_alert_subj`, `note_alert_body`, `assigned_alert_subj`, `assigned_alert_body`, `transfer_alert_subj`, `transfer_alert_body`, `ticket_overdue_subj`, `ticket_overdue_body`, `ticket_overlimit_subj`, `ticket_overlimit_body`, `ticket_reply_subj`, `ticket_reply_body`, `created`, `updated`) VALUES
-(1, 1, 1, 'osTicket Default Template', 'Default osTicket templates', 'Support Ticket Opened [#%ticket]', '%name,\r\n\r\nA request for support has been created and assigned ticket #%ticket. A representative will follow-up with you as soon as possible.\r\n\r\nYou can view this ticket''s progress online here: %url/view.php?e=%email&t=%ticket.\r\n\r\nIf you wish to send additional comments or information regarding this issue, please don''t open a new ticket. Simply login using the link above and update the ticket.\r\n\r\n%signature', '[#%ticket] %subject', '%name,\r\n\r\nOur customer care team has created a ticket, #%ticket on your behalf, with the following message.\r\n\r\n%message\r\n\r\nIf you wish to provide additional comments or information regarding this issue, please don''t open a new ticket. You can update or view this ticket''s progress online here: %url/view.php?e=%email&t=%ticket.\r\n\r\n%signature', 'New Ticket Alert', '%staff,\r\n\r\nNew ticket #%ticket created.\r\n-------------------\r\nName: %name\r\nEmail: %email\r\nDept: %dept\r\n\r\n%message\r\n-------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', '[#%ticket] Message Added', '%name,\r\n\r\nYour reply to support request #%ticket has been noted.\r\n\r\nYou can view this support request progress online here: %url/view.php?e=%email&t=%ticket.\r\n\r\n%signature', 'New Message Alert', '%staff,\r\n\r\nNew message appended to ticket #%ticket\r\n\r\n----------------------\r\nName: %name\r\nEmail: %email\r\nDept: %dept\r\n\r\n%message\r\n-------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', 'New Internal Note Alert', '%staff,\r\n\r\nInternal note appended to ticket #%ticket\r\n\r\n----------------------\r\nName: %name\r\n\r\n%note\r\n-------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', 'Ticket #%ticket Assigned to you', '%assignee,\r\n\r\n%assigner has assigned ticket #%ticket to you or one of your teams!\r\n\r\n%note\r\n\r\nTo view complete details, simply login to the support system.\r\n\r\n%url/scp/tickets.php?id=%id\r\n\r\n- Your friendly Support Ticket System - powered by osTicket.', 'Ticket Transfer #%ticket - %dept', '%staff,\r\n\r\nTicket #%ticket has been transferred to %dept department\r\n\r\n----------------------\r\n\r\n%note\r\n\r\n-------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%url/scp/ticket.php?id=%id\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', 'Stale Ticket Alert', '%staff,\r\n\r\nA ticket, #%ticket assigned to you or in your department is seriously overdue.\r\n\r\n%url/scp/tickets.php?id=%id\r\n\r\nWe should all work hard to guarantee that all tickets are being addressed in a timely manner. Enough baby talk...please address the issue or you will hear from me again.\r\n\r\n\r\n- Your friendly (although with limited patience) Support Ticket System - powered by osTicket.', 'Open Tickets Limit Reached', '%name\r\n\r\nYou have reached the maximum number of open tickets allowed.\r\n\r\nTo be able to open another ticket, one of your pending tickets must be closed. To update or add comments to an open ticket simply login using the link below.\r\n\r\n%url/view.php?e=%email\r\n\r\nThank you.\r\n\r\nSupport Ticket System', '[#%ticket] %subject', '%name,\r\n\r\nA customer support staff member has replied to your support request, #%ticket with the following response:\r\n\r\n%response\r\n\r\nWe hope this response has sufficiently answered your questions. If not, please do not send another email. Instead, reply to this email or login to your account for a complete archive of all your support requests and responses.\r\n\r\n%url/view.php?e=%email&t=%ticket\r\n\r\n%signature', '2011-08-05 17:00:03', '2012-03-19 01:44:54');
+(1, 1, 1, 'osTicket Default Template', 'Default osTicket templates', 'Support Ticket Opened [#%{ticket.number}]', '%{ticket.name},\r\n\r\nA request for support has been created and assigned ticket #%{ticket.number}. A representative will follow-up with you as soon as possible.\r\n\r\nYou can view this ticket''s progress online here: %{ticket.client_link}.\r\n\r\nIf you wish to send additional comments or information regarding this issue, please don''t open a new ticket. Simply login using the link above and update the ticket.\r\n\r\n%{signature}', '[#%{ticket.number}] %{ticket.subject}', '%{ticket.name},\r\n\r\nOur customer care team has created a ticket, #%{ticket.number} on your behalf, with the following message.\r\n\r\n%{message}\r\n\r\nIf you wish to provide additional comments or information regarding this issue, please don''t open a new ticket. You can update or view this ticket''s progress online here: %{ticket.client_link}.\r\n\r\n%{signature}', 'New Ticket Alert', '%{recipient},\r\n\r\nNew ticket #%{ticket.number} created.\r\n\r\n-----------------------\r\nName: %{ticket.name}\r\nEmail: %{ticket.email}\r\nDept: %{ticket.dept.name}\r\n\r\n%{message}\r\n-----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', '[#%{ticket.number}] Message Added', '%{ticket.name},\r\n\r\nYour reply to support request #%{ticket.number} has been noted.\r\n\r\nYou can view this support request progress online here: %{ticket.client_link}.\r\n\r\n%{signature}', 'New Message Alert', '%{recipient},\r\n\r\nNew message appended to ticket #%{ticket.number}\r\n\r\n----------------------\r\nName: %{ticket.name}\r\nEmail: %{ticket.email}\r\nDept: %{ticket.dept.name}\r\n\r\n%{message}\r\n----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', 'New Internal Note Alert', '%{recipient},\r\n\r\nInternal note appended to ticket #%{ticket.number}\r\n\r\n----------------------\r\n* %{note.title} *\r\n\r\n%{note.message}\r\n----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', 'Ticket #%{ticket.number} Assigned to you', '%{assignee},\r\n\r\nTicket #%{ticket.number} has been assigned to you by %{assigner}\r\n\r\n----------------------\r\n\r\n%{comments}\r\n\r\n----------------------\r\n\r\nTo view complete details, simply login to the support system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Support Ticket System - powered by osTicket.', 'Ticket Transfer #%{ticket.number} - %{ticket.dept.name}', '%{recipient},\r\n\r\nTicket #%{ticket.number} has been transferred to %{ticket.dept.name} department by %{staff.name}\r\n\r\n----------------------\r\n\r\n%{comments}\r\n\r\n----------------------\r\n\r\nTo view/respond to the ticket, please login to the support ticket system.\r\n\r\n%{ticket.staff_link}\r\n\r\n- Your friendly Customer Support System - powered by osTicket.', 'Stale Ticket Alert', '%{recipient},\r\n\r\nA ticket, #%{ticket.number} assigned to you or in your department is seriously overdue.\r\n\r\n%{ticket.staff_link}\r\n\r\nWe should all work hard to guarantee that all tickets are being addressed in a timely manner.\r\n\r\n- Your friendly (although with limited patience) Support Ticket System - powered by osTicket.', 'Open Tickets Limit Reached', '%{ticket.name}\r\n\r\nYou have reached the maximum number of open tickets allowed.\r\n\r\nTo be able to open another ticket, one of your pending tickets must be closed. To update or add comments to an open ticket simply login using the link below.\r\n\r\n%{url}/tickets.php?e=%{ticket.email}\r\n\r\nThank you.\r\n\r\nSupport Ticket System', '[#%{ticket.number}] %{ticket.subject}', '%{ticket.name},\r\n\r\nA customer support staff member has replied to your support request, #%{ticket.number} with the following response:\r\n\r\n%{response}\r\n\r\nWe hope this response has sufficiently answered your questions. If not, please do not send another email. Instead, reply to this email or login to your account for a complete archive of all your support requests and responses.\r\n\r\n%{ticket.client_link}\r\n\r\n%{signature}', NOW(), NOW());
 
 DROP TABLE IF EXISTS `%TABLE_PREFIX%file`;
 CREATE TABLE `%TABLE_PREFIX%file` (
@@ -431,7 +431,7 @@ CREATE TABLE `%TABLE_PREFIX%canned_response` (
 
 INSERT INTO `%TABLE_PREFIX%canned_response` (`canned_id`, `dept_id`, `isenabled`, `title`, `response`) VALUES
     (1, 0, 1, 'What is osTicket (sample)?', '\r\nosTicket is a widely-used open source support ticket system, an attractive alternative to higher-cost and complex customer support systems - simple, lightweight, reliable, open source, web-based and easy to setup and use.'),
-    (2, 0, 1, 'Sample (with variables)', '\r\n%name,\r\n\r\nYour ticket #%ticket created on %createdate is in %dept department.\r\n\r\n');
+    (2, 0, 1, 'Sample (with variables)', '\r\n%{ticket.name},\r\n\r\nYour ticket #%{ticket.number} created on %{ticket.create_date} is in %{ticket.dept.name} department.\r\n\r\n');
 
 DROP TABLE IF EXISTS `%TABLE_PREFIX%canned_attachment`;
 CREATE TABLE IF NOT EXISTS `%TABLE_PREFIX%canned_attachment` (
diff --git a/setup/inc/sql/osTicket-mysql.sql.md5 b/setup/inc/sql/osTicket-mysql.sql.md5
index e96b33654d6d528ac92f4613636491d6ffee3e0a..d6d0340e6558e27fc296c43407e88191f3430e99 100644
--- a/setup/inc/sql/osTicket-mysql.sql.md5
+++ b/setup/inc/sql/osTicket-mysql.sql.md5
@@ -1 +1 @@
-dd0022fb14892c0bb6a9700392df2de7
+f4da0c9befa257b5a20a923d4e9c0e91