Interface::MessagePart::Ptr MultiPartAlternativeBodyPartFormatter::process(Interface::BodyPart &part) const
{
    KMime::Content *node = part.content();
    if (node->contents().isEmpty()) {
        return MessagePart::Ptr();
    }

    KMime::Content *dataHtml = findTypeInDirectChilds(node, "text/html");
    KMime::Content *dataPlain = findTypeInDirectChilds(node, "text/plain");

    if (!dataHtml) {
        // If we didn't find the HTML part as the first child of the multipart/alternative, it might
        // be that this is a HTML message with images, and text/plain and multipart/related are the
        // immediate children of this multipart/alternative node.
        // In this case, the HTML node is a child of multipart/related.
        dataHtml = findTypeInDirectChilds(node, "multipart/related");

        // Still not found? Stupid apple mail actually puts the attachments inside of the
        // multipart/alternative, which is wrong. Therefore we also have to look for multipart/mixed
        // here.
        // Do this only when prefering HTML mail, though, since otherwise the attachments are hidden
        // when displaying plain text.
        if (!dataHtml && part.source()->htmlMail()) {
            dataHtml = findTypeInDirectChilds(node, "multipart/mixed");
        }
    }

    if (dataPlain || dataHtml) {
        AlternativeMessagePart::Ptr mp(new AlternativeMessagePart(part.objectTreeParser(), dataPlain, dataHtml));

        if ((part.source()->htmlMail() && dataHtml) ||
                (dataHtml && dataPlain && dataPlain->body().isEmpty())) {
            if (dataPlain) {
                part.nodeHelper()->setNodeProcessed(dataPlain, false);
            }
            part.source()->setHtmlMode(Util::MultipartHtml);
            mp->setViewHtml(true);
        }

        if (!part.source()->htmlMail() && dataPlain) {
            part.nodeHelper()->setNodeProcessed(dataHtml, false);
            part.source()->setHtmlMode(Util::MultipartPlain);
            mp->setViewHtml(false);
        }
        return mp;
    }

    MimeMessagePart::Ptr mp(new MimeMessagePart(part.objectTreeParser(), node->contents().at(0), false));
    return mp;
}
Interface::MessagePart::Ptr TextHtmlBodyPartFormatter::process(Interface::BodyPart &part) const
{
    KMime::Content *node = part.content();
    HtmlMessagePart::Ptr mp(new HtmlMessagePart(part.objectTreeParser(), node, part.source()));
    return mp;
}