Merge pull request #5 from tobiasbaum/master

added some testcases for MimeMessage parsing + some simple refactorings (2)
This commit is contained in:
cketti 2014-09-22 01:32:49 +02:00
commit 3b89c6a139
20 changed files with 295 additions and 124 deletions

View file

@ -8,7 +8,21 @@ import java.io.OutputStream;
import com.fsck.k9.mail.store.UnavailableStorageException;
public interface Body {
/**
* Returns the raw data of the body, without transfer encoding etc applied.
* TODO perhaps it would be better to have an intermediate "simple part" class where this method could reside
* because it makes no sense for multiparts
*/
public InputStream getInputStream() throws MessagingException;
/**
* Sets the content transfer encoding (7bit, 8bit, quoted-printable or base64).
*/
public void setEncoding(String encoding) throws UnavailableStorageException, MessagingException;
/**
* Writes the body's data to the given {@link OutputStream}.
* The written data is transfer encoded (e.g. transformed to Base64 when needed).
*/
public void writeTo(OutputStream out) throws IOException, MessagingException;
}

View file

@ -14,5 +14,6 @@ public abstract class BodyPart implements Part {
public abstract void setEncoding(String encoding) throws MessagingException;
@Override
public abstract void setUsing7bitTransport() throws MessagingException;
}

View file

@ -23,7 +23,6 @@ public interface CompositeBody extends Body {
* @throws MessagingException
*
*/
public abstract void setUsing7bitTransport() throws MessagingException;
}

View file

