Example usage for javax.mail.internet MimeMessage getFrom

List of usage examples for javax.mail.internet MimeMessage getFrom

Introduction

In this page you can find the example usage for javax.mail.internet MimeMessage getFrom.

Prototype

@Override
public Address[] getFrom() throws MessagingException 

Source Link

Document

Returns the value of the RFC 822 "From" header fields.

Usage

From source file:org.apache.camel.component.mail.MailBinding.java

public void populateMailMessage(MailEndpoint endpoint, MimeMessage mimeMessage, Exchange exchange)
        throws MessagingException, IOException {

    // camel message headers takes precedence over endpoint configuration
    if (hasRecipientHeaders(exchange)) {
        setRecipientFromCamelMessage(mimeMessage, exchange);
    } else {/* w w w  . ja  v a  2 s  . c o m*/
        // fallback to endpoint configuration
        setRecipientFromEndpointConfiguration(mimeMessage, endpoint);
    }

    // must have at least one recipients otherwise we do not know where to send the mail
    if (mimeMessage.getAllRecipients() == null) {
        throw new IllegalArgumentException("The mail message does not have any recipients set.");
    }

    // set the subject if it was passed in as an option in the uri. Note: if it is in both the URI
    // and headers the headers win.
    String subject = endpoint.getConfiguration().getSubject();
    if (subject != null) {
        mimeMessage.setSubject(subject, IOConverter.getCharsetName(exchange, false));
    }

    // append the rest of the headers (no recipients) that could be subject, reply-to etc.
    appendHeadersFromCamelMessage(mimeMessage, endpoint.getConfiguration(), exchange);

    if (empty(mimeMessage.getFrom())) {
        // lets default the address to the endpoint destination
        String from = endpoint.getConfiguration().getFrom();
        mimeMessage.setFrom(new InternetAddress(from));
    }

    // if there is an alternative body provided, set up a mime multipart alternative message
    if (hasAlternativeBody(endpoint.getConfiguration(), exchange)) {
        createMultipartAlternativeMessage(mimeMessage, endpoint.getConfiguration(), exchange);
    } else {
        if (exchange.getIn().hasAttachments()) {
            appendAttachmentsFromCamel(mimeMessage, endpoint.getConfiguration(), exchange);
        } else {
            populateContentOnMimeMessage(mimeMessage, endpoint.getConfiguration(), exchange);
        }
    }
}

From source file:org.sakaiproject.email.impl.BasicEmailService.java

/**
 * fix up From and ReplyTo if we need it to be from Postmaster
 *//*from   w ww  .  j  a v a  2  s  .  c o m*/
