diff --git a/include/class.mailer.php b/include/class.mailer.php
index 49b15ec285a0f84176cc5f235389e2dc970f51f2..ee22db849f18ff121bad2c9d84313fc3f088de5b 100644
--- a/include/class.mailer.php
+++ b/include/class.mailer.php
@@ -150,14 +150,27 @@ class Mailer {
         $thread = $entry ? $entry->getThread()
             : (isset($options['thread']) && $options['thread'] instanceof Thread
                 ? $options['thread'] : false);
+
+        switch (true) {
+        case $recipient instanceof Staff:
+            $utype = 'S';
+            break;
+        case $recipient instanceof TicketOwner:
+            $utype = 'U';
+            break;
+        case $recipient instanceof Collaborator:
+            $utype = 'C';
+            break;
+        default:
+            $utype = $options['utype'] ?: '?';
+        }
+
+
         $tag = pack('VVVa',
             $recipient instanceof EmailContact ? $recipient->getUserId() : 0,
             $entry ? $entry->getId() : 0,
             $thread ? $thread->getId() : 0,
-            ($recipient instanceof Staff ? 'S'
-                : ($recipient instanceof TicketOwner ? 'U'
-                : ($recipient instanceof Collaborator ? 'C'
-                : '?')))
+            $utype ?: '?'
         );
         // Sign the tag with the system secret salt
         $tag .= substr(hash_hmac('sha1', $tag.$rand.$sysid, SECRET_SALT, true), -5);
diff --git a/include/class.mailparse.php b/include/class.mailparse.php
index f530ac50bdafdfaa6f9bedf1c74c99c9096b4b49..1efd5a8b15fa48c88a9936172451840cffe72015 100644
--- a/include/class.mailparse.php
+++ b/include/class.mailparse.php
@@ -208,14 +208,14 @@ class Mail_Parse {
         if (!($header = $this->struct->headers['from']))
             return null;
 
-        return Mail_Parse::parseAddressList($header);
+        return Mail_Parse::parseAddressList($header, $this->charset);
     }
 
     function getDeliveredToAddressList() {
         if (!($header = $this->struct->headers['delivered-to']))
             return null;
 
-        return Mail_Parse::parseAddressList($header);
+        return Mail_Parse::parseAddressList($header, $this->charset);
     }
 
     function getToAddressList(){
@@ -223,7 +223,7 @@ class Mail_Parse {
         $tolist = array();
         if ($header = $this->struct->headers['to'])
             $tolist = array_merge($tolist,
-                Mail_Parse::parseAddressList($header));
+                Mail_Parse::parseAddressList($header, $this->charset));
         return $tolist ? $tolist : null;
     }
 
@@ -231,14 +231,14 @@ class Mail_Parse {
         if (!($header = @$this->struct->headers['cc']))
             return null;
 
-        return Mail_Parse::parseAddressList($header);
+        return Mail_Parse::parseAddressList($header, $this->charset);
     }
 
     function getBccAddressList(){
         if (!($header = @$this->struct->headers['bcc']))
             return null;
 
-        return Mail_Parse::parseAddressList($header);
+        return Mail_Parse::parseAddressList($header, $this->charset);
     }
 
     function getMessageId(){
@@ -258,7 +258,7 @@ class Mail_Parse {
         if (!($header = @$this->struct->headers['reply-to']))
             return null;
 
-        return Mail_Parse::parseAddressList($header);
+        return Mail_Parse::parseAddressList($header, $this->charset);
     }
 
     function isBounceNotice() {
@@ -543,7 +543,7 @@ class Mail_Parse {
     	return 0;
     }
 
-    function parseAddressList($address){
+    function parseAddressList($address, $charset='UTF-8'){
         if (!$address)
             return array();
 
@@ -558,11 +558,11 @@ class Mail_Parse {
 
         // Decode name and mailbox
         foreach ($parsed as $p) {
-            $p->personal = Format::mimedecode($p->personal, $this->charset);
+            $p->personal = Format::mimedecode($p->personal, $charset);
             // Some mail clients may send ISO-8859-1 strings without proper encoding.
             // Also, handle the more sane case where the mailbox is properly encoded
             // against RFC2047
-            $p->mailbox = Format::mimedecode($p->mailbox, $this->charset);
+            $p->mailbox = Format::mimedecode($p->mailbox, $charset);
         }
 
         return $parsed;
diff --git a/include/class.task.php b/include/class.task.php
index 55671d1af58b9ac43cb9939bd94ecaf5b95f8df7..f327a6cb1e39af0fe1f983b7299b4f578f6601db 100644
--- a/include/class.task.php
+++ b/include/class.task.php
@@ -1078,7 +1078,7 @@ class Task extends TaskModel implements RestrictedAccess, Threadable {
 
         // Who posted the entry?
         $skip = array();
-        if ($entry instanceof Message) {
+        if ($entry instanceof MessageThreadEntry) {
             $poster = $entry->getUser();
             // Skip the person who sent in the message
             $skip[$entry->getUserId()] = 1;
diff --git a/include/class.thread.php b/include/class.thread.php
index 5e3ef13a64659354c79778d54a1996d68d8d7cf9..aa78db5ddea37c73b32504fcf6231578f32e5fb4 100644
--- a/include/class.thread.php
+++ b/include/class.thread.php
@@ -348,7 +348,6 @@ class Thread extends VerySimpleModel {
             $vars['attachments'] = $mailinfo['attachments'];
 
         $body = $mailinfo['message'];
-        $poster = $mailinfo['email'];
 
         // Attempt to determine the user posting the entry and the
         // corresponding entry type by the information determined by the
@@ -403,6 +402,10 @@ class Thread extends VerySimpleModel {
             }
         }
 
+        // Ensure we record the name of the person posting
+        $vars['poster'] = $vars['poster']
+            ?: $mailinfo['name'] ?: $mailinfo['email'];
+
         // TODO: Consider security constraints
         if (!$vars['thread-type']) {
             //XXX: Are we potentially leaking the email address to
@@ -432,7 +435,6 @@ class Thread extends VerySimpleModel {
 
         case 'N':
             $vars['note'] = $body;
-            $vars['poster'] = $vars['poster'] ?: $poster;
 
             if ($object instanceof Threadable)
                 return $object->postThreadEntry('N', $vars);
@@ -1180,6 +1182,12 @@ implements TemplateVariable {
                 elseif (@$mid_info['staffId']) {
                     $mailinfo['staffId'] = $mid_info['staffId'];
                 }
+
+                // Capture the user type
+                if (@$mid_info['userClass'])
+                    $mailinfo['userClass'] = $mid_info['userClass'];
+
+
                 // ThreadEntry was positively identified
                 return $t;
             }
diff --git a/include/class.ticket.php b/include/class.ticket.php
index c93b9856ad462f002da8b07e85d832b91958d356..55e3f9fbbb1da0e82d2aecf0df3258ad6e4d96e3 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -1275,21 +1275,16 @@ implements RestrictedAccess, Threadable {
             if ($message instanceof ThreadEntry && $message->isAutoReply())
                 $sentlist[] = $this->getEmail();
 
-            // Alert admin??
-            if ($cfg->alertAdminONNewTicket()) {
-                $alert = $this->replaceVars($msg, array('recipient' => 'Admin'));
-                $email->sendAlert($cfg->getAdminEmail(), $alert['subj'], $alert['body'], null, $options);
-                $sentlist[]=$cfg->getAdminEmail();
-            }
-
             // Only alerts dept members if the ticket is NOT assigned.
             if ($cfg->alertDeptMembersONNewTicket() && !$this->isAssigned()) {
                 if ($members = $dept->getMembersForAlerts()->all())
                     $recipients = array_merge($recipients, $members);
             }
 
-            if ($cfg->alertDeptManagerONNewTicket() && $dept && ($manager=$dept->getManager()))
+            if ($cfg->alertDeptManagerONNewTicket() && $dept &&
+                    ($manager=$dept->getManager())) {
                 $recipients[] = $manager;
+            }
 
             // Account manager
             if ($cfg->alertAcctManagerONNewMessage()
@@ -1313,6 +1308,16 @@ implements RestrictedAccess, Threadable {
                 $email->sendAlert($staff, $alert['subj'], $alert['body'], null, $options);
                 $sentlist[] = $staff->getEmail();
             }
+
+            // Alert admin ONLY if not already a staff??
+            if ($cfg->alertAdminONNewTicket()
+                    && !in_array($cfg->getAdminEmail(), $sentlist)) {
+                $options += array('utype'=>'A');
+                $alert = $this->replaceVars($msg, array('recipient' => 'Admin'));
+                $email->sendAlert($cfg->getAdminEmail(), $alert['subj'],
+                        $alert['body'], null, $options);
+            }
+
         }
         return true;
     }
@@ -1388,7 +1393,7 @@ implements RestrictedAccess, Threadable {
         }
         // Who posted the entry?
         $skip = array();
-        if ($entry instanceof Message) {
+        if ($entry instanceof MessageThreadEntry) {
             $poster = $entry->getUser();
             // Skip the person who sent in the message
             $skip[$entry->getUserId()] = 1;
@@ -2478,7 +2483,10 @@ implements RestrictedAccess, Threadable {
         global $cfg, $thisstaff;
 
         //Who is posting the note - staff or system?
-        $vars['staffId'] = 0;
+        if ($vars['staffId'] && !$poster)
+            $poster = Staff::lookup($vars['staffId']);
+
+        $vars['staffId'] = $vars['staffId'] ?: 0;
         if ($poster && is_object($poster)) {
             $vars['staffId'] = $poster->getId();
             $vars['poster'] = $poster->getName();