Conversation.java revision 00ffece08e94ff5774b2a53c0adeb2f3d0815d66
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
19732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.database.Cursor;
20732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.net.Uri;
21732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.os.Parcel;
22732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangimport android.os.Parcelable;
23e623a0f6e3caa9cafec913cf826e946628833517Andy Huangimport android.provider.BaseColumns;
245c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereiraimport android.text.TextUtils;
25732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
26ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereiraimport com.android.mail.providers.UIProvider.ConversationColumns;
27648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereiraimport com.android.mail.utils.LogTag;
28648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereiraimport com.android.mail.utils.LogUtils;
29a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blankimport com.google.common.collect.ImmutableList;
30a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank
31648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereiraimport org.json.JSONException;
32648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira
3300ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereiraimport java.util.ArrayList;
34440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwalimport java.util.Collection;
35440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwalimport java.util.Collections;
36440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
37732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huangpublic class Conversation implements Parcelable {
38f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public static final int NO_POSITION = -1;
39732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
40e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
41e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see BaseColumns#_ID
42e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
43732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long id;
44e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
45e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#URI
46e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
47c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank    public Uri uri;
48e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
49e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SUBJECT
50e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
51732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String subject;
52e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
53e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#DATE_RECEIVED_MS
54e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
55732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public long dateMs;
56e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
57e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SNIPPET
58e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
59aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    @Deprecated
60732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String snippet;
61e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
62e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#HAS_ATTACHMENTS
63e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
64732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public boolean hasAttachments;
65e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
66e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MESSAGE_LIST_URI
67e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
68cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira    public Uri messageListUri;
69e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
70e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDER_INFO
71e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
72648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    @Deprecated
734db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public String senders;
74e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
75e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_MESSAGES
76e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
774db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int numMessages;
78e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
79e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#NUM_DRAFTS
80e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
814db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int numDrafts;
82e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
83e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SENDING_STATE
84e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
854db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int sendingState;
86e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
87e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PRIORITY
88e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
894db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira    public int priority;
90e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
91e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#READ
92e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
93c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean read;
94e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
95e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#STARRED
96e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
97c8a994227b9c686d88ee05840544162711a85712Marc Blank    public boolean starred;
98e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
99e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#RAW_FOLDERS
100e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
101cc8211df898ba9dac17a766b89f28d6e6f0afef0Mindy Pereira    public String rawFolders;
102e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
103e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#FLAGS
104e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
10522657529437c160dec072115c5982409306c1313Mindy Pereira    public int convFlags;
106e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
107e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#PERSONAL_LEVEL
108e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
10922657529437c160dec072115c5982409306c1313Mindy Pereira    public int personalLevel;
110e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
111e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#SPAM
112e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
113863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean spam;
114e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
115e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#MUTED
116e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
117863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public boolean muted;
118e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
11976b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     * @see UIProvider.ConversationColumns#PHISHING
12076b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook     */
12176b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    public boolean phishing;
12276b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook    /**
123e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#COLOR
124e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
12592939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank    public int color;
126e623a0f6e3caa9cafec913cf826e946628833517Andy Huang    /**
127e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     * @see UIProvider.ConversationColumns#ACCOUNT_URI
128e623a0f6e3caa9cafec913cf826e946628833517Andy Huang     */
129a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank    public Uri accountUri;
130648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    /**
131648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * @see UIProvider.ConversationColumns#CONVERSATION_INFO
132648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     */
133648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    public ConversationInfo conversationInfo;
13422657529437c160dec072115c5982409306c1313Mindy Pereira
135ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    // Used within the UI to indicate the adapter position of this conversation
136f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank    public transient int position;
137648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Used within the UI to indicate that a Conversation should be removed from
138648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the ConversationCursor when executing an update, e.g. the the
139648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Conversation is no longer in the ConversationList for the current folder,
140648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // that is it's now in some other folder(s)
141ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank    public transient boolean localDeleteOnUpdate;
142732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
14300ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    private ArrayList<Folder> cachedRawFolders;
14400ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
145e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    // Constituents of convFlags below
146648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // Flag indicating that the item has been deleted, but will continue being
147648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // shown in the list Delete/Archive of a mostly-dead item will NOT propagate
148648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    // the delete/archive, but WILL remove the item from the cursor
149e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public static final int FLAG_MOSTLY_DEAD = 1 << 0;
150e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
151440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /** An immutable, empty conversation list */
152440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static final Collection<Conversation> EMPTY = Collections.emptyList();
153440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
154732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
155732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public int describeContents() {
156732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        return 0;
157732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
158732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
159732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
160732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public void writeToParcel(Parcel dest, int flags) {
161732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(id);
162c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        dest.writeParcelable(uri, flags);
163732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(subject);
164732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeLong(dateMs);
165732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeString(snippet);
166732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dest.writeByte(hasAttachments ? (byte) 1 : 0);
167cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        dest.writeParcelable(messageListUri, 0);
1684db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeString(senders);
1694db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numMessages);
1704db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(numDrafts);
1714db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(sendingState);
1724db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        dest.writeInt(priority);
173c8a994227b9c686d88ee05840544162711a85712Marc Blank        dest.writeByte(read ? (byte) 1 : 0);
174c8a994227b9c686d88ee05840544162711a85712Marc Blank        dest.writeByte(starred ? (byte) 1 : 0);
175cc8211df898ba9dac17a766b89f28d6e6f0afef0Mindy Pereira        dest.writeString(rawFolders);
17622657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(convFlags);
17722657529437c160dec072115c5982409306c1313Mindy Pereira        dest.writeInt(personalLevel);
178863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(spam ? 1 : 0);
17976b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        dest.writeInt(phishing ? 1 : 0);
180863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        dest.writeInt(muted ? 1 : 0);
18192939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        dest.writeInt(color);
182a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        dest.writeParcelable(accountUri, 0);
18300c67ae6212de5b56c0c94af185061ee2fa36925Mindy Pereira        try {
18400c67ae6212de5b56c0c94af185061ee2fa36925Mindy Pereira            dest.writeString(ConversationInfo.toString(conversationInfo));
18500c67ae6212de5b56c0c94af185061ee2fa36925Mindy Pereira        } catch (JSONException e) {
18600c67ae6212de5b56c0c94af185061ee2fa36925Mindy Pereira            LogUtils.d(LOG_TAG, e, "Error adding conversationinfo to parcel");
18700c67ae6212de5b56c0c94af185061ee2fa36925Mindy Pereira        }
188732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
189732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
190732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    private Conversation(Parcel in) {
191732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        id = in.readLong();
192c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank        uri = in.readParcelable(null);
193732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        subject = in.readString();
194732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        dateMs = in.readLong();
195732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        snippet = in.readString();
196732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        hasAttachments = (in.readByte() != 0);
197cfb7f33ff8ef9dc60b9143af32de64c7a3d71f36Mindy Pereira        messageListUri = in.readParcelable(null);
1984db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        senders = in.readString();
1994db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numMessages = in.readInt();
2004db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        numDrafts = in.readInt();
2014db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        sendingState = in.readInt();
2024db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira        priority = in.readInt();
203c8a994227b9c686d88ee05840544162711a85712Marc Blank        read = (in.readByte() != 0);
204c8a994227b9c686d88ee05840544162711a85712Marc Blank        starred = (in.readByte() != 0);
205cc8211df898ba9dac17a766b89f28d6e6f0afef0Mindy Pereira        rawFolders = in.readString();
20622657529437c160dec072115c5982409306c1313Mindy Pereira        convFlags = in.readInt();
20722657529437c160dec072115c5982409306c1313Mindy Pereira        personalLevel = in.readInt();
208863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        spam = in.readInt() != 0;
20976b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        phishing = in.readInt() != 0;
210863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        muted = in.readInt() != 0;
21192939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        color = in.readInt();
212a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        accountUri = in.readParcelable(null);
213f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank        position = NO_POSITION;
214ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank        localDeleteOnUpdate = false;
21500c67ae6212de5b56c0c94af185061ee2fa36925Mindy Pereira        try {
21600c67ae6212de5b56c0c94af185061ee2fa36925Mindy Pereira            conversationInfo = ConversationInfo.fromString(in.readString());
21700c67ae6212de5b56c0c94af185061ee2fa36925Mindy Pereira        } catch (JSONException e) {
21800c67ae6212de5b56c0c94af185061ee2fa36925Mindy Pereira            LogUtils.d(LOG_TAG, e, "Error retrieving conversation info from parcel");
21900c67ae6212de5b56c0c94af185061ee2fa36925Mindy Pereira        }
220732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
221732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
222732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    @Override
223732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public String toString() {
2247dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return "[conversation id=" + id + ", subject =" + subject + "]";
225732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
226732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
227732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    public static final Creator<Conversation> CREATOR = new Creator<Conversation>() {
228732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
229732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
230732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation createFromParcel(Parcel source) {
231732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            return new Conversation(source);
232732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
233732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
234732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        @Override
235732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        public Conversation[] newArray(int size) {
236732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            return new Conversation[size];
237732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
238732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
239732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    };
240732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
241acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira    public static final Uri MOVE_CONVERSATIONS_URI = Uri.parse("content://moveconversations");
242acf6039a23382f18c35f6b487d90d53cb67b5858Mindy Pereira
243ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira    /**
24400ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira     * The column that needs to be updated to change the read state of a conversation.
245ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira     */
24600ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    public static final String UPDATE_FOLDER_COLUMN = ConversationColumns.RAW_FOLDERS;
247ebdfd98264104cb5a6888acd663970b7c0b31382Mindy Pereira
248648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira    private static final String LOG_TAG = LogTag.getLogTag();
249648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira
250a831b2f1ba6d3c18d5e54563df8bae1f589c4257Mindy Pereira    public Conversation(Cursor cursor) {
251732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        if (cursor != null) {
252732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            id = cursor.getLong(UIProvider.CONVERSATION_ID_COLUMN);
253c43bc0a606e41144a780c4f873b5450e0ede0c91Marc Blank            uri = Uri.parse(cursor.getString(UIProvider.CONVERSATION_URI_COLUMN));
254732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            dateMs = cursor.getLong(UIProvider.CONVERSATION_DATE_RECEIVED_MS_COLUMN);
255732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            subject = cursor.getString(UIProvider.CONVERSATION_SUBJECT_COLUMN);
256374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            // Don't allow null subject
257374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            if (subject == null) {
258374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank                subject = "";
259374863eeb0ee37f1ca7d57840e6f02aaa052e284Marc Blank            }
260732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang            snippet = cursor.getString(UIProvider.CONVERSATION_SNIPPET_COLUMN);
26187d535fe423d782c3a0343c649330d309976f655Mindy Pereira            hasAttachments = cursor.getInt(UIProvider.CONVERSATION_HAS_ATTACHMENTS_COLUMN) != 0;
262648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            String messageList = cursor.getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN);
2635c765b9c5dd8a9a9421260ba8b46d06073391c73Mindy Pereira            messageListUri = !TextUtils.isEmpty(messageList) ? Uri.parse(messageList) : null;
2644db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            numMessages = cursor.getInt(UIProvider.CONVERSATION_NUM_MESSAGES_COLUMN);
2654db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            numDrafts = cursor.getInt(UIProvider.CONVERSATION_NUM_DRAFTS_COLUMN);
2664db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            sendingState = cursor.getInt(UIProvider.CONVERSATION_SENDING_STATE_COLUMN);
2674db59c58c0af9f44d95a12dbe21322bed58cc518Mindy Pereira            priority = cursor.getInt(UIProvider.CONVERSATION_PRIORITY_COLUMN);
26887d535fe423d782c3a0343c649330d309976f655Mindy Pereira            read = cursor.getInt(UIProvider.CONVERSATION_READ_COLUMN) != 0;
26987d535fe423d782c3a0343c649330d309976f655Mindy Pereira            starred = cursor.getInt(UIProvider.CONVERSATION_STARRED_COLUMN) != 0;
270cc8211df898ba9dac17a766b89f28d6e6f0afef0Mindy Pereira            rawFolders = cursor.getString(UIProvider.CONVERSATION_RAW_FOLDERS_COLUMN);
27122657529437c160dec072115c5982409306c1313Mindy Pereira            convFlags = cursor.getInt(UIProvider.CONVERSATION_FLAGS_COLUMN);
27222657529437c160dec072115c5982409306c1313Mindy Pereira            personalLevel = cursor.getInt(UIProvider.CONVERSATION_PERSONAL_LEVEL_COLUMN);
273863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            spam = cursor.getInt(UIProvider.CONVERSATION_IS_SPAM_COLUMN) != 0;
27476b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook            phishing = cursor.getInt(UIProvider.CONVERSATION_IS_PHISHING_COLUMN) != 0;
275863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            muted = cursor.getInt(UIProvider.CONVERSATION_MUTED_COLUMN) != 0;
27692939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank            color = cursor.getInt(UIProvider.CONVERSATION_COLOR_COLUMN);
277a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            String account = cursor.getString(UIProvider.CONVERSATION_ACCOUNT_URI_COLUMN);
278a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank            accountUri = !TextUtils.isEmpty(account) ? Uri.parse(account) : null;
279f892f0a57d5c24b09fdc805f0fe2007ecd0d0e91Marc Blank            position = NO_POSITION;
280ce53818e1e185a845bd2f7f601c20e7085b40725Marc Blank            localDeleteOnUpdate = false;
281648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            senders = cursor.getString(UIProvider.CONVERSATION_SENDER_INFO_COLUMN);
282648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            try {
283648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira                conversationInfo = ConversationInfo.fromString(cursor
284648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira                        .getString(UIProvider.CONVERSATION_INFO_COLUMN));
285648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            } catch (JSONException e) {
286648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira                LogUtils.w(LOG_TAG, e,
287648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira                        "Unable to instantiate ConversationInfo. Try to continue anyway");
288648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            }
289732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang        }
290732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang    }
291732600e38891db139bae02dc91dd0c5b0987e8e9Andy Huang
292bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook    public Conversation() {
293ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
294ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
295863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira    public static Conversation create(long id, Uri uri, String subject, long dateMs,
296863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            String snippet, boolean hasAttachment, Uri messageListUri, String senders,
297863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira            int numMessages, int numDrafts, int sendingState, int priority, boolean read,
29800ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira            boolean starred, String rawFolders, int convFlags,
2997e854f52f0890b9621846ac7fe201a5681e65666Andy Huang            int personalLevel, boolean spam, boolean phishing, boolean muted, Uri accountUri,
3007e854f52f0890b9621846ac7fe201a5681e65666Andy Huang            ConversationInfo conversationInfo) {
301ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
302ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        final Conversation conversation = new Conversation();
303ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
304ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.id = id;
305ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.uri = uri;
306ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.subject = subject;
307ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.dateMs = dateMs;
308ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.snippet = snippet;
309ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.hasAttachments = hasAttachment;
310ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.messageListUri = messageListUri;
311ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.senders = senders;
312ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numMessages = numMessages;
313ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.numDrafts = numDrafts;
314ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.sendingState = sendingState;
315ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.priority = priority;
316ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.read = read;
317ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.starred = starred;
318ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.rawFolders = rawFolders;
319ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.convFlags = convFlags;
320ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        conversation.personalLevel = personalLevel;
321863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.spam = spam;
32276b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        conversation.phishing = phishing;
323863e44160d9175023d30e7e225ecb69ad3892eecMindy Pereira        conversation.muted = muted;
32492939fc7b40a56e17fb0d2fde987133ca1614e29Marc Blank        conversation.color = 0;
325a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank        conversation.accountUri = accountUri;
3267e854f52f0890b9621846ac7fe201a5681e65666Andy Huang        conversation.conversationInfo = conversationInfo;
327ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook        return conversation;
328ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook    }
329ff5c757ed2bcf7004a70b0675382ef894196558dPaul Westbrook
33000ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    public ArrayList<Folder> getRawFolders() {
33100ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira        if (cachedRawFolders == null) {
33200ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira            // Create cached folders.
33300ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira            cachedRawFolders = Folder.getFoldersArray(rawFolders);
33400ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira        }
33500ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira        return cachedRawFolders;
33600ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira    }
33700ffece08e94ff5774b2a53c0adeb2f3d0815d66Mindy Pereira
338e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
339e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean equals(Object o) {
3403c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        if (o instanceof Conversation) {
341648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            Conversation conv = (Conversation) o;
3423c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank            return conv.uri.equals(uri);
3433c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        }
3443c9bcef43b4f103697034abbf2eab99111e8d987Marc Blank        return false;
345e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
346e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
347e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    @Override
348e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public int hashCode() {
349e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return uri.hashCode();
350e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
351e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank
3527f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    /**
3537f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     * Get if this conversation is marked as high priority.
3547f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira     */
3557f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    public boolean isImportant() {
35622657529437c160dec072115c5982409306c1313Mindy Pereira        return priority == UIProvider.ConversationPriority.IMPORTANT;
3577f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    }
3587f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira
359e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    /**
360e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     * Get if this conversation is mostly dead
361e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank     */
362e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    public boolean isMostlyDead() {
363e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank        return (convFlags & FLAG_MOSTLY_DEAD) != 0;
364e1d1b07cdb0026097eb80f6c2912a16353aacec1Marc Blank    }
365440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal
366440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    /**
367648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns true if the URI of the conversation specified as the needle was
368648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * found in the collection of conversations specified as the haystack. False
369192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal     * otherwise. This method is safe to call with null arguments.
370648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     *
371d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param haystack
372d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @param needle
373d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     * @return true if the needle was found in the haystack, false otherwise.
374d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal     */
375d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    public final static boolean contains(Collection<Conversation> haystack, Conversation needle) {
376d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // If the haystack is empty, it cannot contain anything.
377d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (haystack == null || haystack.size() <= 0) {
378d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return false;
379d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
380d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        // The null folder exists everywhere.
381d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        if (needle == null) {
382d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            return true;
383d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
3847dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final long toFind = needle.id;
385d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        for (final Conversation c : haystack) {
3867dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            if (toFind == c.id) {
387d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal                return true;
388d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal            }
389d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        }
390d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        return false;
391d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    }
392d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal
393d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal    /**
394648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * Returns a collection of a single conversation. This method always returns
395648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     * a valid collection even if the input conversation is null.
396648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     *
397440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @param in a conversation, possibly null.
398440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     * @return a collection of the conversation.
399440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal     */
400440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    public static Collection<Conversation> listOf(Conversation in) {
401440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        final Collection<Conversation> target = (in == null) ? EMPTY : ImmutableList.of(in);
402440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal        return target;
403440fe79194314b25ef5829702494735ce2f1e2e8Vikram Aggarwal    }
4047dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal
4057dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    /**
406aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * Get the snippet for this conversation. Masks that it may come from
407aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     * conversation info or the original deprecated snippet string.
408aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira     */
409aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    public String getSnippet() {
410d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira        return conversationInfo != null && !TextUtils.isEmpty(conversationInfo.firstSnippet) ?
411d97782206889a5508279b75cce19d7c0fb8a3bcaMindy Pereira                conversationInfo.firstSnippet : snippet;
412aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    }
413aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira
414aa1f945612847bc4cf5c8909b8acfab4b5ecf54eMindy Pereira    /**
4157dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * Create a human-readable string of all the conversations
416648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira     *
4177dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @param collection Any collection of conversations
4187dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     * @return string with a human readable representation of the conversations.
4197dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal     */
4207dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    public static String toString(Collection<Conversation> collection) {
4217dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        final StringBuilder out = new StringBuilder(collection.size() + " conversations:");
4227dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        int count = 0;
4237dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        for (final Conversation c : collection) {
4247dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            count++;
425648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // Indent the conversations to make them easy to read in debug
426648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira            // output.
4277dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal            out.append("      " + count + ": " + c.toString() + "\n");
4287dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        }
4297dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal        return out.toString();
4307dd054e39986de84a213c56a3c11ac94731402e6Vikram Aggarwal    }
431648df3f0b0ebcd3c4adf907d70ff0938e5dfc78fMindy Pereira}
432