private void checkFrom(MimeMessage msg) {

    String sendFromSakai = serverConfigurationService.getString(MAIL_SENDFROMSAKAI, "true");
    String sendExceptions = serverConfigurationService.getString(MAIL_SENDFROMSAKAI_EXCEPTIONS, null);
    InternetAddress from = null;
    InternetAddress[] replyTo = null;

    try {
        Address[] fromA = msg.getFrom();
        if (fromA == null || fromA.length == 0) {
            M_log.info("message from missing");
            return;
        } else if (fromA.length > 1) {
            M_log.info("message from more than 1");
            return;
        } else if (fromA instanceof InternetAddress[]) {
            from = (InternetAddress) fromA[0];
        } else {
            M_log.info("message from not InternetAddress");
            return;
        }

        Address[] replyToA = msg.getReplyTo();
        if (replyToA == null)
            replyTo = null;
        else if (replyToA instanceof InternetAddress[])
            replyTo = (InternetAddress[]) replyToA;
        else {
            M_log.info("message replyto isn't internet address");
            return;
        }

        // should we replace from address with a Sakai address?
        if (sendFromSakai != null && !sendFromSakai.equalsIgnoreCase("false")) {
            // exceptions -- addresses to leave alone. Our own addresses are always exceptions.
            // you can also configure a regexp of exceptions.
            if (!from.getAddress().toLowerCase()
                    .endsWith("@" + serverConfigurationService.getServerName().toLowerCase())
                    && (sendExceptions == null || sendExceptions.equals("")
                            || !from.getAddress().toLowerCase().matches(sendExceptions))) {

                // not an exception. do the replacement.
                // First, decide on the replacement address. The config variable
                // may be the replacement address. If not, use postmaster
                if (sendFromSakai.indexOf("@") < 0)
                    sendFromSakai = POSTMASTER + "@" + serverConfigurationService.getServerName();

                // put the original from into reply-to, unless a replyto exists
                if (replyTo == null || replyTo.length == 0 || replyTo[0].getAddress().equals("")) {
                    replyTo = new InternetAddress[1];
                    replyTo[0] = from;
                    msg.setReplyTo(replyTo);
                }
                // for some reason setReplyTo doesn't work, though setFrom does. Have to create the
                // actual header line
                if (msg.getHeader(EmailHeaders.REPLY_TO) == null)
                    msg.addHeader(EmailHeaders.REPLY_TO, from.getAddress());

                // and use the new from address
                // biggest issue is the "personal address", i.e. the comment text

                String origFromText = from.getPersonal();
                String origFromAddress = from.getAddress();
                String fromTextPattern = serverConfigurationService.getString(MAIL_SENDFROMSAKAI_FROMTEXT,
                        "{}");

                String fromText = null;
                if (origFromText != null && !origFromText.equals(""))
                    fromText = fromTextPattern.replace("{}", origFromText + " (" + origFromAddress + ")");
                else
                    fromText = fromTextPattern.replace("{}", origFromAddress);

                from = new InternetAddress(sendFromSakai);
                try {
                    from.setPersonal(fromText);
                } catch (Exception e) {
                }

                msg.setFrom(from);
            }
        }
    } catch (javax.mail.internet.AddressException e) {
        M_log.info("checkfrom address exception " + e);
    } catch (javax.mail.MessagingException e) {
        M_log.info("checkfrom messaging exception " + e);
    }

}

From source file:com.github.thorqin.webapi.mail.MailService.java

