This method sends an email notification.

    Args:
      to_addresses: blah@mycompany.com string, list of addresses as csv string,
                    or rdf_standard.DomainEmailAddress
      from_address: blah@mycompany.com string
      subject: email subject string
      message: message contents string, as HTML or plain text
      attachments: iterable of filename string and file data tuples,
                   e.g. {"/file/name/string": filedata}
      is_html: true if message is in HTML format
      cc_addresses: blah@mycompany.com string, or list of addresses as
                    csv string
      message_id: smtp message_id. Used to enable conversation threading
      headers: dict of str-> str, headers to set
    Raises:
      RuntimeError: for problems connecting to smtp server.

def SendEmail(self,
                to_addresses,
                from_address,
                subject,
                message,
                attachments=None,
                is_html=True,
                cc_addresses=None,
                message_id=None,
                headers=None):
    """This method sends an email notification.

    Args:
      to_addresses: blah@mycompany.com string, list of addresses as csv string,
                    or rdf_standard.DomainEmailAddress
      from_address: blah@mycompany.com string
      subject: email subject string
      message: message contents string, as HTML or plain text
      attachments: iterable of filename string and file data tuples,
                   e.g. {"/file/name/string": filedata}
      is_html: true if message is in HTML format
      cc_addresses: blah@mycompany.com string, or list of addresses as
                    csv string
      message_id: smtp message_id. Used to enable conversation threading
      headers: dict of str-> str, headers to set
    Raises:
      RuntimeError: for problems connecting to smtp server.
    """
    headers = headers or {}
    msg = MIMEMultipart("alternative")
    if is_html:
      text = self.RemoveHtmlTags(message)
      part1 = MIMEText(text, "plain")
      msg.attach(part1)
      part2 = MIMEText(message, "html")
      msg.attach(part2)
    else:
      part1 = MIMEText(message, "plain")
      msg.attach(part1)

    if attachments:
      for file_name, file_data in iteritems(attachments):
        part = MIMEBase("application", "octet-stream")
        part.set_payload(file_data)
        encoders.encode_base64(part)
        part.add_header("Content-Disposition",
                        "attachment; filename=\"%s\"" % file_name)
        msg.attach(part)

    msg["Subject"] = subject

    from_address = self.AddEmailDomain(from_address)
    to_addresses = self.SplitEmailsAndAppendEmailDomain(to_addresses)
    cc_addresses = self.SplitEmailsAndAppendEmailDomain(cc_addresses or "")

    msg["From"] = from_address
    msg["To"] = ",".join(to_addresses)
    if cc_addresses:
      msg["CC"] = ",".join(cc_addresses)

    if message_id:
      msg.add_header("Message-ID", message_id)

    for header, value in iteritems(headers):
      msg.add_header(header, value)

    try:
      s = smtplib.SMTP(config.CONFIG["Worker.smtp_server"],
                       int(config.CONFIG["Worker.smtp_port"]))
      s.ehlo()
      if config.CONFIG["Worker.smtp_starttls"]:
        s.starttls()
        s.ehlo()
      if (config.CONFIG["Worker.smtp_user"] and
          config.CONFIG["Worker.smtp_password"]):
        s.login(config.CONFIG["Worker.smtp_user"],
                config.CONFIG["Worker.smtp_password"])

      s.sendmail(from_address, to_addresses + cc_addresses, msg.as_string())
      s.quit()
    except (socket.error, smtplib.SMTPException) as e:
      raise RuntimeError("Could not connect to SMTP server to send email. "
                         "Please check config option Worker.smtp_server. "
                         "Currently set to %s. Error: %s" %
                         (config.CONFIG["Worker.smtp_server"], e))