Conversation.java revision 67aa9e5162a15fb8b46b4113ac627cd20668f095
1732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang/**
2732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * Copyright (c) 2012, Google Inc.
3732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *
4732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * Licensed under the Apache License, Version 2.0 (the "License");
5732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * you may not use this file except in compliance with the License.
6732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * You may obtain a copy of the License at
7732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *
8732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *     http://www.apache.org/licenses/LICENSE-2.0
9732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang *
10732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * Unless required by applicable law or agreed to in writing, software
11732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * distributed under the License is distributed on an "AS IS" BASIS,
12732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * See the License for the specific language governing permissions and
14732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang * limitations under the License.
15732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang */
16732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
17732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangpackage com.android.mail.providers;
18732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
191bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huangimport android.content.ContentValues;
20bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereiraimport android.content.Context;
21732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.database.Cursor;
22732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.net.Uri;
23732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.os.Parcel;
24732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.os.Parcelable;
25e623a0f6e3caa9cafec913cf826e946628833517Andy Huangimport android.provider.BaseColumns;
265c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereiraimport android.text.TextUtils;
27732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
28bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereiraimport com.android.mail.R;
29ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereiraimport com.android.mail.providers.UIProvider.ConversationColumns;
309e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huangimport com.android.mail.utils.LogTag;
319e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huangimport com.android.mail.utils.LogUtils;
32a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blankimport com.google.common.collect.ImmutableList;
33a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank
3400ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereiraimport java.util.ArrayList;
35440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwalimport java.util.Collection;
36440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwalimport java.util.Collections;
37b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huangimport java.util.List;
38440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
39732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangpublic class Conversation implements Parcelable {
40f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public static final int NO_POSITION = -1;
41732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
429e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang    private static final String LOG_TAG = LogTag.getLogTag();
439e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang
44820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static final String EMPTY_STRING = "";
45820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
46e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
47e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see BaseColumns#_ID
48e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
49732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long id;
50e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
51e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#URI
52e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
53c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank    public Uri uri;
54e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
55e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SUBJECT
56e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
57732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String subject;
58e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
59e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#DATE_RECEIVED_MS
60e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
61732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long dateMs;
62e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
63e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SNIPPET
64e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
65aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    @Deprecated
66732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String snippet;
67e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
68e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#HAS_ATTACHMENTS
69e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
70732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public boolean hasAttachments;
71e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
72e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MESSAGE_LIST_URI
73e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
74cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira    public Uri messageListUri;
75e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
76e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDER_INFO
77e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
78648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    @Deprecated
794db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public String senders;
80e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
81e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_MESSAGES
82e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
830972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numMessages;
84e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
85e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_DRAFTS
86e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
870972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numDrafts;
88e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
89e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDING_STATE
90e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
914db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int sendingState;
92e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
93e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PRIORITY
94e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
954db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int priority;
96e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
97e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#READ
98e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
99c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean read;
100e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
101d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @see UIProvider.ConversationColumns#SEEN
102d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
103d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public boolean seen;
104d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
105e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#STARRED
106e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
107c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean starred;
108e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
109e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#RAW_FOLDERS
110e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
111b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    private FolderList rawFolders;
112e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
113e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#FLAGS
114e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
11522657529437c160dec072115c5982409306c1313Mindy Pereira    public int convFlags;
116e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
117e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PERSONAL_LEVEL
118e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
11922657529437c160dec072115c5982409306c1313Mindy Pereira    public int personalLevel;
120e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
121e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SPAM
122e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
123863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean spam;
124e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
125e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MUTED
126e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
127863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean muted;
128e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
12976b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     * @see UIProvider.ConversationColumns#PHISHING
13076b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     */
13176b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    public boolean phishing;
13276b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    /**
133e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#COLOR
134e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
13592939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank    public int color;
136e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
137e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#ACCOUNT_URI
138e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
139a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank    public Uri accountUri;
140648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    /**
141648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * @see UIProvider.ConversationColumns#CONVERSATION_INFO
142648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     */
143648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    public ConversationInfo conversationInfo;
14441dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    /**
145cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook     * @see UIProvider.ConversationColumns#CONVERSATION_BASE_URI
14641dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook     */
14741dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    public Uri conversationBaseUri;
148f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    /**
149f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     * @see UIProvider.ConversationColumns#REMOTE
150f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     */
151f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    public boolean isRemote;
15222657529437c160dec072115c5982409306c1313Mindy Pereira
153ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    // Used within the UI to indicate the adapter position of this conversation
154f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public transient int position;
155648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Used within the UI to indicate that a Conversation should be removed from
156648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the ConversationCursor when executing an update, e.g. the the
157648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Conversation is no longer in the ConversationList for the current folder,
158648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // that is it's now in some other folder(s)
159ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    public transient boolean localDeleteOnUpdate;
160732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
161cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    private transient boolean viewed;
162cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
16385c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    private ArrayList<Folder> cachedDisplayableFolders;
16400ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
1653bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp    private static String sSendersDelimeter;
1663bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp
1672909b7442130800d6c6c20c1227d65295262f03emindyp    private static String sSubjectAndSnippet;
1682909b7442130800d6c6c20c1227d65295262f03emindyp
169e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    // Constituents of convFlags below
170648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Flag indicating that the item has been deleted, but will continue being
171648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // shown in the list Delete/Archive of a mostly-dead item will NOT propagate
172648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the delete/archive, but WILL remove the item from the cursor
173e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public static final int FLAG_MOSTLY_DEAD = 1 << 0;
174e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
175440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /** An immutable, empty conversation list */
176440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static final Collection<Conversation> EMPTY = Collections.emptyList();
177440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
178732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
179732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public int describeContents() {
180732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        return 0;
181732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
182732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
183732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
184732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public void writeToParcel(Parcel dest, int flags) {
185732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(id);
186c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        dest.writeParcelable(uri, flags);
187732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(subject);
188732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(dateMs);
189732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(snippet);
190f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(hasAttachments ? 1 : 0);
191cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        dest.writeParcelable(messageListUri, 0);
1924db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeString(senders);
1934db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numMessages);
1944db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numDrafts);
1954db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(sendingState);
1964db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(priority);
197f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(read ? 1 : 0);
198d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        dest.writeInt(seen ? 1 : 0);
199f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(starred ? 1 : 0);
200b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        dest.writeParcelable(rawFolders, 0);
20122657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(convFlags);
20222657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(personalLevel);
203863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(spam ? 1 : 0);
20476b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        dest.writeInt(phishing ? 1 : 0);
205863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(muted ? 1 : 0);
20692939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        dest.writeInt(color);
207a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        dest.writeParcelable(accountUri, 0);
208351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        dest.writeParcelable(conversationInfo, 0);
20941dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        dest.writeParcelable(conversationBaseUri, 0);
210f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(isRemote ? 1 : 0);
211732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
212732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
213351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    private Conversation(Parcel in, ClassLoader loader) {
214732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        id = in.readLong();
215c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        uri = in.readParcelable(null);
216732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        subject = in.readString();
217732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dateMs = in.readLong();
218732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        snippet = in.readString();
219f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        hasAttachments = (in.readInt() != 0);
220cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        messageListUri = in.readParcelable(null);
221820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        senders = emptyIfNull(in.readString());
2224db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numMessages = in.readInt();
2234db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numDrafts = in.readInt();
2244db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        sendingState = in.readInt();
2254db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        priority = in.readInt();
226f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        read = (in.readInt() != 0);
227d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        seen = (in.readInt() != 0);
228f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        starred = (in.readInt() != 0);
229b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        rawFolders = in.readParcelable(loader);
23022657529437c160dec072115c5982409306c1313Mindy Pereira        convFlags = in.readInt();
23122657529437c160dec072115c5982409306c1313Mindy Pereira        personalLevel = in.readInt();
232863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        spam = in.readInt() != 0;
23376b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        phishing = in.readInt() != 0;
234863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        muted = in.readInt() != 0;
23592939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        color = in.readInt();
236a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        accountUri = in.readParcelable(null);
237f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank        position = NO_POSITION;
238ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank        localDeleteOnUpdate = false;
239351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        conversationInfo = in.readParcelable(loader);
24041dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversationBaseUri = in.readParcelable(null);
241f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        isRemote = in.readInt() != 0;
242732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
243732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
244732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
245732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String toString() {
2469e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        // log extra info at DEBUG level or finer
2479e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        final StringBuilder sb = new StringBuilder("[conversation id=");
2489e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        sb.append(id);
2499e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        if (LogUtils.isLoggable(LOG_TAG, LogUtils.DEBUG)) {
2509e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang            sb.append(", subject=");
2519e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang            sb.append(subject);
2529e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        }
2539e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        sb.append("]");
2549e4ca7993213d296043d20fe9cf4e166b5d595e8Andy Huang        return sb.toString();
255732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
256732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
257351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    public static final ClassLoaderCreator<Conversation> CREATOR =
258351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            new ClassLoaderCreator<Conversation>() {
259732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
260732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
261732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation createFromParcel(Parcel source) {
262351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            return new Conversation(source, null);
263351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        }
264351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang
265351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        @Override
266351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        public Conversation createFromParcel(Parcel source, ClassLoader loader) {
267351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            return new Conversation(source, loader);
268732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
269732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
270732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
271732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation[] newArray(int size) {
272732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            return new Conversation[size];
273732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
274732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
275732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    };
276732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
277acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira    public static final Uri MOVE_CONVERSATIONS_URI = Uri.parse("content://moveconversations");
278acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira
279ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira    /**
280ae7e6a0786a2d890b77c783d7ac39a90523b8154mindyp     * The column that needs to be updated to change the folders for a conversation.
281ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira     */
28200ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    public static final String UPDATE_FOLDER_COLUMN = ConversationColumns.RAW_FOLDERS;
283ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira
284a831b2f1ba6d3c18d5e54563df8bae1f589c4257Mindy Pereira    public Conversation(Cursor cursor) {
285732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        if (cursor != null) {
286732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            id = cursor.getLong(UIProvider.CONVERSATION_ID_COLUMN);
287c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank            uri = Uri.parse(cursor.getString(UIProvider.CONVERSATION_URI_COLUMN));
288732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            dateMs = cursor.getLong(UIProvider.CONVERSATION_DATE_RECEIVED_MS_COLUMN);
289732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            subject = cursor.getString(UIProvider.CONVERSATION_SUBJECT_COLUMN);
290374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            // Don't allow null subject
291374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            if (subject == null) {
292374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank                subject = "";
293374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            }
29487d535fe423d782c3a0343c649330d309976f655Mindy Pereira            hasAttachments = cursor.getInt(UIProvider.CONVERSATION_HAS_ATTACHMENTS_COLUMN) != 0;
295648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            String messageList = cursor.getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN);
2965c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereira            messageListUri = !TextUtils.isEmpty(messageList) ? Uri.parse(messageList) : null;
2974db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            sendingState = cursor.getInt(UIProvider.CONVERSATION_SENDING_STATE_COLUMN);
2984db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            priority = cursor.getInt(UIProvider.CONVERSATION_PRIORITY_COLUMN);
29987d535fe423d782c3a0343c649330d309976f655Mindy Pereira            read = cursor.getInt(UIProvider.CONVERSATION_READ_COLUMN) != 0;
300d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            seen = cursor.getInt(UIProvider.CONVERSATION_SEEN_COLUMN) != 0;
30187d535fe423d782c3a0343c649330d309976f655Mindy Pereira            starred = cursor.getInt(UIProvider.CONVERSATION_STARRED_COLUMN) != 0;
302b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang            rawFolders = FolderList.fromBlob(
303b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang                    cursor.getBlob(UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN));
30422657529437c160dec072115c5982409306c1313Mindy Pereira            convFlags = cursor.getInt(UIProvider.CONVERSATION_FLAGS_COLUMN);
30522657529437c160dec072115c5982409306c1313Mindy Pereira            personalLevel = cursor.getInt(UIProvider.CONVERSATION_PERSONAL_LEVEL_COLUMN);
306863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            spam = cursor.getInt(UIProvider.CONVERSATION_IS_SPAM_COLUMN) != 0;
30776b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook            phishing = cursor.getInt(UIProvider.CONVERSATION_IS_PHISHING_COLUMN) != 0;
308863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            muted = cursor.getInt(UIProvider.CONVERSATION_MUTED_COLUMN) != 0;
30992939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank            color = cursor.getInt(UIProvider.CONVERSATION_COLOR_COLUMN);
310a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            String account = cursor.getString(UIProvider.CONVERSATION_ACCOUNT_URI_COLUMN);
311a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            accountUri = !TextUtils.isEmpty(account) ? Uri.parse(account) : null;
312f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank            position = NO_POSITION;
313ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank            localDeleteOnUpdate = false;
314351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            conversationInfo = ConversationInfo.fromBlob(
315351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang                    cursor.getBlob(UIProvider.CONVERSATION_INFO_COLUMN));
31641dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            final String conversationBase =
31741dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    cursor.getString(UIProvider.CONVERSATION_BASE_URI_COLUMN);
31841dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            conversationBaseUri = !TextUtils.isEmpty(conversationBase) ?
31941dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    Uri.parse(conversationBase) : null;
320e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            if (conversationInfo == null) {
321e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira                snippet = cursor.getString(UIProvider.CONVERSATION_SNIPPET_COLUMN);
322820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook                senders = emptyIfNull(cursor.getString(UIProvider.CONVERSATION_SENDER_INFO_COLUMN));
3230972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numMessages = cursor.getInt(UIProvider.CONVERSATION_NUM_MESSAGES_COLUMN);
3240972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numDrafts = cursor.getInt(UIProvider.CONVERSATION_NUM_DRAFTS_COLUMN);
325e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            }
326f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang            isRemote = cursor.getInt(UIProvider.CONVERSATION_REMOTE_COLUMN) != 0;
327732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
328732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
329732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
3301bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    public Conversation(Conversation other) {
3311bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        if (other == null) {
3321bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            return;
3331bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
3341bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
3351bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        id = other.id;
3361bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        uri = other.uri;
3371bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        dateMs = other.dateMs;
3381bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        subject = other.subject;
3391bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        hasAttachments = other.hasAttachments;
3401bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        messageListUri = other.messageListUri;
3411bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        sendingState = other.sendingState;
3421bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        priority = other.priority;
3431bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        read = other.read;
3441bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        seen = other.seen;
3451bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        starred = other.starred;
3461bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        rawFolders = other.rawFolders; // FolderList is immutable, shallow copy is OK
3471bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        convFlags = other.convFlags;
3481bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        personalLevel = other.personalLevel;
3491bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        spam = other.spam;
3501bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        phishing = other.phishing;
3511bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        muted = other.muted;
3521bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        color = other.color;
3531bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        accountUri = other.accountUri;
3541bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        position = other.position;
3551bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        localDeleteOnUpdate = other.localDeleteOnUpdate;
3561bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        // although ConversationInfo is mutable (see ConversationInfo.markRead), applyCachedValues
3571bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        // will overwrite this if cached changes exist anyway, so a shallow copy is OK
3581bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        conversationInfo = other.conversationInfo;
3591bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        conversationBaseUri = other.conversationBaseUri;
3601bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        snippet = other.snippet;
3611bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        senders = other.senders;
3621bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        numMessages = other.numMessages;
3631bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        numDrafts = other.numDrafts;
3641bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        isRemote = other.isRemote;
3651bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    }
3661bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
367bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook    public Conversation() {
368ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
369ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
370863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public static Conversation create(long id, Uri uri, String subject, long dateMs,
371863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            String snippet, boolean hasAttachment, Uri messageListUri, String senders,
372863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            int numMessages, int numDrafts, int sendingState, int priority, boolean read,
373d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            boolean seen, boolean starred, FolderList rawFolders, int convFlags, int personalLevel,
374d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            boolean spam, boolean phishing, boolean muted, Uri accountUri,
375d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            ConversationInfo conversationInfo, Uri conversationBase, boolean isRemote) {
376ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
377ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        final Conversation conversation = new Conversation();
378ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
379ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.id = id;
380ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.uri = uri;
381ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.subject = subject;
382ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.dateMs = dateMs;
383ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.snippet = snippet;
384ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.hasAttachments = hasAttachment;
385ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.messageListUri = messageListUri;
386820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        conversation.senders = emptyIfNull(senders);
387ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numMessages = numMessages;
388ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numDrafts = numDrafts;
389ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.sendingState = sendingState;
390ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.priority = priority;
391ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.read = read;
392d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        conversation.seen = seen;
393ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.starred = starred;
394ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.rawFolders = rawFolders;
395ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.convFlags = convFlags;
396ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.personalLevel = personalLevel;
397863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.spam = spam;
39876b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        conversation.phishing = phishing;
399863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.muted = muted;
40092939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        conversation.color = 0;
401a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        conversation.accountUri = accountUri;
4027e854f52f0890b9621846ac7fe201a5681e65666Andy Huang        conversation.conversationInfo = conversationInfo;
40341dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversation.conversationBaseUri = conversationBase;
404f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        conversation.isRemote = isRemote;
405ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        return conversation;
406ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
407ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
408b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    /**
4091bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     * Apply any column values from the given {@link ContentValues} (where column names are the
4101bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     * keys) to this conversation.
4111bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     *
4121bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang     */
4131bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    public void applyCachedValues(ContentValues values) {
4141bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        if (values == null) {
4151bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            return;
4161bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
4171bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        for (String key : values.keySet()) {
4181bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            final Object val = values.get(key);
4191bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            LogUtils.i(LOG_TAG, "Conversation: applying cached value to col=%s val=%s", key,
4201bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                    val);
4211bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            if (ConversationColumns.READ.equals(key)) {
4221bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                read = (Integer) val != 0;
4231bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.CONVERSATION_INFO.equals(key)) {
4241bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                conversationInfo = ConversationInfo.fromBlob((byte[]) val);
4251bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.FLAGS.equals(key)) {
4261bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                convFlags = (Integer) val;
4271bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.STARRED.equals(key)) {
4281bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                starred = (Integer) val != 0;
4297f4b6140b40c1d1d2624ca1dabe229fbb5c6959aAndy Huang            } else if (ConversationColumns.SEEN.equals(key)) {
4307f4b6140b40c1d1d2624ca1dabe229fbb5c6959aAndy Huang                seen = (Integer) val != 0;
4318ebc2ce34ed7d979662cf88b1c9fa60d63142fe4Andy Huang            } else if (ConversationColumns.RAW_FOLDERS.equals(key)) {
4328ebc2ce34ed7d979662cf88b1c9fa60d63142fe4Andy Huang                rawFolders = FolderList.fromBlob((byte[]) val);
4331bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else if (ConversationColumns.VIEWED.equals(key)) {
4341bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                // ignore. this is not read from the cursor, either.
4351bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            } else {
4361bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                LogUtils.e(LOG_TAG, new UnsupportedOperationException(),
4371bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang                        "unsupported cached conv value in col=%s", key);
4381bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang            }
4391bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang        }
4401bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    }
4411bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang
4421bca265b7a8a3f9ea08e0ae51eeb145f0883a266Andy Huang    /**
443b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * Get the <strong>immutable</strong> list of {@link Folder}s for this conversation. To modify
444b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * this list, make a new {@link FolderList} and use {@link #setRawFolders(FolderList)}.
445b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     *
446b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * @return <strong>Immutable</strong> list of {@link Folder}s.
447b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     */
448b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    public List<Folder> getRawFolders() {
449b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        return rawFolders.folders;
45000ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    }
45100ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
452b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    public void setRawFolders(FolderList folders) {
45385c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        clearCachedFolders();
454b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        rawFolders = folders;
45585c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
45685c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
45785c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    private void clearCachedFolders() {
45885c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        cachedDisplayableFolders = null;
45985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
46085c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
46167aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy    public ArrayList<Folder> getRawFoldersForDisplay(final Uri ignoreFolderUri,
46267aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy            final int ignoreFolderType) {
46385c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        if (cachedDisplayableFolders == null) {
46485c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira            cachedDisplayableFolders = new ArrayList<Folder>();
465b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang            for (Folder folder : rawFolders.folders) {
4668eca4db9069941d2b8afbe6f75e3af75a4310f27Andy Huang                // skip the ignoreFolder
467b39aaf53a555c1046ef31b3fecf15d086acca013Scott Kennedy                if (ignoreFolderUri != null && ignoreFolderUri.equals(folder.uri)) {
46885c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                    continue;
46985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                }
47067aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy                // Skip the ignoreFolderType
47167aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy                if (ignoreFolderType >= 0 && folder.isType(ignoreFolderType)) {
47267aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy                    continue;
47367aa9e5162a15fb8b46b4113ac627cd20668f095Scott Kennedy                }
47485c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                cachedDisplayableFolders.add(folder);
47585c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira            }
47685c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        }
47785c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        return cachedDisplayableFolders;
47885c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
47985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
480e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
481e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean equals(Object o) {
4823c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        if (o instanceof Conversation) {
483648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            Conversation conv = (Conversation) o;
4843c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank            return conv.uri.equals(uri);
4853c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        }
4863c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        return false;
487e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
488e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
489e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
490e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public int hashCode() {
491e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return uri.hashCode();
492e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
493e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
4947f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    /**
4957f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     * Get if this conversation is marked as high priority.
4967f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     */
4977f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    public boolean isImportant() {
49822657529437c160dec072115c5982409306c1313Mindy Pereira        return priority == UIProvider.ConversationPriority.IMPORTANT;
4997f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    }
5007f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira
501e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    /**
502e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     * Get if this conversation is mostly dead
503e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     */
504e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean isMostlyDead() {
505e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return (convFlags & FLAG_MOSTLY_DEAD) != 0;
506e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
507440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
508440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /**
509648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns true if the URI of the conversation specified as the needle was
510648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * found in the collection of conversations specified as the haystack. False
511192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal     * otherwise. This method is safe to call with null arguments.
512f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
513d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param haystack
514d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param needle
515d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @return true if the needle was found in the haystack, false otherwise.
516d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     */
517d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    public final static boolean contains(Collection<Conversation> haystack, Conversation needle) {
518d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // If the haystack is empty, it cannot contain anything.
519d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (haystack == null || haystack.size() <= 0) {
520d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return false;
521d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
522d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // The null folder exists everywhere.
523d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (needle == null) {
524d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return true;
525d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
5267dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final long toFind = needle.id;
527d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        for (final Conversation c : haystack) {
5287dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            if (toFind == c.id) {
529d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal                return true;
530d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            }
531d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
532d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        return false;
533d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    }
534d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal
535d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    /**
536648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns a collection of a single conversation. This method always returns
537648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * a valid collection even if the input conversation is null.
538f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
539440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @param in a conversation, possibly null.
540440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @return a collection of the conversation.
541440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     */
542440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static Collection<Conversation> listOf(Conversation in) {
543440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        final Collection<Conversation> target = (in == null) ? EMPTY : ImmutableList.of(in);
544440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        return target;
545440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    }
5467dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal
5477dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    /**
548aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * Get the snippet for this conversation. Masks that it may come from
549aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * conversation info or the original deprecated snippet string.
550aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     */
551aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    public String getSnippet() {
552d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira        return conversationInfo != null && !TextUtils.isEmpty(conversationInfo.firstSnippet) ?
553d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira                conversationInfo.firstSnippet : snippet;
554aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    }
555aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira
5563bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp    public String getSenders(Context context) {
5573bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        if (conversationInfo != null) {
5583bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            ArrayList<String> senders = new ArrayList<String>();
5593bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            for (MessageInfo m : this.conversationInfo.messageInfos) {
5603bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp                senders.add(m.sender);
5613bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            }
5623bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            return TextUtils.join(getSendersDelimeter(context), senders);
5633bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        } else {
5643bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            return senders;
5653bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        }
5663bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp    }
5673bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp
56861bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy    private static String getSendersDelimeter(Context context) {
5693bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        if (sSendersDelimeter == null) {
5703bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            sSendersDelimeter = context.getResources().getString(R.string.senders_split_token);
5713bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        }
5723bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        return sSendersDelimeter;
5733bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp    }
5743bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp
575aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    /**
5760972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of messages for this conversation.
5770972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
5780972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int getNumMessages() {
5790972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.messageCount : numMessages;
5800972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
5810972e0793cc321670391d063348aecb5031b2677Mindy Pereira
5820972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
5830972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of drafts for this conversation.
5840972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
5850972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int numDrafts() {
5860972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.draftCount : numDrafts;
5870972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
5880972e0793cc321670391d063348aecb5031b2677Mindy Pereira
589cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public boolean isViewed() {
590cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        return viewed;
591cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
592cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
593cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public void markViewed() {
594cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        viewed = true;
595cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
596cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
597c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang    public String getBaseUri(String defaultValue) {
598c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang        return conversationBaseUri != null ? conversationBaseUri.toString() : defaultValue;
599c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang    }
600c1fb9a9c2730178105977fca629e80951bfc3cdcAndy Huang
6010972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
6027dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * Create a human-readable string of all the conversations
6037dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @param collection Any collection of conversations
6047dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @return string with a human readable representation of the conversations.
6057dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     */
6067dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    public static String toString(Collection<Conversation> collection) {
6077dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final StringBuilder out = new StringBuilder(collection.size() + " conversations:");
6087dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        int count = 0;
6097dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        for (final Conversation c : collection) {
6107dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            count++;
611648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // Indent the conversations to make them easy to read in debug
612648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // output.
6137dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            out.append("      " + count + ": " + c.toString() + "\n");
6147dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        }
6157dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return out.toString();
6167dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    }
617820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
618820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    /**
619820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     * Returns an empty string if the specified string is null
620820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     */
621820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static String emptyIfNull(String in) {
622820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        return in != null ? in : EMPTY_STRING;
623820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    }
624bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira
625bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    /**
626f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * Get the properly formatted subject and snippet string for display a
627f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * conversation.
628f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     *
629f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param context
630f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param filteredSubject
631f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param snippet
632bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira     */
633c046e4a310462aa6998a34ff50439eb5e2508d85mindyp    public static String getSubjectAndSnippetForDisplay(Context context,
634c046e4a310462aa6998a34ff50439eb5e2508d85mindyp            String filteredSubject, String snippet) {
6352909b7442130800d6c6c20c1227d65295262f03emindyp        if (sSubjectAndSnippet == null) {
6362909b7442130800d6c6c20c1227d65295262f03emindyp            sSubjectAndSnippet = context.getString(R.string.subject_and_snippet);
6372909b7442130800d6c6c20c1227d65295262f03emindyp        }
63861bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        if (TextUtils.isEmpty(filteredSubject) && TextUtils.isEmpty(snippet)) {
63961bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return "";
64061bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        } else if (TextUtils.isEmpty(filteredSubject)) {
64161bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return snippet;
64261bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        } else if (TextUtils.isEmpty(snippet)) {
64361bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy            return filteredSubject;
64461bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        }
64561bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy
64661bd0e84a3b0545a722bbfe931233b47afdf52e2Scott Kennedy        return String.format(sSubjectAndSnippet, filteredSubject, snippet);
647bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    }
648648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira}
649