private void doSendMail(Mail mail) {
    long beginTime = System.currentTimeMillis();
    Properties props = new Properties();
    Session session;//  w  w  w  . j  av  a  2s. c  o m
    props.put("mail.smtp.auth", String.valueOf(serverConfig.useAuthentication()));
    // If want to display SMTP protocol detail then uncomment following statement
    // props.put("mail.debug", "true");
    props.put("mail.smtp.host", serverConfig.getHost());
    if (serverConfig.getPort() != null) {
        props.put("mail.smtp.port", serverConfig.getPort());
    }
    if (serverConfig.getSecure().equals(MailConfig.SECURE_STARTTLS)) {
        props.put("mail.smtp.starttls.enable", "true");
        if (!serverConfig.useAuthentication())
            session = Session.getInstance(props);
        else
            session = Session.getInstance(props, new javax.mail.Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(serverConfig.getUsername(), serverConfig.getPassword());
                }
            });
    } else if (serverConfig.getSecure().equals(MailConfig.SECURE_SSL)) {
        props.put("mail.smtp.socketFactory.port", serverConfig.getPort());
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");
        if (!serverConfig.useAuthentication())
            session = Session.getInstance(props);
        else
            session = Session.getInstance(props, new javax.mail.Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(serverConfig.getUsername(), serverConfig.getPassword());
                }
            });
    } else {
        if (!serverConfig.useAuthentication())
            session = Session.getInstance(props);
        else
            session = Session.getInstance(props, new javax.mail.Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(serverConfig.getUsername(), serverConfig.getPassword());
                }
            });
    }

    // Uncomment to show SMTP protocal
    // session.setDebug(true);

    MimeMessage message = new MimeMessage(session);
    StringBuilder mailTo = new StringBuilder();
    try {
        if (mail.from != null)
            message.setFrom(new InternetAddress(mail.from));
        else if (serverConfig.getFrom() != null)
            message.setFrom(new InternetAddress(serverConfig.getFrom()));
        if (mail.to != null) {
            for (String to : mail.to) {
                if (mailTo.length() > 0)
                    mailTo.append(",");
                mailTo.append(to);
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            }
        }
        if (mail.subject != null)
            message.setSubject("=?UTF-8?B?" + Base64.encodeBase64String(mail.subject.getBytes("utf-8")) + "?=");
        message.setSentDate(new Date());

        BodyPart bodyPart = new MimeBodyPart();
        if (mail.htmlBody != null)
            bodyPart.setContent(mail.htmlBody, "text/html;charset=utf-8");
        else if (mail.textBody != null)
            bodyPart.setText(mail.textBody);
        Multipart multipart = new MimeMultipart();
        multipart.addBodyPart(bodyPart);

        if (mail.attachments != null) {
            for (String attachment : mail.attachments) {
                BodyPart attachedBody = new MimeBodyPart();
                File attachedFile = new File(attachment);
                DataSource source = new FileDataSource(attachedFile);
                attachedBody.setDataHandler(new DataHandler(source));
                attachedBody.setDisposition(MimeBodyPart.ATTACHMENT);
                String filename = attachedFile.getName();
                attachedBody.setFileName(
                        "=?UTF-8?B?" + Base64.encodeBase64String(filename.getBytes("utf-8")) + "?=");
                multipart.addBodyPart(attachedBody);
            }
        }

        message.setContent(multipart);
        message.saveChanges();
        Transport transport = session.getTransport("smtp");
        transport.connect();

        transport.sendMessage(message, message.getAllRecipients());
        transport.close();
        if (serverConfig.enableTrace()) {
            MailInfo info = new MailInfo();
            info.recipients = mail.to;
            info.sender = StringUtil.join(message.getFrom());
            info.smtpServer = serverConfig.getHost();
            info.smtpUser = serverConfig.getUsername();
            info.subject = mail.subject;
            info.startTime = beginTime;
            info.runningTime = System.currentTimeMillis() - beginTime;
            MonitorService.record(info);
        }
    } catch (Exception ex) {
        logger.log(Level.SEVERE, "Send mail failed!", ex);
    }
}

From source file:com.github.thorqin.toolkit.mail.MailService.java

