diff -upN sites/all/modules/mimemail-head/LICENSE.txt sites/all/modules/mimemail/LICENSE.txt
--- sites/all/modules/mimemail-head/LICENSE.txt	2006-04-23 02:54:26.000000000 -0700
+++ sites/all/modules/mimemail/LICENSE.txt	1969-12-31 16:00:00.000000000 -0800
@@ -1,274 +0,0 @@
-GNU GENERAL PUBLIC LICENSE
-
-              Version 2, June 1991
-
-Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,
-Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute
-verbatim copies of this license document, but changing it is not allowed.
-
-                  Preamble
-
-The licenses for most software are designed to take away your freedom to
-share and change it. By contrast, the GNU General Public License is
-intended to guarantee your freedom to share and change free software--to
-make sure the software is free for all its users. This General Public License
-applies to most of the Free Software Foundation's software and to any other
-program whose authors commit to using it. (Some other Free Software
-Foundation software is covered by the GNU Library General Public License
-instead.) You can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the
-freedom to distribute copies of free software (and charge for this service if
-you wish), that you receive source code or can get it if you want it, that you
-can change the software or use pieces of it in new free programs; and that
-you know you can do these things.
-
-To protect your rights, we need to make restrictions that forbid anyone to
-deny you these rights or to ask you to surrender the rights. These restrictions
-translate to certain responsibilities for you if you distribute copies of the
-software, or if you modify it.
-
-For example, if you distribute copies of such a program, whether gratis or for
-a fee, you must give the recipients all the rights that you have. You must make
-sure that they, too, receive or can get the source code. And you must show
-them these terms so they know their rights.
-
-We protect your rights with two steps: (1) copyright the software, and (2)
-offer you this license which gives you legal permission to copy, distribute
-and/or modify the software.
-
-Also, for each author's protection and ours, we want to make certain that
-everyone understands that there is no warranty for this free software. If the
-software is modified by someone else and passed on, we want its recipients
-to know that what they have is not the original, so that any problems
-introduced by others will not reflect on the original authors' reputations.
-
-Finally, any free program is threatened constantly by software patents. We
-wish to avoid the danger that redistributors of a free program will individually
-obtain patent licenses, in effect making the program proprietary. To prevent
-this, we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
-           GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
-               MODIFICATION
-
-0. This License applies to any program or other work which contains a notice
-placed by the copyright holder saying it may be distributed under the terms
-of this General Public License. The "Program", below, refers to any such
-program or work, and a "work based on the Program" means either the
-Program or any derivative work under copyright law: that is to say, a work
-containing the Program or a portion of it, either verbatim or with
-modifications and/or translated into another language. (Hereinafter, translation
-is included without limitation in the term "modification".) Each licensee is
-addressed as "you".
-
-Activities other than copying, distribution and modification are not covered
-by this License; they are outside its scope. The act of running the Program is
-not restricted, and the output from the Program is covered only if its contents
-constitute a work based on the Program (independent of having been made
-by running the Program). Whether that is true depends on what the Program
-does.
-
-1. You may copy and distribute verbatim copies of the Program's source
-code as you receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice and
-disclaimer of warranty; keep intact all the notices that refer to this License
-and to the absence of any warranty; and give any other recipients of the
-Program a copy of this License along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and you
-may at your option offer warranty protection in exchange for a fee.
-
-2. You may modify your copy or copies of the Program or any portion of it,
-thus forming a work based on the Program, and copy and distribute such
-modifications or work under the terms of Section 1 above, provided that you
-also meet all of these conditions:
-
-a) You must cause the modified files to carry prominent notices stating that
-you changed the files and the date of any change.
-
-b) You must cause any work that you distribute or publish, that in whole or in
-part contains or is derived from the Program or any part thereof, to be
-licensed as a whole at no charge to all third parties under the terms of this
-License.
-
-c) If the modified program normally reads commands interactively when run,
-you must cause it, when started running for such interactive use in the most
-ordinary way, to print or display an announcement including an appropriate
-copyright notice and a notice that there is no warranty (or else, saying that
-you provide a warranty) and that users may redistribute the program under
-these conditions, and telling the user how to view a copy of this License.
-(Exception: if the Program itself is interactive but does not normally print such
-an announcement, your work based on the Program is not required to print
-an announcement.)
-
-These requirements apply to the modified work as a whole. If identifiable
-sections of that work are not derived from the Program, and can be
-reasonably considered independent and separate works in themselves, then
-this License, and its terms, do not apply to those sections when you distribute
-them as separate works. But when you distribute the same sections as part
-of a whole which is a work based on the Program, the distribution of the
-whole must be on the terms of this License, whose permissions for other
-licensees extend to the entire whole, and thus to each and every part
-regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest your rights to
-work written entirely by you; rather, the intent is to exercise the right to
-control the distribution of derivative or collective works based on the
-Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of a
-storage or distribution medium does not bring the other work under the scope
-of this License.
-
-3. You may copy and distribute the Program (or a work based on it, under
-Section 2) in object code or executable form under the terms of Sections 1
-and 2 above provided that you also do one of the following:
-
-a) Accompany it with the complete corresponding machine-readable source
-code, which must be distributed under the terms of Sections 1 and 2 above
-on a medium customarily used for software interchange; or,
-
-b) Accompany it with a written offer, valid for at least three years, to give
-any third party, for a charge no more than your cost of physically performing
-source distribution, a complete machine-readable copy of the corresponding
-source code, to be distributed under the terms of Sections 1 and 2 above on
-a medium customarily used for software interchange; or,
-
-c) Accompany it with the information you received as to the offer to distribute
-corresponding source code. (This alternative is allowed only for
-noncommercial distribution and only if you received the program in object
-code or executable form with such an offer, in accord with Subsection b
-above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source code
-means all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation and
-installation of the executable. However, as a special exception, the source
-code distributed need not include anything that is normally distributed (in
-either source or binary form) with the major components (compiler, kernel,
-and so on) of the operating system on which the executable runs, unless that
-component itself accompanies the executable.
-
-If distribution of executable or object code is made by offering access to
-copy from a designated place, then offering equivalent access to copy the
-source code from the same place counts as distribution of the source code,
-even though third parties are not compelled to copy the source along with the
-object code.
-
-4. You may not copy, modify, sublicense, or distribute the Program except as
-expressly provided under this License. Any attempt otherwise to copy,
-modify, sublicense or distribute the Program is void, and will automatically
-terminate your rights under this License. However, parties who have received
-copies, or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-5. You are not required to accept this License, since you have not signed it.
-However, nothing else grants you permission to modify or distribute the
-Program or its derivative works. These actions are prohibited by law if you
-do not accept this License. Therefore, by modifying or distributing the
-Program (or any work based on the Program), you indicate your acceptance
-of this License to do so, and all its terms and conditions for copying,
-distributing or modifying the Program or works based on it.
-
-6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the original
-licensor to copy, distribute or modify the Program subject to these terms and
-conditions. You may not impose any further restrictions on the recipients'
-exercise of the rights granted herein. You are not responsible for enforcing
-compliance by third parties to this License.
-
-7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues), conditions
-are imposed on you (whether by court order, agreement or otherwise) that
-contradict the conditions of this License, they do not excuse you from the
-conditions of this License. If you cannot distribute so as to satisfy
-simultaneously your obligations under this License and any other pertinent
-obligations, then as a consequence you may not distribute the Program at all.
-For example, if a patent license would not permit royalty-free redistribution
-of the Program by all those who receive copies directly or indirectly through
-you, then the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply and
-the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any patents or
-other property right claims or to contest validity of any such claims; this
-section has the sole purpose of protecting the integrity of the free software
-distribution system, which is implemented by public license practices. Many
-people have made generous contributions to the wide range of software
-distributed through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing to
-distribute software through any other system and a licensee cannot impose
-that choice.
-
-This section is intended to make thoroughly clear what is believed to be a
-consequence of the rest of this License.
-
-8. If the distribution and/or use of the Program is restricted in certain
-countries either by patents or by copyrighted interfaces, the original copyright
-holder who places the Program under this License may add an explicit
-geographical distribution limitation excluding those countries, so that
-distribution is permitted only in or among countries not thus excluded. In such
-case, this License incorporates the limitation as if written in the body of this
-License.
-
-9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will be
-similar in spirit to the present version, but may differ in detail to address new
-problems or concerns.
-
-Each version is given a distinguishing version number. If the Program specifies
-a version number of this License which applies to it and "any later version",
-you have the option of following the terms and conditions either of that
-version or of any later version published by the Free Software Foundation. If
-the Program does not specify a version number of this License, you may
-choose any version ever published by the Free Software Foundation.
-
-10. If you wish to incorporate parts of the Program into other free programs
-whose distribution conditions are different, write to the author to ask for
-permission. For software which is copyrighted by the Free Software
-Foundation, write to the Free Software Foundation; we sometimes make
-exceptions for this. Our decision will be guided by the two goals of
-preserving the free status of all derivatives of our free software and of
-promoting the sharing and reuse of software generally.
-
-               NO WARRANTY
-
-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE,
-THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT
-PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
-STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
-WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
-PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
-NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
-AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR
-ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
-LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
-SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
-ARISING OUT OF THE USE OR INABILITY TO USE THE
-PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
-OR DATA BEING RENDERED INACCURATE OR LOSSES
-SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
-PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN
-IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.
-
-          END OF TERMS AND CONDITIONS
diff -upN sites/all/modules/mimemail-head/README.txt sites/all/modules/mimemail/README.txt
--- sites/all/modules/mimemail-head/README.txt	2005-11-16 18:56:38.000000000 -0800
+++ sites/all/modules/mimemail/README.txt	2008-09-05 14:02:43.000000000 -0700
@@ -1,4 +1,4 @@
-$Id: README.txt,v 1.1 2005/11/17 02:56:38 vauxia Exp $
+$Id$
 
 INSTALLATION
 	Hopefully, you know the drill by now :)
