'Constructs an RFC2822 email.message.Message object based on the keyword arguments passed, and returns it.
:param string email_from: sender email address
:param list email_to: list of recipient addresses (to be joined with commas)
:param string subject: email subject (no pre-encoding/quoting necessary)
:param string body: email body, of the type ``subtype`` (by default, plaintext).
If html subtype is used, the message will be automatically converted
to plaintext and wrapped in multipart/alternative, unless an explicit
``body_alternative`` version is passed.
:param string body_alternative: optional alternative body, of the type specified in ``subtype_alternative``
:param string reply_to: optional value of Reply-To header
:param string object_id: optional tracking identifier, to be included in the message-id for
recognizing replies. Suggested format for object-id is "res_id-model",
e.g. "12345-crm.lead".
:param string subtype: optional mime subtype for the text body (usually \'plain\' or \'html\'),
must match the format of the ``body`` parameter. Default is \'plain\',
making the content part of the mail "text/plain".
:param string subtype_alternative: optional mime subtype of ``body_alternative`` (usually \'plain\'
or \'html\'). Default is \'plain\'.
:param list attachments: list of (filename, filecontents) pairs, where filecontents is a string
containing the bytes of the attachment
:param list email_cc: optional list of string values for CC header (to be joined with commas)
:param list email_bcc: optional list of string values for BCC header (to be joined with commas)
:param dict headers: optional map of headers to set on the outgoing mail (may override the
other headers, including Subject, Reply-To, Message-Id, etc.)
:rtype: email.message.Message (usually MIMEMultipart)
:return: the new RFC2822 email message'

def build_email(self, email_from, email_to, subject, body, email_cc=None, email_bcc=None, reply_to=False, attachments=None, message_id=None, references=None, object_id=False, subtype='plain', headers=None, body_alternative=None, subtype_alternative='plain'):

    email_from = (email_from or tools.config.get('email_from'))
    assert email_from, 'You    must    either    provide    a    sender    address    explicitly    or    configure    a    global    sender    address    in    the    server    configuration    or    with    the    --email-from    startup    parameter.'
    headers = (headers or {})
    email_cc = (email_cc or [])
    email_bcc = (email_bcc or [])
    body = (body or u'')
    email_body_utf8 = ustr(body).encode('utf-8')
    email_text_part = MIMEText(email_body_utf8, _subtype=subtype, _charset='utf-8')
    msg = MIMEMultipart()
    if (not message_id):
        if object_id:
            message_id = tools.generate_tracking_message_id(object_id)
        else:
            message_id = make_msgid()
    msg['Message-Id'] = encode_header(message_id)
    if references:
        msg['references'] = encode_header(references)
    msg['Subject'] = encode_header(subject)
    msg['From'] = encode_rfc2822_address_header(email_from)
    del msg['Reply-To']
    if reply_to:
        msg['Reply-To'] = encode_rfc2822_address_header(reply_to)
    else:
        msg['Reply-To'] = msg['From']
    msg['To'] = encode_rfc2822_address_header(COMMASPACE.join(email_to))
    if email_cc:
        msg['Cc'] = encode_rfc2822_address_header(COMMASPACE.join(email_cc))
    if email_bcc:
        msg['Bcc'] = encode_rfc2822_address_header(COMMASPACE.join(email_bcc))
    msg['Date'] = formatdate()
    for (key, value) in headers.iteritems():
        msg[ustr(key).encode('utf-8')] = encode_header(value)
    if ((subtype == 'html') and (not body_alternative) and html2text):
        text_utf8 = tools.html2text(email_body_utf8.decode('utf-8')).encode('utf-8')
        alternative_part = MIMEMultipart(_subtype='alternative')
        alternative_part.attach(MIMEText(text_utf8, _charset='utf-8', _subtype='plain'))
        alternative_part.attach(email_text_part)
        msg.attach(alternative_part)
    elif body_alternative:
        alternative_part = MIMEMultipart(_subtype='alternative')
        body_alternative_utf8 = ustr(body_alternative).encode('utf-8')
        alternative_body_part = MIMEText(body_alternative_utf8, _subtype=subtype_alternative, _charset='utf-8')
        alternative_part.attach(alternative_body_part)
        alternative_part.attach(email_text_part)
        msg.attach(alternative_part)
    else:
        msg.attach(email_text_part)
    if attachments:
        for (fname, fcontent) in attachments:
            filename_rfc2047 = encode_header_param(fname)
            part = MIMEBase('application', 'octet-stream')
            part.set_param('name', filename_rfc2047)
            part.add_header('Content-Disposition', 'attachment', filename=filename_rfc2047)
            part.set_payload(fcontent)
            Encoders.encode_base64(part)
            msg.attach(part)
    return msg