private void sendMail(Mail mail) {
    long beginTime = System.currentTimeMillis();
    Properties props = new Properties();
    final Session session;
    props.put("mail.smtp.auth", String.valueOf(setting.auth));
    // If want to display SMTP protocol detail then uncomment following statement
    // props.put("mail.debug", "true");
    props.put("mail.smtp.host", setting.host);
    props.put("mail.smtp.port", setting.port);
    if (setting.secure.equals(SECURE_STARTTLS)) {
        props.put("mail.smtp.starttls.enable", "true");

    } else if (setting.secure.equals(SECURE_SSL)) {
        props.put("mail.smtp.socketFactory.port", setting.port);
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");
    }//from   w  ww  .j a v  a2 s. c  o  m
    if (!setting.auth)
        session = Session.getInstance(props);
    else
        session = Session.getInstance(props, new javax.mail.Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(setting.user, setting.password);
            }
        });

    if (setting.debug)
        session.setDebug(true);

    MimeMessage message = new MimeMessage(session);
    StringBuilder mailTo = new StringBuilder();
    try {
        if (mail.from != null)
            message.setFrom(new InternetAddress(mail.from));
        else if (setting.from != null)
            message.setFrom(new InternetAddress(setting.from));
        if (mail.to != null) {
            for (String to : mail.to) {
                if (mailTo.length() > 0)
                    mailTo.append(",");
                mailTo.append(to);
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            }
        }
        if (mail.subject != null)
            message.setSubject("=?UTF-8?B?" + Base64.encodeBase64String(mail.subject.getBytes("utf-8")) + "?=");
        message.setSentDate(new Date());

        BodyPart bodyPart = new MimeBodyPart();
        if (mail.htmlBody != null)
            bodyPart.setContent(mail.htmlBody, "text/html;charset=utf-8");
        else if (mail.textBody != null)
            bodyPart.setText(mail.textBody);
        Multipart multipart = new MimeMultipart();
        multipart.addBodyPart(bodyPart);

        if (mail.attachments != null) {
            for (String attachment : mail.attachments) {
                BodyPart attachedBody = new MimeBodyPart();
                File attachedFile = new File(attachment);
                DataSource source = new FileDataSource(attachedFile);
                attachedBody.setDataHandler(new DataHandler(source));
                attachedBody.setDisposition(MimeBodyPart.ATTACHMENT);
                String filename = attachedFile.getName();
                attachedBody.setFileName(
                        "=?UTF-8?B?" + Base64.encodeBase64String(filename.getBytes("utf-8")) + "?=");
                multipart.addBodyPart(attachedBody);
            }
        }

        message.setContent(multipart);
        message.saveChanges();
        Transport transport = session.getTransport("smtp");
        transport.connect();

        transport.sendMessage(message, message.getAllRecipients());
        transport.close();
        if (setting.trace && tracer != null) {
            Tracer.Info info = new Tracer.Info();
            info.catalog = "mail";
            info.name = "send";
            info.put("sender", StringUtils.join(message.getFrom()));
            info.put("recipients", mail.to);
            info.put("SMTPServer", setting.host);
            info.put("SMTPAccount", setting.user);
            info.put("subject", mail.subject);
            info.put("startTime", beginTime);
            info.put("runningTime", System.currentTimeMillis() - beginTime);
            tracer.trace(info);
        }
    } catch (Exception ex) {
        logger.log(Level.SEVERE, "Send mail failed!", ex);
    }
}

From source file:net.wastl.webmail.server.WebMailSession.java

/**
 * Fetch a message from a folder.//from  www  . j a  va  2 s. c  o m
 * Will put the messages parameters in the sessions environment
 *
 * @param foldername Name of the folder were the message should be fetched from
 * @param msgnum Number of the message to fetch
 * @param mode there are three different modes: standard, reply and forward. reply and forward will enter the message
 *             into the current work element of the user and set some additional flags on the message if the user
 *             has enabled this option.
 * @see net.wastl.webmail.server.WebMailSession.GETMESSAGE_MODE_STANDARD
 * @see net.wastl.webmail.server.WebMailSession.GETMESSAGE_MODE_REPLY
 * @see net.wastl.webmail.server.WebMailSession.GETMESSAGE_MODE_FORWARD
 */