@ -45,6 +45,7 @@ public abstract class Message implements Part, CompositeBody {
}
return false;
}
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof Message)) {
@ -144,6 +145,8 @@ public abstract class Message implements Part, CompositeBody {
public abstract String getPreview();
public abstract boolean hasAttachments();
public abstract int getSize();
/*
* calculateContentPreview
* Takes a plain text message body as a string.

View file

@ -28,9 +28,9 @@ public class MessagingException extends Exception {
return permanentFailure;
}
//TODO setters in Exception are bad style, remove (it's nearly unused anyway)
public void setPermanentFailure(boolean permanentFailure) {
this.permanentFailure = permanentFailure;
}
}

View file

@ -2,6 +2,8 @@
package com.fsck.k9.mail;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.james.mime4j.util.MimeUtil;
@ -20,15 +22,14 @@ public abstract class Multipart implements CompositeBody {
part.setParent(this);
}
public void addBodyPart(BodyPart part, int index) {
mParts.add(index, part);
part.setParent(this);
}
public BodyPart getBodyPart(int index) {
return mParts.get(index);
}
public List<BodyPart> getBodyParts() {
return Collections.unmodifiableList(mParts);
}
public String getContentType() {
return mContentType;
}
@ -37,16 +38,6 @@ public abstract class Multipart implements CompositeBody {
return mParts.size();
}
public boolean removeBodyPart(BodyPart part) {
part.setParent(null);
return mParts.remove(part);
}
public void removeBodyPart(int index) {
mParts.get(index).setParent(null);
mParts.remove(index);
}
public Part getParent() {
return mParent;
}
@ -55,6 +46,7 @@ public abstract class Multipart implements CompositeBody {
this.mParent = parent;
}
@Override
public void setEncoding(String encoding) throws MessagingException {
if (!MimeUtil.ENC_7BIT.equalsIgnoreCase(encoding)
&& !MimeUtil.ENC_8BIT.equalsIgnoreCase(encoding)) {

View file

@ -21,8 +21,6 @@ public interface Part {
public String[] getHeader(String name) throws MessagingException;
public int getSize();
public boolean isMimeType(String mimeType) throws MessagingException;
public String getMimeType() throws MessagingException;
@ -42,5 +40,6 @@ public interface Part {
* @throws MessagingException
*
*/
//TODO perhaps it would be clearer to use a flag "force7bit" in writeTo
public abstract void setUsing7bitTransport() throws MessagingException;
}

View file

@ -20,9 +20,8 @@ import org.apache.james.mime4j.util.MimeUtil;
* Message.
*/
public class MimeBodyPart extends BodyPart {
protected MimeHeader mHeader = new MimeHeader();
protected final MimeHeader mHeader = new MimeHeader();
protected Body mBody;
protected int mSize;
public MimeBodyPart() throws MessagingException {
this(null);
@ -125,10 +124,6 @@ public class MimeBodyPart extends BodyPart {
return getMimeType().equalsIgnoreCase(mimeType);
}
public int getSize() {
return mSize;
}
/**
* Write the MimeMessage out in MIME format.
*/

View file

@ -25,6 +25,7 @@ import org.apache.james.mime4j.stream.Field;
import org.apache.james.mime4j.stream.MimeConfig;
import org.apache.james.mime4j.util.MimeUtil;
import com.fsck.k9.BuildConfig;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.BodyPart;
@ -62,20 +63,6 @@ public class MimeMessage extends Message {
}
/**
* Parse the given InputStream using Apache Mime4J to build a MimeMessage.
* Nested messages will not be recursively parsed.
*
* @param in
* @throws IOException
* @throws MessagingException
*
* @see #MimeMessage(InputStream in, boolean recurse)
*/
public MimeMessage(InputStream in) throws IOException, MessagingException {
parse(in);
}
/**
* Parse the given InputStream using Apache Mime4J to build a MimeMessage.
*
@ -88,11 +75,15 @@ public class MimeMessage extends Message {
parse(in, recurse);
}
protected void parse(InputStream in) throws IOException, MessagingException {
/**
* Parse the given InputStream using Apache Mime4J to build a MimeMessage.
* Does not recurse through nested bodyparts.
*/
public final void parse(InputStream in) throws IOException, MessagingException {
parse(in, false);
}
protected void parse(InputStream in, boolean recurse) throws IOException, MessagingException {
private void parse(InputStream in, boolean recurse) throws IOException, MessagingException {
mHeader.clear();
mFrom = null;
mTo = null;
@ -121,8 +112,8 @@ public class MimeMessage extends Message {
try {
parser.parse(new EOLConvertingInputStream(in));
} catch (MimeException me) {
//TODO wouldn't a MessagingException be better?
throw new Error(me);
}
}
@ -482,7 +473,7 @@ public class MimeMessage extends Message {
}
}
class MimeMessageBuilder implements ContentHandler {
private class MimeMessageBuilder implements ContentHandler {
private final LinkedList<Object> stack = new LinkedList<Object>();
public MimeMessageBuilder() {
@ -519,9 +510,6 @@ public class MimeMessage extends Message {
expect(Part.class);
}
public void endHeader() {
expect(Part.class);
}
@ -571,16 +559,6 @@ public class MimeMessage extends Message {
stack.removeFirst();
}
public void epilogue(InputStream is) throws IOException {
expect(MimeMultipart.class);
StringBuilder sb = new StringBuilder();
int b;
while ((b = is.read()) != -1) {
sb.append((char)b);
}
// ((Multipart) stack.peek()).setEpilogue(sb.toString());
}
public void preamble(InputStream is) throws IOException {
expect(MimeMultipart.class);
StringBuilder sb = new StringBuilder();
@ -589,7 +567,9 @@ public class MimeMessage extends Message {
sb.append((char)b);
}
((MimeMultipart)stack.peek()).setPreamble(sb.toString());
}
public void epilogue(InputStream is) throws IOException {
}
public void raw(InputStream is) throws IOException {

View file

@ -993,8 +993,7 @@ public class MimeUtility {
throws MessagingException {
if (part.getBody() instanceof Multipart) {
Multipart multipart = (Multipart)part.getBody();
for (int i = 0, count = multipart.getCount(); i < count; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
for (BodyPart bodyPart : multipart.getBodyParts()) {
Part ret = findFirstPartByMimeType(bodyPart, mimeType);
if (ret != null) {
return ret;
@ -1009,8 +1008,7 @@ public class MimeUtility {
public static Part findPartByContentId(Part part, String contentId) throws Exception {
if (part.getBody() instanceof Multipart) {
Multipart multipart = (Multipart)part.getBody();
for (int i = 0, count = multipart.getCount(); i < count; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
for (BodyPart bodyPart : multipart.getBodyParts()) {
Part ret = findPartByContentId(bodyPart, contentId);
if (ret != null) {
return ret;
@ -1490,9 +1488,7 @@ public class MimeUtility {
}
} else {
// For all other multipart parts we recurse to grab all viewable children.
int childCount = multipart.getCount();
for (int i = 0; i < childCount; i++) {
Part bodyPart = multipart.getBodyPart(i);
for (Part bodyPart : multipart.getBodyParts()) {
viewables.addAll(getViewables(bodyPart, attachments));
}
}
@ -1547,9 +1543,7 @@ public class MimeUtility {
throws MessagingException {
List<Viewable> viewables = new ArrayList<Viewable>();
int childCount = multipart.getCount();
for (int i = 0; i < childCount; i++) {
Part part = multipart.getBodyPart(i);
for (Part part : multipart.getBodyParts()) {
Body body = part.getBody();
if (body instanceof Multipart) {
Multipart innerMultipart = (Multipart) body;
@ -1612,9 +1606,7 @@ public class MimeUtility {
List<Viewable> viewables = new ArrayList<Viewable>();
boolean partFound = false;
int childCount = multipart.getCount();
for (int i = 0; i < childCount; i++) {
Part part = multipart.getBodyPart(i);
for (Part part : multipart.getBodyParts()) {
Body body = part.getBody();
if (body instanceof Multipart) {
Multipart innerMultipart = (Multipart) body;
@ -1698,9 +1690,7 @@ public class MimeUtility {
*/
private static void findAttachments(Multipart multipart, Set<Part> knownTextParts,
List<Part> attachments) {
int childCount = multipart.getCount();
for (int i = 0; i < childCount; i++) {
Part part = multipart.getBodyPart(i);
for (Part part : multipart.getBodyParts()) {
Body body = part.getBody();
if (body instanceof Multipart) {
Multipart innerMultipart = (Multipart) body;
@ -3422,8 +3412,7 @@ public class MimeUtility {
} else if (part.isMimeType("multipart/alternative") &&
firstBody instanceof MimeMultipart) {
MimeMultipart multipart = (MimeMultipart) firstBody;
for (int i = 0, count = multipart.getCount(); i < count; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
for (BodyPart bodyPart : multipart.getBodyParts()) {
String bodyText = getTextFromPart(bodyPart);
if (bodyText != null) {
if (text.isEmpty() && bodyPart.isMimeType("text/plain")) {

View file

@ -1834,7 +1834,7 @@ public class ImapStore extends Store {
* For each part in the message we're going to add a new BodyPart and parse
* into it.
*/
ImapBodyPart bp = new ImapBodyPart();
MimeBodyPart bp = new MimeBodyPart();
if (id.equalsIgnoreCase("TEXT")) {
parseBodyStructure(bs.getList(i), bp, Integer.toString(i + 1));
} else {
@ -1970,10 +1970,6 @@ public class ImapStore extends Store {
if (part instanceof ImapMessage) {
((ImapMessage) part).setSize(size);
} else if (part instanceof ImapBodyPart) {
((ImapBodyPart) part).setSize(size);
} else {
throw new MessagingException("Unknown part type " + part.toString());
}
part.setHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA, id);
}
@ -2931,11 +2927,6 @@ public class ImapStore extends Store {
this.mSize = size;
}
@Override
public void parse(InputStream in) throws IOException, MessagingException {
super.parse(in);
}
public void setFlagInternal(Flag flag, boolean set) throws MessagingException {
super.setFlag(flag, set);
}
@ -2953,16 +2944,6 @@ public class ImapStore extends Store {
}
}
static class ImapBodyPart extends MimeBodyPart {
public ImapBodyPart() throws MessagingException {
super();
}
public void setSize(int size) {
this.mSize = size;
}
}
static class ImapException extends MessagingException {
private static final long serialVersionUID = 3725007182205882394L;
String mAlertText;

View file

@ -1194,11 +1194,6 @@ public class Pop3Store extends Store {
mSize = size;
}
@Override
protected void parse(InputStream in) throws IOException, MessagingException {
super.parse(in);
}
@Override
public void setFlag(Flag flag, boolean set) throws MessagingException {
super.setFlag(flag, set);

View file

@ -2029,11 +2029,6 @@ public class WebDavStore extends Store {
this.mSize = size;
}
@Override
public void parse(InputStream in) throws IOException, MessagingException {
super.parse(in);
}
public void setFlagInternal(Flag flag, boolean set) throws MessagingException {
super.setFlag(flag, set);
}

View file

@ -6,11 +6,7 @@ public class LocalTextBody extends TextBody {
/**
* This is an HTML-ified version of the message for display purposes.
*/
private String mBodyForDisplay;
public LocalTextBody(String body) {
super(body);
}
private final String mBodyForDisplay;
public LocalTextBody(String body, String bodyForDisplay) {
super(body);
@ -21,8 +17,4 @@ public class LocalTextBody extends TextBody {
return mBodyForDisplay;
}
public void setBodyForDisplay(String mBodyForDisplay) {
this.mBodyForDisplay = mBodyForDisplay;
}
}//LocalTextBody

View file

@ -511,6 +511,7 @@ public class SmtpTransport extends Transport {
if (mLargestAcceptableMessage > 0 && ((LocalMessage)message).hasAttachments()) {
if (message.calculateSize() > mLargestAcceptableMessage) {
MessagingException me = new MessagingException("Message too large for server");
//TODO this looks rather suspicious... shouldn't it be true?
me.setPermanentFailure(possibleSend);
throw me;
}
@ -545,14 +546,13 @@ public class SmtpTransport extends Transport {
possibleSend = false;
}
//TODO this looks rather suspicious... why is possibleSend used, and why are 5xx NOT permanent (in contrast to the log text)
me.setPermanentFailure(possibleSend);
throw me;
} finally {
close();
}
}
@Override

View file

@ -54,7 +54,7 @@ public class ConditionsTreeNode implements Parcelable {
* should point to rows representing the nodes of the tree.
*
* @param cursor Cursor pointing to the first of a bunch or rows. Each rows
* should contains 1 tree node.
* should contains 1 tree node.
* @return A condition tree.
*/
public static ConditionsTreeNode buildTreeFromDB(Cursor cursor) {

View file

@ -240,8 +240,8 @@ public class LocalSearch implements SearchSpecification {
public void addAllowedFolder(String name) {
/*
* TODO find folder sub-tree
* - do and on root of it & rest of search
* - do or between folder nodes
* - do and on root of it & rest of search
* - do or between folder nodes
*/
mConditions = and(new SearchCondition(Searchfield.FOLDER, Attribute.EQUALS, name));
}

View file

@ -58,8 +58,8 @@ public interface SearchSpecification extends Parcelable {
* By result, only the fields in here are searchable.
*
* Fields not in here at this moment ( and by effect not searchable ):
* id, html_content, internal_date, message_id,
* preview, mime_type
* id, html_content, internal_date, message_id,
* preview, mime_type
*
*/
public enum Searchfield {
@ -92,9 +92,9 @@ public interface SearchSpecification extends Parcelable {
/**
* This class represents 1 value for a certain search field. One
* value consists of three things:
* an attribute: equals, starts with, contains,...
* a searchfield: date, flags, sender, subject,...
* a value: "apple", "jesse",..
* an attribute: equals, starts with, contains,...
* a searchfield: date, flags, sender, subject,...
* a value: "apple", "jesse",..
*
* @author dzan
*/

View file

@ -0,0 +1,236 @@
package com.fsck.k9.mail.internet;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.io.IOUtils;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.BodyPart;
import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mail.Multipart;
import com.fsck.k9.mail.internet.MimeMessage;
import android.test.AndroidTestCase;
public class MimeMessageParseTest extends AndroidTestCase {
static {
BinaryTempFileBody.setTempDirectory(new File(System.getProperty("java.io.tmpdir")));
}
private static ByteArrayInputStream toStream(String rawMailData) throws Exception {
return new ByteArrayInputStream(rawMailData.getBytes("ISO-8859-1"));
}
private static MimeMessage parseWithoutRecurse(InputStream data) throws Exception {
return new MimeMessage(data, false);
}
private static MimeMessage parseWithRecurse(InputStream data) throws Exception {
return new MimeMessage(data, true);
}
private static void checkAddresses(Address[] actual, String... expected) {
for (int i = 0; i < actual.length; i++) {
assertEquals(actual[i].toEncodedString(), expected[i]);
}
assertEquals(expected.length, actual.length);
}
private static String streamToString(InputStream stream) throws Exception {
return IOUtils.toString(stream, "ISO-8859-1");
}
private static List<Body> getLeafParts(Body body) {
if (body instanceof Multipart) {
List<Body> ret = new ArrayList<Body>();
for (BodyPart child : ((Multipart) body).getBodyParts()) {
ret.addAll(getLeafParts(child.getBody()));
}
return ret;
} else {
return Collections.singletonList(body);
}
}
private static void checkLeafParts(MimeMessage msg, String... expectedParts) throws Exception {
List<String> actual = new ArrayList<String>();
for (Body leaf : getLeafParts(msg.getBody())) {
actual.add(streamToString(leaf.getInputStream()));
}
assertEquals(Arrays.asList(expectedParts), actual);
}
public static void testSinglePart7BitNoRecurse() throws Exception {
MimeMessage msg = parseWithoutRecurse(toStream(
"From: <adam@example.org>\r\n" +
"To: <eva@example.org>\r\n" +
"Subject: Testmail\r\n" +
"MIME-Version: 1.0\r\n" +
"Content-type: text/plain\r\n" +
"Content-Transfer-Encoding: 7bit\r\n" +
"\r\n" +
"this is some test text."));
checkAddresses(msg.getFrom(), "adam@example.org");
checkAddresses(msg.getRecipients(RecipientType.TO), "eva@example.org");
assertEquals("Testmail", msg.getSubject());
assertEquals("text/plain", msg.getContentType());
assertEquals("this is some test text.", streamToString(msg.getBody().getInputStream()));
}
public static void testSinglePart8BitRecurse() throws Exception {
MimeMessage msg = parseWithRecurse(toStream(
"From: <adam@example.org>\r\n" +
"To: <eva@example.org>\r\n" +
"Subject: Testmail\r\n" +
"MIME-Version: 1.0\r\n" +
"Content-type: text/plain; encoding=ISO-8859-1\r\n" +
"Content-Transfer-Encoding: 8bit\r\n" +
"\r\n" +
"gefährliche Umlaute"));
checkAddresses(msg.getFrom(), "adam@example.org");
checkAddresses(msg.getRecipients(RecipientType.TO), "eva@example.org");
assertEquals("Testmail", msg.getSubject());
assertEquals("text/plain; encoding=ISO-8859-1", msg.getContentType());
assertEquals("gefährliche Umlaute", streamToString(msg.getBody().getInputStream()));
}
public static void testSinglePartBase64NoRecurse() throws Exception {
MimeMessage msg = parseWithoutRecurse(toStream(
"From: <adam@example.org>\r\n" +
"To: <eva@example.org>\r\n" +
"Subject: Testmail\r\n" +
"MIME-Version: 1.0\r\n" +
"Content-type: text/plain\r\n" +
"Content-Transfer-Encoding: base64\r\n" +
"\r\n" +
"dGhpcyBpcyBzb21lIG1vcmUgdGVzdCB0ZXh0Lg==\r\n"));
checkAddresses(msg.getFrom(), "adam@example.org");
checkAddresses(msg.getRecipients(RecipientType.TO), "eva@example.org");
assertEquals("Testmail", msg.getSubject());
assertEquals("text/plain", msg.getContentType());
assertEquals("this is some more test text.", streamToString(msg.getBody().getInputStream()));
}
public static void testMultipartSingleLayerNoRecurse() throws Exception {
MimeMessage msg = parseWithoutRecurse(toStream(
"From: <x@example.org>\r\n" +
"To: <y@example.org>\r\n" +
"Subject: Testmail 2\r\n" +
"MIME-Version: 1.0\n" +
"Content-Type: multipart/mixed; boundary=frontier\n" +
"\n" +
"This is a message with multiple parts in MIME format.\n" +
"--frontier\n" +
"Content-Type: text/plain\n" +
"\n" +
"This is the body of the message.\n" +
"--frontier\n" +
"Content-Type: application/octet-stream\n" +
"Content-Transfer-Encoding: base64\n" +
"\n" +
"PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg\n" +
"Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg=\n" +
"--frontier--"));
checkAddresses(msg.getFrom(), "x@example.org");
checkAddresses(msg.getRecipients(RecipientType.TO), "y@example.org");
assertEquals("Testmail 2", msg.getSubject());
assertEquals("multipart/mixed; boundary=frontier", msg.getContentType());
checkLeafParts(msg,
"This is the body of the message.",
"<html>\n" +
" <head>\n" +
" </head>\n" +
" <body>\n" +
" <p>This is the body of the message.</p>\n" +
" </body>\n" +
"</html>\n" +
"");
}
public static void testMultipartSingleLayerRecurse() throws Exception {
MimeMessage msg = parseWithRecurse(toStream(
"From: <x@example.org>\r\n" +
"To: <y@example.org>\r\n" +
"Subject: Testmail 2\r\n" +
"MIME-Version: 1.0\n" +
"Content-Type: multipart/mixed; boundary=frontier\n" +
"\n" +
"This is a message with multiple parts in MIME format.\n" +
"--frontier\n" +
"Content-Type: text/plain\n" +
"\n" +
"This is the body of the message.\n" +
"--frontier\n" +
"Content-Type: application/octet-stream\n" +
"Content-Transfer-Encoding: base64\n" +
"\n" +
"PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg\n" +
"Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg=\n" +
"--frontier--"));
checkAddresses(msg.getFrom(), "x@example.org");
checkAddresses(msg.getRecipients(RecipientType.TO), "y@example.org");
assertEquals("Testmail 2", msg.getSubject());
assertEquals("multipart/mixed; boundary=frontier", msg.getContentType());
checkLeafParts(msg,
"This is the body of the message.",
"<html>\n" +
" <head>\n" +
" </head>\n" +
" <body>\n" +
" <p>This is the body of the message.</p>\n" +
" </body>\n" +
"</html>\n" +
"");
}
public static void testMultipartTwoLayersRecurse() throws Exception {
MimeMessage msg = parseWithRecurse(toStream(
"From: <x@example.org>\r\n" +
"To: <y@example.org>\r\n" +
"Subject: Testmail 2\r\n" +
"MIME-Version: 1.0\n" +
"Content-Type: multipart/mixed; boundary=1\n" +
"\n" +
"This is a message with multiple parts in MIME format.\n" +
"--1\n" +
"Content-Type: text/plain\n" +
"\n" +
"some text in the first part\n" +
"--1\n" +
"Content-Type: multipart/alternative; boundary=2\n" +
"\n" +
"--2\n" +
"Content-Type: text/plain\n" +
"\n" +
"alternative 1\n" +
"--2\n" +
"Content-Type: text/plain\n" +
"\n" +
"alternative 2\n" +
"--2--\n" +
"--1--"));
checkAddresses(msg.getFrom(), "x@example.org");
checkAddresses(msg.getRecipients(RecipientType.TO), "y@example.org");
assertEquals("Testmail 2", msg.getSubject());
assertEquals("multipart/mixed; boundary=1", msg.getContentType());
checkLeafParts(msg,
"some text in the first part",
"alternative 1",
"alternative 2");
}
}

View file

@ -100,7 +100,7 @@ public class ViewablesTest extends AndroidTestCase {
}
public void testTextPlusRfc822Message() throws MessagingException {
K9ActivityCommon.setLanguage(getContext(), "en");
K9ActivityCommon.setLanguage(getContext(), "en");
Locale.setDefault(Locale.US);
TimeZone.setDefault(TimeZone.getTimeZone("GMT+01:00"));