from email import Charset, generator, header
from email.mime import multipart, text

try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO


# Yay global state!
Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8')


def buildMessage(headers, parts):
    message = multipart.MIMEMultipart('alternative')

    for name, value in headers.iteritems():
        multipart[name] = _encodeHeader(value)

    for partType, part in parts.iteritems():
        mt = text.MIMEText(part.encode("utf-8"), partType, "UTF-8").encode()
        message.attach(mt)

    return message


def _encodeHeader(headerValue):
    """
    Encodes a header value.

    Returns ASCII if possible, else returns an UTF-8 encoded e-mail header.
    """
    try:
        return headerValue.encode('ascii', 'strict')
    except UnicodeError:
        encoded = headerValue.encode("utf-8")
        return header.Header(encoded, "UTF-8").encode()


def messageToFile(message):
    """
    Flattens a message into a file-like object.
    """
    outFile = StringIO()
    messageGenerator = generator.Generator(outFile, False)
    messageGenerator.flatten(message)
    outFile.seek(0, 0)
    return outFile

@@ -76,16 +76,62 @@
 rt, text
+%0Afrom email.utils import formataddr, parseaddr
 %0A%0Atry:%0A 
@@ -338,16 +338,87 @@
 parts):%0A
+    %22%22%22%0A    Builds a message from some headers and MIME parts.%0A    %22%22%22%0A
     mess
@@ -499,32 +499,225 @@
 rs.iteritems():%0A
+        if name == %22From%22:%0A            multipart%5Bname%5D = _encodeAddresses(value)%0A        elif name in %5B%22To%22, %22Cc%22, %22Bcc%22%5D:%0A            multipart%5Bname%5D = _encodeAddress(value)%0A        else:%0A    
         multipar
@@ -802,16 +802,22 @@
        m
+imeTex
 t = text
@@ -866,25 +866,16 @@
 %22UTF-8%22)
-.encode()
 %0A       
@@ -891,17 +891,32 @@
 attach(m
-t
+imeText.encode()
 )%0A%0A    r
@@ -1271,24 +1271,613 @@
 .encode()%0A%0A%0A
+def _encodeAddress(address):%0A    %22%22%22%0A    Encodes an address.%0A%0A    This parses the address into the real name and the actual address. Each%0A    part is then encoded as per %60%60_encodeHeader%60%60.%0A    %22%22%22%0A    return formataddr(map(_encodeHeader, parseaddr(address)))%0A%0A%0ACOMMASPACE = %22, %22%0A%0A%0Adef _encodeAddresses(addresses):%0A    %22%22%22%0A    Encodes multiple e-mail addresses.%0A%0A    Splits on a comma followed by a space to produce individual addresses.%0A    Each such address is then encoded as per %60%60_encodeAddress%60%60.%0A    %22%22%22%0A    return COMMASPACE.join(map(_encodeAddress, addresses.split(COMMASPACE)))%0A%0A%0A
 def messageT

Support unicode address headers better