public void getMessage(String folderhash, int msgnum, int mode) throws NoSuchFolderException, WebMailException {
    // security reasons:
    // attachments=null;

    try {
        TimeZone tz = TimeZone.getDefault();
        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT,
                user.getPreferredLocale());
        df.setTimeZone(tz);
        Folder folder = getFolder(folderhash);
        Element xml_folder = model.getFolder(folderhash);

        if (folder == null) {
            throw new NoSuchFolderException("No such folder: " + folderhash);
        }

        if (folder.isOpen() && folder.getMode() == Folder.READ_WRITE) {
            folder.close(false);
            folder.open(Folder.READ_ONLY);
        } else if (!folder.isOpen()) {
            folder.open(Folder.READ_ONLY);
        }

        MimeMessage m = (MimeMessage) folder.getMessage(msgnum);

        String messageid;
        try {
            StringTokenizer tok = new StringTokenizer(m.getMessageID(), "<>");
            messageid = tok.nextToken();
        } catch (NullPointerException ex) {
            // For mail servers that don't generate a Message-ID (Outlook et al)
            messageid = user.getLogin() + "." + msgnum + ".jwebmail@" + user.getDomain();
        }

        Element xml_current = model.setCurrentMessage(messageid);
        XMLMessage xml_message = model.getMessage(xml_folder, m.getMessageNumber() + "", messageid);

        /* Check whether we already cached this message (not only headers but complete)*/
        boolean cached = xml_message.messageCompletelyCached();
        /* If we cached the message, we don't need to fetch it again */
        if (!cached) {
            //Element xml_header=model.getHeader(xml_message);

            try {
                String from = MimeUtility.decodeText(Helper.joinAddress(m.getFrom()));
                String replyto = MimeUtility.decodeText(Helper.joinAddress(m.getReplyTo()));
                String to = MimeUtility
                        .decodeText(Helper.joinAddress(m.getRecipients(Message.RecipientType.TO)));
                String cc = MimeUtility
                        .decodeText(Helper.joinAddress(m.getRecipients(Message.RecipientType.CC)));
                String bcc = MimeUtility
                        .decodeText(Helper.joinAddress(m.getRecipients(Message.RecipientType.BCC)));
                Date date_orig = m.getSentDate();
                String date = getStringResource("no date");
                if (date_orig != null) {
                    date = df.format(date_orig);
                }
                String subject = "";
                if (m.getSubject() != null) {
                    subject = MimeUtility.decodeText(m.getSubject());
                }
                if (subject == null || subject.equals("")) {
                    subject = getStringResource("no subject");
                }

                try {
                    Flags.Flag[] sf = m.getFlags().getSystemFlags();
                    for (int j = 0; j < sf.length; j++) {
                        if (sf[j] == Flags.Flag.RECENT)
                            xml_message.setAttribute("recent", "true");
                        if (sf[j] == Flags.Flag.SEEN)
                            xml_message.setAttribute("seen", "true");
                        if (sf[j] == Flags.Flag.DELETED)
                            xml_message.setAttribute("deleted", "true");
                        if (sf[j] == Flags.Flag.ANSWERED)
                            xml_message.setAttribute("answered", "true");
                        if (sf[j] == Flags.Flag.DRAFT)
                            xml_message.setAttribute("draft", "true");
                        if (sf[j] == Flags.Flag.FLAGGED)
                            xml_message.setAttribute("flagged", "true");
                        if (sf[j] == Flags.Flag.USER)
                            xml_message.setAttribute("user", "true");
                    }
                } catch (NullPointerException ex) {
                }
                if (m.getContentType().toUpperCase().startsWith("MULTIPART/")) {
                    xml_message.setAttribute("attachment", "true");
                }

                int size = m.getSize();
                size /= 1024;
                xml_message.setAttribute("size", (size > 0 ? size + "" : "<1") + " kB");

                /* Set all of what we found into the DOM */
                xml_message.setHeader("FROM", from);
                xml_message.setHeader("SUBJECT", Fancyfier.apply(subject));
                xml_message.setHeader("TO", to);
                xml_message.setHeader("CC", cc);
                xml_message.setHeader("BCC", bcc);
                xml_message.setHeader("REPLY-TO", replyto);
                xml_message.setHeader("DATE", date);

                /* Decode MIME contents recursively */
                xml_message.removeAllParts();
                parseMIMEContent(m, xml_message, messageid);

            } catch (UnsupportedEncodingException e) {
                log.warn("Unsupported Encoding in parseMIMEContent: " + e.getMessage());
            }
        }
        /* Set seen flag (Maybe make that threaded to improve performance) */
        if (user.wantsSetFlags()) {
            if (folder.isOpen() && folder.getMode() == Folder.READ_ONLY) {
                folder.close(false);
                folder.open(Folder.READ_WRITE);
            } else if (!folder.isOpen()) {
                folder.open(Folder.READ_WRITE);
            }
            folder.setFlags(msgnum, msgnum, new Flags(Flags.Flag.SEEN), true);
            folder.setFlags(msgnum, msgnum, new Flags(Flags.Flag.RECENT), false);
            if ((mode & GETMESSAGE_MODE_REPLY) == GETMESSAGE_MODE_REPLY) {
                folder.setFlags(msgnum, msgnum, new Flags(Flags.Flag.ANSWERED), true);
            }
        }
        folder.close(false);

        /* In this part we determine whether the message was requested so that it may be used for
           further editing (replying or forwarding). In this case we set the current "work" message to the
           message we just fetched and then modifiy it a little (quote, add a "Re" to the subject, etc). */
        XMLMessage work = null;
        if ((mode & GETMESSAGE_MODE_REPLY) == GETMESSAGE_MODE_REPLY
                || (mode & GETMESSAGE_MODE_FORWARD) == GETMESSAGE_MODE_FORWARD) {
            log.debug("Setting work message!");
            work = model.setWorkMessage(xml_message);

            String newmsgid = WebMailServer.generateMessageID(user.getUserName());

            if (work != null && (mode & GETMESSAGE_MODE_REPLY) == GETMESSAGE_MODE_REPLY) {
                String from = work.getHeader("FROM");
                work.setHeader("FROM", user.getDefaultEmail());
                work.setHeader("TO", from);
                work.prepareReply(getStringResource("reply subject prefix"),
                        getStringResource("reply subject postfix"), getStringResource("reply message prefix"),
                        getStringResource("reply message postfix"));

            } else if (work != null && (mode & GETMESSAGE_MODE_FORWARD) == GETMESSAGE_MODE_FORWARD) {
                String from = work.getHeader("FROM");
                work.setHeader("FROM", user.getDefaultEmail());
                work.setHeader("TO", "");
                work.setHeader("CC", "");
                work.prepareForward(getStringResource("forward subject prefix"),
                        getStringResource("forward subject postfix"),
                        getStringResource("forward message prefix"),
                        getStringResource("forward message postfix"));

                /* Copy all references to MIME parts to the new message id */
                for (String key : getMimeParts(work.getAttribute("msgid"))) {
                    StringTokenizer tok2 = new StringTokenizer(key, "/");
                    tok2.nextToken();
                    String newkey = tok2.nextToken();
                    mime_parts_decoded.put(newmsgid + "/" + newkey, mime_parts_decoded.get(key));
                }
            }

            /* Clear the msgnr and msgid fields at last */
            work.setAttribute("msgnr", "0");
            work.setAttribute("msgid", newmsgid);
            prepareCompose();
        }
    } catch (MessagingException ex) {
        log.error("Failed to get message.  Doing nothing instead.", ex);
    }
}

