Conversation.java revision cd5c5eeae167885ffa2959c200233fea2f39c5f7
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
19bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereiraimport android.content.Context;
20732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.database.Cursor;
21732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.net.Uri;
22732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.os.Parcel;
23732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.os.Parcelable;
24e623a0f6e3caa9cafec913cf826e946628833517Andy Huangimport android.provider.BaseColumns;
25bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereiraimport android.text.SpannableStringBuilder;
265c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereiraimport android.text.TextUtils;
27732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
28bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereiraimport com.android.mail.R;
29ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereiraimport com.android.mail.providers.UIProvider.ConversationColumns;
30a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blankimport com.google.common.collect.ImmutableList;
31a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank
3200ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereiraimport java.util.ArrayList;
33440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwalimport java.util.Collection;
34440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwalimport java.util.Collections;
35440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
36732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangpublic class Conversation implements Parcelable {
37f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public static final int NO_POSITION = -1;
38732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
39820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static final String EMPTY_STRING = "";
40820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
41e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
42e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see BaseColumns#_ID
43e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
44732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long id;
45e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
46e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#URI
47e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
48c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank    public Uri uri;
49e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
50e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SUBJECT
51e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
52732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String subject;
53e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
54e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#DATE_RECEIVED_MS
55e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
56732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long dateMs;
57e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
58e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SNIPPET
59e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
60aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    @Deprecated
61732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String snippet;
62e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
63e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#HAS_ATTACHMENTS
64e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
65732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public boolean hasAttachments;
66e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
67e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MESSAGE_LIST_URI
68e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
69cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira    public Uri messageListUri;
70e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
71e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDER_INFO
72e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
73648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    @Deprecated
744db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public String senders;
75e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
76e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_MESSAGES
77e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
780972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numMessages;
79e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
80e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_DRAFTS
81e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
820972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numDrafts;
83e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
84e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDING_STATE
85e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
864db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int sendingState;
87e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
88e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PRIORITY
89e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
904db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int priority;
91e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
92e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#READ
93e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
94c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean read;
95e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
96e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#STARRED
97e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
98c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean starred;
99e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
100e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#RAW_FOLDERS
101e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
10285c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    private String rawFolders;
103e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
104e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#FLAGS
105e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
10622657529437c160dec072115c5982409306c1313Mindy Pereira    public int convFlags;
107e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
108e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PERSONAL_LEVEL
109e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
11022657529437c160dec072115c5982409306c1313Mindy Pereira    public int personalLevel;
111e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
112e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SPAM
113e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
114863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean spam;
115e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
116e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MUTED
117e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
118863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean muted;
119e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
12076b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     * @see UIProvider.ConversationColumns#PHISHING
12176b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     */
12276b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    public boolean phishing;
12376b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    /**
124e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#COLOR
125e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
12692939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank    public int color;
127e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
128e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#ACCOUNT_URI
129e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
130a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank    public Uri accountUri;
131648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    /**
132648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * @see UIProvider.ConversationColumns#CONVERSATION_INFO
133648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     */
134648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    public ConversationInfo conversationInfo;
13541dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    /**
136cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook     * @see UIProvider.ConversationColumns#CONVERSATION_BASE_URI
13741dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook     */
13841dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    public Uri conversationBaseUri;
139f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    /**
140cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook     * @see UIProvider.ConversationColumns#CONVERSATION_COOKIE
141cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook     */
142cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook    public String conversationCookie;
143cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook    /**
144f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     * @see UIProvider.ConversationColumns#REMOTE
145f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     */
146f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    public boolean isRemote;
14722657529437c160dec072115c5982409306c1313Mindy Pereira
148ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    // Used within the UI to indicate the adapter position of this conversation
149f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public transient int position;
150648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Used within the UI to indicate that a Conversation should be removed from
151648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the ConversationCursor when executing an update, e.g. the the
152648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Conversation is no longer in the ConversationList for the current folder,
153648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // that is it's now in some other folder(s)
154ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    public transient boolean localDeleteOnUpdate;
155732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
156cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    private transient boolean viewed;
157cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
15800ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    private ArrayList<Folder> cachedRawFolders;
15985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    private ArrayList<Folder> cachedDisplayableFolders;
16000ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
161e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    // Constituents of convFlags below
162648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Flag indicating that the item has been deleted, but will continue being
163648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // shown in the list Delete/Archive of a mostly-dead item will NOT propagate
164648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the delete/archive, but WILL remove the item from the cursor
165e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public static final int FLAG_MOSTLY_DEAD = 1 << 0;
166e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
167440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /** An immutable, empty conversation list */
168440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static final Collection<Conversation> EMPTY = Collections.emptyList();
169440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
170732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
171732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public int describeContents() {
172732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        return 0;
173732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
174732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
175732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
176732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public void writeToParcel(Parcel dest, int flags) {
177732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(id);
178c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        dest.writeParcelable(uri, flags);
179732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(subject);
180732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(dateMs);
181732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(snippet);
182f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(hasAttachments ? 1 : 0);
183cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        dest.writeParcelable(messageListUri, 0);
1844db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeString(senders);
1854db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numMessages);
1864db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numDrafts);
1874db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(sendingState);
1884db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(priority);
189f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(read ? 1 : 0);
190f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(starred ? 1 : 0);
191cc8211df898ba9dac17a766b89f28d6e6f0afef0Mindy Pereira        dest.writeString(rawFolders);
19222657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(convFlags);
19322657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(personalLevel);
194863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(spam ? 1 : 0);
19576b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        dest.writeInt(phishing ? 1 : 0);
196863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(muted ? 1 : 0);
19792939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        dest.writeInt(color);
198a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        dest.writeParcelable(accountUri, 0);
1995f424372f9a801120b5dc8d3f56e907baaa04e25Mindy Pereira        dest.writeString(ConversationInfo.toString(conversationInfo));
20041dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        dest.writeParcelable(conversationBaseUri, 0);
201cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook        dest.writeString(conversationCookie);
202f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(isRemote ? 1 : 0);
203732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
204732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
205732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    private Conversation(Parcel in) {
206732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        id = in.readLong();
207c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        uri = in.readParcelable(null);
208732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        subject = in.readString();
209732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dateMs = in.readLong();
210732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        snippet = in.readString();
211f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        hasAttachments = (in.readInt() != 0);
212cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        messageListUri = in.readParcelable(null);
213820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        senders = emptyIfNull(in.readString());
2144db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numMessages = in.readInt();
2154db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numDrafts = in.readInt();
2164db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        sendingState = in.readInt();
2174db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        priority = in.readInt();
218f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        read = (in.readInt() != 0);
219f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        starred = (in.readInt() != 0);
220cc8211df898ba9dac17a766b89f28d6e6f0afef0Mindy Pereira        rawFolders = in.readString();
22122657529437c160dec072115c5982409306c1313Mindy Pereira        convFlags = in.readInt();
22222657529437c160dec072115c5982409306c1313Mindy Pereira        personalLevel = in.readInt();
223863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        spam = in.readInt() != 0;
22476b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        phishing = in.readInt() != 0;
225863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        muted = in.readInt() != 0;
22692939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        color = in.readInt();
227a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        accountUri = in.readParcelable(null);
228f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank        position = NO_POSITION;
229ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank        localDeleteOnUpdate = false;
2305f424372f9a801120b5dc8d3f56e907baaa04e25Mindy Pereira        conversationInfo = ConversationInfo.fromString(in.readString());
23141dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversationBaseUri = in.readParcelable(null);
232cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook        conversationCookie = in.readString();
233f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        isRemote = in.readInt() != 0;
234732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
235732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
236732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
237732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String toString() {
2387dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return "[conversation id=" + id + ", subject =" + subject + "]";
239732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
240732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
241732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public static final Creator<Conversation> CREATOR = new Creator<Conversation>() {
242732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
243732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
244732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation createFromParcel(Parcel source) {
245732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            return new Conversation(source);
246732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
247732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
248732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
249732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation[] newArray(int size) {
250732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            return new Conversation[size];
251732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
252732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
253732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    };
254732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
255acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira    public static final Uri MOVE_CONVERSATIONS_URI = Uri.parse("content://moveconversations");
256acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira
257ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira    /**
2584f2224c70d4d07df85b325fa3faf78218f92aae6Mindy Pereira     * The column that needs to be updated to change the read state of a
2594f2224c70d4d07df85b325fa3faf78218f92aae6Mindy Pereira     * conversation.
260ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira     */
26100ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    public static final String UPDATE_FOLDER_COLUMN = ConversationColumns.RAW_FOLDERS;
262ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira
263a831b2f1ba6d3c18d5e54563df8bae1f589c4257Mindy Pereira    public Conversation(Cursor cursor) {
264732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        if (cursor != null) {
265732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            id = cursor.getLong(UIProvider.CONVERSATION_ID_COLUMN);
266c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank            uri = Uri.parse(cursor.getString(UIProvider.CONVERSATION_URI_COLUMN));
267732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            dateMs = cursor.getLong(UIProvider.CONVERSATION_DATE_RECEIVED_MS_COLUMN);
268732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            subject = cursor.getString(UIProvider.CONVERSATION_SUBJECT_COLUMN);
269374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            // Don't allow null subject
270374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            if (subject == null) {
271374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank                subject = "";
272374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            }
27387d535fe423d782c3a0343c649330d309976f655Mindy Pereira            hasAttachments = cursor.getInt(UIProvider.CONVERSATION_HAS_ATTACHMENTS_COLUMN) != 0;
274648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            String messageList = cursor.getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN);
2755c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereira            messageListUri = !TextUtils.isEmpty(messageList) ? Uri.parse(messageList) : null;
2764db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            sendingState = cursor.getInt(UIProvider.CONVERSATION_SENDING_STATE_COLUMN);
2774db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            priority = cursor.getInt(UIProvider.CONVERSATION_PRIORITY_COLUMN);
27887d535fe423d782c3a0343c649330d309976f655Mindy Pereira            read = cursor.getInt(UIProvider.CONVERSATION_READ_COLUMN) != 0;
27987d535fe423d782c3a0343c649330d309976f655Mindy Pereira            starred = cursor.getInt(UIProvider.CONVERSATION_STARRED_COLUMN) != 0;
280cc8211df898ba9dac17a766b89f28d6e6f0afef0Mindy Pereira            rawFolders = cursor.getString(UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN);
28122657529437c160dec072115c5982409306c1313Mindy Pereira            convFlags = cursor.getInt(UIProvider.CONVERSATION_FLAGS_COLUMN);
28222657529437c160dec072115c5982409306c1313Mindy Pereira            personalLevel = cursor.getInt(UIProvider.CONVERSATION_PERSONAL_LEVEL_COLUMN);
283863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            spam = cursor.getInt(UIProvider.CONVERSATION_IS_SPAM_COLUMN) != 0;
28476b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook            phishing = cursor.getInt(UIProvider.CONVERSATION_IS_PHISHING_COLUMN) != 0;
285863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            muted = cursor.getInt(UIProvider.CONVERSATION_MUTED_COLUMN) != 0;
28692939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank            color = cursor.getInt(UIProvider.CONVERSATION_COLOR_COLUMN);
287a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            String account = cursor.getString(UIProvider.CONVERSATION_ACCOUNT_URI_COLUMN);
288a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            accountUri = !TextUtils.isEmpty(account) ? Uri.parse(account) : null;
289f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank            position = NO_POSITION;
290ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank            localDeleteOnUpdate = false;
2915f424372f9a801120b5dc8d3f56e907baaa04e25Mindy Pereira            conversationInfo = ConversationInfo.fromString(cursor
2925f424372f9a801120b5dc8d3f56e907baaa04e25Mindy Pereira                    .getString(UIProvider.CONVERSATION_INFO_COLUMN));
29341dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            final String conversationBase =
29441dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    cursor.getString(UIProvider.CONVERSATION_BASE_URI_COLUMN);
29541dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            conversationBaseUri = !TextUtils.isEmpty(conversationBase) ?
29641dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    Uri.parse(conversationBase) : null;
297cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook            conversationCookie = cursor.getString(UIProvider.CONVERSATION_COOKIE_COLUMN);
298e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            if (conversationInfo == null) {
299e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira                snippet = cursor.getString(UIProvider.CONVERSATION_SNIPPET_COLUMN);
300820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook                senders = emptyIfNull(cursor.getString(UIProvider.CONVERSATION_SENDER_INFO_COLUMN));
3010972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numMessages = cursor.getInt(UIProvider.CONVERSATION_NUM_MESSAGES_COLUMN);
3020972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numDrafts = cursor.getInt(UIProvider.CONVERSATION_NUM_DRAFTS_COLUMN);
303e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            }
304f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang            isRemote = cursor.getInt(UIProvider.CONVERSATION_REMOTE_COLUMN) != 0;
305732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
306732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
307732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
308bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook    public Conversation() {
309ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
310ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
311863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public static Conversation create(long id, Uri uri, String subject, long dateMs,
312863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            String snippet, boolean hasAttachment, Uri messageListUri, String senders,
313863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            int numMessages, int numDrafts, int sendingState, int priority, boolean read,
3144f2224c70d4d07df85b325fa3faf78218f92aae6Mindy Pereira            boolean starred, String rawFolders, int convFlags, int personalLevel, boolean spam,
31541dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            boolean phishing, boolean muted, Uri accountUri, ConversationInfo conversationInfo,
316cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook            Uri conversationBase, String conversationCookie, boolean isRemote) {
317ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
318ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        final Conversation conversation = new Conversation();
319ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
320ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.id = id;
321ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.uri = uri;
322ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.subject = subject;
323ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.dateMs = dateMs;
324ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.snippet = snippet;
325ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.hasAttachments = hasAttachment;
326ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.messageListUri = messageListUri;
327820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        conversation.senders = emptyIfNull(senders);
328ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numMessages = numMessages;
329ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numDrafts = numDrafts;
330ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.sendingState = sendingState;
331ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.priority = priority;
332ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.read = read;
333ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.starred = starred;
334ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.rawFolders = rawFolders;
335ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.convFlags = convFlags;
336ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.personalLevel = personalLevel;
337863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.spam = spam;
33876b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        conversation.phishing = phishing;
339863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.muted = muted;
34092939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        conversation.color = 0;
341a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        conversation.accountUri = accountUri;
3427e854f52f0890b9621846ac7fe201a5681e65666Andy Huang        conversation.conversationInfo = conversationInfo;
34341dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversation.conversationBaseUri = conversationBase;
344cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook        conversation.conversationCookie = conversationCookie;
345f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        conversation.isRemote = isRemote;
346ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        return conversation;
347ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
348ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
34900ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    public ArrayList<Folder> getRawFolders() {
35000ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira        if (cachedRawFolders == null) {
35100ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira            // Create cached folders.
3527269c6fe45420cebf90841497e74d55783ea3a46Mindy Pereira            if (!TextUtils.isEmpty(rawFolders)) {
3537269c6fe45420cebf90841497e74d55783ea3a46Mindy Pereira                cachedRawFolders = Folder.getFoldersArray(rawFolders);
3547269c6fe45420cebf90841497e74d55783ea3a46Mindy Pereira            } else {
3557269c6fe45420cebf90841497e74d55783ea3a46Mindy Pereira                return new ArrayList<Folder>();
3567269c6fe45420cebf90841497e74d55783ea3a46Mindy Pereira            }
35700ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira        }
35800ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira        return cachedRawFolders;
35900ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    }
36000ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
36185c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    public void setRawFolders(String raw) {
36285c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        clearCachedFolders();
36385c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        rawFolders = raw;
36485c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
36585c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
36685c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    public String getRawFoldersString() {
36785c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        return rawFolders;
36885c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
36985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
37085c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    private void clearCachedFolders() {
37185c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        cachedRawFolders = null;
37285c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        cachedDisplayableFolders = null;
37385c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
37485c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
37585c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    public ArrayList<Folder> getRawFoldersForDisplay(Folder ignoreFolder) {
37685c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        ArrayList<Folder> folders = getRawFolders();
37785c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        if (cachedDisplayableFolders == null) {
37885c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira            cachedDisplayableFolders = new ArrayList<Folder>();
37985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira            for (Folder folder : folders) {
3808eca4db9069941d2b8afbe6f75e3af75a4310f27Andy Huang                // skip the ignoreFolder
3818eca4db9069941d2b8afbe6f75e3af75a4310f27Andy Huang                if (ignoreFolder != null && ignoreFolder.equals(folder)) {
38285c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                    continue;
38385c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                }
38485c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                cachedDisplayableFolders.add(folder);
38585c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira            }
38685c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        }
38785c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        return cachedDisplayableFolders;
38885c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
38985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
390e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
391e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean equals(Object o) {
3923c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        if (o instanceof Conversation) {
393648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            Conversation conv = (Conversation) o;
3943c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank            return conv.uri.equals(uri);
3953c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        }
3963c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        return false;
397e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
398e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
399e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
400e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public int hashCode() {
401e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return uri.hashCode();
402e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
403e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
4047f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    /**
4057f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     * Get if this conversation is marked as high priority.
4067f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     */
4077f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    public boolean isImportant() {
40822657529437c160dec072115c5982409306c1313Mindy Pereira        return priority == UIProvider.ConversationPriority.IMPORTANT;
4097f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    }
4107f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira
411e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    /**
412e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     * Get if this conversation is mostly dead
413e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     */
414e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean isMostlyDead() {
415e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return (convFlags & FLAG_MOSTLY_DEAD) != 0;
416e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
417440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
418440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /**
419648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns true if the URI of the conversation specified as the needle was
420648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * found in the collection of conversations specified as the haystack. False
421192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal     * otherwise. This method is safe to call with null arguments.
422f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
423d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param haystack
424d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param needle
425d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @return true if the needle was found in the haystack, false otherwise.
426d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     */
427d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    public final static boolean contains(Collection<Conversation> haystack, Conversation needle) {
428d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // If the haystack is empty, it cannot contain anything.
429d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (haystack == null || haystack.size() <= 0) {
430d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return false;
431d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
432d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // The null folder exists everywhere.
433d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (needle == null) {
434d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return true;
435d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
4367dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final long toFind = needle.id;
437d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        for (final Conversation c : haystack) {
4387dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            if (toFind == c.id) {
439d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal                return true;
440d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            }
441d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
442d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        return false;
443d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    }
444d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal
445d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    /**
446648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns a collection of a single conversation. This method always returns
447648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * a valid collection even if the input conversation is null.
448f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
449440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @param in a conversation, possibly null.
450440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @return a collection of the conversation.
451440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     */
452440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static Collection<Conversation> listOf(Conversation in) {
453440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        final Collection<Conversation> target = (in == null) ? EMPTY : ImmutableList.of(in);
454440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        return target;
455440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    }
4567dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal
4577dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    /**
458aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * Get the snippet for this conversation. Masks that it may come from
459aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * conversation info or the original deprecated snippet string.
460aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     */
461aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    public String getSnippet() {
462d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira        return conversationInfo != null && !TextUtils.isEmpty(conversationInfo.firstSnippet) ?
463d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira                conversationInfo.firstSnippet : snippet;
464aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    }
465aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira
466aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    /**
4670972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of messages for this conversation.
4680972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
4690972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int getNumMessages() {
4700972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.messageCount : numMessages;
4710972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
4720972e0793cc321670391d063348aecb5031b2677Mindy Pereira
4730972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
4740972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of drafts for this conversation.
4750972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
4760972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int numDrafts() {
4770972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.draftCount : numDrafts;
4780972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
4790972e0793cc321670391d063348aecb5031b2677Mindy Pereira
480cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public boolean isViewed() {
481cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        return viewed;
482cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
483cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
484cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public void markViewed() {
485cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        viewed = true;
486cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
487cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
4880972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
4897dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * Create a human-readable string of all the conversations
4907dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @param collection Any collection of conversations
4917dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @return string with a human readable representation of the conversations.
4927dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     */
4937dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    public static String toString(Collection<Conversation> collection) {
4947dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final StringBuilder out = new StringBuilder(collection.size() + " conversations:");
4957dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        int count = 0;
4967dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        for (final Conversation c : collection) {
4977dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            count++;
498648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // Indent the conversations to make them easy to read in debug
499648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // output.
5007dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            out.append("      " + count + ": " + c.toString() + "\n");
5017dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        }
5027dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return out.toString();
5037dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    }
504820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
505820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    /**
506820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     * Returns an empty string if the specified string is null
507820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     */
508820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static String emptyIfNull(String in) {
509820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        return in != null ? in : EMPTY_STRING;
510820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    }
511bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira
512bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    /**
513bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira     * Get the properly formatted subject and snippet string for display a conversation.
514bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira     */
515bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    public static SpannableStringBuilder getSubjectAndSnippetForDisplay(Context context,
516bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira            String filteredSubject, String snippet) {
517bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira        return new SpannableStringBuilder((!TextUtils.isEmpty(snippet)) ?
518bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira                context.getString(R.string.subject_and_snippet, filteredSubject, snippet)
519bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira                : filteredSubject);
520bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    }
521648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira}
522