Conversation.java revision d5edd2d02649dffb40065fdb6a16acf91552b800
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;
35b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huangimport java.util.List;
36440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
37732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangpublic class Conversation implements Parcelable {
38f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public static final int NO_POSITION = -1;
39732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
40820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static final String EMPTY_STRING = "";
41820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
42e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
43e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see BaseColumns#_ID
44e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
45732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long id;
46e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
47e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#URI
48e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
49c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank    public Uri uri;
50e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
51e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SUBJECT
52e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
53732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String subject;
54e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
55e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#DATE_RECEIVED_MS
56e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
57732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long dateMs;
58e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
59e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SNIPPET
60e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
61aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    @Deprecated
62732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String snippet;
63e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
64e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#HAS_ATTACHMENTS
65e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
66732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public boolean hasAttachments;
67e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
68e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MESSAGE_LIST_URI
69e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
70cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira    public Uri messageListUri;
71e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
72e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDER_INFO
73e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
74648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    @Deprecated
754db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public String senders;
76e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
77e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_MESSAGES
78e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
790972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numMessages;
80e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
81e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_DRAFTS
82e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
830972e0793cc321670391d063348aecb5031b2677Mindy Pereira    private int numDrafts;
84e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
85e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDING_STATE
86e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
874db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int sendingState;
88e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
89e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PRIORITY
90e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
914db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int priority;
92e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
93e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#READ
94e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
95c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean read;
96e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
97d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     * @see UIProvider.ConversationColumns#SEEN
98d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy     */
99d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    public boolean seen;
100d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy    /**
101e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#STARRED
102e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
103c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean starred;
104e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
105e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#RAW_FOLDERS
106e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
107b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    private FolderList rawFolders;
108e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
109e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#FLAGS
110e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
11122657529437c160dec072115c5982409306c1313Mindy Pereira    public int convFlags;
112e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
113e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PERSONAL_LEVEL
114e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
11522657529437c160dec072115c5982409306c1313Mindy Pereira    public int personalLevel;
116e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
117e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SPAM
118e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
119863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean spam;
120e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
121e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MUTED
122e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
123863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean muted;
124e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
12576b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     * @see UIProvider.ConversationColumns#PHISHING
12676b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     */
12776b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    public boolean phishing;
12876b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    /**
129e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#COLOR
130e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
13192939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank    public int color;
132e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
133e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#ACCOUNT_URI
134e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
135a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank    public Uri accountUri;
136648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    /**
137648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * @see UIProvider.ConversationColumns#CONVERSATION_INFO
138648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     */
139648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    public ConversationInfo conversationInfo;
14041dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    /**
141cebcc64fbd69618ff89f9fac0bfe9b9e7d7ce104Paul Westbrook     * @see UIProvider.ConversationColumns#CONVERSATION_BASE_URI
14241dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook     */
14341dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook    public Uri conversationBaseUri;
144f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    /**
145f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     * @see UIProvider.ConversationColumns#REMOTE
146f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     */
147f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang    public boolean isRemote;
14822657529437c160dec072115c5982409306c1313Mindy Pereira
149ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    // Used within the UI to indicate the adapter position of this conversation
150f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public transient int position;
151648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Used within the UI to indicate that a Conversation should be removed from
152648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the ConversationCursor when executing an update, e.g. the the
153648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Conversation is no longer in the ConversationList for the current folder,
154648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // that is it's now in some other folder(s)
155ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    public transient boolean localDeleteOnUpdate;
156732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
157cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    private transient boolean viewed;
158cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
15985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    private ArrayList<Folder> cachedDisplayableFolders;
16000ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
1613bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp    private static String sSendersDelimeter;
1623bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp
1632909b7442130800d6c6c20c1227d65295262f03emindyp    private static String sSubjectAndSnippet;
1642909b7442130800d6c6c20c1227d65295262f03emindyp
165e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    // Constituents of convFlags below
166648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Flag indicating that the item has been deleted, but will continue being
167648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // shown in the list Delete/Archive of a mostly-dead item will NOT propagate
168648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the delete/archive, but WILL remove the item from the cursor
169e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public static final int FLAG_MOSTLY_DEAD = 1 << 0;
170e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
171440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /** An immutable, empty conversation list */
172440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static final Collection<Conversation> EMPTY = Collections.emptyList();
173440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
174732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
175732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public int describeContents() {
176732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        return 0;
177732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
178732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
179732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
180732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public void writeToParcel(Parcel dest, int flags) {
181732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(id);
182c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        dest.writeParcelable(uri, flags);
183732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(subject);
184732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(dateMs);
185732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(snippet);
186f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(hasAttachments ? 1 : 0);
187cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        dest.writeParcelable(messageListUri, 0);
1884db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeString(senders);
1894db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numMessages);
1904db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numDrafts);
1914db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(sendingState);
1924db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(priority);
193f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(read ? 1 : 0);
194d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        dest.writeInt(seen ? 1 : 0);
195f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(starred ? 1 : 0);
196b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        dest.writeParcelable(rawFolders, 0);
19722657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(convFlags);
19822657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(personalLevel);
199863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(spam ? 1 : 0);
20076b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        dest.writeInt(phishing ? 1 : 0);
201863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(muted ? 1 : 0);
20292939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        dest.writeInt(color);
203a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        dest.writeParcelable(accountUri, 0);
204351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        dest.writeParcelable(conversationInfo, 0);
20541dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        dest.writeParcelable(conversationBaseUri, 0);
206f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        dest.writeInt(isRemote ? 1 : 0);
207732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
208732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
209351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    private Conversation(Parcel in, ClassLoader loader) {
210732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        id = in.readLong();
211c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        uri = in.readParcelable(null);
212732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        subject = in.readString();
213732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dateMs = in.readLong();
214732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        snippet = in.readString();
215f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        hasAttachments = (in.readInt() != 0);
216cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        messageListUri = in.readParcelable(null);
217820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        senders = emptyIfNull(in.readString());
2184db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numMessages = in.readInt();
2194db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numDrafts = in.readInt();
2204db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        sendingState = in.readInt();
2214db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        priority = in.readInt();
222f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        read = (in.readInt() != 0);
223d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        seen = (in.readInt() != 0);
224f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        starred = (in.readInt() != 0);
225b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        rawFolders = in.readParcelable(loader);
22622657529437c160dec072115c5982409306c1313Mindy Pereira        convFlags = in.readInt();
22722657529437c160dec072115c5982409306c1313Mindy Pereira        personalLevel = in.readInt();
228863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        spam = in.readInt() != 0;
22976b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        phishing = in.readInt() != 0;
230863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        muted = in.readInt() != 0;
23192939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        color = in.readInt();
232a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        accountUri = in.readParcelable(null);
233f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank        position = NO_POSITION;
234ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank        localDeleteOnUpdate = false;
235351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        conversationInfo = in.readParcelable(loader);
23641dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversationBaseUri = in.readParcelable(null);
237f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        isRemote = in.readInt() != 0;
238732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
239732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
240732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
241732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String toString() {
2427dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return "[conversation id=" + id + ", subject =" + subject + "]";
243732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
244732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
245351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang    public static final ClassLoaderCreator<Conversation> CREATOR =
246351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            new ClassLoaderCreator<Conversation>() {
247732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
248732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
249732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation createFromParcel(Parcel source) {
250351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            return new Conversation(source, null);
251351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        }
252351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang
253351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        @Override
254351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang        public Conversation createFromParcel(Parcel source, ClassLoader loader) {
255351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            return new Conversation(source, loader);
256732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
257732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
258732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
259732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation[] newArray(int size) {
260732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            return new Conversation[size];
261732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
262732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
263732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    };
264732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
265acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira    public static final Uri MOVE_CONVERSATIONS_URI = Uri.parse("content://moveconversations");
266acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira
267ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira    /**
268ae7e6a0786a2d890b77c783d7ac39a90523b8154mindyp     * The column that needs to be updated to change the folders for a conversation.
269ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira     */
27000ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    public static final String UPDATE_FOLDER_COLUMN = ConversationColumns.RAW_FOLDERS;
271ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira
272a831b2f1ba6d3c18d5e54563df8bae1f589c4257Mindy Pereira    public Conversation(Cursor cursor) {
273732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        if (cursor != null) {
274732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            id = cursor.getLong(UIProvider.CONVERSATION_ID_COLUMN);
275c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank            uri = Uri.parse(cursor.getString(UIProvider.CONVERSATION_URI_COLUMN));
276732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            dateMs = cursor.getLong(UIProvider.CONVERSATION_DATE_RECEIVED_MS_COLUMN);
277732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            subject = cursor.getString(UIProvider.CONVERSATION_SUBJECT_COLUMN);
278374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            // Don't allow null subject
279374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            if (subject == null) {
280374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank                subject = "";
281374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            }
28287d535fe423d782c3a0343c649330d309976f655Mindy Pereira            hasAttachments = cursor.getInt(UIProvider.CONVERSATION_HAS_ATTACHMENTS_COLUMN) != 0;
283648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            String messageList = cursor.getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN);
2845c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereira            messageListUri = !TextUtils.isEmpty(messageList) ? Uri.parse(messageList) : null;
2854db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            sendingState = cursor.getInt(UIProvider.CONVERSATION_SENDING_STATE_COLUMN);
2864db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            priority = cursor.getInt(UIProvider.CONVERSATION_PRIORITY_COLUMN);
28787d535fe423d782c3a0343c649330d309976f655Mindy Pereira            read = cursor.getInt(UIProvider.CONVERSATION_READ_COLUMN) != 0;
288d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            seen = cursor.getInt(UIProvider.CONVERSATION_SEEN_COLUMN) != 0;
28987d535fe423d782c3a0343c649330d309976f655Mindy Pereira            starred = cursor.getInt(UIProvider.CONVERSATION_STARRED_COLUMN) != 0;
290b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang            rawFolders = FolderList.fromBlob(
291b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang                    cursor.getBlob(UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN));
29222657529437c160dec072115c5982409306c1313Mindy Pereira            convFlags = cursor.getInt(UIProvider.CONVERSATION_FLAGS_COLUMN);
29322657529437c160dec072115c5982409306c1313Mindy Pereira            personalLevel = cursor.getInt(UIProvider.CONVERSATION_PERSONAL_LEVEL_COLUMN);
294863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            spam = cursor.getInt(UIProvider.CONVERSATION_IS_SPAM_COLUMN) != 0;
29576b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook            phishing = cursor.getInt(UIProvider.CONVERSATION_IS_PHISHING_COLUMN) != 0;
296863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            muted = cursor.getInt(UIProvider.CONVERSATION_MUTED_COLUMN) != 0;
29792939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank            color = cursor.getInt(UIProvider.CONVERSATION_COLOR_COLUMN);
298a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            String account = cursor.getString(UIProvider.CONVERSATION_ACCOUNT_URI_COLUMN);
299a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            accountUri = !TextUtils.isEmpty(account) ? Uri.parse(account) : null;
300f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank            position = NO_POSITION;
301ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank            localDeleteOnUpdate = false;
302351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang            conversationInfo = ConversationInfo.fromBlob(
303351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang                    cursor.getBlob(UIProvider.CONVERSATION_INFO_COLUMN));
30441dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            final String conversationBase =
30541dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    cursor.getString(UIProvider.CONVERSATION_BASE_URI_COLUMN);
30641dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook            conversationBaseUri = !TextUtils.isEmpty(conversationBase) ?
30741dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook                    Uri.parse(conversationBase) : null;
308e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            if (conversationInfo == null) {
309e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira                snippet = cursor.getString(UIProvider.CONVERSATION_SNIPPET_COLUMN);
310820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook                senders = emptyIfNull(cursor.getString(UIProvider.CONVERSATION_SENDER_INFO_COLUMN));
3110972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numMessages = cursor.getInt(UIProvider.CONVERSATION_NUM_MESSAGES_COLUMN);
3120972e0793cc321670391d063348aecb5031b2677Mindy Pereira                numDrafts = cursor.getInt(UIProvider.CONVERSATION_NUM_DRAFTS_COLUMN);
313e8a3eecf0a481665c5e886ebfb4a6184b5125f78Mindy Pereira            }
314f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang            isRemote = cursor.getInt(UIProvider.CONVERSATION_REMOTE_COLUMN) != 0;
315732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
316732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
317732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
318bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook    public Conversation() {
319ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
320ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
321863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public static Conversation create(long id, Uri uri, String subject, long dateMs,
322863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            String snippet, boolean hasAttachment, Uri messageListUri, String senders,
323863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            int numMessages, int numDrafts, int sendingState, int priority, boolean read,
324d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            boolean seen, boolean starred, FolderList rawFolders, int convFlags, int personalLevel,
325d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            boolean spam, boolean phishing, boolean muted, Uri accountUri,
326d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy            ConversationInfo conversationInfo, Uri conversationBase, boolean isRemote) {
327ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
328ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        final Conversation conversation = new Conversation();
329ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
330ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.id = id;
331ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.uri = uri;
332ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.subject = subject;
333ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.dateMs = dateMs;
334ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.snippet = snippet;
335ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.hasAttachments = hasAttachment;
336ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.messageListUri = messageListUri;
337820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        conversation.senders = emptyIfNull(senders);
338ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numMessages = numMessages;
339ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numDrafts = numDrafts;
340ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.sendingState = sendingState;
341ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.priority = priority;
342ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.read = read;
343d5edd2d02649dffb40065fdb6a16acf91552b800Scott Kennedy        conversation.seen = seen;
344ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.starred = starred;
345ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.rawFolders = rawFolders;
346ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.convFlags = convFlags;
347ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.personalLevel = personalLevel;
348863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.spam = spam;
34976b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        conversation.phishing = phishing;
350863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.muted = muted;
35192939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        conversation.color = 0;
352a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        conversation.accountUri = accountUri;
3537e854f52f0890b9621846ac7fe201a5681e65666Andy Huang        conversation.conversationInfo = conversationInfo;
35441dca185f7683b36bdafd9520c0648c897a95834Paul Westbrook        conversation.conversationBaseUri = conversationBase;
355f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang        conversation.isRemote = isRemote;
356ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        return conversation;
357ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
358ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
359b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    /**
360b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * Get the <strong>immutable</strong> list of {@link Folder}s for this conversation. To modify
361b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * this list, make a new {@link FolderList} and use {@link #setRawFolders(FolderList)}.
362b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     *
363b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     * @return <strong>Immutable</strong> list of {@link Folder}s.
364b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang     */
365b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    public List<Folder> getRawFolders() {
366b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        return rawFolders.folders;
36700ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    }
36800ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
369b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang    public void setRawFolders(FolderList folders) {
37085c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        clearCachedFolders();
371b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang        rawFolders = folders;
37285c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
37385c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
37485c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    private void clearCachedFolders() {
37585c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        cachedDisplayableFolders = null;
37685c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
37785c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
37885c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    public ArrayList<Folder> getRawFoldersForDisplay(Folder ignoreFolder) {
37985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        if (cachedDisplayableFolders == null) {
38085c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira            cachedDisplayableFolders = new ArrayList<Folder>();
381b2033d855ab0f13e253e5403ce25989bcbc49488Andy Huang            for (Folder folder : rawFolders.folders) {
3828eca4db9069941d2b8afbe6f75e3af75a4310f27Andy Huang                // skip the ignoreFolder
3838eca4db9069941d2b8afbe6f75e3af75a4310f27Andy Huang                if (ignoreFolder != null && ignoreFolder.equals(folder)) {
38485c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                    continue;
38585c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                }
38685c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira                cachedDisplayableFolders.add(folder);
38785c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira            }
38885c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        }
38985c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira        return cachedDisplayableFolders;
39085c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira    }
39185c4a77abd849f5f3f0236d51554bb1bb99fe8f6Mindy Pereira
392e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
393e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean equals(Object o) {
3943c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        if (o instanceof Conversation) {
395648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            Conversation conv = (Conversation) o;
3963c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank            return conv.uri.equals(uri);
3973c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        }
3983c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        return false;
399e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
400e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
401e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
402e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public int hashCode() {
403e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return uri.hashCode();
404e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
405e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
4067f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    /**
4077f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     * Get if this conversation is marked as high priority.
4087f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     */
4097f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    public boolean isImportant() {
41022657529437c160dec072115c5982409306c1313Mindy Pereira        return priority == UIProvider.ConversationPriority.IMPORTANT;
4117f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    }
4127f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira
413e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    /**
414e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     * Get if this conversation is mostly dead
415e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     */
416e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean isMostlyDead() {
417e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return (convFlags & FLAG_MOSTLY_DEAD) != 0;
418e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
419440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
420440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /**
421648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns true if the URI of the conversation specified as the needle was
422648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * found in the collection of conversations specified as the haystack. False
423192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal     * otherwise. This method is safe to call with null arguments.
424f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
425d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param haystack
426d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param needle
427d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @return true if the needle was found in the haystack, false otherwise.
428d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     */
429d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    public final static boolean contains(Collection<Conversation> haystack, Conversation needle) {
430d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // If the haystack is empty, it cannot contain anything.
431d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (haystack == null || haystack.size() <= 0) {
432d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return false;
433d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
434d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // The null folder exists everywhere.
435d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (needle == null) {
436d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return true;
437d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
4387dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final long toFind = needle.id;
439d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        for (final Conversation c : haystack) {
4407dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            if (toFind == c.id) {
441d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal                return true;
442d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            }
443d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
444d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        return false;
445d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    }
446d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal
447d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    /**
448648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns a collection of a single conversation. This method always returns
449648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * a valid collection even if the input conversation is null.
450f98bc898cbc7014a203c35a13427d3f949bce705Andy Huang     *
451440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @param in a conversation, possibly null.
452440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @return a collection of the conversation.
453440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     */
454440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static Collection<Conversation> listOf(Conversation in) {
455440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        final Collection<Conversation> target = (in == null) ? EMPTY : ImmutableList.of(in);
456440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        return target;
457440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    }
4587dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal
4597dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    /**
460aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * Get the snippet for this conversation. Masks that it may come from
461aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * conversation info or the original deprecated snippet string.
462aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     */
463aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    public String getSnippet() {
464d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira        return conversationInfo != null && !TextUtils.isEmpty(conversationInfo.firstSnippet) ?
465d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira                conversationInfo.firstSnippet : snippet;
466aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    }
467aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira
4683bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp    public String getSenders(Context context) {
4693bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        if (conversationInfo != null) {
4703bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            ArrayList<String> senders = new ArrayList<String>();
4713bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            for (MessageInfo m : this.conversationInfo.messageInfos) {
4723bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp                senders.add(m.sender);
4733bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            }
4743bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            return TextUtils.join(getSendersDelimeter(context), senders);
4753bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        } else {
4763bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            return senders;
4773bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        }
4783bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp    }
4793bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp
4803bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp    private String getSendersDelimeter(Context context) {
4813bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        if (sSendersDelimeter == null) {
4823bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp            sSendersDelimeter = context.getResources().getString(R.string.senders_split_token);
4833bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        }
4843bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp        return sSendersDelimeter;
4853bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp    }
4863bcf180f8104bc27319086a9a6ece5a3c2917c37mindyp
487aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    /**
4880972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of messages for this conversation.
4890972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
4900972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int getNumMessages() {
4910972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.messageCount : numMessages;
4920972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
4930972e0793cc321670391d063348aecb5031b2677Mindy Pereira
4940972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
4950972e0793cc321670391d063348aecb5031b2677Mindy Pereira     * Get the number of drafts for this conversation.
4960972e0793cc321670391d063348aecb5031b2677Mindy Pereira     */
4970972e0793cc321670391d063348aecb5031b2677Mindy Pereira    public int numDrafts() {
4980972e0793cc321670391d063348aecb5031b2677Mindy Pereira        return conversationInfo != null ? conversationInfo.draftCount : numDrafts;
4990972e0793cc321670391d063348aecb5031b2677Mindy Pereira    }
5000972e0793cc321670391d063348aecb5031b2677Mindy Pereira
501cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public boolean isViewed() {
502cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        return viewed;
503cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
504cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
505cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    public void markViewed() {
506cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang        viewed = true;
507cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang    }
508cd5c5eeae167885ffa2959c200233fea2f39c5f7Andy Huang
5090972e0793cc321670391d063348aecb5031b2677Mindy Pereira    /**
5107dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * Create a human-readable string of all the conversations
5117dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @param collection Any collection of conversations
5127dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @return string with a human readable representation of the conversations.
5137dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     */
5147dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    public static String toString(Collection<Conversation> collection) {
5157dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final StringBuilder out = new StringBuilder(collection.size() + " conversations:");
5167dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        int count = 0;
5177dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        for (final Conversation c : collection) {
5187dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            count++;
519648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // Indent the conversations to make them easy to read in debug
520648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // output.
5217dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            out.append("      " + count + ": " + c.toString() + "\n");
5227dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        }
5237dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return out.toString();
5247dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    }
525820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook
526820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    /**
527820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     * Returns an empty string if the specified string is null
528820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook     */
529820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    private static String emptyIfNull(String in) {
530820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook        return in != null ? in : EMPTY_STRING;
531820f051b37b45b3e3729bda5c4302a879ee6aa4dPaul Westbrook    }
532bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira
533bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    /**
534f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * Get the properly formatted subject and snippet string for display a
535f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * conversation.
536f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     *
537f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param context
538f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param filteredSubject
539f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp     * @param snippet
540bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira     */
541c046e4a310462aa6998a34ff50439eb5e2508d85mindyp    public static String getSubjectAndSnippetForDisplay(Context context,
542c046e4a310462aa6998a34ff50439eb5e2508d85mindyp            String filteredSubject, String snippet) {
5432909b7442130800d6c6c20c1227d65295262f03emindyp        if (sSubjectAndSnippet == null) {
5442909b7442130800d6c6c20c1227d65295262f03emindyp            sSubjectAndSnippet = context.getString(R.string.subject_and_snippet);
5452909b7442130800d6c6c20c1227d65295262f03emindyp        }
546c046e4a310462aa6998a34ff50439eb5e2508d85mindyp        return (!TextUtils.isEmpty(snippet)) ?
5472909b7442130800d6c6c20c1227d65295262f03emindyp                String.format(sSubjectAndSnippet, filteredSubject, snippet)
548f2caf91209e4e2d4182d6b379a3cd79eed81af71mindyp                : filteredSubject;
549bf9508d3877d05742b2f5d23e1780366d3e1aa2eMindy Pereira    }
550648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira}
551