diff --git a/include/class.config.php b/include/class.config.php
index e61c068140e396ed989afae21757797e90d7e714..9f4440314a9deaed31ea49cfa5d330d07ba29ec7 100644
--- a/include/class.config.php
+++ b/include/class.config.php
@@ -673,19 +673,20 @@ class OsticketConfig extends Config {
         return ($this->get('message_alert_acct_manager'));
     }
 
-    function alertONNewNote() {
+    //TODO: change note_alert to activity_alert
+    function alertONNewActivity() {
         return ($this->get('note_alert_active'));
     }
 
-    function alertLastRespondentONNewNote() {
+    function alertLastRespondentONNewActivity() {
         return ($this->get('note_alert_laststaff'));
     }
 
-    function alertAssignedONNewNote() {
+    function alertAssignedONNewActivity() {
         return ($this->get('note_alert_assigned'));
     }
 
-    function alertDeptManagerONNewNote() {
+    function alertDeptManagerONNewActivity() {
         return ($this->get('note_alert_dept_manager'));
     }
 
diff --git a/include/class.ticket.php b/include/class.ticket.php
index e7546870eba255341c0819fc8d2af7d98ac5c4eb..3b7ff8afa351a3ca406f707a7f540394d60d1a70 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -1080,9 +1080,15 @@ class Ticket {
         return true;
     }
 
-    function onResponse() {
+    function onResponse($response, $options=array()) {
         db_query('UPDATE '.TICKET_TABLE.' SET isanswered=1, lastresponse=NOW(), updated=NOW() WHERE ticket_id='.db_input($this->getId()));
         $this->reload();
+        $vars = array_merge($options,
+                array(
+                    'activity' => _S('New Response'),
+                    'threadentry' => $response));
+
+        $this->onActivity($vars);
     }
 
     /*
@@ -1199,6 +1205,85 @@ class Ticket {
         }
     }
 
+    function onActivity($vars, $alert=true) {
+        global $cfg, $thisstaff;
+
+        //TODO: do some shit
+
+        if (!$alert // Check if alert is enabled
+                || !$cfg->alertONNewActivity()
+                || !($dept=$this->getDept())
+                || !($email=$cfg->getAlertEmail())
+                || !($tpl = $dept->getTemplate())
+                || !($msg=$tpl->getNoteAlertMsgTemplate()))
+            return;
+
+        // Alert recipients
+        $recipients=array();
+
+        //Last respondent.
+        if ($cfg->alertLastRespondentONNewActivity())
+            $recipients[] = $this->getLastRespondent();
+
+        // Assigned staff / team
+        if ($cfg->alertAssignedONNewActivity()) {
+
+            if (isset($vars['assignee'])
+                    && $vars['assignee'] instanceof Staff)
+                 $recipients[] = $vars['assignee'];
+            elseif ($this->isOpen() && ($assignee = $this->getStaff()))
+                $recipients[] = $assignee;
+
+            if ($team = $this->getTeam())
+                $recipients = array_merge($recipients, $team->getMembers());
+        }
+
+        // Dept manager
+        if ($cfg->alertDeptManagerONNewActivity() && $dept && $dept->getManagerId())
+            $recipients[] = $dept->getManager();
+
+        $options = array();
+        $staffId = $thisstaff ? $thisstaff->getId() : 0;
+        if ($vars['threadentry'] && $vars['threadentry'] instanceof ThreadEntry) {
+            $options = array(
+                'inreplyto' => $vars['threadentry']->getEmailMessageId(),
+                'references' => $vars['threadentry']->getEmailReferences(),
+                'thread' => $vars['threadentry']);
+
+            // Activity details
+            if (!$vars['comments'])
+                $vars['comments'] = $vars['threadentry'];
+
+            // Staff doing the activity
+            $staffId = $vars['threadentry']->getStaffId() ?: $staffId;
+        }
+
+        $msg = $this->replaceVars($msg->asArray(),
+                array(
+                    'activity' => $vars['activity'],
+                    'comments' => $vars['comments']));
+
+        $isClosed = $this->isClosed();
+        $sentlist=array();
+        foreach ($recipients as $k=>$staff) {
+            if (!is_object($staff)
+                    // Don't bother vacationing staff.
+                    || !$staff->isAvailable()
+                    // No need to alert the poster!
+                    || $staffId == $staff->getId()
+                    // No duplicates.
+                    || isset($sentlist[$staff->getEmail()])
+                    // Make sure staff has access to ticket
+                    || ($isClosed && !$this->checkStaffAccess($staff))
+                    )
+                continue;
+            $alert = $this->replaceVars($msg, array('recipient' => $staff));
+            $email->sendAlert($staff, $alert['subj'], $alert['body'], null, $options);
+            $sentlist[$staff->getEmail()] = 1;
+        }
+
+    }
+
     function onAssign($assignee, $comments, $alert=true) {
         global $cfg, $thisstaff;
 
@@ -1826,6 +1911,7 @@ class Ticket {
         if(!($response = $this->getThread()->addResponse($vars, $errors)))
             return null;
 
+        $assignee = $this->getStaff();
         // Set status - if checked.
         if ($vars['reply_status_id']
                 && $vars['reply_status_id'] != $this->getStatusId())
@@ -1835,10 +1921,11 @@ class Ticket {
                 && $cfg->autoClaimTickets())
             $this->setStaffId($thisstaff->getId()); //direct assignment;
 
-        $this->onResponse(); //do house cleaning..
+
+        $this->onResponse($response, array('assignee' => $assignee)); //do house cleaning..
 
         /* email the user??  - if disabled - then bail out */
-        if(!$alert) return $response;
+        if (!$alert) return $response;
 
         $dept = $this->getDept();
 
@@ -1962,62 +2049,12 @@ class Ticket {
                 $this->reload();
         }
 
-        // If alerts are not enabled then return a success.
-        if(!$alert || !$cfg->alertONNewNote() || !($dept=$this->getDept()))
-            return $note;
-
-        if (($email = $dept->getAlertEmail())
-                && ($tpl = $dept->getTemplate())
-                && ($msg=$tpl->getNoteAlertMsgTemplate())) {
-
-            $msg = $this->replaceVars($msg->asArray(),
-                array('note' => $note));
-
-            // Alert recipients
-            $recipients=array();
-
-            //Last respondent.
-            if ($cfg->alertLastRespondentONNewNote())
-                $recipients[] = $this->getLastRespondent();
-
-            // Assigned staff / team
-            if ($cfg->alertAssignedONNewNote()) {
-
-                if ($assignee && $assignee instanceof Staff)
-                    $recipients[] = $assignee;
-
-                if ($team = $this->getTeam())
-                    $recipients = array_merge($recipients, $team->getMembers());
-            }
-
-            // Dept manager
-            if ($cfg->alertDeptManagerONNewNote() && $dept && $dept->getManagerId())
-                $recipients[] = $dept->getManager();
-
-            $options = array(
-                'inreplyto'=>$note->getEmailMessageId(),
-                'references'=>$note->getEmailReferences(),
-                'thread'=>$note);
-
-            $isClosed = $this->isClosed();
-            $sentlist=array();
-            foreach( $recipients as $k=>$staff) {
-                if(!is_object($staff)
-                        // Don't bother vacationing staff.
-                        || !$staff->isAvailable()
-                        // No duplicates.
-                        || isset($sentlist[$staff->getEmail()])
-                        // No need to alert the poster!
-                        || $note->getStaffId() == $staff->getId()
-                        // Make sure staff has access to ticket
-                        || ($isClosed && !$this->checkStaffAccess($staff))
-                        )
-                    continue;
-                $alert = $this->replaceVars($msg, array('recipient' => $staff));
-                $email->sendAlert($staff, $alert['subj'], $alert['body'], null, $options);
-                $sentlist[$staff->getEmail()] = 1;
-            }
-        }
+        $activity = $vars['activity'] ?: _S('New Internal Note');
+        $this->onActivity(array(
+            'activity' => $activity,
+            'threadentry' => $note,
+            'assignee' => $assignee
+        ), $alert);
 
         return $note;
     }
diff --git a/include/pear/Mail.php b/include/pear/Mail.php
index 75132ac2a6c3e9d99bd1784feb41154f0cd71d3d..5d4d3b09dd61c14a501cc52cb8d2f9f1499bb98a 100644
--- a/include/pear/Mail.php
+++ b/include/pear/Mail.php
@@ -74,14 +74,16 @@ class Mail
     function &factory($driver, $params = array())
     {
         $driver = strtolower($driver);
-        @include_once 'Mail/' . $driver . '.php';
         $class = 'Mail_' . $driver;
+        if (!class_exists($class))
+            include_once PEAR_DIR.'Mail/' . $driver . '.php';
+
         if (class_exists($class)) {
             $mailer = new $class($params);
             return $mailer;
-        } else {
-            return PEAR::raiseError('Unable to find class for driver ' . $driver);
         }
+
+        return PEAR::raiseError('Unable to find class for driver ' . $driver);
     }
 
     /**