From source file:edu.stanford.muse.email.EmailFetcherStats.java

/**
 * Key method for importing email: converts a javamail obj. to our own data structure (EmailDocument)
 *///w  w  w  .  j  a  va2s  . c o  m
//public EmailDocument convertToEmailDocument(MimeMessage m, int num, String url) throws MessagingException, IOException
private EmailDocument convertToEmailDocument(MimeMessage m, String id) throws MessagingException, IOException {
    // get the date.
    // prevDate is a hack for the cases where the message is lacking an explicit Date: header. e.g.
    //      From hangal Sun Jun 10 13:46:46 2001
    //      To: ewatkins@stanford.edu
    //      Subject: Re: return value bugs
    // though the date is on the From separator line, the mbox provider fails to parse it and provide it to us.
    // so as a hack, we will assign such messages the same date as the previous one this fetcher has seen! ;-)
    // update: having the exact same date causes the message to be considered a duplicate, so just increment
    // the timestamp it by 1 millisecond!
    // a better fix would be to improve the parsing in the provider

    boolean hackyDate = false;
    Date d = m.getSentDate();
    if (d == null)
        d = m.getReceivedDate();
    if (d == null) {
        if (prevDate != null) {
            long newTime = prevDate.getTime() + 1L; // added +1 so that this email is not considered the same object as the prev. one if they are in the same thread
            d = new Date(newTime);
            dataErrors.add("No date for message id:" + id + ": " + EmailUtils.formatMessageHeader(m)
                    + " assigned approximate date");
        } else {
            d = INVALID_DATE; // wrong, but what can we do... :-(
            dataErrors.add("No date for message id:" + id + ": " + EmailUtils.formatMessageHeader(m)
                    + " assigned deliberately invalid date");
        }
        hackyDate = true;
    } else {
        Calendar c = new GregorianCalendar();
        c.setTime(d);
        int yy = c.get(Calendar.YEAR);
        if (yy < 1960 || yy > 2020) {
            dataErrors.add("Probably bad date: " + Util.formatDate(c) + " message: "
                    + EmailUtils.formatMessageHeader(m));
            hackyDate = true;
        }
    }

    if (hackyDate && prevDate != null) {
        long newTime = prevDate.getTime() + 1L; // added +1 so that this email is not considered the same object as the prev. one if they are in the same thread
        d = new Date(newTime);
        Util.ASSERT(!d.equals(prevDate));
    }

    Calendar c = new GregorianCalendar();
    c.setTime(d != null ? d : new Date());

    prevDate = d;

    Address to[] = null, cc[] = null, bcc[] = null;
    Address[] from = null;
    try {
        //          allrecip = m.getAllRecipients(); // turns out to be too expensive because it looks for newsgroup headers for imap
        // assemble to, cc, bcc into a list and copy it into allrecip
        List<Address> list = new ArrayList<Address>();
        from = m.getFrom();
        to = m.getRecipients(Message.RecipientType.TO);
        if (to != null)
            list.addAll(Arrays.asList(to));
        cc = m.getRecipients(Message.RecipientType.CC);
        if (cc != null)
            list.addAll(Arrays.asList(cc));
        bcc = m.getRecipients(Message.RecipientType.BCC);
        if (bcc != null)
            list.addAll(Arrays.asList(bcc));

        // intern the strings in these addresses to save memory cos they are repeated often in a large archive
        internAddressList(from);
        internAddressList(to);
        internAddressList(cc);
        internAddressList(bcc);
    } catch (AddressException ae) {
        String s = "Bad address in folder " + folder_name() + " message id" + id + " " + ae;
        dataErrors.add(s);
    }

    // take a deep breath. This object is going to live longer than most of us.
    EmailDocument ed = new EmailDocument(id, email_source(), folder_name(), to, cc, bcc, from, m.getSubject(),
            m.getMessageID(), c.getTime());

    String[] headers = m.getHeader("List-Post");
    if (headers != null && headers.length > 0) {
        // trim the headers because they usually look like: "<mailto:prpl-devel@lists.stanford.edu>"
        ed.sentToMailingLists = new String[headers.length];
        int i = 0;
        for (String header : headers) {
            header = header.trim();
            header = header.toLowerCase();

            if (header.startsWith("<") && header.endsWith(">"))
                header = header.substring(1, header.length() - 1);
            if (header.startsWith("mailto:") && !"mailto:".equals(header)) // defensive check in case header == "mailto:"
                header = header.substring(("mailto:").length());
            ed.sentToMailingLists[i++] = header;
        }
    }
    if (hackyDate) {
        String s = "Guessed date " + Util.formatDate(c) + " for message id: " + id + ": " + ed.getHeader();
        dataErrors.add(s);
        ed.hackyDate = true;
    }

    // check if the message has attachments.
    // if it does and we're not downloading attachments, then we mark the ed as such.
    // otherwise we had a problem where a message header (and maybe text) was downloaded but without attachments in one run
    // but in a subsequent run where attachments were needed, we thought the message was already cached and there was no
    // need to recompute it, leaving the attachments field in this ed incorrect.
    List<String> attachmentNames = getAttachmentNames(m, m);
    if (!Util.nullOrEmpty(attachmentNames)) {
        ed.attachmentsYetToBeDownloaded = true; // will set it to false later if attachments really were downloaded (not sure why)
        //         log.info ("added " + attachmentNames.size() + " attachments to message: " + ed);
    }
    return ed;
}