diff --git a/include/class.email.php b/include/class.email.php
index e5ebabf40eb1c9a2f8c52ec5d0a6e8917b53737b..fc6f9f8f5535b4882b72b82107d90620960eb946 100644
--- a/include/class.email.php
+++ b/include/class.email.php
@@ -160,7 +160,7 @@ class Email {
     }
 
     function sendAlert($to, $subject, $message, $attachments=null, $options=array()) {
-        $options+= array('bulk' => true);
+        $options+= array('notice' => true);
         return $this->send($to, $subject, $message, $attachments, $options);
     }
 
diff --git a/include/class.format.php b/include/class.format.php
index ef56399d60424b871e6dab8eed87587a1ac7013b..5cbcd048e9a26527e97311790a653a18b1855952 100644
--- a/include/class.format.php
+++ b/include/class.format.php
@@ -30,10 +30,6 @@ class Format {
         return round(($bytes/1048576),1).' mb';
     }
 
-    function file_name($filename) {
-        return preg_replace('/\s+/', '_', $filename);
-    }
-
     /* encode text into desired encoding - taking into accout charset when available. */
     function encode($text, $charset=null, $encoding='utf-8') {
 
@@ -149,7 +145,7 @@ class Format {
 
         # See if advanced html2text is available (requires xml extension)
         if (function_exists('convert_html_to_text')
-                && extension_loaded('xml'))
+                && extension_loaded('dom'))
             return convert_html_to_text($html, $width);
 
         # Try simple html2text  - insert line breaks after new line tags.
@@ -313,23 +309,28 @@ class Format {
         $text = preg_replace_callback(':^[^<]+|>[^<]+:',
             function($match) use ($token) {
                 // Scan for things that look like URLs
-                $links = preg_replace_callback(
-                    '`(?<!>)(((f|ht)tp(s?)://|(?<!//)www\.)([a-zA-Z0-9_-]+(\.|/|$))+\S*)`',
+                return preg_replace_callback(
+                    '`(?<!>)(((f|ht)tp(s?)://|(?<!//)www\.)([-+~%/.\w]+)(?:[-?#+=&;%@.\w]*)?)'
+                   .'|(\b[_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,4})`',
                     function ($match) use ($token) {
-                        if (in_array(substr($match[1], -1),
-                                array(',','.','?','!',':',';'))) {
-                            $match[7] = substr($match[1], -1);
-                            $match[1] = substr($match[1], 0, strlen($match[1])-1);
+                        if ($match[1]) {
+                            while (in_array(substr($match[1], -1),
+                                    array('.','?','-',':',';'))) {
+                                $match[9] = substr($match[1], -1) . $match[9];
+                                $match[1] = substr($match[1], 0, strlen($match[1])-1);
+                            }
+                            if (strpos($match[2], '//') === false) {
+                                $match[1] = 'http://' . $match[1];
+                            }
+                            return '<a href="l.php?url='.urlencode($match[1])
+                                .sprintf('&auth=%s" target="_blank">', $token)
+                                .$match[1].'</a>'.$match[9];
+                        } elseif ($match[6]) {
+                            return sprintf('<a href="mailto:%1$s" target="_blank">%1$s</a>',
+                                $match[6]);
                         }
-                        return '<a href="l.php?url='.urlencode($match[1])
-                            .sprintf('&auth=%s" target="_blank">', $token)
-                            .$match[1].'</a>'.$match[7];
                     },
                     $match[0]);
-                // Now change email addresses to links with mailto: scheme
-                return preg_replace(
-                    '/(\b[_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,4})/',
-                    '<a href="mailto:\\1" target="_blank">\\1</a>', $links);
             },
             $text);
 
@@ -341,6 +342,7 @@ class Format {
                     'hr'=>1, 'img'=>1, 'input'=>1, 'isindex'=>1, 'param'=>1);
                 if ($e == 'a' && $a) {
                     if (isset($a['href'])
+                            && strpos($a['href'], 'mailto:') !== 0
                             && strpos($a['href'], 'l.php?') === false)
                         $a['href'] = 'l.php?url='.urlencode($a['href'])
                             .'&amp;auth='.$token;
@@ -380,10 +382,6 @@ class Format {
     }
 
 
-    function linebreaks($string) {
-        return urldecode(ereg_replace("%0D", " ", urlencode($string)));
-    }
-
     function viewableImages($html, $script='image.php') {
         return preg_replace_callback('/"cid:([\w.-_]{32})"/',
         function($match) use ($script) {
diff --git a/include/class.mailer.php b/include/class.mailer.php
index 2ad10dd5a2743936bb1cf5701f0f27422c38ae28..c80421fcb798e51b2aa7011c902e78f9d6e30615 100644
--- a/include/class.mailer.php
+++ b/include/class.mailer.php
@@ -113,19 +113,26 @@ class Mailer {
                 'Return-Path' => $this->getEmail()->getEmail(),
                );
 
-        //Set bulk/auto-response headers.
-        if($options && ($options['autoreply'] or $options['bulk'])) {
+
+        //Bulk.
+        if (isset($options['bulk']) && $options['bulk'])
+            $headers+= array('Precedence' => 'bulk');
+
+        //Auto-reply - mark as autoreply and supress all auto-replies
+        if (isset($options['autoreply']) && $options['autoreply']) {
             $headers+= array(
+                    'Precedence' => 'auto_reply',
                     'X-Autoreply' => 'yes',
-                    'X-Auto-Response-Suppress' => 'ALL, AutoReply',
+                    'X-Auto-Response-Suppress' => 'DR, RN, OOF, AutoReply',
                     'Auto-Submitted' => 'auto-replied');
-
-            if($options['bulk'])
-                $headers+= array('Precedence' => 'bulk');
-            else
-                $headers+= array('Precedence' => 'auto_reply');
         }
 
+        //Notice (sort of automated - but we don't want auto-replies back
+        if (isset($options['notice']) && $options['notice'])
+            $headers+= array(
+                    'X-Auto-Response-Suppress' => 'OOF, AutoReply',
+                    'Auto-Submitted' => 'auto-generated');
+
         if ($options) {
             if (isset($options['inreplyto']) && $options['inreplyto'])
                 $headers += array('In-Reply-To' => $options['inreplyto']);
diff --git a/include/htmLawed.php b/include/htmLawed.php
index 6d25f1f98a714269c3b65d87ca6f3dcb5db96dcb..9d0cc9e95e8210746f52933e0615eb2df29a7275 100644
--- a/include/htmLawed.php
+++ b/include/htmLawed.php
@@ -644,7 +644,7 @@ return '';
 function hl_tidy($t, $w, $p){
 // Tidy/compact HTM
 if(strpos(' pre,script,textarea', "$p,")){return $t;}
-$t = preg_replace('`\s+`', ' ', preg_replace_callback(array('`(<(!\[CDATA\[))(.+?)(\]\]>)`sm', '`(<(!--))(.+?)(-->)`sm', '`(<(pre|script|textarea)[^>]*?>)(.+?)(</\2>)`sm'), create_function('$m', 'return $m[1]. str_replace(array("<", ">", "\n", "\r", "\t", " "), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), $m[3]). $m[4];'), $t));
+$t = preg_replace('`[ \t\r\n\f]+`', ' ', preg_replace_callback(array('`(<(!\[CDATA\[))(.+?)(\]\]>)`sm', '`(<(!--))(.+?)(-->)`sm', '`(<(pre|script|textarea)[^>]*?>)(.+?)(</\2>)`sm'), create_function('$m', 'return $m[1]. str_replace(array("<", ">", "\n", "\r", "\t", " "), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), $m[3]). $m[4];'), $t));
 if(($w = strtolower($w)) == -1){
  return str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), array('<', '>', "\n", "\r", "\t", ' '), $t);
 }
diff --git a/include/html2text.php b/include/html2text.php
index 322342fe0325f3ea225d2a2dfbf209b68ec55a32..c4499761467e9d8a100dd9fb2302644cafb9bf2f 100644
--- a/include/html2text.php
+++ b/include/html2text.php
@@ -49,7 +49,7 @@ function convert_html_to_text($html, $width=74) {
         HtmlStylesheet::fromArray(array(
             'html' => array('white-space' => 'pre'), # Don't wrap footnotes
             'p' => array('margin-bottom' => '1em'),
-            'pre' => array('border-width' => '1em', 'white-space' => 'pre'),
+            'pre' => array('white-space' => 'pre'),
         ))
     );
     $options = array();
diff --git a/include/staff/system.inc.php b/include/staff/system.inc.php
index 9c45c3dabd873d6e5be5ec8ceb9a61d2dee71c90..6b59f0a08c13dd35cff13a7a22576aba6a81ae84 100644
--- a/include/staff/system.inc.php
+++ b/include/staff/system.inc.php
@@ -31,7 +31,11 @@ if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access
             <tr><td><i class="icon icon-<?php
                     echo extension_loaded('xml')?'check':'warning-sign'; ?>"></i></td>
                 <td>xml</td>
-                <td>Used for HTML email processing and XML API</td></tr>
+                <td>XML API</td></tr>
+            <tr><td><i class="icon icon-<?php
+                    echo extension_loaded('dom')?'check':'warning-sign'; ?>"></i></td>
+                <td>xml-dom</td>
+                <td>Used for HTML email processing</td></tr>
             <tr><td><i class="icon icon-<?php
                     echo extension_loaded('json')?'check':'warning-sign'; ?>"></i></td>
                 <td>json</td>
diff --git a/js/redactor-osticket.js b/js/redactor-osticket.js
index 337d525a5d1cbc5a85601313cf2e941b242d00d4..09629a041ad1e60d9a4f5988210aa56564aea6c2 100644
--- a/js/redactor-osticket.js
+++ b/js/redactor-osticket.js
@@ -126,8 +126,9 @@ $(function() {
             // TODO: Rewrite the entire <img> tag. Otherwise the @width
             // and @height attributes will begin to accumulate
             before = img.outerHTML;
-            $(img).attr('width', img.clientWidth)
-                  .attr('height',img.clientHeight);
+            if (img.clientWidth && img.clientHeight)
+                $(img).attr('width', img.clientWidth)
+                      .attr('height',img.clientHeight);
             html = html.replace(before, img.outerHTML);
         });
         // Drop <inline> elements if found in the text (shady mojo happening
diff --git a/setup/inc/install-prereq.inc.php b/setup/inc/install-prereq.inc.php
index 90e0f176ac0f0cb138b136a2e76ff16427f73898..a6c3340b5902ed979991404731a6ef33e0bc6009 100644
--- a/setup/inc/install-prereq.inc.php
+++ b/setup/inc/install-prereq.inc.php
@@ -24,7 +24,8 @@ if(!defined('SETUPINC')) die('Kwaheri!');
             <ul class="progress">
                 <li class="<?php echo extension_loaded('gd')?'yes':'no'; ?>">Gdlib extension</li>
                 <li class="<?php echo extension_loaded('imap')?'yes':'no'; ?>">PHP IMAP extension. <em>Required for mail fetching</em></li>
-                <li class="<?php echo extension_loaded('xml')?'yes':'no'; ?>">PHP XML extension (for HTML email processing, and XML API)</li>
+                <li class="<?php echo extension_loaded('xml') ?'yes':'no'; ?>">PHP XML extension (for XML API)</li>
+                <li class="<?php echo extension_loaded('dom') ?'yes':'no'; ?>">PHP XML-DOM extension (for HTML email processing)</li>
                 <li class="<?php echo extension_loaded('json')?'yes':'no'; ?>">PHP JSON extension (faster performance)</li>
                 <li class="<?php echo extension_loaded('gettext')?'yes':'no'; ?>">Gettext is used for translations (faster performance)</li>
                 <li class="<?php echo extension_loaded('mbstring')?'yes':'no'; ?>">Mbstring is <b>strongly</b> recommended for all installations</li>