diff -upN sites/all/modules/mimemail-head/html_to_text.inc sites/all/modules/mimemail/html_to_text.inc
--- sites/all/modules/mimemail-head/html_to_text.inc	1969-12-31 16:00:00.000000000 -0800
+++ sites/all/modules/mimemail/html_to_text.inc	2008-09-11 09:59:28.000000000 -0700
@@ -0,0 +1,369 @@
+<?php
+// $Id: mail.inc,v 1.1.2.1 2008/02/16 20:54:55 chx Exp $
+
+/**
+ * To generate this file from Drupal 6 mail.inc, delete mimemail_mail and
+ * mimemail_mail_send functions.
+ */
+
+/**
+ * Perform format=flowed soft wrapping for mail (RFC 3676).
+ *
+ * We use delsp=yes wrapping, but only break non-spaced languages when
+ * absolutely necessary to avoid compatibility issues.
+ *
+ * We deliberately use LF rather than CRLF, see mimemail_mail().
+ *
+ * @param $text
+ *   The plain text to process.
+ * @param $indent (optional)
+ *   A string to indent the text with. Only '>' characters are repeated on
+ *   subsequent wrapped lines. Others are replaced by spaces.
+ */
+function mimemail_wrap_mail($text, $indent = '') {
+  // Convert CRLF into LF.
+  $text = str_replace("\r", '', $text);
+  // See if soft-wrapping is allowed.
+  $clean_indent = _mimemail_html_to_text_clean($indent);
+  $soft = strpos($clean_indent, ' ') === FALSE;
+  // Check if the string has line breaks.
+  if (strpos($text, "\n") !== FALSE) {
+    // Remove trailing spaces to make existing breaks hard.
+    $text = preg_replace('/ +\n/m', "\n", $text);
+    // Wrap each line at the needed width.
+    $lines = explode("\n", $text);
+    array_walk($lines, '_mimemail_wrap_mail_line', array('soft' => $soft, 'length' => strlen($indent)));
+    $text = implode("\n", $lines);
+  }
+  else {
+    // Wrap this line.
+    _mimemail_wrap_mail_line($text, 0, array('soft' => $soft, 'length' => strlen($indent)));
+  }
+  // Empty lines with nothing but spaces.
+  $text = preg_replace('/^ +\n/m', "\n", $text);
+  // Space-stuff special lines.
+  $text = preg_replace('/^(>| |From)/m', ' $1', $text);
+  // Apply indentation. We only include non-'>' indentation on the first line.
+  $text = $indent . substr(preg_replace('/^/m', $clean_indent, $text), strlen($indent));
+
+  return $text;
+}
+
+/**
+ * Transform an HTML string into plain text, preserving the structure of the
+ * markup. Useful for preparing the body of a node to be sent by e-mail.
+ *
+ * The output will be suitable for use as 'format=flowed; delsp=yes' text
+ * (RFC 3676) and can be passed directly to mimemail_mail() for sending.
+ *
+ * We deliberately use LF rather than CRLF, see mimemail_mail().
+ *
+ * This function provides suitable alternatives for the following tags:
+ * <a> <em> <i> <strong> <b> <br> <p> <blockquote> <ul> <ol> <li> <dl> <dt>
+ * <dd> <h1> <h2> <h3> <h4> <h5> <h6> <hr>
+ *
+ * @param $string
+ *   The string to be transformed.
+ * @param $allowed_tags (optional)
+ *   If supplied, a list of tags that will be transformed. If omitted, all
+ *   all supported tags are transformed.
+ * @return
+ *   The transformed string.
+ */
+function mimemail_html_to_text($string, $allowed_tags = NULL) {
+  // Cache list of supported tags.
+  static $supported_tags;
+  if (empty($supported_tags)) {
+    $supported_tags = array('a', 'em', 'i', 'strong', 'b', 'br', 'p', 'blockquote', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr');
+  }
+
+  // Make sure only supported tags are kept.
+  $allowed_tags = isset($allowed_tags) ? array_intersect($supported_tags, $allowed_tags) : $supported_tags;
+
+  // Make sure tags, entities and attributes are well-formed and properly nested.
+  $string = _mimemail_filter_htmlcorrector(filter_xss($string, $allowed_tags));
+
+  // Apply inline styles.
+  $string = preg_replace('!</?(em|i)>!i', '/', $string);
+  $string = preg_replace('!</?(strong|b)>!i', '*', $string);
+
+  // Replace inline <a> tags with the text of link and a footnote.
+  // 'See <a href="http://mimemail.org">the Drupal site</a>' becomes
+  // 'See the Drupal site [1]' with the URL included as a footnote.
+  _mimemail_html_to_mail_urls(NULL, TRUE);
+  $pattern = '@(<a[^>]+?href="([^"]*)"[^>]*?>(.+?)</a>)@i';
+  $string = preg_replace_callback($pattern, '_mimemail_html_to_mail_urls', $string);
+  $urls = _mimemail_html_to_mail_urls();
+  $footnotes = '';
+  if (count($urls)) {
+    $footnotes .= "\n";
+    for ($i = 0, $max = count($urls); $i < $max; $i++) {
+      $footnotes .= '['. ($i + 1) .'] '. $urls[$i] ."\n";
+    }
+  }
+
+  // Split tags from text.
+  $split = preg_split('/<([^>]+?)>/', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
+  // Note: PHP ensures the array consists of alternating delimiters and literals
+  // and begins and ends with a literal (inserting $null as required).
+
+  $tag = FALSE; // Odd/even counter (tag or no tag)
+  $casing = NULL; // Case conversion function
+  $output = '';
+  $indent = array(); // All current indentation string chunks
+  $lists = array(); // Array of counters for opened lists
+  foreach ($split as $value) {
+    $chunk = NULL; // Holds a string ready to be formatted and output.
+
+    // Process HTML tags (but don't output any literally).
+    if ($tag) {
+      list($tagname) = explode(' ', strtolower($value), 2);
+      switch ($tagname) {
+        // List counters
+        case 'ul':
+          array_unshift($lists, '*');
+          break;
+        case 'ol':
+          array_unshift($lists, 1);
+          break;
+        case '/ul':
+        case '/ol':
+          array_shift($lists);
+          $chunk = ''; // Ensure blank new-line.
+          break;
+
+        // Quotation/list markers, non-fancy headers
+        case 'blockquote':
+          // Format=flowed indentation cannot be mixed with lists.
+          $indent[] = count($lists) ? ' "' : '>';
+          break;
+        case 'li':
+          $indent[] = is_numeric($lists[0]) ? ' '. $lists[0]++ .') ' : ' * ';
+          break;
+        case 'dd':
+          $indent[] = '    ';
+          break;
+        case 'h3':
+          $indent[] = '.... ';
+          break;
+        case 'h4':
+          $indent[] = '.. ';
+          break;
+        case '/blockquote':
+          if (count($lists)) {
+            // Append closing quote for inline quotes (immediately).
+            $output = rtrim($output, "> \n") ."\"\n";
+            $chunk = ''; // Ensure blank new-line.
+          }
+          // Fall-through
+        case '/li':
+        case '/dd':
+          array_pop($indent);
+          break;
+        case '/h3':
+        case '/h4':
+          array_pop($indent);
+        case '/h5':
+        case '/h6':
+          $chunk = ''; // Ensure blank new-line.
+          break;
+
+        // Fancy headers
+        case 'h1':
+          $indent[] = '======== ';
+          $casing = 'drupal_strtoupper';
+          break;
+        case 'h2':
+          $indent[] = '-------- ';
+          $casing = 'drupal_strtoupper';
+          break;
+        case '/h1':
+        case '/h2':
+          $casing = NULL;
+          // Pad the line with dashes.
+          $output = _mimemail_html_to_text_pad($output, ($tagname == '/h1') ? '=' : '-', ' ');
+          array_pop($indent);
+          $chunk = ''; // Ensure blank new-line.
+          break;
+
+        // Horizontal rulers
+        case 'hr':
+          // Insert immediately.
+          $output .= mimemail_wrap_mail('', implode('', $indent)) ."\n";
+          $output = _mimemail_html_to_text_pad($output, '-');
+          break;
+
+        // Paragraphs and definition lists
+        case '/p':
+        case '/dl':
+          $chunk = ''; // Ensure blank new-line.
+          break;
+      }
+    }
+    // Process blocks of text.
+    else {
+      // Convert inline HTML text to plain text.
+      $value = trim(preg_replace('/\s+/', ' ', decode_entities($value)));
+      if (strlen($value)) {
+        $chunk = $value;
+      }
+    }
+
+    // See if there is something waiting to be output.
+    if (isset($chunk)) {
+      // Apply any necessary case conversion.
+      if (isset($casing)) {
+        $chunk = $casing($chunk);
+      }
+      // Format it and apply the current indentation.
+      $output .= mimemail_wrap_mail($chunk, implode('', $indent)) ."\n";
+      // Remove non-quotation markers from indentation.
+      $indent = array_map('_mimemail_html_to_text_clean', $indent);
+    }
+
+    $tag = !$tag;
+  }
+
+  return $output . $footnotes;
+}
+
+/**
+ * Helper function for array_walk in mimemail_wrap_mail().
+ *
+ * Wraps words on a single line.
+ */
+function _mimemail_wrap_mail_line(&$line, $key, $values) {
+  // Use soft-breaks only for purely quoted or unindented text.
+  $line = wordwrap($line, 77 - $values['length'], $values['soft'] ? "  \n" : "\n");
+  // Break really long words at the maximum width allowed.
+  $line = wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n");
+}
+
+/**
+ * Helper function for mimemail_html_to_text().
+ *
+ * Keeps track of URLs and replaces them with placeholder tokens.
+ */
+function _mimemail_html_to_mail_urls($match = NULL, $reset = FALSE) {
+  global $base_url, $base_path;
+  static $urls = array(), $regexp;
+  
+  if ($reset) {
+    // Reset internal URL list.
+    $urls = array();
+  }
+  else {
+    if (empty($regexp)) {
+      $regexp = '@^'. preg_quote($base_path, '@') .'@';
+    }
+    if ($match) {
+      list(, , $url, $label) = $match;
+      // Ensure all URLs are absolute.
+      $urls[] = strpos($url, '://') ? $url : preg_replace($regexp, $base_url .'/', $url);
+      return $label .' ['. count($urls) .']';
+    }
+  }
+  return $urls;
+}
+
+/**
+ * Helper function for mimemail_wrap_mail() and mimemail_html_to_text().
+ *
+ * Replace all non-quotation markers from a given piece of indentation with spaces.
+ */
+function _mimemail_html_to_text_clean($indent) {
+  return preg_replace('/[^>]/', ' ', $indent);
+}
+
+/**
+ * Helper function for mimemail_html_to_text().
+ *
+ * Pad the last line with the given character.
+ */
+function _mimemail_html_to_text_pad($text, $pad, $prefix = '') {
+  // Remove last line break.
+  $text = substr($text, 0, -1);
+  // Calculate needed padding space and add it.
+  if (($p = strrpos($text, "\n")) === FALSE) {
+    $p = -1;
+  }
+  $n = max(0, 79 - (strlen($text) - $p));
+  // Add prefix and padding, and restore linebreak.
+  return $text . $prefix . str_repeat($pad, $n - strlen($prefix)) ."\n";
+}
+
+/**
+ * Scan input and make sure that all HTML tags are properly closed and nested.
+ *
+ * Copied from,Drupal 6 filter.module.
+ */
+function _mimemail_filter_htmlcorrector($text) {
+  // Prepare tag lists.
+  static $no_nesting, $single_use;
+  if (!isset($no_nesting)) {
+    // Tags which cannot be nested but are typically left unclosed.
+    $no_nesting = drupal_map_assoc(array('li', 'p'));
+
+    // Single use tags in HTML4
+    $single_use = drupal_map_assoc(array('base', 'meta', 'link', 'hr', 'br', 'param', 'img', 'area', 'input', 'col', 'frame'));
+  }
+
+  // Properly entify angles.
+  $text = preg_replace('!<([^a-zA-Z/])!', '&lt;\1', $text);
+
+  // Split tags from text.
+  $split = preg_split('/<([^>]+?)>/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
+  // Note: PHP ensures the array consists of alternating delimiters and literals
+  // and begins and ends with a literal (inserting $null as required).
+
+  $tag = false; // Odd/even counter. Tag or no tag.
+  $stack = array();
+  $output = '';
+  foreach ($split as $value) {
+    // Process HTML tags.
+    if ($tag) {
+      list($tagname) = explode(' ', strtolower($value), 2);
+      // Closing tag
+      if ($tagname{0} == '/') {
+        $tagname = substr($tagname, 1);
+        // Discard XHTML closing tags for single use tags.
+        if (!isset($single_use[$tagname])) {
+          // See if we possibly have a matching opening tag on the stack.
+          if (in_array($tagname, $stack)) {
+            // Close other tags lingering first.
+            do {
+              $output .= '</'. $stack[0] .'>';
+            } while (array_shift($stack) != $tagname);
+          }
+          // Otherwise, discard it.
+        }
+      }
+      // Opening tag
+      else {
+        // See if we have an identical 'no nesting' tag already open and close it if found.
+        if (count($stack) && ($stack[0] == $tagname) && isset($no_nesting[$stack[0]])) {
+          $output .= '</'. array_shift($stack) .'>';
+        }
+        // Push non-single-use tags onto the stack
+        if (!isset($single_use[$tagname])) {
+          array_unshift($stack, $tagname);
+        }
+        // Add trailing slash to single-use tags as per X(HT)ML.
+        else {
+          $value = rtrim($value, ' /') .' /';
+        }
+        $output .= '<'. $value .'>';
+      }
+    }
+    else {
+      // Passthrough all text.
+      $output .= $value;
+    }
+    $tag = !$tag;
+  }
+  // Close remaining tags.
+  while (count($stack) > 0) {
+    $output .= '</'. array_shift($stack) .'>';
+  }
+  return $output;
+}
diff -upN sites/all/modules/mimemail-head/mimemail.inc sites/all/modules/mimemail/mimemail.inc
--- sites/all/modules/mimemail-head/mimemail.inc	2008-02-17 16:43:36.000000000 -0800
+++ sites/all/modules/mimemail/mimemail.inc	2008-09-11 10:03:35.000000000 -0700
@@ -1,17 +1,19 @@
 <?php
-/* $Id: mimemail.inc,v 1.24 2008/02/18 00:43:36 vauxia Exp $ */
+/* $Id: mimemail.inc,v 1.28 2008/08/07 23:33:35 jerdavis Exp $ */
 
 /**
  * @file
- * Common mail functions for sending e-mail.  Originally written by Gerhard.  
- * 
+ * Common mail functions for sending e-mail.  Originally written by Gerhard.
+ *
  *   Allie Micka < allie at pajunas dot com >
  */
 
+include drupal_get_path('module', 'mimemail') . '/html_to_text.inc';
+
 /**
  * Attempts to RFC822-compliant headers for the mail message or its MIME parts
- * TODO could use some enhancement and stress testing 
- * 
+ * TODO could use some enhancement and stress testing
+ *
  * @param $headers An array of headers
  * @return header string
  */
@@ -22,15 +24,15 @@ function mimemail_rfc_headers($headers) 
     $key = trim($key);
     // collapse spaces and get rid of newline characters
     $value = preg_replace('/(\s+|\n|\r|^\s|\s$)/', ' ', $value);
-    
+
     //fold headers if they're too long
     if (strlen($value) > 60) {
       //if there's a semicolon, use that to separate
       if (count($array = preg_split('/;\s*/', $value)) > 1) {
         $value = trim(join(";$crlf    ", $array));
-      } 
+      }
       else {
-        $value = wordwrap($value, 50, "$crlf    ", false);
+        $value = wordwrap($value, 50, "$crlf    ", FALSE);
       }
     }
     $header .= "$key: $value$crlf";
@@ -44,7 +46,7 @@ function mimemail_rfc_headers($headers) 
  * @param $headers An array of headers
  * @return header string.
  */
-function mimemail_headers($headers, $from='') {
+function mimemail_headers($headers, $from = '') {
   // Note: This may not work. The MTA may rewrite the Return-Path, and Errors-To is deprecated.
   if (!$from) {
     $from = variable_get('site_mail', ini_get('sendmail_from'));
@@ -54,45 +56,13 @@ function mimemail_headers($headers, $fro
   // allow a mail to overwrite standard headers.
   $headers = array_merge(array('Return-Path' => "<$from_email>", 'Errors-To' => $from, 'From' => $from, 'Content-Type' => 'text/plain; charset=utf-8; format=flowed'), $headers);
 
-  return $headers;
-}
-
-/**
- * Converts html to utf-8 encoded text.
- *
- * @param $txt html text that needs formatting.
- * @param $inline Optional. If TRUE put links in the text, 
- *               if FALSE put a footnote into the text and
- *               a list of links below it. Default: FALSE
- *
- * @return formatted text encoded in utf-8
- */
-function mimemail_html_to_text($txt, $inline = FALSE) {
-  $pattern = '@(<a href="(.\S+?)"[^>]*>(.+?)</a>)@emi';
-  if ($inline) {
-    $txt = preg_replace($pattern, "_mimemail_uri('\\2', '\\3')", $txt);
-  }
-  else {
-    $txt = preg_replace($pattern, "'\\3 ['. _mimemail_urls('\\2') .']'", $txt);
-    $urls = _mimemail_urls();
-    if (count($urls)) {
-      $txt .= "\n";
-      $i = 0;
-      for ($max = count($urls); $i < $max; $i++) {
-        $url = preg_replace('/^mailto:(.+@.+)(\?.*)?/', '\1', $urls[$i]);
-        $txt .= '['. ($i + 1) .'] '. $url ."\n";
-      }
-    }
-    _mimemail_urls(0, TRUE);
+  // Run all headers through mime_header_encode() to convert non-ascii
+  // characters to an rfc compliant string, similar to drupal_mail().
+  foreach($headers as $key => $value) {
+    $headers[$key] = mime_header_encode($value);
   }
 
-  // some basic html to text conversion
-  $replace = _mimemail_html2text();
-  $txt = preg_replace(array_keys($replace), $replace, $txt);
-  $txt = preg_replace("/\n\s+\n/", "\n\n", $txt);
-  $txt = strip_tags($txt);
-  $txt = decode_entities($txt);
-  return wordwrap($txt, 80);
+  return $headers;
 }
 
 /**
@@ -110,7 +80,7 @@ function mimemail_html_to_text($txt, $in
  *                     'name' => file name,
  *                     'file' => reference to local file,
  *                     'Content-ID' => generated Content-ID,
- *                     'Content-Type' => derived using mime_content_type 
+ *                     'Content-Type' => derived using mime_content_type
  *                                       if available, educated guess otherwise
  *                     )
  *                  )
@@ -118,15 +88,15 @@ function mimemail_html_to_text($txt, $in
 function mimemail_extract_files($html) {
   $pattern = '/(<link[^>]+href="?|<object[^>]+codebase="?|@import |src="?)\/?([^"]+)("?)/emis';
   $html = preg_replace($pattern, '"\\1". _mimemail_file("\\2") ."\\3"', $html);
-  
+
   $document = array(array(
     'Content-Type' => "text/html; charset=utf-8",
     'Content-Transfer-Encoding' => 'base64',
     'content' => chunk_split(base64_encode($html)),
   ));
-  
+
   $files = _mimemail_file();
-  
+
   return array_merge($document, $files);
 }
 
@@ -137,13 +107,17 @@ function mimemail_extract_files($html) {
  *
  * @return an absolute :
  */
-function _mimemail_file($file = NULL, $type = '', $disposition = 'related') {
+function _mimemail_file($file = NULL, $name = '', $type = '', $disposition = 'related') {
   static $files = array();
 
   if ($file && !preg_match('@://|mailto:@', $file) && file_exists($file)) {
     $content_id = md5($file) .'@'. $_SERVER['HTTP_HOST'];
 
-    $new_file = array('name' => substr($file, strrpos($file, '/') + 1),
+    if (!$name) {
+      $name = substr($file, strrpos($file, '/') + 1);
+    }
+
+    $new_file = array('name' => $name,
       'file' => $file,
       'Content-ID' => $content_id,
       'Content-Disposition' => $disposition,
@@ -154,11 +128,11 @@ function _mimemail_file($file = NULL, $t
 
     return 'cid:'. $content_id;
   }
-  
+
   if ($file) {
     return $file;
   }
-  
+
   $ret = $files;
   $files = array();
   return $ret;
@@ -166,7 +140,7 @@ function _mimemail_file($file = NULL, $t
 
 /**
  *
- * @param $parts 
+ * @param $parts
  *        an array of parts to be included
  *        each part is itself an array:
  *        array(
@@ -195,39 +169,39 @@ function _mimemail_file($file = NULL, $t
  *     'body' is the mime encoded multipart body of a mail.
  *     'headers' is an array that includes some headers for the mail to be sent.
  */
-function mimemail_multipart_body($parts, $content_type = 'multipart/mixed; charset=utf-8', $sub_part=false) {
+function mimemail_multipart_body($parts, $content_type = 'multipart/mixed; charset=utf-8', $sub_part = FALSE) {
   $boundary = md5(uniqid(time()));
   $body = '';
   $headers = array(
     'Content-Type' => "$content_type; boundary=\"$boundary\"",
   );
   if (!$sub_part) {
-    $headers['MIME-Version'] = '1.0'; 
+    $headers['MIME-Version'] = '1.0';
     $body = "This is a multi-part message in MIME format.\n";
   }
 
   foreach ($parts as $part) {
     $part_headers = array();
-    
+
     if (isset($part['Content-ID'])) {
       $part_headers['Content-ID'] = '<'. $part['Content-ID'] .'>';
     }
-    
+
     if (isset($part['Content-Type'])) {
       $part_headers['Content-Type'] = $part['Content-Type'];
     }
-    
+
     if (isset($part['Content-Disposition'])) {
       $part_headers['Content-Disposition'] = $part['Content-Disposition'];
     }
-    else { 
+    else {
       $part_headers['Content-Disposition'] = 'inline';
     }
-    
+
     if ($part['Content-Transfer-Encoding']) {
       $part_headers['Content-Transfer-Encoding'] = $part['Content-Transfer-Encoding'];
     }
-    
+
     // mail content provided as a string
     if (isset($part['content']) && $part['content']) {
       if (!isset($part['Content-Transfer-Encoding'])) {
@@ -238,14 +212,14 @@ function mimemail_multipart_body($parts,
         $part_headers['Content-Type'] .= '; name="'. $part['name'] .'"';
         $part_headers['Content-Disposition'] .= '; filename="'. $part['name'] .'"';
       }
-      
+
     // mail content references in a filename
-    } 
+    }
     else {
       if (!isset($part['Content-Transfer-Encoding'])) {
         $part_headers['Content-Transfer-Encoding'] = 'base64';
       }
-      
+
       if (!isset($part['Content-Type'])) {
         $part['Content-Type'] = _mimemail_mimetype($part['file'], $type);
       }
@@ -254,10 +228,10 @@ function mimemail_multipart_body($parts,
         $part_headers['Content-Type'] .= '; name="'. $part['name'] .'"';
         $part_headers['Content-Disposition'] .= '; filename="'. $part['name'] .'"';
       }
-      
+
       $part_body = chunk_split(base64_encode(file_get_contents($part['file'])));
     }
-    
+
     $body .= "\n--$boundary\n";
     $body .= mimemail_rfc_headers($part_headers) ."\n\n";
     $body .= $part_body;
@@ -272,7 +246,7 @@ function mimemail_multipart_body($parts,
  * @param $body An HTML message body
  * @param $subject The message subject
  * @param $plaintext Whether the recipient prefers plaintext-only messages (default false)
- * 
+ *
  * @return
  *     an array containing the elements 'header' and 'body'.
  *     'body' is the mime encoded multipart body of a mail.
@@ -282,29 +256,39 @@ function mimemail_multipart_body($parts,
  * sub-parts for HTML and plaintext.  Each subsequent part is the required
  * image/attachment
  */
-function mimemail_html_body($body, $subject, $plaintext=false, $text=null, $attachments = array()) {
+function mimemail_html_body($body, $subject, $plaintext = FALSE, $text = NULL, $attachments = array()) {
   if (is_null($text)) {
     //generate plaintext alternative
     $text = mimemail_html_to_text($body);
   }
   if ($plaintext) {
-    return array(
-      'body' => $text, 
-      'headers' => array('Content-Type' => 'text/plain; charset=utf-8'),
-    );
+    //Plain mail without attachment
+    if (empty($attachments)) {
+      return array(
+        'body' => $text, 
+        'headers' => array('Content-Type' => 'text/plain; charset=utf-8'),
+      );
+    }
+    //Plain mail has attachement
+    else {
+      $parts = array(array(
+      'content' => $text, 
+        'Content-Type' => 'text/plain; charset=utf-8',
+      ));
+    }
   }
   $content_type = 'multipart/alternative';
 
   $text_part = array('Content-Type' => 'text/plain; charset=utf-8', 'content' => $text);
-  
+
   //expand all local links
   $pattern = '/(<a[^>]+href=")([^"]*)/emi';
   $body = preg_replace($pattern, '"\\1"._mimemail_url("\2")', $body);
-  
+
   $mime_parts = mimemail_extract_files($body);
 
-  $content = array($text_part, array_shift($mime_parts)); 
-  $content = mimemail_multipart_body($content, $content_type, true);
+  $content = array($text_part, array_shift($mime_parts));
+  $content = mimemail_multipart_body($content, $content_type, TRUE);
   $parts = array(array('Content-Type' => $content['headers']['Content-Type'], 'content' => $content['body']));
 
   if ($mime_parts) {
@@ -315,7 +299,7 @@ function mimemail_html_body($body, $subj
   foreach ($attachments as $a) {
     $a = (object) $a;
     $content_type = 'multipart/mixed';
-    _mimemail_file($a->filepath, $a->filemime, 'attachment');
+    _mimemail_file($a->filepath, $a->filename, $a->filemime, 'attachment');
     $parts = array_merge($parts, _mimemail_file());
   }
 
@@ -375,7 +359,7 @@ function mimemail_parse($message) {
 
   // Make sure our text and html parts are accounted for
   if (isset($mail['html']) && !isset($mail['text'])) {
-    $mail['text'] = mimemail_html_to_text($mail['html']);
+     $mail['text'] = mimemail_html_to_text($mail['html']);
   }
   elseif (isset($mail['text']) && !isset($mail['html'])) {
     $mail['html'] = check_markup($mail['text']);
@@ -505,27 +489,27 @@ function _mimemail_url($url) {
   if (strpos($url, '://')) {
     return $url;
   }
-  
+
   if (preg_match('!mailto:!i', $url)) {
     return $url;
   }
-  
+
   $url = preg_replace( '!'. base_path() .'!', '', $url, 1);
   $url = str_replace('?q=', '', $url);
   list($url, $fragment) = explode('#', $url, 2);
   list($path, $query) = explode('?', $url, 2);
 
   if (empty($path) && !empty($fragment)) {
-    return '#' . $fragment;
+    return '#'. $fragment;
   }
-  
-  return url($path, $query, $fragment, TRUE);
+
+  return url($path, array('query' => $query, 'fragment' => $fragment, 'absolute' => TRUE));
 }
 
 /**
  * Helper function to store processed urls.
  *
- * @param $url Optional. 
+ * @param $url Optional.
  * @param $refresh Optional. If TRUE refresh the cache.
  *
  * @return a count of stored if $url evaluates to false, the stored urls ortherwise.
@@ -545,74 +529,26 @@ function _mimemail_urls($url = 0, $refre
   return $urls;
 }
 
-function _mimemail_html2text() {
-  return array(
-    "/\r/"                              => '',
-    "/[\t]+/"                           => '  ',
-    '/<script[^>]*>.*?<\/script>/i'     => '',
-    '/<style[^>]*>.*?<\/style>/i'       => '',
-    '!<h1[^>]*>(.+?)</h1>!ie'           => "\"\n\" .strtoupper('\\1').\"\n============================================================\n\"",
-    '!<h2[^>]*>(.+?)</h2>!ie'           => "\"\n------------------------------------------------------------\n\" .'\\1'.\"\n------------------------------------------------------------\n\"",
-    '/<h3[^>]*>(.+?)<\/h3>/ie'          => "\"\n\n\\1\n\n\"",
-    '/<h[456][^>]*>(.+?)<\/h[456]>/ie'  => "\"\n\\1\n\"",
-    '!<blockquote[^>]*>!i'              => "\n\n\t",
-    '!</blockquote>!i'                  => "\n\n",
-    '!</?p[^>]*>!i'                     => "\n\n",
-    '/<br[^>]*>/i'                      => "\n",
-    '/(<(u|o|d)l[^>]*>|<\/(u|o|d)l>)/i' => "\n\n",
-    '!<(li|dt)[^>]*>!i'                 => "  * ",
-    '!<dd[^>]*>!i'                      => "    ",
-    '!</(li|dt|dd)>!i'                  => "\n",
-    '/<hr[^>]*>/i'                      => "\n-------------------------\n",
-    '/(<table[^>]*>|<\/table>)/i'       => "\n\n",
-    '/(<tr[^>]*>|<\/tr>)/i'             => "\n",
-    '/<td[^>]*>(.+?)<\/td>/i'           => "\t\t\\1\n",
-    '/<th[^>]*>(.+?)<\/th>/i'           => "\"\t\t\\1\n\"",
-    '/&nbsp;/i'                         => " ",
-    '/&quot;/i'                         => '"',
-    '/&gt;/i'                           => '>',
-    '/&lt;/i'                           => '<',
-    '/&amp;/i'                          => '&',
-    '/&copy;/i'                         => '(c)',
-    '/&trade;/i'                        => '(tm)',
-    '/&#8220;/'                         => '"',
-    '/&#8221;/'                         => '"',
-    '/&#8211;/'                         => '-',
-    '/&#8217;/'                         => "'",
-    '/&#38;/'                           => '&',
-    '/&#169;/'                          => '(c)',
-    '/&#8482;/'                         => '(tm)',
-    '/&#151;/'                          => '--',
-    '/&#145;/'                          => '\'',
-    '/&#147;/'                          => '"',
-    '/&#148;/'                          => '"',
-    '/&#149;/'                          => '*',
-    '/&reg;/i'                          => '(R)',
-    '/&bull;/i'                         => '*',
-    '/&[&;]+;/i'                        => '',
-  );
-}
-
 /**
- * Attempt to determine the mimetime from or filename .  While not ideal, 
+ * Attempt to determine the mimetime from or filename .  While not ideal,
  * using the filename as a fallback ensures that images will appear inline
  * in HTML messages
  *
  * @param $name Name of the file
- * 
+ *
  * @return best-guess mimetype string
  */
-function _mimemail_mimetype($file, $type='') {
+function _mimemail_mimetype($file, $type = '') {
   if ($type) {
     return $type;
-  } 
+  }
 
   if (function_exists('mime_content_type')) {
       return mime_content_type($file);
   }
 
   // some common embedded/attachment types
-  $types = array( 
+  $types = array(
     'jpg'  => 'image/jpeg',
     'jpeg' => 'image/jpeg',
     'gif'  => 'image/gif',
diff -upN sites/all/modules/mimemail-head/mimemail.info sites/all/modules/mimemail/mimemail.info
--- sites/all/modules/mimemail-head/mimemail.info	2008-03-01 04:05:26.000000000 -0800
+++ sites/all/modules/mimemail/mimemail.info	2008-09-05 14:05:39.000000000 -0700
@@ -1,10 +1,5 @@
-; $Id: mimemail.info,v 1.1 2007/01/05 05:44:09 vauxia Exp $
+; $Id$
 name = Mime Mail
 description = E-mail with HTML and attachments
 package = Mail
-
-; Information added by drupal.org packaging script on 2008-03-01
-version = "HEAD"
-project = "mimemail"
-datestamp = "1204373126"
-
+core = 6.x
\ No newline at end of file
diff -upN sites/all/modules/mimemail-head/mimemail.install sites/all/modules/mimemail/mimemail.install
--- sites/all/modules/mimemail-head/mimemail.install	1969-12-31 16:00:00.000000000 -0800
+++ sites/all/modules/mimemail/mimemail.install	2008-09-05 14:01:57.000000000 -0700
@@ -0,0 +1,19 @@
+<?php /* $Id$ */
+
+/**
+ * Implementation of hook_uninstall()
+ */
+function mimemail_uninstall() {
+  $variables = array(
+    'mimemail_alter',
+    'mimemail_crlf',
+    'mimemail_engine',
+    'mimemail_incoming',
+    'mimemail_key',
+    'mimemail_textonly',
+  );
+  foreach ($variables as $variable) {
+    variable_del($variable);
+  }
+}
+
diff -upN sites/all/modules/mimemail-head/mimemail.module sites/all/modules/mimemail/mimemail.module
--- sites/all/modules/mimemail-head/mimemail.module	2008-02-29 21:11:52.000000000 -0800
+++ sites/all/modules/mimemail/mimemail.module	2008-09-12 16:47:21.000000000 -0700
@@ -1,32 +1,36 @@
-<?php /* $Id: mimemail.module,v 1.24 2008/03/01 05:11:52 vauxia Exp $ */
+<?php /* $Id: mimemail.module,v 1.28 2008/08/09 00:53:14 jerdavis Exp $ */
 
 /**
- * @file Component module for sending Mime-encoded emails
- * 
+ * @file 
+ * Component module for sending Mime-encoded emails.
  */
  
 /**
  * Implementation of hook_menu()
  */
 function mimemail_menu() {
-  $items[] = array(
-    'path' => 'admin/settings/mimemail',
-    'title' => t('Mail'),
-    'description' => t('HTML E-mail settings'),
-    'callback' => 'drupal_get_form',
-    'callback arguments' => 'mimemail_settings',
-    'access' => user_access('administer site configuration'),
+  $items['admin/settings/mimemail'] = array(
+    'title' => 'Mime Mail',
+    'description' => 'HTML E-mail settings',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('mimemail_settings'),
+    'access arguments' => array('administer site configuration'),
     'type' => MENU_NORMAL_ITEM,
   );
-  $items[] = array(
-    'path' => 'mimemail',
-    'callback' => 'mimemail_post',
-    'access' => variable_get('mimemail_incoming', FALSE),
+  $items['mimemail'] = array(
+    'page callback' => 'mimemail_post',
+    'access callback' => variable_get('mimemail_incoming', FALSE),
     'type' => MENU_CALLBACK,
   );
   return $items;
 }
 
+/**
+ * Administration settings.
+ *
+ * @return
+ *   The administration from.
+ */
 function mimemail_settings() {
 
   // override the smtp_library value if mimemail is chosen to handle all mail
@@ -43,14 +47,14 @@ function mimemail_settings() {
   }
 
   $engines = mimemail_get_engines();
-  
+
   $form = array();
   $form['site_mail'] = array(
-    '#type'          => 'textfield', 
-    '#title'         => t('E-mail address'), 
-    '#default_value' => variable_get('site_mail', ini_get('sendmail_from')), 
-    '#size'          => 60, 
-    '#maxlength'     => 128, 
+    '#type'          => 'textfield',
+    '#title'         => t('E-mail address'),
+    '#default_value' => variable_get('site_mail', ini_get('sendmail_from')),
+    '#size'          => 60,
+    '#maxlength'     => 128,
     '#description'   => t('A valid e-mail address for this website, used by the auto-mailer during registration, new password requests, notifications, etc.')
   );
   $form['mimemail']['mimemail_alter'] = array(
@@ -59,6 +63,10 @@ function mimemail_settings() {
     '#default_value' => variable_get('mimemail_alter', 0),
     '#description'   => t('Use the mime mail module to deliver all site messages.  With this option, system emails will have styles and formatting'),
   );
+
+  $filter_format = variable_get('mimemail_format', FILTER_FORMAT_DEFAULT);
+  $form['mimemail']['mimemail_format'] =  filter_form($filter_format, NULL, array("mimemail_format"));
+
   $form['mimemail']['mimemail_textonly'] = array(
     '#type'          => 'checkbox',
     '#title'         => t('Plaintext email only'),
@@ -85,24 +93,24 @@ function mimemail_settings() {
     '#required'      => TRUE,
     '#description'   => t('This string will be used to validate incoming messages.  It can be anything, but must be used on both sides of the transfer'),
   );
-  
+
   // hide the settings if only 1 engine is available
   if (count($engines) == 1) {
     variable_set('mimemail_engine', key($engines));
     $form['mimemail_engine'] = array(
         '#type'          => 'hidden',
-        '#title'         => t('E-mail engine'), 
-        '#default_value' => variable_get('mimemail_engine', 'mail'), 
-        '#options'       => $engines, 
+        '#title'         => t('E-mail engine'),
+        '#default_value' => variable_get('mimemail_engine', 'mail'),
+        '#options'       => $engines,
         '#description'   => t('Choose an e-mail engine for sending mails from your site.')
     );
   }
   else {
     $form['mimemail_engine'] = array(
         '#type'          => 'select',
-        '#title'         => t('E-mail engine'), 
-        '#default_value' => variable_get('mimemail_engine', 'mail'), 
-        '#options'       => $engines, 
+        '#title'         => t('E-mail engine'),
+        '#default_value' => variable_get('mimemail_engine', 'mail'),
+        '#options'       => $engines,
         '#description'   => t('Choose an e-mail engine for sending mails from your site.')
     );
   }
@@ -111,7 +119,7 @@ function mimemail_settings() {
     $settings = module_invoke(variable_get('mimemail_engine', 'mail'), 'mailengine', 'settings');
     if ($settings) {
         $form['mimemail_engine_settings'] = array(
-          '#type'        => 'fieldset', 
+          '#type'        => 'fieldset',
           '#title'       => t('Engine specific settings'),
       );
       foreach ($settings as $name => $value) {
@@ -127,16 +135,16 @@ function mimemail_settings() {
 }
 
 /**
- * Implementation of hook_user()
+ * Implementation of hook_user().
  */
-function mimemail_user($op, &$edit, &$user, $category='') {
-  if ( $op == 'form' && $category == 'account') { 
+function mimemail_user($op, &$edit, &$user, $category = '') {
+  if ($op == 'form' && $category == 'account') {
     $form = array();
     $form['mimemail'] = array(
         '#type'          => 'fieldset',
         '#title'         => t('Email settings'),
-        '#weight'        => 5, 
-        '#collapsible' => true,
+        '#weight'        => 5,
+        '#collapsible' => TRUE,
     );
     $form['mimemail']['mimemail_textonly'] = array(
       '#type'           => 'checkbox',
@@ -145,23 +153,50 @@ function mimemail_user($op, &$edit, &$us
       '#description'     => t('Check this option if you do not wish to receive email messages with graphics and styles'),
     );
     return $form;
-  } 
+  }
   return;
 }
 
 /**
- * Send a mime-encoded email
- * 
- * @param $sender The email address or user object
- * @param $recipient An email address or user object * @param $subject An subject line string
- * @param $body An HTML body
- * @param $plaintext Whether to send message as plaintext only
- * @param $headers Optional e-mail headers in a keyed array
- * @param $text Optional plaintext portion of a multipart e-mail (instead of auto-generated)
- * 
- * @return result from mail() call
+ * Sends a mime-encoded e-mail.
+ *
+ * This function first determines the mail engine to use, then prepares the
+ * message by calling the mail engine's prepare function, or
+ * mimemail_prepare() if another one does not exist, then sends the message.
+ *
+ * @param $sender
+ *   The email address or user object who is sending the message.
+ * @param $recipient+  
+ *   An email address or user object who is receiving the message.
+ * @param $subject
+ *   A subject line string.
+ * @param $body
+ *   The message body in HTML format.
+ * @param $plaintext
+ *   Whether to send the message as plaintext only or HTML. If set to 1, Yes
+ *   or TRUE, then the message will be sent as plaintext.
+ * @param $headers
+ *   Optional e-mail headers in a keyed array.
+ * @param $text
+ *   Optional plaintext portion of a multipart e-mail.
+ * @param $attachments
+ *   An array of arrays which describe one or more attachments. The internal
+ *   array consists of two parts: the file's path and the file's MIME type.
+ *   The array of arrays looks something like this:
+ *   Array
+ *   (
+ *     [0] => Array
+ *       (
+ *         [filepath] => '/path/to/file.name'
+ *         [filemime] => 'mime/type'
+ *       )
+ *   )
+ * @param $mailkey
+ *   An identifier for the message.
+ * @return
+ *   An array containing the MIME encoded message, including headers and body.
  */
-function mimemail_prepare($sender, $recipient, $subject, $body, $plaintext=null, $headers=array(), $text=null, $attachments=array(), $mailkey = '') {
+function mimemail_prepare($sender, $recipient, $subject, $body, $plaintext = NULL, $headers = array(), $text = NULL, $attachments = array(), $mailkey = '') {
 
   require_once dirname(__FILE__) .'/mimemail.inc';
 
@@ -171,7 +206,7 @@ function mimemail_prepare($sender, $reci
         'mail' => variable_get('site_mail', ini_get('sendmail_from')),
     );
   }
-  
+
   // try to determine recpient's text mail preference
   if (is_null($plaintext)) {
     if (is_object($recipient)) {
@@ -187,7 +222,7 @@ function mimemail_prepare($sender, $reci
     }
   }
   $subject = mime_header_encode($subject);
-  
+
   $plaintext = $plaintext || variable_get('mimemail_textonly', 0);
   $sender    = mimemail_address($sender);
   $mail      = mimemail_html_body(theme('mimemail_message', $body, $mailkey), $subject, $plaintext, $text, $attachments);
@@ -203,12 +238,11 @@ function mimemail_prepare($sender, $reci
   return $message;
 }
 
-function mimemail($sender, $recipient, $subject, $body, $plaintext = NULL, $headers=array(), $text = NULL, $attachments = array(), $mailkey = '') {
-
+function mimemail($sender, $recipient, $subject, $body, $plaintext = NULL, $headers = array(), $text = NULL, $attachments = array(), $mailkey = '') {
   $engine = variable_get('mimemail_engine', 'mimemail') .'_mailengine';
-  
+
   if (!function_exists($engine)) {
-    return false;
+    return FALSE;
   }
 
   $engine_prepare = variable_get('mimemail_engine', 'mimemail') .'_prepare';
@@ -221,13 +255,14 @@ function mimemail($sender, $recipient, $
 
   return $engine('send', $message);
 
-  return false;
+  return FALSE;
 }
 
 /**
- * Returns available mailer engines.
+ * Retreives a list of all available mailer engines.
  *
- * @return an array of mailer engine names.
+ * @return
+ *   An array of mailer engine names.
  */
 function mimemail_get_engines() {
   $engines = array();
@@ -241,35 +276,42 @@ function mimemail_get_engines() {
 }
 
 /**
- * Default mailengine
+ * The default mailengine.
+ *
+ * @param $op
+ *   The operation to perform on the message.
+ * @param $message
+ *   The message to be sent.
+ * @return
+ *   Returns TRUE if the operation was successful or FALSE if it was not.
  */
 function mimemail_mailengine($op, $message = array()) {
   //default values
   $message = array_merge( array(
-      'address' => '', 
-      'subject' => '', 
-      'body' => '', 
-      'sender' => '', 
-      'headers' => '', 
+      'address' => '',
+      'subject' => '',
+      'body' => '',
+      'sender' => '',
+      'headers' => '',
       ), $message);
-      
+
   switch ($op) {
     case 'name':
       return t('Mime Mail');
-      
+
     case 'description':
       return t("Default mailing engine using drupal_mail().");
-      
+
     case 'settings': //not implemented
-      return false;
-      
+      return FALSE;
+
     case 'multiple':
     case 'single':
     case 'send':
       if (!is_array($message['address'])) {
         $message['address'] = array($message['address']);
       }
-      $status = true;
+      $status = TRUE;
       foreach ($message['address'] as $a) {
         $status = mail(
           $a,
@@ -277,32 +319,60 @@ function mimemail_mailengine($op, $messa
           $message['body'],
           mimemail_rfc_headers($message['headers'])
         ) && $status;
-    
+
       }
       return $status;
   }
 
-  return false;
+  return FALSE;
 }
 
+/**
+ * Overrides Drupal's default mail sending process.
+ *
+ * @param $mailkey
+ *   An identifier for the message.
+ * @param $to
+ *   An email address or user object who is receiving the message.
+ * @param $subject
+ *   A subject line string.
+ * @param $body
+ *   The message body in HTML format.
+ * @param $from
+ *   The email address or user object who is sending the message.
+ * @param $headers
+ *   Optional e-mail headers in a keyed array.
+ * @return
+ *   Returns the resultss of the call to mimemail().
+ */
 if (strpos(variable_get('smtp_library', ''), 'mimemail')
   && !function_exists('drupal_mail_wrapper')) {
 
   function drupal_mail_wrapper($mailkey, $to, $subject, $body, $from, $headers) {
+    $from = $message['from'];
+    $to = $message['to'];
+    $subject = $message['subject'];
+    if ($format = variable_get('mimemail_format', FILTER_FORMAT_DEFAULT)) {
+      $body = check_markup($body, $format);
+    }
+    else {
+      $body = $message['body'];
+    }
+    $headers = isset($message['headers']) ? $message['headers'] : array();
+    $mailkey = isset($message['mailkey']) ? $message['mailkey'] : '';
     return mimemail($from, $to, $subject, $body, NULL, $headers, NULL, array(), $mailkey);
   }
-} 
-
-function mimemail_mail_alter($mailkey, &$recipient, &$subject, &$body, &$sender, &$headers) {
-
-  if (!variable_get('mimemail_alter', 0)) return;
-
-  // attempt to fixup non-html messages that are being sent through drupal_mail
-  // I'm open to suggestions for better ways of doing this
-  $body = check_markup($body, FILTER_FORMAT_DEFAULT);
-  return;
 }
 
+/**
+ * Receive messages POSTed from an external source.
+ *
+ * This function enables messages to be sent via POST or some other RFC822
+ * source input (e.g. directly from a mail server).
+ *
+ * @return
+ *   The POSTed message.
+ */
 function mimemail_post() {
   $message = $_POST['message'];
   $token   = $_POST['token'];
@@ -315,39 +385,47 @@ function mimemail_post() {
   return mimemail_incoming($message);
 }
 
+/**
+ * Parses an externally received message.
+ *
+ * @param $message
+ *   The message to parse.
+ */
 function mimemail_incoming($message) {
   require_once dirname(__FILE__) .'/mimemail.inc';
   $mail = mimemail_parse($message);
 
-  foreach (module_implements('mimemail_incoming_alter') as $module) { 
-    call_user_func_array($module .'_mimemail_incoming_alter', $mail); 
+  foreach (module_implements('mimemail_incoming_alter') as $module) {
+    call_user_func_array($module .'_mimemail_incoming_alter', $mail);
   }
 
   module_invoke_all('mimemail_incoming', $mail);
 }
 
 /**
- * Formats an address string 
- * TODO could use some enhancement and stress testing 
- * 
- * @param $address - a user object, a text email address or an array containing name, mail
- * @return formatted address string
+ * Formats an address string.
+ * TODO could use some enhancement and stress testing.
+ *
+ * @param $address
+ *   A user object, a text email address or an array containing name, mail.
+ * @return 
+ *   A formatted address string or FALSE.
  */
 function mimemail_address($address) {
-  
+
   if (is_array($address)) {
-    
+
     // it's an array containing 'mail' and/or 'name'
     if (isset($address['mail'])) {
       $output = '';
       if (empty($address['name'])) {
         return $address['mail'];
-      } 
+      }
       else {
-        return '"'. addslashes($address['name']) .'" <'. $address['mail'] .'>';
+        return '"'. addslashes(mime_header_encode($address['name'])) .'" <'. $address['mail'] .'>';
       }
     }
-    
+
     // it's an array of address items
     $addresses = array();
     foreach ($address as $a) {
@@ -355,12 +433,12 @@ function mimemail_address($address) {
     }
     return $addresses;
   }
-  
+
   // it's a user object
   if (is_object($address) && isset($address->mail)) {
-    return '"'. addslashes($address->name) .'" <'. $address->mail .'>';
+    return '"'. addslashes(mime_header_encode($address->name)) .'" <'. $address->mail .'>';
   }
-  
+
   // it's formatted or unformatted string
   // TODO shouldn't assume it's valid - should try to re-parse
   if (is_string($address)) {
@@ -370,18 +448,36 @@ function mimemail_address($address) {
   // it's null.  return the site default address
   if (is_null($address)) {
     return array(
-      'name' => variable_get('site_name', 'Drupal'),
+      'name' => mime_header_encode(variable_get('site_name', 'Drupal')),
       'mail' => variable_get('site_mail', ini_get('sendmail_from')),
     );
   }
 
-  return false;
+  return FALSE;
 }
 
 /**
- * Themeable message body
+ * Implementation of hook_theme().
+ */
+function mimemail_theme() {
+  return array(
+    'mimemail_message' => array(
+      'arguments' => array('body' => NULL, 'mailkey' => NULL)
+    )
+  );
+}
+
+/**
+ * Themes the message body.
+ *
+ * @param $body
+ *   The message body to theme.
+ * @param $mailkey
+ *   An identifier for the message.
+ * @return
+ *   The themed HTML message body.
  */
-function theme_mimemail_message($body, $mailkey = null) {
+function theme_mimemail_message($body, $mailkey = NULL) {
   $output = '<html><head>';
   $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
 
@@ -392,7 +488,7 @@ function theme_mimemail_message($body, $
   $output .= '<style type="text/css"><!--';
   if (!file_exists($styles)) {
     // embed a version of all style definitions
-    $styles = preg_replace('|<style.*"'. base_path() .'([^"]*)".*|', '\1', drupal_get_css());
+    $styles = preg_replace('|<link.*href="'. base_path() .'([^"?]*)[?"].*|', '\1', drupal_get_css());
   }
   foreach (explode("\n", $styles) as $style) {
     $output .= file_get_contents($style);
