Message.java revision 4d3e937bb3ca208c320e8a124c6f26079c4090d0
13ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira/**
23ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira * Copyright (c) 2012, Google Inc.
33ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira *
43ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License");
53ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira * you may not use this file except in compliance with the License.
63ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira * You may obtain a copy of the License at
73ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira *
83ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira *     http://www.apache.org/licenses/LICENSE-2.0
93ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira *
103ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira * Unless required by applicable law or agreed to in writing, software
113ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS,
123ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira * See the License for the specific language governing permissions and
143ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira * limitations under the License.
153ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira */
163ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
173ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereirapackage com.android.mail.providers;
183ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
193233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huangimport android.content.AsyncQueryHandler;
203233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huangimport android.content.ContentValues;
217434e800d4313a227120ca36bd95683752a7879fAndrew Sappersteinimport android.content.Context;
223ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereiraimport android.database.Cursor;
23cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereiraimport android.net.Uri;
243ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereiraimport android.os.Parcel;
253ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereiraimport android.os.Parcelable;
26e623a0f6e3caa9cafec913cf826e946628833517Andy Huangimport android.provider.BaseColumns;
27014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huangimport android.text.Html;
288d6e803bf63d5dad5cb0187c82171e42147e8a44Yu Ping Huimport android.text.SpannableString;
29cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereiraimport android.text.TextUtils;
308d6e803bf63d5dad5cb0187c82171e42147e8a44Yu Ping Huimport android.text.util.Linkify;
315ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindypimport android.text.util.Rfc822Token;
325ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindypimport android.text.util.Rfc822Tokenizer;
333ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
34821e578a71c7015646522e729600618f0ec16fc0Tony Mantlerimport com.android.emailcommon.mail.Address;
358812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sappersteinimport com.android.emailcommon.internet.MimeMessage;
368812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sappersteinimport com.android.emailcommon.internet.MimeUtility;
378812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sappersteinimport com.android.emailcommon.mail.MessagingException;
388812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sappersteinimport com.android.emailcommon.mail.Part;
398812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sappersteinimport com.android.emailcommon.utility.ConversionUtilities;
4026846d859a4714ff90ea02dba251a54cac1f1e9fMarc Blankimport com.android.mail.providers.UIProvider.MessageColumns;
41606dbd7a44b8445e872c25c0fe080e3e12a47adfAndrew Sappersteinimport com.android.mail.ui.HtmlMessage;
4226846d859a4714ff90ea02dba251a54cac1f1e9fMarc Blankimport com.android.mail.utils.Utils;
432bae2f5ef13424f8d932f5e45a2e276b531ecfe6Martin Hibdonimport com.google.common.annotations.VisibleForTesting;
44cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huangimport com.google.common.base.Objects;
457434e800d4313a227120ca36bd95683752a7879fAndrew Sappersteinimport com.google.common.collect.Lists;
4626846d859a4714ff90ea02dba251a54cac1f1e9fMarc Blank
478812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sappersteinimport java.util.ArrayList;
489ab47b16e0189d219c16e2eddfbd66c741c01229Andy Huangimport java.util.Collections;
4920dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sappersteinimport java.util.Date;
505a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport java.util.List;
5141dca185f7683b36bdafd9520c0648c897a95834Paul Westbrookimport java.util.regex.Pattern;
525a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang
533ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
54606dbd7a44b8445e872c25c0fe080e3e12a47adfAndrew Sappersteinpublic class Message implements Parcelable, HtmlMessage {
55e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
5641dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook     * Regex pattern used to look for any inline images in message bodies, including Gmail-hosted
5741dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook     * relative-URL images, Gmail emoticons, and any external inline images (although we usually
5841dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook     * count on the server to detect external images).
5941dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook     */
6041dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    private static Pattern INLINE_IMAGE_PATTERN = Pattern.compile("<img\\s+[^>]*src=",
6141dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
6241dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook
6341dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    /**
64e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see BaseColumns#_ID
65e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
663ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public long id;
67e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
68e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#SERVER_ID
69e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
70d47877e3860ea4249eddb3f6efefbc6cd39f2320Andy Huang    public String serverId;
71e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
72e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#URI
73e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
74cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira    public Uri uri;
75e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
76e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#CONVERSATION_ID
77e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
78daa06aba887e8e3748453f45ae52c1e571fe9f2eAndy Huang    public Uri conversationUri;
79e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
80e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#SUBJECT
81e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
823ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public String subject;
83e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
84e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#SNIPPET
85e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
863ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public String snippet;
87e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
88e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#FROM
89e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
908960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    private String mFrom;
91e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
92e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#TO
93e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
948960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    private String mTo;
95e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
96e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#CC
97e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
988960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    private String mCc;
99e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
100e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#BCC
101e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1028960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    private String mBcc;
103e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
104e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#REPLY_TO
105e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1068960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    private String mReplyTo;
107e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
108e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#DATE_RECEIVED_MS
109e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1103ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public long dateReceivedMs;
111e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
112e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#BODY_HTML
113e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1143ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public String bodyHtml;
115e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
116e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#BODY_TEXT
117e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1183ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public String bodyText;
119e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
120e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#EMBEDS_EXTERNAL_RESOURCES
121e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1223ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public boolean embedsExternalResources;
123e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
124e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#REF_MESSAGE_ID
125e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
126a990a715012379451344246c5156d29938f12886Alice Yang    public Uri refMessageUri;
127e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
128e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#DRAFT_TYPE
129e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1303ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public int draftType;
131e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
132e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#APPEND_REF_MESSAGE_CONTENT
133e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1343ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public boolean appendRefMessageContent;
135e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
136e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#HAS_ATTACHMENTS
137e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1383ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public boolean hasAttachments;
139e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
140e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#ATTACHMENT_LIST_URI
141e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
142cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira    public Uri attachmentListUri;
143e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
144e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#MESSAGE_FLAGS
145e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1463ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public long messageFlags;
147e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
148e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#ALWAYS_SHOW_IMAGES
149e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
150104f729c284f9b7b31a251350252f8ae31d09f86Paul Westbrook    public boolean alwaysShowImages;
151e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
152e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#READ
153e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
154d8e249ee7abb0e1ad24e17e4e299736d4a150936Andy Huang    public boolean read;
155e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
156d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @see UIProvider.MessageColumns#SEEN
157d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
158d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public boolean seen;
159d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
160e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#STARRED
161e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
162d8e249ee7abb0e1ad24e17e4e299736d4a150936Andy Huang    public boolean starred;
163e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
164e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#QUOTE_START_POS
165e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1664dbbf9f91da20d89b13d412038c0b19b91983f8cMindy Pereira    public int quotedTextOffset;
167e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
168e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#ATTACHMENTS
1696766b6e5468d2f1935587b3bc1f8e65be94cd6fbAndy Huang     *<p>
1706766b6e5468d2f1935587b3bc1f8e65be94cd6fbAndy Huang     * N.B. this value is NOT immutable and may change during conversation view render.
171e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1725a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang    public String attachmentsJson;
173e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
174e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#MESSAGE_ACCOUNT_URI
175e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
17662de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira    public Uri accountUri;
177e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
178e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.MessageColumns#EVENT_INTENT_URI
179e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
1803842af9e8ba90ebf5b75dc5018bbfdfb2e044f99Marc Blank    public Uri eventIntentUri;
181d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein    /**
182d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein     * @see UIProvider.MessageColumns#SPAM_WARNING_STRING
183d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein     */
1843b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein    public String spamWarningString;
185d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein    /**
186d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein     * @see UIProvider.MessageColumns#SPAM_WARNING_LEVEL
187d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein     */
1883b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein    public int spamWarningLevel;
189d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein    /**
190d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein     * @see UIProvider.MessageColumns#SPAM_WARNING_LINK_TYPE
191d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein     */
1923b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein    public int spamLinkType;
193d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein    /**
194d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein     * @see UIProvider.MessageColumns#VIA_DOMAIN
195d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein     */
196d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein    public String viaDomain;
19747aa9c991b33c722a6ba1946fc02e0aba17bc1c9Andy Huang    /**
19847aa9c991b33c722a6ba1946fc02e0aba17bc1c9Andy Huang     * @see UIProvider.MessageColumns#IS_SENDING
19947aa9c991b33c722a6ba1946fc02e0aba17bc1c9Andy Huang     */
20047aa9c991b33c722a6ba1946fc02e0aba17bc1c9Andy Huang    public boolean isSending;
2015a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang
202d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein    private transient String[] mFromAddresses = null;
2035a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang    private transient String[] mToAddresses = null;
2045a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang    private transient String[] mCcAddresses = null;
2055a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang    private transient String[] mBccAddresses = null;
2065a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang    private transient String[] mReplyToAddresses = null;
2073ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
2085a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang    private transient List<Attachment> mAttachments = null;
209845f87e34179bcbb2862c09572576ab775be472dmindyp
2103ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    @Override
2113ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public int describeContents() {
2123ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        return 0;
2133ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    }
2143ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
2153ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    @Override
2163233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    public boolean equals(Object o) {
217cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        return this == o || (o != null && o instanceof Message
218cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang                && Objects.equal(uri, ((Message) o).uri));
2193233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    }
2203233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang
2213233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    @Override
2223233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    public int hashCode() {
2233233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang        return uri == null ? 0 : uri.hashCode();
2243233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    }
2253233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang
2263233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    @Override
2273ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public void writeToParcel(Parcel dest, int flags) {
2283ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeLong(id);
229d47877e3860ea4249eddb3f6efefbc6cd39f2320Andy Huang        dest.writeString(serverId);
230cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        dest.writeParcelable(uri, 0);
231daa06aba887e8e3748453f45ae52c1e571fe9f2eAndy Huang        dest.writeParcelable(conversationUri, 0);
2323ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeString(subject);
2333ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeString(snippet);
2348960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        dest.writeString(mFrom);
2358960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        dest.writeString(mTo);
2368960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        dest.writeString(mCc);
2378960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        dest.writeString(mBcc);
2388960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        dest.writeString(mReplyTo);
2393ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeLong(dateReceivedMs);
2403ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeString(bodyHtml);
2413ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeString(bodyText);
2423ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeInt(embedsExternalResources ? 1 : 0);
243a990a715012379451344246c5156d29938f12886Alice Yang        dest.writeParcelable(refMessageUri, 0);
2443ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeInt(draftType);
2453ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeInt(appendRefMessageContent ? 1 : 0);
2463ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeInt(hasAttachments ? 1 : 0);
247cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        dest.writeParcelable(attachmentListUri, 0);
2483ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dest.writeLong(messageFlags);
249104f729c284f9b7b31a251350252f8ae31d09f86Paul Westbrook        dest.writeInt(alwaysShowImages ? 1 : 0);
2504dbbf9f91da20d89b13d412038c0b19b91983f8cMindy Pereira        dest.writeInt(quotedTextOffset);
2512421dc8d6d0b4c727ab7ab0e5ce730f415089e86Mindy Pereira        dest.writeString(attachmentsJson);
25262de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira        dest.writeParcelable(accountUri, 0);
2533842af9e8ba90ebf5b75dc5018bbfdfb2e044f99Marc Blank        dest.writeParcelable(eventIntentUri, 0);
2543b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein        dest.writeString(spamWarningString);
2553b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein        dest.writeInt(spamWarningLevel);
2563b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein        dest.writeInt(spamLinkType);
257d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein        dest.writeString(viaDomain);
25847aa9c991b33c722a6ba1946fc02e0aba17bc1c9Andy Huang        dest.writeInt(isSending ? 1 : 0);
2593ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    }
2603ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
2613ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    private Message(Parcel in) {
2623ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        id = in.readLong();
263d47877e3860ea4249eddb3f6efefbc6cd39f2320Andy Huang        serverId = in.readString();
264cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        uri = in.readParcelable(null);
265daa06aba887e8e3748453f45ae52c1e571fe9f2eAndy Huang        conversationUri = in.readParcelable(null);
2663ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        subject = in.readString();
2673ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        snippet = in.readString();
2688960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mFrom = in.readString();
2698960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mTo = in.readString();
2708960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mCc = in.readString();
2718960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mBcc = in.readString();
2728960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mReplyTo = in.readString();
2733ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        dateReceivedMs = in.readLong();
2743ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        bodyHtml = in.readString();
2753ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        bodyText = in.readString();
2763ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        embedsExternalResources = in.readInt() != 0;
277a990a715012379451344246c5156d29938f12886Alice Yang        refMessageUri = in.readParcelable(null);
2783ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        draftType = in.readInt();
2793ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        appendRefMessageContent = in.readInt() != 0;
2803ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        hasAttachments = in.readInt() != 0;
281cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        attachmentListUri = in.readParcelable(null);
2823ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        messageFlags = in.readLong();
283104f729c284f9b7b31a251350252f8ae31d09f86Paul Westbrook        alwaysShowImages = in.readInt() != 0;
2844dbbf9f91da20d89b13d412038c0b19b91983f8cMindy Pereira        quotedTextOffset = in.readInt();
2852421dc8d6d0b4c727ab7ab0e5ce730f415089e86Mindy Pereira        attachmentsJson = in.readString();
28662de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira        accountUri = in.readParcelable(null);
2873842af9e8ba90ebf5b75dc5018bbfdfb2e044f99Marc Blank        eventIntentUri = in.readParcelable(null);
2883b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein        spamWarningString = in.readString();
2893b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein        spamWarningLevel = in.readInt();
2903b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein        spamLinkType = in.readInt();
291d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein        viaDomain = in.readString();
29247aa9c991b33c722a6ba1946fc02e0aba17bc1c9Andy Huang        isSending = in.readInt() != 0;
293104f729c284f9b7b31a251350252f8ae31d09f86Paul Westbrook    }
294104f729c284f9b7b31a251350252f8ae31d09f86Paul Westbrook
295104f729c284f9b7b31a251350252f8ae31d09f86Paul Westbrook    public Message() {
296104f729c284f9b7b31a251350252f8ae31d09f86Paul Westbrook
2973ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    }
2983ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
2993ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    @Override
3003ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public String toString() {
3013ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        return "[message id=" + id + "]";
3023ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    }
3033ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
3043ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    public static final Creator<Message> CREATOR = new Creator<Message>() {
3053ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
3063ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        @Override
3073ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        public Message createFromParcel(Parcel source) {
3083ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            return new Message(source);
3093ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        }
3103ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
3113ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        @Override
3123ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        public Message[] newArray(int size) {
3133ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            return new Message[size];
3143ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        }
3153ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
3163ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    };
3173ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira
318a831b2f1ba6d3c18d5e54563df8bae1f589c4257Mindy Pereira    public Message(Cursor cursor) {
3193ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        if (cursor != null) {
3203ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            id = cursor.getLong(UIProvider.MESSAGE_ID_COLUMN);
321d47877e3860ea4249eddb3f6efefbc6cd39f2320Andy Huang            serverId = cursor.getString(UIProvider.MESSAGE_SERVER_ID_COLUMN);
322daa06aba887e8e3748453f45ae52c1e571fe9f2eAndy Huang            final String messageUriStr = cursor.getString(UIProvider.MESSAGE_URI_COLUMN);
323daa06aba887e8e3748453f45ae52c1e571fe9f2eAndy Huang            uri = !TextUtils.isEmpty(messageUriStr) ? Uri.parse(messageUriStr) : null;
324daa06aba887e8e3748453f45ae52c1e571fe9f2eAndy Huang            final String convUriStr = cursor.getString(UIProvider.MESSAGE_CONVERSATION_URI_COLUMN);
325daa06aba887e8e3748453f45ae52c1e571fe9f2eAndy Huang            conversationUri = !TextUtils.isEmpty(convUriStr) ? Uri.parse(convUriStr) : null;
3263ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            subject = cursor.getString(UIProvider.MESSAGE_SUBJECT_COLUMN);
3273ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            snippet = cursor.getString(UIProvider.MESSAGE_SNIPPET_COLUMN);
3288960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy            mFrom = cursor.getString(UIProvider.MESSAGE_FROM_COLUMN);
3298960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy            mTo = cursor.getString(UIProvider.MESSAGE_TO_COLUMN);
3308960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy            mCc = cursor.getString(UIProvider.MESSAGE_CC_COLUMN);
3318960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy            mBcc = cursor.getString(UIProvider.MESSAGE_BCC_COLUMN);
3328960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy            mReplyTo = cursor.getString(UIProvider.MESSAGE_REPLY_TO_COLUMN);
3333ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            dateReceivedMs = cursor.getLong(UIProvider.MESSAGE_DATE_RECEIVED_MS_COLUMN);
3343ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            bodyHtml = cursor.getString(UIProvider.MESSAGE_BODY_HTML_COLUMN);
3353ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            bodyText = cursor.getString(UIProvider.MESSAGE_BODY_TEXT_COLUMN);
3363ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            embedsExternalResources = cursor
3373ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira                    .getInt(UIProvider.MESSAGE_EMBEDS_EXTERNAL_RESOURCES_COLUMN) != 0;
338a990a715012379451344246c5156d29938f12886Alice Yang            final String refMessageUriStr =
339a990a715012379451344246c5156d29938f12886Alice Yang                    cursor.getString(UIProvider.MESSAGE_REF_MESSAGE_URI_COLUMN);
340a990a715012379451344246c5156d29938f12886Alice Yang            refMessageUri = !TextUtils.isEmpty(refMessageUriStr) ?
341a990a715012379451344246c5156d29938f12886Alice Yang                    Uri.parse(refMessageUriStr) : null;
3423ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            draftType = cursor.getInt(UIProvider.MESSAGE_DRAFT_TYPE_COLUMN);
3433ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            appendRefMessageContent = cursor
3443ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira                    .getInt(UIProvider.MESSAGE_APPEND_REF_MESSAGE_CONTENT_COLUMN) != 0;
3453ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            hasAttachments = cursor.getInt(UIProvider.MESSAGE_HAS_ATTACHMENTS_COLUMN) != 0;
3467bb27253d9eb377d13da55b67b0babd047eca367Mindy Pereira            final String attachmentsUri = cursor
3477bb27253d9eb377d13da55b67b0babd047eca367Mindy Pereira                    .getString(UIProvider.MESSAGE_ATTACHMENT_LIST_URI_COLUMN);
3487bb27253d9eb377d13da55b67b0babd047eca367Mindy Pereira            attachmentListUri = hasAttachments && !TextUtils.isEmpty(attachmentsUri) ? Uri
3497bb27253d9eb377d13da55b67b0babd047eca367Mindy Pereira                    .parse(attachmentsUri) : null;
3503ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira            messageFlags = cursor.getLong(UIProvider.MESSAGE_FLAGS_COLUMN);
351d8e249ee7abb0e1ad24e17e4e299736d4a150936Andy Huang            alwaysShowImages = cursor.getInt(UIProvider.MESSAGE_ALWAYS_SHOW_IMAGES_COLUMN) != 0;
352d8e249ee7abb0e1ad24e17e4e299736d4a150936Andy Huang            read = cursor.getInt(UIProvider.MESSAGE_READ_COLUMN) != 0;
353d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            seen = cursor.getInt(UIProvider.MESSAGE_SEEN_COLUMN) != 0;
354d8e249ee7abb0e1ad24e17e4e299736d4a150936Andy Huang            starred = cursor.getInt(UIProvider.MESSAGE_STARRED_COLUMN) != 0;
3554dbbf9f91da20d89b13d412038c0b19b91983f8cMindy Pereira            quotedTextOffset = cursor.getInt(UIProvider.QUOTED_TEXT_OFFSET_COLUMN);
3565a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang            attachmentsJson = cursor.getString(UIProvider.MESSAGE_ATTACHMENTS_COLUMN);
35762de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira            String accountUriString = cursor.getString(UIProvider.MESSAGE_ACCOUNT_URI_COLUMN);
35862de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira            accountUri = !TextUtils.isEmpty(accountUriString) ? Uri.parse(accountUriString) : null;
3593842af9e8ba90ebf5b75dc5018bbfdfb2e044f99Marc Blank            eventIntentUri =
3603842af9e8ba90ebf5b75dc5018bbfdfb2e044f99Marc Blank                    Utils.getValidUri(cursor.getString(UIProvider.MESSAGE_EVENT_INTENT_COLUMN));
3613b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein            spamWarningString =
3623b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein                    cursor.getString(UIProvider.MESSAGE_SPAM_WARNING_STRING_ID_COLUMN);
3633b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein            spamWarningLevel = cursor.getInt(UIProvider.MESSAGE_SPAM_WARNING_LEVEL_COLUMN);
3643b08c51ec46794b3c22c8649eb86bf77c72e0d9aAndrew Sapperstein            spamLinkType = cursor.getInt(UIProvider.MESSAGE_SPAM_WARNING_LINK_TYPE_COLUMN);
365d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein            viaDomain = cursor.getString(UIProvider.MESSAGE_VIA_DOMAIN_COLUMN);
36647aa9c991b33c722a6ba1946fc02e0aba17bc1c9Andy Huang            isSending = cursor.getInt(UIProvider.MESSAGE_IS_SENDING_COLUMN) != 0;
3673ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira        }
3683ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira    }
3690a22047bb6c54d8f1ce980762f75908e35b08c3dAndy Huang
3707434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein    public Message(Context context, MimeMessage mimeMessage, Uri emlFileUri)
3717434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein            throws MessagingException {
3728812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        // Set message header values.
3734d3e937bb3ca208c320e8a124c6f26079c4090d0James Lemieux        setFrom(Address.toHeader(mimeMessage.getFrom()));
3744d3e937bb3ca208c320e8a124c6f26079c4090d0James Lemieux        setTo(Address.toHeader(mimeMessage.getRecipients(
3758812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein                com.android.emailcommon.mail.Message.RecipientType.TO)));
3764d3e937bb3ca208c320e8a124c6f26079c4090d0James Lemieux        setCc(Address.toHeader(mimeMessage.getRecipients(
3778812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein                com.android.emailcommon.mail.Message.RecipientType.CC)));
3784d3e937bb3ca208c320e8a124c6f26079c4090d0James Lemieux        setBcc(Address.toHeader(mimeMessage.getRecipients(
3798812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein                com.android.emailcommon.mail.Message.RecipientType.BCC)));
3804d3e937bb3ca208c320e8a124c6f26079c4090d0James Lemieux        setReplyTo(Address.toHeader(mimeMessage.getReplyTo()));
3818812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        subject = mimeMessage.getSubject();
38220dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sapperstein
38320dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sapperstein        final Date sentDate = mimeMessage.getSentDate();
38420dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sapperstein        final Date internalDate = mimeMessage.getInternalDate();
38520dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sapperstein        if (sentDate != null) {
38620dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sapperstein            dateReceivedMs = sentDate.getTime();
38720dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sapperstein        } else if (internalDate != null) {
38820dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sapperstein            dateReceivedMs = internalDate.getTime();
38920dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sapperstein        } else {
39020dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sapperstein            dateReceivedMs = System.currentTimeMillis();
39120dbbd66471f23520fbddf63c5af6a517839f5e8Andrew Sapperstein        }
3928812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein
3938812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        // for now, always set defaults
3948812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        alwaysShowImages = false;
3958812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        viaDomain = null;
3968812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        draftType = UIProvider.DraftType.NOT_A_DRAFT;
3978812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        isSending = false;
3988812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        starred = false;
3998812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        spamWarningString = null;
4008812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        messageFlags = 0;
4018812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        hasAttachments = false;
4028812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein
4038812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        // body values (snippet/bodyText/bodyHtml)
4048812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        // Now process body parts & attachments
4058812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        ArrayList<Part> viewables = new ArrayList<Part>();
4068812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        ArrayList<Part> attachments = new ArrayList<Part>();
4078812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        MimeUtility.collectParts(mimeMessage, viewables, attachments);
4088812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein
4098812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        ConversionUtilities.BodyFieldData data =
4108812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein                ConversionUtilities.parseBodyFields(viewables);
4118812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein
4128812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        snippet = data.snippet;
4138812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        bodyText = data.textContent;
4148812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein        bodyHtml = data.htmlContent;
4157434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein
4167434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein        // populate mAttachments
4177434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein        mAttachments = Lists.newArrayList();
4187434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein
4197434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein        int partId = 0;
4207434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein        final String messageId = mimeMessage.getMessageId();
4217434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein        for (final Part attachmentPart : attachments) {
4227434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein            mAttachments.add(new Attachment(context, attachmentPart,
4237434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein                    emlFileUri, messageId, Integer.toString(partId++)));
4247434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein        }
4257434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein
4267434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein        hasAttachments = !mAttachments.isEmpty();
4277434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein
4287434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein        attachmentListUri =  hasAttachments ?
4297434e800d4313a227120ca36bd95683752a7879fAndrew Sapperstein                EmlAttachmentProvider.getAttachmentsListUri(emlFileUri, messageId) : null;
4308812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein    }
4318812d3c50e35c4f2a02d29c35c76082c4ebec0cdAndrew Sapperstein
432a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang    public boolean isFlaggedReplied() {
433a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang        return (messageFlags & UIProvider.MessageFlags.REPLIED) ==
434a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang                UIProvider.MessageFlags.REPLIED;
435a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang    }
436a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang
437a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang    public boolean isFlaggedForwarded() {
438a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang        return (messageFlags & UIProvider.MessageFlags.FORWARDED) ==
439a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang                UIProvider.MessageFlags.FORWARDED;
440a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang    }
441a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang
442a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang    public boolean isFlaggedCalendarInvite() {
443a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang        return (messageFlags & UIProvider.MessageFlags.CALENDAR_INVITE) ==
444a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang                UIProvider.MessageFlags.CALENDAR_INVITE;
445a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang    }
446a71f1f3368f26b6627512298f64484611fd6b0e8Andy Huang
4478960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    public String getFrom() {
4488960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        return mFrom;
4498960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    }
4508960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy
4518960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    public synchronized void setFrom(final String from) {
4528960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mFrom = from;
4538960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mFromAddresses = null;
4548960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    }
4558960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy
4568960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    public String getTo() {
4578960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        return mTo;
4588960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    }
4598960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy
4608960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    public synchronized void setTo(final String to) {
4618960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mTo = to;
4628960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mToAddresses = null;
4638960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    }
4648960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy
4658960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    public String getCc() {
4668960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        return mCc;
4678960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    }
4688960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy
4698960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    public synchronized void setCc(final String cc) {
4708960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mCc = cc;
4718960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mCcAddresses = null;
4728960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    }
4738960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy
4748960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    public String getBcc() {
4758960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        return mBcc;
4768960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    }
4778960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy
4788960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    public synchronized void setBcc(final String bcc) {
4798960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mBcc = bcc;
4808960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mBccAddresses = null;
4818960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    }
4828960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy
4832bae2f5ef13424f8d932f5e45a2e276b531ecfe6Martin Hibdon    @VisibleForTesting
4848960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    public String getReplyTo() {
4858960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        return mReplyTo;
4868960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    }
4878960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy
4888960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    public synchronized void setReplyTo(final String replyTo) {
4898960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mReplyTo = replyTo;
4908960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy        mReplyToAddresses = null;
4918960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy    }
4928960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy
493d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein    public synchronized String[] getFromAddresses() {
494d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein        if (mFromAddresses == null) {
4958960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy            mFromAddresses = tokenizeAddresses(mFrom);
496d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein        }
497d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein        return mFromAddresses;
498d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein    }
499d5b369b324a22d28b63def902eefaf6591edf004Andrew Sapperstein
5009016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    public String[] getFromAddressesUnescaped() {
5019016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler        return unescapeAddresses(getFromAddresses());
5029016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    }
5039016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler
504bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook    public synchronized String[] getToAddresses() {
505bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        if (mToAddresses == null) {
5068960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy            mToAddresses = tokenizeAddresses(mTo);
507bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        }
508bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        return mToAddresses;
509bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook    }
510bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook
5119016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    public String[] getToAddressesUnescaped() {
5129016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler        return unescapeAddresses(getToAddresses());
5139016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    }
5149016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler
515bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook    public synchronized String[] getCcAddresses() {
516bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        if (mCcAddresses == null) {
5178960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy            mCcAddresses = tokenizeAddresses(mCc);
518bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        }
519bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        return mCcAddresses;
520bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook    }
521bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook
5229016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    public String[] getCcAddressesUnescaped() {
5239016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler        return unescapeAddresses(getCcAddresses());
5249016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    }
5259016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler
526bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook    public synchronized String[] getBccAddresses() {
527bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        if (mBccAddresses == null) {
5288960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy            mBccAddresses = tokenizeAddresses(mBcc);
529bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        }
530bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        return mBccAddresses;
531bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook    }
532bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook
5339016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    public String[] getBccAddressesUnescaped() {
5349016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler        return unescapeAddresses(getBccAddresses());
5359016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    }
5369016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler
537bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook    public synchronized String[] getReplyToAddresses() {
538bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        if (mReplyToAddresses == null) {
5398960f0af431bc164003e09b3c8981aab808d9ec1Scott Kennedy            mReplyToAddresses = tokenizeAddresses(mReplyTo);
540bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        }
541bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook        return mReplyToAddresses;
542bb87b7fa57f25fc9cee1f572dd253f33f58f81daPaul Westbrook    }
5433233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang
5449016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    public String[] getReplyToAddressesUnescaped() {
5459016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler        return unescapeAddresses(getReplyToAddresses());
5469016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    }
5479016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler
5489016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    private static String[] unescapeAddresses(String[] escaped) {
5499016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler        final String[] unescaped = new String[escaped.length];
5509016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler        for (int i = 0; i < escaped.length; i++) {
5519016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler            final String escapeMore = escaped[i].replace("<", "&lt;").replace(">", "&gt;");
5529016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler            unescaped[i] = Html.fromHtml(escapeMore).toString();
5539016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler        }
5549016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler        return unescaped;
5559016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler    }
5569016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler
557233f562368e4e3af9ca86b16d1b0a151df6157eaPaul Westbrook    public static String[] tokenizeAddresses(String addresses) {
5585ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindyp        if (TextUtils.isEmpty(addresses)) {
5595ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindyp            return new String[0];
5605ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindyp        }
5619016a5e827ae7baff9199811ecc8a9de9690b838Tony Mantler
562845f87e34179bcbb2862c09572576ab775be472dmindyp        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(addresses);
5635ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindyp        String[] strings = new String[tokens.length];
5645ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindyp        for (int i = 0; i < tokens.length;i++) {
5655ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindyp            strings[i] = tokens[i].toString();
5665ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindyp        }
5675ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindyp        return strings;
5685ed6311d6beb968e83585a43d7cdf5909e0a2cf6mindyp    }
5696766b6e5468d2f1935587b3bc1f8e65be94cd6fbAndy Huang
5706766b6e5468d2f1935587b3bc1f8e65be94cd6fbAndy Huang    public List<Attachment> getAttachments() {
5719ab47b16e0189d219c16e2eddfbd66c741c01229Andy Huang        if (mAttachments == null) {
5729ab47b16e0189d219c16e2eddfbd66c741c01229Andy Huang            if (attachmentsJson != null) {
5739ab47b16e0189d219c16e2eddfbd66c741c01229Andy Huang                mAttachments = Attachment.fromJSONArray(attachmentsJson);
5749ab47b16e0189d219c16e2eddfbd66c741c01229Andy Huang            } else {
5759ab47b16e0189d219c16e2eddfbd66c741c01229Andy Huang                mAttachments = Collections.emptyList();
5769ab47b16e0189d219c16e2eddfbd66c741c01229Andy Huang            }
5775a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang        }
5785a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang        return mAttachments;
5795a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang    }
5805a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang
5813233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    /**
5823233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     * Returns whether a "Show Pictures" button should initially appear for this message. If the
5833233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     * button is shown, the message must also block all non-local images in the body. Inversely, if
5843233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     * the button is not shown, the message must show all images within (or else the user would be
5853233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     * stuck with no images and no way to reveal them).
5863233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     *
5873233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     * @return true if a "Show Pictures" button should appear.
5883233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     */
5893233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    public boolean shouldShowImagePrompt() {
590606dbd7a44b8445e872c25c0fe080e3e12a47adfAndrew Sapperstein        return !alwaysShowImages && (embedsExternalResources ||
591606dbd7a44b8445e872c25c0fe080e3e12a47adfAndrew Sapperstein                (!TextUtils.isEmpty(bodyHtml) && INLINE_IMAGE_PATTERN.matcher(bodyHtml).find()));
59241dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    }
59341dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook
594aa27bc0e1c3bb6be4609b00007637a9d3e960f5eScott Kennedy    @Override
595606dbd7a44b8445e872c25c0fe080e3e12a47adfAndrew Sapperstein    public boolean embedsExternalResources() {
596606dbd7a44b8445e872c25c0fe080e3e12a47adfAndrew Sapperstein        return embedsExternalResources;
5973233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    }
5983233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang
5993233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    /**
6003233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     * Helper method to command a provider to mark all messages from this sender with the
6013233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     * {@link MessageColumns#ALWAYS_SHOW_IMAGES} flag set.
6023233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     *
6033233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     * @param handler a caller-provided handler to run the query on
6043233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     * @param token (optional) token to identify the command to the handler
6053233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     * @param cookie (optional) cookie to pass to the handler
6063233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang     */
6073233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang    public void markAlwaysShowImages(AsyncQueryHandler handler, int token, Object cookie) {
608839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        alwaysShowImages = true;
6093233bff8ae08a56543c9f5abf1bc6ab38f0574ceAndy Huang
610d8e249ee7abb0e1ad24e17e4e299736d4a150936Andy Huang        final ContentValues values = new ContentValues(1);
611839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        values.put(UIProvider.MessageColumns.ALWAYS_SHOW_IMAGES, 1);
612d8e249ee7abb0e1ad24e17e4e299736d4a150936Andy Huang
613d8e249ee7abb0e1ad24e17e4e299736d4a150936Andy Huang        handler.startUpdate(token, cookie, uri, values, null, null);
614d8e249ee7abb0e1ad24e17e4e299736d4a150936Andy Huang    }
615d8e249ee7abb0e1ad24e17e4e299736d4a150936Andy Huang
616aa27bc0e1c3bb6be4609b00007637a9d3e960f5eScott Kennedy    @Override
617014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huang    public String getBodyAsHtml() {
618014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huang        String body = "";
619014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huang        if (!TextUtils.isEmpty(bodyHtml)) {
620014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huang            body = bodyHtml;
621014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huang        } else if (!TextUtils.isEmpty(bodyText)) {
6228d6e803bf63d5dad5cb0187c82171e42147e8a44Yu Ping Hu            final SpannableString spannable = new SpannableString(bodyText);
623da153fb1651c2f70fbb3a2f9930950faec8b798bYu Ping Hu            Linkify.addLinks(spannable, Linkify.EMAIL_ADDRESSES);
6248d6e803bf63d5dad5cb0187c82171e42147e8a44Yu Ping Hu            body = Html.toHtml(spannable);
625014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huang        }
626014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huang        return body;
627014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huang    }
628014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huang
629aa27bc0e1c3bb6be4609b00007637a9d3e960f5eScott Kennedy    @Override
630606dbd7a44b8445e872c25c0fe080e3e12a47adfAndrew Sapperstein    public long getId() {
631606dbd7a44b8445e872c25c0fe080e3e12a47adfAndrew Sapperstein        return id;
632606dbd7a44b8445e872c25c0fe080e3e12a47adfAndrew Sapperstein    }
6333ce64e7ceb6246130342385d91550bcf33b31cc8Mindy Pereira}
634