diff --git a/include/class.mailparse.php b/include/class.mailparse.php
index 5b1a0271037fe473f760db7535e9c2f2277220de..dad841ffb1a5067c5e37ef4a42df5ff622ab0fc1 100644
--- a/include/class.mailparse.php
+++ b/include/class.mailparse.php
@@ -32,9 +32,9 @@ class Mail_Parse {
 
     var $tnef = false;      // TNEF encoded mail
 
-    function Mail_parse($mimeMessage, $charset=null){
+    function Mail_parse(&$mimeMessage, $charset=null){
 
-        $this->mime_message = $mimeMessage;
+        $this->mime_message = &$mimeMessage;
 
         if($charset)
             $this->charset = $charset;
@@ -54,18 +54,18 @@ class Mail_Parse {
 
         $params = array('crlf'          => "\r\n",
                         'charset'       => $this->charset,
-                        'input'         => $this->mime_message,
                         'include_bodies'=> $this->include_bodies,
                         'decode_headers'=> $this->decode_headers,
                         'decode_bodies' => $this->decode_bodies);
 
-        $this->struct=Mail_mimeDecode::decode($params);
+        $this->splitBodyHeader();
+
+        $decoder = new Mail_mimeDecode($this->mime_message);
+        $this->struct = $decoder->decode($params);
 
         if (PEAR::isError($this->struct))
             return false;
 
-        $this->splitBodyHeader();
-
         // Handle wrapped emails when forwarded
         if ($this->struct && $this->struct->parts) {
             $outer = $this->struct;
@@ -119,7 +119,7 @@ class Mail_Parse {
 
     function splitBodyHeader() {
         $match = array();
-        if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s",
+        if (preg_match("/^(.*?)\r?\n\r?\n./s",
                 $this->mime_message,
                 $match)) {
             $this->header=$match[1];
diff --git a/include/pear/Mail/mimeDecode.php b/include/pear/Mail/mimeDecode.php
index b300195824c30528f7ff44987679fd11875889e3..bc524f0cc2cbc8abd75d4c26dcb06201cbd1b98e 100644
--- a/include/pear/Mail/mimeDecode.php
+++ b/include/pear/Mail/mimeDecode.php
@@ -91,14 +91,6 @@ require_once 'PEAR.php';
  */
 class Mail_mimeDecode extends PEAR
 {
-    /**
-     * The raw email to decode
-     *
-     * @var    string
-     * @access private
-     */
-    var $_input;
-
     /**
      * The header part of the input
      *
@@ -157,13 +149,13 @@ class Mail_mimeDecode extends PEAR
      * @param string The input to decode
      * @access public
      */
-    function Mail_mimeDecode($input)
+    function Mail_mimeDecode(&$input)
     {
         list($header, $body)   = $this->_splitBodyHeader($input);
 
-        $this->_input          = $input;
-        $this->_header         = $header;
-        $this->_body           = $body;
+        $this->_input          = &$input;
+        $this->_header         = &$header;
+        $this->_body           = &$body;
         $this->_decode_bodies  = false;
         $this->_include_bodies = true;
     }
@@ -241,7 +233,7 @@ class Mail_mimeDecode extends PEAR
      * @return object Results of decoding process
      * @access private
      */
-    function _decode($headers, $body, $default_ctype = 'text/plain')
+    function _decode(&$headers, &$body, $default_ctype = 'text/plain')
     {
         $return = new stdClass;
         $return->headers = array();
@@ -324,8 +316,9 @@ class Mail_mimeDecode extends PEAR
                     $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain';
 
                     $parts = $this->_boundarySplit($body, $content_type['other']['boundary']);
-                    for ($i = 0; $i < count($parts); $i++) {
-                        list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]);
+                    while (count($parts)) {
+                        $part = array_shift($parts);
+                        list($part_header, $part_body) = $this->_splitBodyHeader($part);
                         $part = $this->_decode($part_header, $part_body, $default_ctype);
                         if($part === false)
                             $part = $this->raiseError($this->_error);
@@ -409,10 +402,18 @@ class Mail_mimeDecode extends PEAR
      * @return array Contains header and body section
      * @access private
      */
-    function _splitBodyHeader($input)
+    function _splitBodyHeader(&$input)
     {
-        if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) {
-            return array($match[1], $match[2]);
+        if ($input instanceof StringView)
+            $check = $input->substr(0, 64<<10);
+        else
+            $check = &$input;
+        if (preg_match("/^.*?(\r?\n\r?\n)(.)/s", $check, $match, PREG_OFFSET_CAPTURE)) {
+            $headers = ($input instanceof StringView)
+                ? (string) $input->substr(0, $match[1][1]) : substr($input, 0, $match[1][1]);
+            $body = ($input instanceof StringView)
+                ? $input->substr($match[2][1]) : new StringView($input, $match[2][1]);
+            return array($headers, $body);
         }
         $this->_error = 'Could not split header and body';
         return false;
@@ -524,6 +525,12 @@ class Mail_mimeDecode extends PEAR
             $boundary = $bs_possible;
         }
 
+        if ($input instanceof StringView) {
+            $parts = $input->split('--' . $boundary);
+            array_shift($parts);
+            return $parts;
+        }
+
         $tmp = explode('--' . $boundary, $input);
 
         for ($i = 1; $i < count($tmp) - 1; $i++) {
@@ -871,3 +878,51 @@ class Mail_mimeDecode extends PEAR
     }
 
 } // End of class
+
+class StringView {
+    var $string;
+    var $start;
+    var $end;
+
+    function __construct(&$string, $start=0, $end=false) {
+        $this->string = &$string;
+        $this->start = $start;
+        $this->end = $end;
+    }
+
+    function __toString() {
+        return $this->end
+            ? substr($this->string, $this->start, $this->end - $this->start)
+            : substr($this->string, $this->start);
+    }
+
+    function substr($start, $end=false) {
+        return new StringView($this->string, $this->start + $start,
+            $end ? min($this->start + $end, $this->end ?: PHP_INT_MAX) : $this->end);
+    }
+
+    function split($token) {
+        $ltoken = strlen($token);
+        $windows = array();
+        $offset = $this->start;
+        for ($i = 0;; $i++) {
+            $windows[$i] = array('start' => $offset);
+            $offset = strpos($this->string, $token, $offset);
+            if (!$offset || ($this->end && $offset >= $this->end))
+                break;
+
+            // Enforce local window
+            $windows[$i]['stop'] = min($this->end ?: $offset, $offset);
+            $offset += $ltoken;
+            if ($this->end && $offset > $this->end)
+                break;
+        }
+
+        $parts = array();
+        foreach ($windows as $w) {
+            $parts[] = new static($this->string, $w['start'], @$w['stop'] ?: false);
+        }
+        return $parts;
+
+    }
+}