/*
 * Copyright (C) 2014 Samsung System LSI
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.bluetooth.map;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserManager;
import android.provider.Telephony;
import android.provider.Telephony.Mms;
import android.provider.Telephony.MmsSms;
import android.provider.Telephony.Sms;
import android.provider.Telephony.Sms.Inbox;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SmsManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.Xml;

import com.android.bluetooth.Utils;
import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
import com.android.bluetooth.map.BluetoothMapbMessageMime.MimePart;
import com.android.bluetooth.mapapi.BluetoothMapContract;
import com.android.bluetooth.mapapi.BluetoothMapContract.MessageColumns;

import com.google.android.mms.pdu.PduHeaders;

import org.xmlpull.v1.XmlSerializer;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import javax.obex.ResponseCodes;

@TargetApi(19)
public class BluetoothMapContentObserver {
    private static final String TAG = "BluetoothMapContentObserver";

    private static final boolean D = BluetoothMapService.DEBUG;
    private static final boolean V = BluetoothMapService.VERBOSE;

    private static final String EVENT_TYPE_NEW = "NewMessage";
    private static final String EVENT_TYPE_DELETE = "MessageDeleted";
    private static final String EVENT_TYPE_REMOVED = "MessageRemoved";
    private static final String EVENT_TYPE_SHIFT = "MessageShift";
    private static final String EVENT_TYPE_DELEVERY_SUCCESS = "DeliverySuccess";
    private static final String EVENT_TYPE_SENDING_SUCCESS = "SendingSuccess";
    private static final String EVENT_TYPE_SENDING_FAILURE = "SendingFailure";
    private static final String EVENT_TYPE_DELIVERY_FAILURE = "DeliveryFailure";
    private static final String EVENT_TYPE_READ_STATUS = "ReadStatusChanged";
    private static final String EVENT_TYPE_CONVERSATION = "ConversationChanged";
    private static final String EVENT_TYPE_PRESENCE = "ParticipantPresenceChanged";
    private static final String EVENT_TYPE_CHAT_STATE = "ParticipantChatStateChanged";

    private static final long EVENT_FILTER_NEW_MESSAGE = 1L;
    private static final long EVENT_FILTER_MESSAGE_DELETED = 1L << 1;
    private static final long EVENT_FILTER_MESSAGE_SHIFT = 1L << 2;
    private static final long EVENT_FILTER_SENDING_SUCCESS = 1L << 3;
    private static final long EVENT_FILTER_SENDING_FAILED = 1L << 4;
    private static final long EVENT_FILTER_DELIVERY_SUCCESS = 1L << 5;
    private static final long EVENT_FILTER_DELIVERY_FAILED = 1L << 6;
    private static final long EVENT_FILTER_MEMORY_FULL = 1L << 7; // Unused
    private static final long EVENT_FILTER_MEMORY_AVAILABLE = 1L << 8; // Unused
    private static final long EVENT_FILTER_READ_STATUS_CHANGED = 1L << 9;
    private static final long EVENT_FILTER_CONVERSATION_CHANGED = 1L << 10;
    private static final long EVENT_FILTER_PARTICIPANT_PRESENCE_CHANGED = 1L << 11;
    private static final long EVENT_FILTER_PARTICIPANT_CHATSTATE_CHANGED = 1L << 12;
    private static final long EVENT_FILTER_MESSAGE_REMOVED = 1L << 14;

    // TODO: If we are requesting a large message from the network, on a slow connection
    //       20 seconds might not be enough... But then again 20 seconds is long for other
    //       cases.
    private static final long PROVIDER_ANR_TIMEOUT = 20 * DateUtils.SECOND_IN_MILLIS;

    private Context mContext;
    private ContentResolver mResolver;
    private ContentProviderClient mProviderClient = null;
    private BluetoothMnsObexClient mMnsClient;
    private BluetoothMapMasInstance mMasInstance = null;
    private int mMasId;
    private boolean mEnableSmsMms = false;
    private boolean mObserverRegistered = false;
    private BluetoothMapAccountItem mAccount;
    private String mAuthority = null;

    // Default supported feature bit mask is 0x1f
    private int mMapSupportedFeatures = BluetoothMapUtils.MAP_FEATURE_DEFAULT_BITMASK;
    // Default event report version is 1.0
    private int mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V10;

    private BluetoothMapFolderElement mFolders = new BluetoothMapFolderElement("DUMMY", null);
    // Will be set by the MAS when generated.
    private Uri mMessageUri = null;
    private Uri mContactUri = null;

    private boolean mTransmitEvents = true;

    /* To make the filter update atomic, we declare it volatile.
     * To avoid a penalty when using it, copy the value to a local
     * non-volatile variable when used more than once.
     * Actually we only ever use the lower 4 bytes of this variable,
     * hence we could manage without the volatile keyword, but as
     * we tend to copy ways of doing things, we better do it right:-) */
    private volatile long mEventFilter = 0xFFFFFFFFL;

    public static final int DELETED_THREAD_ID = -1;

    // X-Mms-Message-Type field types. These are from PduHeaders.java
    public static final int MESSAGE_TYPE_RETRIEVE_CONF = 0x84;

    // Text only MMS converted to SMS if sms parts less than or equal to defined count
    private static final int CONVERT_MMS_TO_SMS_PART_COUNT = 10;

    private TYPE mSmsType;

    private static final String ACTION_MESSAGE_DELIVERY =
            "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY";
    /*package*/ static final String ACTION_MESSAGE_SENT =
            "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT";

    public static final String EXTRA_MESSAGE_SENT_HANDLE = "HANDLE";
    public static final String EXTRA_MESSAGE_SENT_RESULT = "result";
    public static final String EXTRA_MESSAGE_SENT_MSG_TYPE = "type";
    public static final String EXTRA_MESSAGE_SENT_URI = "uri";
    public static final String EXTRA_MESSAGE_SENT_RETRY = "retry";
    public static final String EXTRA_MESSAGE_SENT_TRANSPARENT = "transparent";
    public static final String EXTRA_MESSAGE_SENT_TIMESTAMP = "timestamp";

    private SmsBroadcastReceiver mSmsBroadcastReceiver = new SmsBroadcastReceiver();
    private CeBroadcastReceiver mCeBroadcastReceiver = new CeBroadcastReceiver();

    private boolean mStorageUnlocked = false;
    private boolean mInitialized = false;


    static final String[] SMS_PROJECTION = new String[]{
            Sms._ID,
            Sms.THREAD_ID,
            Sms.ADDRESS,
            Sms.BODY,
            Sms.DATE,
            Sms.READ,
            Sms.TYPE,
            Sms.STATUS,
            Sms.LOCKED,
            Sms.ERROR_CODE
    };

    static final String[] SMS_PROJECTION_SHORT = new String[]{
            Sms._ID, Sms.THREAD_ID, Sms.TYPE, Sms.READ
    };

    static final String[] SMS_PROJECTION_SHORT_EXT = new String[]{
            Sms._ID, Sms.THREAD_ID, Sms.ADDRESS, Sms.BODY, Sms.DATE, Sms.READ, Sms.TYPE,
    };

    static final String[] MMS_PROJECTION_SHORT = new String[]{
            Mms._ID, Mms.THREAD_ID, Mms.MESSAGE_TYPE, Mms.MESSAGE_BOX, Mms.READ
    };

    static final String[] MMS_PROJECTION_SHORT_EXT = new String[]{
            Mms._ID,
            Mms.THREAD_ID,
            Mms.MESSAGE_TYPE,
            Mms.MESSAGE_BOX,
            Mms.READ,
            Mms.DATE,
            Mms.SUBJECT,
            Mms.PRIORITY
    };

    static final String[] MSG_PROJECTION_SHORT = new String[]{
            BluetoothMapContract.MessageColumns._ID,
            BluetoothMapContract.MessageColumns.FOLDER_ID,
            BluetoothMapContract.MessageColumns.FLAG_READ
    };

    static final String[] MSG_PROJECTION_SHORT_EXT = new String[]{
            BluetoothMapContract.MessageColumns._ID,
            BluetoothMapContract.MessageColumns.FOLDER_ID,
            BluetoothMapContract.MessageColumns.FLAG_READ,
            BluetoothMapContract.MessageColumns.DATE,
            BluetoothMapContract.MessageColumns.SUBJECT,
            BluetoothMapContract.MessageColumns.FROM_LIST,
            BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY
    };

    static final String[] MSG_PROJECTION_SHORT_EXT2 = new String[]{
            BluetoothMapContract.MessageColumns._ID,
            BluetoothMapContract.MessageColumns.FOLDER_ID,
            BluetoothMapContract.MessageColumns.FLAG_READ,
            BluetoothMapContract.MessageColumns.DATE,
            BluetoothMapContract.MessageColumns.SUBJECT,
            BluetoothMapContract.MessageColumns.FROM_LIST,
            BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY,
            BluetoothMapContract.MessageColumns.THREAD_ID,
            BluetoothMapContract.MessageColumns.THREAD_NAME
    };

    public BluetoothMapContentObserver(final Context context, BluetoothMnsObexClient mnsClient,
            BluetoothMapMasInstance masInstance, BluetoothMapAccountItem account,
            boolean enableSmsMms) throws RemoteException {
        mContext = context;
        mResolver = mContext.getContentResolver();
        mAccount = account;
        mMasInstance = masInstance;
        mMasId = mMasInstance.getMasId();
        setObserverRemoteFeatureMask(mMasInstance.getRemoteFeatureMask());

        if (account != null) {
            mAuthority = Uri.parse(account.mBase_uri).getAuthority();
            mMessageUri = Uri.parse(account.mBase_uri + "/" + BluetoothMapContract.TABLE_MESSAGE);
            if (mAccount.getType() == TYPE.IM) {
                mContactUri = Uri.parse(
                        account.mBase_uri + "/" + BluetoothMapContract.TABLE_CONVOCONTACT);
            }
            // TODO: We need to release this again!
            mProviderClient = mResolver.acquireUnstableContentProviderClient(mAuthority);
            if (mProviderClient == null) {
                throw new RemoteException("Failed to acquire provider for " + mAuthority);
            }
            mProviderClient.setDetectNotResponding(PROVIDER_ANR_TIMEOUT);
            mContactList = mMasInstance.getContactList();
            if (mContactList == null) {
                setContactList(new HashMap<String, BluetoothMapConvoContactElement>(), false);
                initContactsList();
            }
        }
        mEnableSmsMms = enableSmsMms;
        mSmsType = getSmsType();
        mMnsClient = mnsClient;
        /* Get the cached list - if any, else create */
        mMsgListSms = mMasInstance.getMsgListSms();
        boolean doInit = false;
        if (mEnableSmsMms) {
            if (mMsgListSms == null) {
                setMsgListSms(new HashMap<Long, Msg>(), false);
                doInit = true;
            }
            mMsgListMms = mMasInstance.getMsgListMms();
            if (mMsgListMms == null) {
                setMsgListMms(new HashMap<Long, Msg>(), false);
                doInit = true;
            }
        }
        if (mAccount != null) {
            mMsgListMsg = mMasInstance.getMsgListMsg();
            if (mMsgListMsg == null) {
                setMsgListMsg(new HashMap<Long, Msg>(), false);
                doInit = true;
            }
        }
        if (doInit) {
            initMsgList();
        }
    }

    public int getObserverRemoteFeatureMask() {
        if (V) {
            Log.v(TAG, "getObserverRemoteFeatureMask : " + mMapEventReportVersion
                    + " mMapSupportedFeatures: " + mMapSupportedFeatures);
        }
        return mMapSupportedFeatures;
    }

    public void setObserverRemoteFeatureMask(int remoteSupportedFeatures) {
        mMapSupportedFeatures =
                remoteSupportedFeatures & BluetoothMapMasInstance.getFeatureMask();
        if ((BluetoothMapUtils.MAP_FEATURE_EXTENDED_EVENT_REPORT_11_BIT & mMapSupportedFeatures)
                != 0) {
            mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11;
        }
        // Make sure support for all formats result in latest version returned
        if ((BluetoothMapUtils.MAP_FEATURE_EVENT_REPORT_V12_BIT & mMapSupportedFeatures) != 0) {
            mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12;
        } else if (((BluetoothMapUtils.MAP_FEATURE_PARTICIPANT_PRESENCE_CHANGE_BIT
                | BluetoothMapUtils.MAP_FEATURE_PARTICIPANT_CHAT_STATE_CHANGE_BIT)
                & mMapSupportedFeatures) != 0) {
            // Warning according to page 46/123 of MAP 1.3 spec
            Log.w(TAG, "setObserverRemoteFeatureMask: Extended Event Reports 1.2 is not set even"
                    + "though PARTICIPANT_PRESENCE_CHANGE_BIT or PARTICIPANT_CHAT_STATE_CHANGE_BIT"
                    + " were set, mMapSupportedFeatures=" + mMapSupportedFeatures);
        }
        if (D) {
            Log.d(TAG,
                    "setObserverRemoteFeatureMask: mMapEventReportVersion=" + mMapEventReportVersion
                            + " mMapSupportedFeatures=" + mMapSupportedFeatures);
        }
    }

    private Map<Long, Msg> getMsgListSms() {
        return mMsgListSms;
    }

    private void setMsgListSms(Map<Long, Msg> msgListSms, boolean changesDetected) {
        mMsgListSms = msgListSms;
        if (changesDetected) {
            mMasInstance.updateFolderVersionCounter();
        }
        mMasInstance.setMsgListSms(msgListSms);
    }


    private Map<Long, Msg> getMsgListMms() {
        return mMsgListMms;
    }


    private void setMsgListMms(Map<Long, Msg> msgListMms, boolean changesDetected) {
        mMsgListMms = msgListMms;
        if (changesDetected) {
            mMasInstance.updateFolderVersionCounter();
        }
        mMasInstance.setMsgListMms(msgListMms);
    }


    private Map<Long, Msg> getMsgListMsg() {
        return mMsgListMsg;
    }


    private void setMsgListMsg(Map<Long, Msg> msgListMsg, boolean changesDetected) {
        mMsgListMsg = msgListMsg;
        if (changesDetected) {
            mMasInstance.updateFolderVersionCounter();
        }
        mMasInstance.setMsgListMsg(msgListMsg);
    }

    private Map<String, BluetoothMapConvoContactElement> getContactList() {
        return mContactList;
    }


    /**
     * Currently we only have data for IM / email contacts
     * @param contactList
     * @param changesDetected that is not chat state changed nor presence state changed.
     */
    private void setContactList(Map<String, BluetoothMapConvoContactElement> contactList,
            boolean changesDetected) {
        mContactList = contactList;
        if (changesDetected) {
            mMasInstance.updateImEmailConvoListVersionCounter();
        }
        mMasInstance.setContactList(contactList);
    }

    private static boolean sendEventNewMessage(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_NEW_MESSAGE) > 0);
    }

    private static boolean sendEventMessageDeleted(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_MESSAGE_DELETED) > 0);
    }

    private static boolean sendEventMessageShift(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_MESSAGE_SHIFT) > 0);
    }

    private static boolean sendEventSendingSuccess(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_SENDING_SUCCESS) > 0);
    }

    private static boolean sendEventSendingFailed(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_SENDING_FAILED) > 0);
    }

    private static boolean sendEventDeliverySuccess(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_DELIVERY_SUCCESS) > 0);
    }

    private static boolean sendEventDeliveryFailed(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_DELIVERY_FAILED) > 0);
    }

    private static boolean sendEventReadStatusChanged(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_READ_STATUS_CHANGED) > 0);
    }

    private static boolean sendEventConversationChanged(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_CONVERSATION_CHANGED) > 0);
    }

    private static boolean sendEventParticipantPresenceChanged(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_PARTICIPANT_PRESENCE_CHANGED) > 0);
    }

    private static boolean sendEventParticipantChatstateChanged(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_PARTICIPANT_CHATSTATE_CHANGED) > 0);
    }

    private static boolean sendEventMessageRemoved(long eventFilter) {
        return ((eventFilter & EVENT_FILTER_MESSAGE_REMOVED) > 0);
    }

    private TYPE getSmsType() {
        TYPE smsType = null;
        TelephonyManager tm =
                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

        if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
            smsType = TYPE.SMS_CDMA;
        } else {
            smsType = TYPE.SMS_GSM;
        }

        return smsType;
    }

    private final ContentObserver mObserver = new ContentObserver(new Handler()) {
        @Override
        public void onChange(boolean selfChange) {
            onChange(selfChange, null);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            if (uri == null) {
                Log.w(TAG, "onChange() with URI == null - not handled.");
                return;
            }

            if (!mStorageUnlocked) {
                Log.v(TAG, "Ignore events until storage is completely unlocked");
                return;
            }

            if (V) {
                Log.d(TAG, "onChange on thread: " + Thread.currentThread().getId() + " Uri: "
                        + uri.toString() + " selfchange: " + selfChange);
            }

            if (uri.toString().contains(BluetoothMapContract.TABLE_CONVOCONTACT)) {
                handleContactListChanges(uri);
            } else {
                handleMsgListChanges(uri);
            }
        }
    };

    private static final HashMap<Integer, String> FOLDER_SMS_MAP;

    static {
        FOLDER_SMS_MAP = new HashMap<Integer, String>();
        FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_INBOX, BluetoothMapContract.FOLDER_NAME_INBOX);
        FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_SENT, BluetoothMapContract.FOLDER_NAME_SENT);
        FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_DRAFT, BluetoothMapContract.FOLDER_NAME_DRAFT);
        FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_OUTBOX, BluetoothMapContract.FOLDER_NAME_OUTBOX);
        FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_FAILED, BluetoothMapContract.FOLDER_NAME_OUTBOX);
        FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_QUEUED, BluetoothMapContract.FOLDER_NAME_OUTBOX);
    }

    private static String getSmsFolderName(int type) {
        String name = FOLDER_SMS_MAP.get(type);
        if (name != null) {
            return name;
        }
        Log.e(TAG, "New SMS mailbox types have been introduced, without an update in BT...");
        return "Unknown";
    }


    private static final HashMap<Integer, String> FOLDER_MMS_MAP;

    static {
        FOLDER_MMS_MAP = new HashMap<Integer, String>();
        FOLDER_MMS_MAP.put(Mms.MESSAGE_BOX_INBOX, BluetoothMapContract.FOLDER_NAME_INBOX);
        FOLDER_MMS_MAP.put(Mms.MESSAGE_BOX_SENT, BluetoothMapContract.FOLDER_NAME_SENT);
        FOLDER_MMS_MAP.put(Mms.MESSAGE_BOX_DRAFTS, BluetoothMapContract.FOLDER_NAME_DRAFT);
        FOLDER_MMS_MAP.put(Mms.MESSAGE_BOX_OUTBOX, BluetoothMapContract.FOLDER_NAME_OUTBOX);
    }

    private static String getMmsFolderName(int mailbox) {
        String name = FOLDER_MMS_MAP.get(mailbox);
        if (name != null) {
            return name;
        }
        Log.e(TAG, "New MMS mailboxes have been introduced, without an update in BT...");
        return "Unknown";
    }

    /**
     * Set the folder structure to be used for this instance.
     * @param folderStructure
     */
    public void setFolderStructure(BluetoothMapFolderElement folderStructure) {
        this.mFolders = folderStructure;
    }

    private class ConvoContactInfo {
        public int mConvoColConvoId = -1;
        public int mConvoColLastActivity = -1;
        public int mConvoColName = -1;
        //        public int mConvoColRead            = -1;
        //        public int mConvoColVersionCounter  = -1;
        public int mContactColUci = -1;
        public int mContactColConvoId = -1;
        public int mContactColName = -1;
        public int mContactColNickname = -1;
        public int mContactColBtUid = -1;
        public int mContactColChatState = -1;
        public int mContactColContactId = -1;
        public int mContactColLastActive = -1;
        public int mContactColPresenceState = -1;
        public int mContactColPresenceText = -1;
        public int mContactColPriority = -1;
        public int mContactColLastOnline = -1;

        public void setConvoColunms(Cursor c) {
            //            mConvoColConvoId         = c.getColumnIndex(
            //                    BluetoothMapContract.ConversationColumns.THREAD_ID);
            //            mConvoColLastActivity    = c.getColumnIndex(
            //                    BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY);
            //            mConvoColName            = c.getColumnIndex(
            //                    BluetoothMapContract.ConversationColumns.THREAD_NAME);
            mContactColConvoId =
                    c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.CONVO_ID);
            mContactColName = c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.NAME);
            mContactColNickname =
                    c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.NICKNAME);
            mContactColBtUid = c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.X_BT_UID);
            mContactColChatState =
                    c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.CHAT_STATE);
            mContactColUci = c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.UCI);
            mContactColNickname =
                    c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.NICKNAME);
            mContactColLastActive =
                    c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE);
            mContactColName = c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.NAME);
            mContactColPresenceState =
                    c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE);
            mContactColPresenceText =
                    c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.STATUS_TEXT);
            mContactColPriority =
                    c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.PRIORITY);
            mContactColLastOnline =
                    c.getColumnIndex(BluetoothMapContract.ConvoContactColumns.LAST_ONLINE);
        }
    }

    private class Event {
        public String eventType;
        public long handle;
        public String folder = null;
        public String oldFolder = null;
        public TYPE msgType;
        /* Extended event parameters in MAP Event version 1.1 */
        public String datetime = null; // OBEX time "YYYYMMDDTHHMMSS"
        public String uci = null;
        public String subject = null;
        public String senderName = null;
        public String priority = null;
        /* Event parameters in MAP Event version 1.2 */
        public String conversationName = null;
        public long conversationID = -1;
        public int presenceState = BluetoothMapContract.PresenceState.UNKNOWN;
        public String presenceStatus = null;
        public int chatState = BluetoothMapContract.ChatState.UNKNOWN;

        static final String PATH = "telecom/msg/";

        private void setFolderPath(String name, TYPE type) {
            if (name != null) {
                if (type == TYPE.EMAIL || type == TYPE.IM) {
                    this.folder = name;
                } else {
                    this.folder = PATH + name;
                }
            } else {
                this.folder = null;
            }
        }

        Event(String eventType, long handle, String folder, String oldFolder, TYPE msgType) {
            this.eventType = eventType;
            this.handle = handle;
            setFolderPath(folder, msgType);
            if (oldFolder != null) {
                if (msgType == TYPE.EMAIL || msgType == TYPE.IM) {
                    this.oldFolder = oldFolder;
                } else {
                    this.oldFolder = PATH + oldFolder;
                }
            } else {
                this.oldFolder = null;
            }
            this.msgType = msgType;
        }

        Event(String eventType, long handle, String folder, TYPE msgType) {
            this.eventType = eventType;
            this.handle = handle;
            setFolderPath(folder, msgType);
            this.msgType = msgType;
        }

        /* extended event type 1.1 */
        Event(String eventType, long handle, String folder, TYPE msgType, String datetime,
                String subject, String senderName, String priority) {
            this.eventType = eventType;
            this.handle = handle;
            setFolderPath(folder, msgType);
            this.msgType = msgType;
            this.datetime = datetime;
            if (subject != null) {
                this.subject = BluetoothMapUtils.stripInvalidChars(subject);
            }
            if (senderName != null) {
                this.senderName = BluetoothMapUtils.stripInvalidChars(senderName);
            }
            this.priority = priority;
        }

        /* extended event type 1.2 message events */
        Event(String eventType, long handle, String folder, TYPE msgType, String datetime,
                String subject, String senderName, String priority, long conversationID,
                String conversationName) {
            this.eventType = eventType;
            this.handle = handle;
            setFolderPath(folder, msgType);
            this.msgType = msgType;
            this.datetime = datetime;
            if (subject != null) {
                this.subject = BluetoothMapUtils.stripInvalidChars(subject);
            }
            if (senderName != null) {
                this.senderName = BluetoothMapUtils.stripInvalidChars(senderName);
            }
            if (conversationID != 0) {
                this.conversationID = conversationID;
            }
            if (conversationName != null) {
                this.conversationName = BluetoothMapUtils.stripInvalidChars(conversationName);
            }
            this.priority = priority;
        }

        /* extended event type 1.2 for conversation, presence or chat state changed events */
        Event(String eventType, String uci, TYPE msgType, String name, String priority,
                String lastActivity, long conversationID, String conversationName,
                int presenceState, String presenceStatus, int chatState) {
            this.eventType = eventType;
            this.uci = uci;
            this.msgType = msgType;
            if (name != null) {
                this.senderName = BluetoothMapUtils.stripInvalidChars(name);
            }
            this.priority = priority;
            this.datetime = lastActivity;
            if (conversationID != 0) {
                this.conversationID = conversationID;
            }
            if (conversationName != null) {
                this.conversationName = BluetoothMapUtils.stripInvalidChars(conversationName);
            }
            if (presenceState != BluetoothMapContract.PresenceState.UNKNOWN) {
                this.presenceState = presenceState;
            }
            if (presenceStatus != null) {
                this.presenceStatus = BluetoothMapUtils.stripInvalidChars(presenceStatus);
            }
            if (chatState != BluetoothMapContract.ChatState.UNKNOWN) {
                this.chatState = chatState;
            }
        }

        public byte[] encode() throws UnsupportedEncodingException {
            StringWriter sw = new StringWriter();
            XmlSerializer xmlEvtReport = Xml.newSerializer();

            try {
                xmlEvtReport.setOutput(sw);
                xmlEvtReport.startDocument("UTF-8", true);
                xmlEvtReport.text("\r\n");
                xmlEvtReport.startTag("", "MAP-event-report");
                if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V12) {
                    xmlEvtReport.attribute("", "version", BluetoothMapUtils.MAP_V12_STR);
                } else if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V11) {
                    xmlEvtReport.attribute("", "version", BluetoothMapUtils.MAP_V11_STR);
                } else {
                    xmlEvtReport.attribute("", "version", BluetoothMapUtils.MAP_V10_STR);
                }
                xmlEvtReport.startTag("", "event");
                xmlEvtReport.attribute("", "type", eventType);
                if (eventType.equals(EVENT_TYPE_CONVERSATION) || eventType.equals(
                        EVENT_TYPE_PRESENCE) || eventType.equals(EVENT_TYPE_CHAT_STATE)) {
                    xmlEvtReport.attribute("", "participant_uci", uci);
                } else {
                    xmlEvtReport.attribute("", "handle",
                            BluetoothMapUtils.getMapHandle(handle, msgType));
                }

                if (folder != null) {
                    xmlEvtReport.attribute("", "folder", folder);
                }
                if (oldFolder != null) {
                    xmlEvtReport.attribute("", "old_folder", oldFolder);
                }
                /* Avoid possible NPE for "msgType" "null" value. "msgType"
                 * is a implied attribute and will be set "null" for events
                 * like "memory full" or "memory available" */
                if (msgType != null) {
                    xmlEvtReport.attribute("", "msg_type", msgType.name());
                }
                /* If MAP event report version is above 1.0 send
                 * extended event report parameters */
                if (datetime != null) {
                    xmlEvtReport.attribute("", "datetime", datetime);
                }
                if (subject != null) {
                    xmlEvtReport.attribute("", "subject",
                            subject.substring(0, subject.length() < 256 ? subject.length() : 256));
                }
                if (senderName != null) {
                    xmlEvtReport.attribute("", "sender_name",
                            senderName.substring(
                                    0, senderName.length() < 256 ? senderName.length() : 255));
                }
                if (priority != null) {
                    xmlEvtReport.attribute("", "priority", priority);
                }

                //}
                /* Include conversation information from event version 1.2 */
                if (mMapEventReportVersion > BluetoothMapUtils.MAP_EVENT_REPORT_V11) {
                    if (conversationName != null) {
                        xmlEvtReport.attribute("", "conversation_name", conversationName);
                    }
                    if (conversationID != -1) {
                        // Convert provider conversation handle to string incl type
                        xmlEvtReport.attribute("", "conversation_id",
                                BluetoothMapUtils.getMapConvoHandle(conversationID, msgType));
                    }
                    if (eventType.equals(EVENT_TYPE_PRESENCE)) {
                        if (presenceState != 0) {
                            // Convert provider conversation handle to string incl type
                            xmlEvtReport.attribute("", "presence_availability",
                                    String.valueOf(presenceState));
                        }
                        if (presenceStatus != null) {
                            // Convert provider conversation handle to string incl type
                            xmlEvtReport.attribute("", "presence_status",
                                    presenceStatus.substring(0,
                                            presenceStatus.length() < 256 ? subject.length()
                                                    : 256));
                        }
                    }
                    if (eventType.equals(EVENT_TYPE_PRESENCE)) {
                        if (chatState != 0) {
                            // Convert provider conversation handle to string incl type
                            xmlEvtReport.attribute("", "chat_state", String.valueOf(chatState));
                        }
                    }

                }
                xmlEvtReport.endTag("", "event");
                xmlEvtReport.endTag("", "MAP-event-report");
                xmlEvtReport.endDocument();
            } catch (IllegalArgumentException e) {
                if (D) {
                    Log.w(TAG, e);
                }
            } catch (IllegalStateException e) {
                if (D) {
                    Log.w(TAG, e);
                }
            } catch (IOException e) {
                if (D) {
                    Log.w(TAG, e);
                }
            }

            if (V) {
                Log.d(TAG, sw.toString());
            }

            return sw.toString().getBytes("UTF-8");
        }
    }

    /*package*/ class Msg {
        public long id;
        public int type;               // Used as folder for SMS/MMS
        public int threadId;           // Used for SMS/MMS at delete
        public long folderId = -1;     // Email folder ID
        public long oldFolderId = -1;  // Used for email undelete
        public boolean localInitiatedSend = false; // Used for MMS to filter out events
        public boolean transparent = false;
        // Used for EMAIL to delete message sent with transparency
        public int flagRead = -1;      // Message status read/unread

        Msg(long id, int type, int threadId, int readFlag) {
            this.id = id;
            this.type = type;
            this.threadId = threadId;
            this.flagRead = readFlag;
        }

        Msg(long id, long folderId, int readFlag) {
            this.id = id;
            this.folderId = folderId;
            this.flagRead = readFlag;
        }

        /* Eclipse generated hashCode() and equals() to make
         * hashMap lookup work independent of whether the obj
         * is used for email or SMS/MMS and whether or not the
         * oldFolder is set. */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + (int) (id ^ (id >>> 32));
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            Msg other = (Msg) obj;
            if (id != other.id) {
                return false;
            }
            return true;
        }
    }

    private Map<Long, Msg> mMsgListSms = null;

    private Map<Long, Msg> mMsgListMms = null;

    private Map<Long, Msg> mMsgListMsg = null;

    private Map<String, BluetoothMapConvoContactElement> mContactList = null;

    public int setNotificationRegistration(int notificationStatus) throws RemoteException {
        // Forward the request to the MNS thread as a message - including the MAS instance ID.
        if (D) {
            Log.d(TAG, "setNotificationRegistration() enter");
        }
        if (mMnsClient == null) {
            return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
        }
        Handler mns = mMnsClient.getMessageHandler();
        if (mns != null) {
            Message msg = mns.obtainMessage();
            if (mMnsClient.isValidMnsRecord()) {
                msg.what = BluetoothMnsObexClient.MSG_MNS_NOTIFICATION_REGISTRATION;
            } else {
                //Trigger SDP Search and notificaiton registration , if SDP record not found.
                msg.what = BluetoothMnsObexClient.MSG_MNS_SDP_SEARCH_REGISTRATION;
                if (mMnsClient.mMnsLstRegRqst != null
                        && (mMnsClient.mMnsLstRegRqst.isSearchInProgress())) {
                    /*  1. Disallow next Notification ON Request :
                     *     - Respond "Service Unavailable" as SDP Search and last notification
                     *       registration ON request is already InProgress.
                     *     - Next notification ON Request will be allowed ONLY after search
                     *       and connect for last saved request [Replied with OK ] is processed.
                     */
                    if (notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_YES) {
                        return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
                    } else {
                        /*  2. Allow next Notification OFF Request:
                         *    - Keep the SDP search still in progress.
                         *    - Disconnect and Deregister the contentObserver.
                         */
                        msg.what = BluetoothMnsObexClient.MSG_MNS_NOTIFICATION_REGISTRATION;
                    }
                }
            }
            msg.arg1 = mMasId;
            msg.arg2 = notificationStatus;
            mns.sendMessageDelayed(msg, 10); // Send message without forcing a context switch
            /* Some devices - e.g. PTS needs to get the unregister confirm before we actually
             * disconnect the MNS. */
            if (D) {
                Log.d(TAG, "setNotificationRegistration() send : " + msg.what + " to MNS ");
            }
            return ResponseCodes.OBEX_HTTP_OK;
        } else {
            // This should not happen except at shutdown.
            if (D) {
                Log.d(TAG, "setNotificationRegistration() Unable to send registration request");
            }
            return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
        }
    }

    boolean eventMaskContainsContacts(long mask) {
        return sendEventParticipantPresenceChanged(mask);
    }

    boolean eventMaskContainsCovo(long mask) {
        return (sendEventConversationChanged(mask) || sendEventParticipantChatstateChanged(mask));
    }

    /* Overwrite the existing notification filter. Will register/deregister observers for
     * the Contacts and Conversation table as needed. We keep the message observer
     * at all times. */
    /*package*/
    synchronized void setNotificationFilter(long newFilter) {
        long oldFilter = mEventFilter;
        mEventFilter = newFilter;
        /* Contacts */
        if (!eventMaskContainsContacts(oldFilter) && eventMaskContainsContacts(newFilter)) {
            // TODO:
            // Enable the observer
            // Reset the contacts list
        }
        /* Conversations */
        if (!eventMaskContainsCovo(oldFilter) && eventMaskContainsCovo(newFilter)) {
            // TODO:
            // Enable the observer
            // Reset the conversations list
        }
    }

    public void registerObserver() throws RemoteException {
        if (V) {
            Log.d(TAG, "registerObserver");
        }

        if (mObserverRegistered) {
            return;
        }

        if (mAccount != null) {

            mProviderClient = mResolver.acquireUnstableContentProviderClient(mAuthority);
            if (mProviderClient == null) {
                throw new RemoteException("Failed to acquire provider for " + mAuthority);
            }
            mProviderClient.setDetectNotResponding(PROVIDER_ANR_TIMEOUT);

            // If there is a change in the database before we init the lists we will be sending
            // loads of events - hence init before register.
            if (mAccount.getType() == TYPE.IM) {
                // Further add contact list tracking
                initContactsList();
            }
        }
        // If there is a change in the database before we init the lists we will be sending
        // loads of events - hence init before register.
        initMsgList();

        /* Use MmsSms Uri since the Sms Uri is not notified on deletes */
        if (mEnableSmsMms) {
            //this is sms/mms
            mResolver.registerContentObserver(MmsSms.CONTENT_URI, false, mObserver);
            mObserverRegistered = true;
        }

        if (mAccount != null) {
            /* For URI's without account ID */
            Uri uri = Uri.parse(
                    mAccount.mBase_uri_no_account + "/" + BluetoothMapContract.TABLE_MESSAGE);
            if (D) {
                Log.d(TAG, "Registering observer for: " + uri);
            }
            mResolver.registerContentObserver(uri, true, mObserver);

            /* For URI's with account ID - is handled the same way as without ID, but is
             * only triggered for MAS instances with matching account ID. */
            uri = Uri.parse(mAccount.mBase_uri + "/" + BluetoothMapContract.TABLE_MESSAGE);
            if (D) {
                Log.d(TAG, "Registering observer for: " + uri);
            }
            mResolver.registerContentObserver(uri, true, mObserver);

            if (mAccount.getType() == TYPE.IM) {

                uri = Uri.parse(mAccount.mBase_uri_no_account + "/"
                        + BluetoothMapContract.TABLE_CONVOCONTACT);
                if (D) {
                    Log.d(TAG, "Registering observer for: " + uri);
                }
                mResolver.registerContentObserver(uri, true, mObserver);

                /* For URI's with account ID - is handled the same way as without ID, but is
                 * only triggered for MAS instances with matching account ID. */
                uri = Uri.parse(mAccount.mBase_uri + "/" + BluetoothMapContract.TABLE_CONVOCONTACT);
                if (D) {
                    Log.d(TAG, "Registering observer for: " + uri);
                }
                mResolver.registerContentObserver(uri, true, mObserver);
            }

            mObserverRegistered = true;
        }
    }

    public void unregisterObserver() {
        if (V) {
            Log.d(TAG, "unregisterObserver");
        }
        mResolver.unregisterContentObserver(mObserver);
        mObserverRegistered = false;
        if (mProviderClient != null) {
            mProviderClient.close();
            mProviderClient = null;
        }
    }

    /**
     * Per design it is only possible to call the refreshXxxx functions sequentially, hence it
     * is safe to modify mTransmitEvents without synchronization.
     */
    /* package */ void refreshFolderVersionCounter() {
        if (mObserverRegistered) {
            // As we have observers, we already keep the counter up-to-date.
            return;
        }
        /* We need to perform the same functionality, as when we receive a notification change,
           hence we:
            - disable the event transmission
            - triggers the code for updates
            - enable the event transmission */
        mTransmitEvents = false;
        try {
            if (mEnableSmsMms) {
                handleMsgListChangesSms();
                handleMsgListChangesMms();
            }
            if (mAccount != null) {
                try {
                    handleMsgListChangesMsg(mMessageUri);
                } catch (RemoteException e) {
                    Log.e(TAG, "Unable to update FolderVersionCounter. - Not fatal, but can cause"
                            + " undesirable user experience!", e);
                }
            }
        } finally {
            // Ensure we always enable events again
            mTransmitEvents = true;
        }
    }

    /* package */ void refreshConvoListVersionCounter() {
        if (mObserverRegistered) {
            // As we have observers, we already keep the counter up-to-date.
            return;
        }
        /* We need to perform the same functionality, as when we receive a notification change,
        hence we:
         - disable event transmission
         - triggers the code for updates
         - enable event transmission */
        mTransmitEvents = false;
        try {
            if ((mAccount != null) && (mContactUri != null)) {
                handleContactListChanges(mContactUri);
            }
        } finally {
            // Ensure we always enable events again
            mTransmitEvents = true;
        }
    }

    private void sendEvent(Event evt) {

        if (!mTransmitEvents) {
            if (V) {
                Log.v(TAG, "mTransmitEvents == false - don't send event.");
            }
            return;
        }

        if (D) {
            Log.d(TAG, "sendEvent: " + evt.eventType + " " + evt.handle + " " + evt.folder + " "
                    + evt.oldFolder + " " + evt.msgType.name() + " " + evt.datetime + " "
                    + evt.subject + " " + evt.senderName + " " + evt.priority);
        }

        if (mMnsClient == null || !mMnsClient.isConnected()) {
            Log.d(TAG, "sendEvent: No MNS client registered or connected- don't send event");
            return;
        }

        /* Enable use of the cache for checking the filter */
        long eventFilter = mEventFilter;

        /* This should have been a switch on the string, but it is not allowed in Java 1.6 */
        /* WARNING: Here we do pointer compare for the string to speed up things, that is.
         * HENCE: always use the EVENT_TYPE_"defines" */
        if (Objects.equals(evt.eventType, EVENT_TYPE_NEW)) {
            if (!sendEventNewMessage(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_DELETE)) {
            if (!sendEventMessageDeleted(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_REMOVED)) {
            if (!sendEventMessageRemoved(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_SHIFT)) {
            if (!sendEventMessageShift(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_DELEVERY_SUCCESS)) {
            if (!sendEventDeliverySuccess(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_SENDING_SUCCESS)) {
            if (!sendEventSendingSuccess(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_SENDING_FAILURE)) {
            if (!sendEventSendingFailed(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_DELIVERY_FAILURE)) {
            if (!sendEventDeliveryFailed(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_READ_STATUS)) {
            if (!sendEventReadStatusChanged(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_CONVERSATION)) {
            if (!sendEventConversationChanged(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_PRESENCE)) {
            if (!sendEventParticipantPresenceChanged(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        } else if (Objects.equals(evt.eventType, EVENT_TYPE_CHAT_STATE)) {
            if (!sendEventParticipantChatstateChanged(eventFilter)) {
                if (D) {
                    Log.d(TAG, "Skip sending event of type: " + evt.eventType);
                }
                return;
            }
        }

        try {
            mMnsClient.sendEvent(evt.encode(), mMasId);
        } catch (UnsupportedEncodingException ex) {
            /* do nothing */
            if (D) {
                Log.e(TAG, "Exception - should not happen: ", ex);
            }
        }
    }

    private void initMsgList() throws RemoteException {
        if (V) {
            Log.d(TAG, "initMsgList");
        }
        UserManager manager = UserManager.get(mContext);
        if (manager == null || !manager.isUserUnlocked()) {
            return;
        }

        if (mEnableSmsMms) {
            HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>();

            Cursor c;
            try {
                c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION_SHORT, null, null, null);
            } catch (SQLiteException e) {
                Log.e(TAG, "Failed to initialize the list of messages: " + e.toString());
                return;
            }

            try {
                if (c != null && c.moveToFirst()) {
                    do {
                        long id = c.getLong(c.getColumnIndex(Sms._ID));
                        int type = c.getInt(c.getColumnIndex(Sms.TYPE));
                        int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
                        int read = c.getInt(c.getColumnIndex(Sms.READ));

                        Msg msg = new Msg(id, type, threadId, read);
                        msgListSms.put(id, msg);
                    } while (c.moveToNext());
                }
            } finally {
                if (c != null) {
                    c.close();
                }
            }

            synchronized (getMsgListSms()) {
                getMsgListSms().clear();
                setMsgListSms(msgListSms, true); // Set initial folder version counter
            }

            HashMap<Long, Msg> msgListMms = new HashMap<Long, Msg>();

            c = mResolver.query(Mms.CONTENT_URI, MMS_PROJECTION_SHORT, null, null, null);
            try {
                if (c != null && c.moveToFirst()) {
                    do {
                        long id = c.getLong(c.getColumnIndex(Mms._ID));
                        int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
                        int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
                        int read = c.getInt(c.getColumnIndex(Mms.READ));

                        Msg msg = new Msg(id, type, threadId, read);
                        msgListMms.put(id, msg);
                    } while (c.moveToNext());
                }
            } finally {
                if (c != null) {
                    c.close();
                }
            }

            synchronized (getMsgListMms()) {
                getMsgListMms().clear();
                setMsgListMms(msgListMms, true); // Set initial folder version counter
            }
        }

        if (mAccount != null) {
            HashMap<Long, Msg> msgList = new HashMap<Long, Msg>();
            Uri uri = mMessageUri;
            Cursor c = mProviderClient.query(uri, MSG_PROJECTION_SHORT, null, null, null);

            try {
                if (c != null && c.moveToFirst()) {
                    do {
                        long id = c.getLong(c.getColumnIndex(MessageColumns._ID));
                        long folderId = c.getInt(
                                c.getColumnIndex(BluetoothMapContract.MessageColumns.FOLDER_ID));
                        int readFlag = c.getInt(
                                c.getColumnIndex(BluetoothMapContract.MessageColumns.FLAG_READ));
                        Msg msg = new Msg(id, folderId, readFlag);
                        msgList.put(id, msg);
                    } while (c.moveToNext());
                }
            } finally {
                if (c != null) {
                    c.close();
                }
            }

            synchronized (getMsgListMsg()) {
                getMsgListMsg().clear();
                setMsgListMsg(msgList, true);
            }
        }
    }

    private void initContactsList() throws RemoteException {
        if (V) {
            Log.d(TAG, "initContactsList");
        }
        if (mContactUri == null) {
            if (D) {
                Log.d(TAG, "initContactsList() no mContactUri - nothing to init");
            }
            return;
        }
        Uri uri = mContactUri;
        Cursor c = mProviderClient.query(uri,
                BluetoothMapContract.BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION, null, null, null);
        Map<String, BluetoothMapConvoContactElement> contactList =
                new HashMap<String, BluetoothMapConvoContactElement>();
        try {
            if (c != null && c.moveToFirst()) {
                ConvoContactInfo cInfo = new ConvoContactInfo();
                cInfo.setConvoColunms(c);
                do {
                    long convoId = c.getLong(cInfo.mContactColConvoId);
                    if (convoId == 0) {
                        continue;
                    }
                    if (V) {
                        BluetoothMapUtils.printCursor(c);
                    }
                    String uci = c.getString(cInfo.mContactColUci);
                    String name = c.getString(cInfo.mContactColName);
                    String displayName = c.getString(cInfo.mContactColNickname);
                    String presenceStatus = c.getString(cInfo.mContactColPresenceText);
                    int presenceState = c.getInt(cInfo.mContactColPresenceState);
                    long lastActivity = c.getLong(cInfo.mContactColLastActive);
                    int chatState = c.getInt(cInfo.mContactColChatState);
                    int priority = c.getInt(cInfo.mContactColPriority);
                    String btUid = c.getString(cInfo.mContactColBtUid);
                    BluetoothMapConvoContactElement contact =
                            new BluetoothMapConvoContactElement(uci, name, displayName,
                                    presenceStatus, presenceState, lastActivity, chatState,
                                    priority, btUid);
                    contactList.put(uci, contact);
                } while (c.moveToNext());
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }
        synchronized (getContactList()) {
            getContactList().clear();
            setContactList(contactList, true);
        }
    }

    private void handleMsgListChangesSms() {
        if (V) {
            Log.d(TAG, "handleMsgListChangesSms");
        }

        HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>();
        boolean listChanged = false;

        Cursor c;
        synchronized (getMsgListSms()) {
            if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V10) {
                c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION_SHORT, null, null, null);
            } else {
                c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION_SHORT_EXT, null, null, null);
            }
            try {
                if (c != null && c.moveToFirst()) {
                    do {
                        int idIndex = c.getColumnIndexOrThrow(Sms._ID);
                        if (c.isNull(idIndex)) {
                            throw new IllegalStateException("ID is null");
                        }
                        long id = c.getLong(idIndex);
                        int type = c.getInt(c.getColumnIndex(Sms.TYPE));
                        int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
                        int read = c.getInt(c.getColumnIndex(Sms.READ));

                        Msg msg = getMsgListSms().remove(id);

                        /* We must filter out any actions made by the MCE, hence do not send e.g.
                         * a message deleted and/or MessageShift for messages deleted by the MCE. */

                        if (msg == null) {
                            /* New message */
                            msg = new Msg(id, type, threadId, read);
                            msgListSms.put(id, msg);
                            listChanged = true;
                            Event evt;
                            if (mTransmitEvents && // extract contact details only if needed
                                    mMapEventReportVersion
                                            > BluetoothMapUtils.MAP_EVENT_REPORT_V10) {
                                String date = BluetoothMapUtils.getDateTimeString(
                                        c.getLong(c.getColumnIndex(Sms.DATE)));
                                String subject = c.getString(c.getColumnIndex(Sms.BODY));
                                if (subject == null) {
                                    subject = "";
                                }
                                String name = "";
                                String phone = "";
                                if (type == 1) { //inbox
                                    phone = c.getString(c.getColumnIndex(Sms.ADDRESS));
                                    if (phone != null && !phone.isEmpty()) {
                                        name = BluetoothMapContent.getContactNameFromPhone(phone,
                                                mResolver);
                                        if (name == null || name.isEmpty()) {
                                            name = phone;
                                        }
                                    } else {
                                        name = phone;
                                    }
                                } else {
                                    TelephonyManager tm =
                                            (TelephonyManager) mContext.getSystemService(
                                                    Context.TELEPHONY_SERVICE);
                                    if (tm != null) {
                                        phone = tm.getLine1Number();
                                        name = phone;
                                    }
                                }
                                String priority = "no"; // no priority for sms
                                /* Incoming message from the network */
                                if (mMapEventReportVersion
                                        == BluetoothMapUtils.MAP_EVENT_REPORT_V11) {
                                    evt = new Event(EVENT_TYPE_NEW, id, getSmsFolderName(type),
                                            mSmsType, date, subject, name, priority);
                                } else {
                                    evt = new Event(EVENT_TYPE_NEW, id, getSmsFolderName(type),
                                            mSmsType, date, subject, name, priority,
                                            (long) threadId, null);
                                }
                            } else {
                                /* Incoming message from the network */
                                evt = new Event(EVENT_TYPE_NEW, id, getSmsFolderName(type), null,
                                        mSmsType);
                            }
                            sendEvent(evt);
                        } else {
                            /* Existing message */
                            if (type != msg.type) {
                                listChanged = true;
                                Log.d(TAG, "new type: " + type + " old type: " + msg.type);
                                String oldFolder = getSmsFolderName(msg.type);
                                String newFolder = getSmsFolderName(type);
                                // Filter out the intermediate outbox steps
                                if (!oldFolder.equalsIgnoreCase(newFolder)) {
                                    Event evt =
                                            new Event(EVENT_TYPE_SHIFT, id, getSmsFolderName(type),
                                                    oldFolder, mSmsType);
                                    sendEvent(evt);
                                }
                                msg.type = type;
                            } else if (threadId != msg.threadId) {
                                listChanged = true;
                                Log.d(TAG, "Message delete change: type: " + type + " old type: "
                                        + msg.type + "\n    threadId: " + threadId
                                        + " old threadId: " + msg.threadId);
                                if (threadId == DELETED_THREAD_ID) { // Message deleted
                                    // TODO:
                                    // We shall only use the folder attribute, but can't remember
                                    // wether to set it to "deleted" or the name of the folder
                                    // from which the message have been deleted.
                                    // "old_folder" used only for MessageShift event
                                    Event evt = new Event(EVENT_TYPE_DELETE, id,
                                            getSmsFolderName(msg.type), null, mSmsType);
                                    sendEvent(evt);
                                    msg.threadId = threadId;
                                } else { // Undelete
                                    Event evt = new Event(EVENT_TYPE_SHIFT, id,
                                            getSmsFolderName(msg.type),
                                            BluetoothMapContract.FOLDER_NAME_DELETED, mSmsType);
                                    sendEvent(evt);
                                    msg.threadId = threadId;
                                }
                            }
                            if (read != msg.flagRead) {
                                listChanged = true;
                                msg.flagRead = read;
                                if (mMapEventReportVersion
                                        > BluetoothMapUtils.MAP_EVENT_REPORT_V10) {
                                    Event evt = new Event(EVENT_TYPE_READ_STATUS, id,
                                            getSmsFolderName(msg.type), mSmsType);
                                    sendEvent(evt);
                                }
                            }
                            msgListSms.put(id, msg);
                        }
                    } while (c.moveToNext());
                }
            } finally {
                if (c != null) {
                    c.close();
                }
            }
            String eventType = EVENT_TYPE_DELETE;
            for (Msg msg : getMsgListSms().values()) {
                // "old_folder" used only for MessageShift event
                if (mMapEventReportVersion >= BluetoothMapUtils.MAP_EVENT_REPORT_V12) {
                    eventType = EVENT_TYPE_REMOVED;
                    if (V) Log.v(TAG," sent EVENT_TYPE_REMOVED");
                }
                Event evt = new Event(eventType, msg.id, getSmsFolderName(msg.type), null,
                        mSmsType);
                sendEvent(evt);
                listChanged = true;
            }

            setMsgListSms(msgListSms, listChanged);
        }
    }

    private void handleMsgListChangesMms() {
        if (V) {
            Log.d(TAG, "handleMsgListChangesMms");
        }

        HashMap<Long, Msg> msgListMms = new HashMap<Long, Msg>();
        boolean listChanged = false;
        Cursor c;
        synchronized (getMsgListMms()) {
            if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V10) {
                c = mResolver.query(Mms.CONTENT_URI, MMS_PROJECTION_SHORT, null, null, null);
            } else {
                c = mResolver.query(Mms.CONTENT_URI, MMS_PROJECTION_SHORT_EXT, null, null, null);
            }

            try {
                if (c != null && c.moveToFirst()) {
                    do {
                        int idIndex = c.getColumnIndexOrThrow(Mms._ID);
                        if (c.isNull(idIndex)) {
                            throw new IllegalStateException("ID is null");
                        }
                        long id = c.getLong(idIndex);
                        int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
                        int mtype = c.getInt(c.getColumnIndex(Mms.MESSAGE_TYPE));
                        int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
                        // TODO: Go through code to see if we have an issue with mismatch in types
                        //       for threadId. Seems to be a long in DB??
                        int read = c.getInt(c.getColumnIndex(Mms.READ));

                        Msg msg = getMsgListMms().remove(id);

                        /* We must filter out any actions made by the MCE, hence do not send
                         * e.g. a message deleted and/or MessageShift for messages deleted by the
                         * MCE.*/

                        if (msg == null) {
                            /* New message - only notify on retrieve conf */
                            listChanged = true;
                            if (getMmsFolderName(type).equalsIgnoreCase(
                                    BluetoothMapContract.FOLDER_NAME_INBOX)
                                    && mtype != MESSAGE_TYPE_RETRIEVE_CONF) {
                                continue;
                            }
                            msg = new Msg(id, type, threadId, read);
                            msgListMms.put(id, msg);
                            Event evt;
                            if (mTransmitEvents && // extract contact details only if needed
                                    mMapEventReportVersion
                                            != BluetoothMapUtils.MAP_EVENT_REPORT_V10) {
                                String date = BluetoothMapUtils.getDateTimeString(
                                        c.getLong(c.getColumnIndex(Mms.DATE)));
                                String subject = c.getString(c.getColumnIndex(Mms.SUBJECT));
                                if (subject == null || subject.length() == 0) {
                                    /* Get subject from mms text body parts - if any exists */
                                    subject = BluetoothMapContent.getTextPartsMms(mResolver, id);
                                    if (subject == null) {
                                        subject = "";
                                    }
                                }
                                int tmpPri = c.getInt(c.getColumnIndex(Mms.PRIORITY));
                                Log.d(TAG, "TEMP handleMsgListChangesMms, "
                                        + "newMessage 'read' state: " + read + "priority: "
                                        + tmpPri);

                                String address = BluetoothMapContent.getAddressMms(mResolver, id,
                                        BluetoothMapContent.MMS_FROM);
                                if (address == null) {
                                    address = "";
                                }

                                String priority = "no";
                                if (tmpPri == PduHeaders.PRIORITY_HIGH) {
                                    priority = "yes";
                                }

                                /* Incoming message from the network */
                                if (mMapEventReportVersion
                                        == BluetoothMapUtils.MAP_EVENT_REPORT_V11) {
                                    evt = new Event(EVENT_TYPE_NEW, id, getMmsFolderName(type),
                                            TYPE.MMS, date, subject, address, priority);
                                } else {
                                    evt = new Event(EVENT_TYPE_NEW, id, getMmsFolderName(type),
                                            TYPE.MMS, date, subject, address, priority,
                                            (long) threadId, null);
                                }

                            } else {
                                /* Incoming message from the network */
                                evt = new Event(EVENT_TYPE_NEW, id, getMmsFolderName(type), null,
                                        TYPE.MMS);
                            }

                            sendEvent(evt);
                        } else {
                            /* Existing message */
                            if (type != msg.type) {
                                Log.d(TAG, "new type: " + type + " old type: " + msg.type);
                                Event evt;
                                listChanged = true;
                                if (!msg.localInitiatedSend) {
                                    // Only send events about local initiated changes
                                    evt = new Event(EVENT_TYPE_SHIFT, id, getMmsFolderName(type),
                                            getMmsFolderName(msg.type), TYPE.MMS);
                                    sendEvent(evt);
                                }
                                msg.type = type;

                                if (getMmsFolderName(type).equalsIgnoreCase(
                                        BluetoothMapContract.FOLDER_NAME_SENT)
                                        && msg.localInitiatedSend) {
                                    // Stop tracking changes for this message
                                    msg.localInitiatedSend = false;
                                    evt = new Event(EVENT_TYPE_SENDING_SUCCESS, id,
                                            getMmsFolderName(type), null, TYPE.MMS);
                                    sendEvent(evt);
                                }
                            } else if (threadId != msg.threadId) {
                                Log.d(TAG, "Message delete change: type: " + type + " old type: "
                                        + msg.type + "\n    threadId: " + threadId
                                        + " old threadId: " + msg.threadId);
                                listChanged = true;
                                if (threadId == DELETED_THREAD_ID) { // Message deleted
                                    // "old_folder" used only for MessageShift event
                                    Event evt = new Event(EVENT_TYPE_DELETE, id,
                                            getMmsFolderName(msg.type), null, TYPE.MMS);
                                    sendEvent(evt);
                                    msg.threadId = threadId;
                                } else { // Undelete
                                    Event evt = new Event(EVENT_TYPE_SHIFT, id,
                                            getMmsFolderName(msg.type),
                                            BluetoothMapContract.FOLDER_NAME_DELETED, TYPE.MMS);
                                    sendEvent(evt);
                                    msg.threadId = threadId;
                                }
                            }
                            if (read != msg.flagRead) {
                                listChanged = true;
                                msg.flagRead = read;
                                if (mMapEventReportVersion
                                        > BluetoothMapUtils.MAP_EVENT_REPORT_V10) {
                                    Event evt = new Event(EVENT_TYPE_READ_STATUS, id,
                                            getMmsFolderName(msg.type), TYPE.MMS);
                                    sendEvent(evt);
                                }
                            }
                            msgListMms.put(id, msg);
                        }
                    } while (c.moveToNext());

                }
            } finally {
                if (c != null) {
                    c.close();
                }
            }
            for (Msg msg : getMsgListMms().values()) {
                // "old_folder" used only for MessageShift event
                Event evt = new Event(EVENT_TYPE_DELETE, msg.id, getMmsFolderName(msg.type), null,
                        TYPE.MMS);
                sendEvent(evt);
                listChanged = true;
            }
            setMsgListMms(msgListMms, listChanged);
        }
    }

    private void handleMsgListChangesMsg(Uri uri) throws RemoteException {
        if (V) {
            Log.v(TAG, "handleMsgListChangesMsg uri: " + uri.toString());
        }

        // TODO: Change observer to handle accountId and message ID if present

        HashMap<Long, Msg> msgList = new HashMap<Long, Msg>();
        Cursor c;
        boolean listChanged = false;
        if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V10) {
            c = mProviderClient.query(mMessageUri, MSG_PROJECTION_SHORT, null, null, null);
        } else if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V11) {
            c = mProviderClient.query(mMessageUri, MSG_PROJECTION_SHORT_EXT, null, null, null);
        } else {
            c = mProviderClient.query(mMessageUri, MSG_PROJECTION_SHORT_EXT2, null, null, null);
        }
        synchronized (getMsgListMsg()) {
            try {
                if (c != null && c.moveToFirst()) {
                    do {
                        long id = c.getLong(
                                c.getColumnIndex(BluetoothMapContract.MessageColumns._ID));
                        int folderId = c.getInt(
                                c.getColumnIndex(BluetoothMapContract.MessageColumns.FOLDER_ID));
                        int readFlag = c.getInt(
                                c.getColumnIndex(BluetoothMapContract.MessageColumns.FLAG_READ));
                        Msg msg = getMsgListMsg().remove(id);
                        BluetoothMapFolderElement folderElement = mFolders.getFolderById(folderId);
                        String newFolder;
                        if (folderElement != null) {
                            newFolder = folderElement.getFullPath();
                        } else {
                            // This can happen if a new folder is created while connected
                            newFolder = "unknown";
                        }
                        /* We must filter out any actions made by the MCE, hence do not send e.g.
                         * a message deleted and/or MessageShift for messages deleted by the MCE. */
                        if (msg == null) {
                            listChanged = true;
                            /* New message - created with message unread */
                            msg = new Msg(id, folderId, 0, readFlag);
                            msgList.put(id, msg);
                            Event evt;
                            /* Incoming message from the network */
                            if (mMapEventReportVersion != BluetoothMapUtils.MAP_EVENT_REPORT_V10) {
                                String date = BluetoothMapUtils.getDateTimeString(c.getLong(
                                        c.getColumnIndex(
                                                BluetoothMapContract.MessageColumns.DATE)));
                                String subject = c.getString(c.getColumnIndex(
                                        BluetoothMapContract.MessageColumns.SUBJECT));
                                String address = c.getString(c.getColumnIndex(
                                        BluetoothMapContract.MessageColumns.FROM_LIST));
                                String priority = "no";
                                if (c.getInt(c.getColumnIndex(
                                        BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY))
                                        == 1) {
                                    priority = "yes";
                                }
                                if (mMapEventReportVersion
                                        == BluetoothMapUtils.MAP_EVENT_REPORT_V11) {
                                    evt = new Event(EVENT_TYPE_NEW, id, newFolder,
                                            mAccount.getType(), date, subject, address, priority);
                                } else {
                                    long threadId = c.getLong(c.getColumnIndex(
                                            BluetoothMapContract.MessageColumns.THREAD_ID));
                                    String threadName = c.getString(c.getColumnIndex(
                                            BluetoothMapContract.MessageColumns.THREAD_NAME));
                                    evt = new Event(EVENT_TYPE_NEW, id, newFolder,
                                            mAccount.getType(), date, subject, address, priority,
                                            threadId, threadName);
                                }
                            } else {
                                evt = new Event(EVENT_TYPE_NEW, id, newFolder, null, TYPE.EMAIL);
                            }
                            sendEvent(evt);
                        } else {
                            /* Existing message */
                            if (folderId != msg.folderId && msg.folderId != -1) {
                                if (D) {
                                    Log.d(TAG, "new folderId: " + folderId + " old folderId: "
                                            + msg.folderId);
                                }
                                BluetoothMapFolderElement oldFolderElement =
                                        mFolders.getFolderById(msg.folderId);
                                String oldFolder;
                                listChanged = true;
                                if (oldFolderElement != null) {
                                    oldFolder = oldFolderElement.getFullPath();
                                } else {
                                    // This can happen if a new folder is created while connected
                                    oldFolder = "unknown";
                                }
                                BluetoothMapFolderElement deletedFolder = mFolders.getFolderByName(
                                        BluetoothMapContract.FOLDER_NAME_DELETED);
                                BluetoothMapFolderElement sentFolder = mFolders.getFolderByName(
                                        BluetoothMapContract.FOLDER_NAME_SENT);
                                /*
                                 *  If the folder is now 'deleted', send a deleted-event in stead of
                                 *  a shift or if message is sent initiated by MAP Client, then send
                                 *  sending-success otherwise send folderShift
                                 */
                                if (deletedFolder != null
                                        && deletedFolder.getFolderId() == folderId) {
                                    // "old_folder" used only for MessageShift event
                                    Event evt =
                                            new Event(EVENT_TYPE_DELETE, msg.id, oldFolder, null,
                                                    mAccount.getType());
                                    sendEvent(evt);
                                } else if (sentFolder != null
                                        && sentFolder.getFolderId() == folderId
                                        && msg.localInitiatedSend) {
                                    if (msg.transparent) {
                                        mResolver.delete(
                                                ContentUris.withAppendedId(mMessageUri, id), null,
                                                null);
                                    } else {
                                        msg.localInitiatedSend = false;
                                        Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, msg.id,
                                                oldFolder, null, mAccount.getType());
                                        sendEvent(evt);
                                    }
                                } else {
                                    if (!oldFolder.equalsIgnoreCase("root")) {
                                        Event evt = new Event(EVENT_TYPE_SHIFT, id, newFolder,
                                                oldFolder, mAccount.getType());
                                        sendEvent(evt);
                                    }
                                }
                                msg.folderId = folderId;
                            }
                            if (readFlag != msg.flagRead) {
                                listChanged = true;

                                if (mMapEventReportVersion
                                        > BluetoothMapUtils.MAP_EVENT_REPORT_V10) {
                                    Event evt = new Event(EVENT_TYPE_READ_STATUS, id, newFolder,
                                            mAccount.getType());
                                    sendEvent(evt);
                                    msg.flagRead = readFlag;
                                }
                            }

                            msgList.put(id, msg);
                        }
                    } while (c.moveToNext());
                }
            } finally {
                if (c != null) {
                    c.close();
                }
            }
            // For all messages no longer in the database send a delete notification
            for (Msg msg : getMsgListMsg().values()) {
                BluetoothMapFolderElement oldFolderElement = mFolders.getFolderById(msg.folderId);
                String oldFolder;
                listChanged = true;
                if (oldFolderElement != null) {
                    oldFolder = oldFolderElement.getFullPath();
                } else {
                    oldFolder = "unknown";
                }
                /* Some e-mail clients delete the message after sending, and creates a
                 * new message in sent. We cannot track the message anymore, hence send both a
                 * send success and delete message.
                 */
                if (msg.localInitiatedSend) {
                    msg.localInitiatedSend = false;
                    // If message is send with transparency don't set folder as message is deleted
                    if (msg.transparent) {
                        oldFolder = null;
                    }
                    Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, msg.id, oldFolder, null,
                            mAccount.getType());
                    sendEvent(evt);
                }
                /* As this message deleted is only send on a real delete - don't set folder.
                 *  - only send delete event if message is not sent with transparency
                 */
                if (!msg.transparent) {

                    // "old_folder" used only for MessageShift event
                    Event evt = new Event(EVENT_TYPE_DELETE, msg.id, oldFolder, null,
                            mAccount.getType());
                    sendEvent(evt);
                }
            }
            setMsgListMsg(msgList, listChanged);
        }
    }

    private void handleMsgListChanges(Uri uri) {
        if (uri.getAuthority().equals(mAuthority)) {
            try {
                if (D) {
                    Log.d(TAG, "handleMsgListChanges: account type = " + mAccount.getType()
                            .toString());
                }
                handleMsgListChangesMsg(uri);
            } catch (RemoteException e) {
                mMasInstance.restartObexServerSession();
                Log.w(TAG, "Problems contacting the ContentProvider in mas Instance " + mMasId
                        + " restaring ObexServerSession");
            }

        }
        // TODO: check to see if there could be problem with IM and SMS in one instance
        if (mEnableSmsMms) {
            handleMsgListChangesSms();
            handleMsgListChangesMms();
        }
    }

    private void handleContactListChanges(Uri uri) {
        if (uri.getAuthority().equals(mAuthority)) {
            try {
                if (V) {
                    Log.v(TAG, "handleContactListChanges uri: " + uri.toString());
                }
                Cursor c = null;
                boolean listChanged = false;
                try {
                    ConvoContactInfo cInfo = new ConvoContactInfo();

                    if (mMapEventReportVersion != BluetoothMapUtils.MAP_EVENT_REPORT_V10
                            && mMapEventReportVersion != BluetoothMapUtils.MAP_EVENT_REPORT_V11) {
                        c = mProviderClient.query(mContactUri,
                                BluetoothMapContract.BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION,
                                null, null, null);
                        cInfo.setConvoColunms(c);
                    } else {
                        if (V) {
                            Log.v(TAG, "handleContactListChanges MAP version does not"
                                    + "support convocontact notifications");
                        }
                        return;
                    }

                    HashMap<String, BluetoothMapConvoContactElement> contactList =
                            new HashMap<String, BluetoothMapConvoContactElement>(
                                    getContactList().size());

                    synchronized (getContactList()) {
                        if (c != null && c.moveToFirst()) {
                            do {
                                String uci = c.getString(cInfo.mContactColUci);
                                long convoId = c.getLong(cInfo.mContactColConvoId);
                                if (convoId == 0) {
                                    continue;
                                }

                                if (V) {
                                    BluetoothMapUtils.printCursor(c);
                                }

                                BluetoothMapConvoContactElement contact =
                                        getContactList().remove(uci);

                                /*
                                 * We must filter out any actions made by the
                                 * MCE, hence do not send e.g. a message deleted
                                 * and/or MessageShift for messages deleted by
                                 * the MCE.
                                 */
                                if (contact == null) {
                                    listChanged = true;
                                    /*
                                     * New contact - added to conversation and
                                     * tracked here
                                     */
                                    if (mMapEventReportVersion
                                            != BluetoothMapUtils.MAP_EVENT_REPORT_V10
                                            && mMapEventReportVersion
                                            != BluetoothMapUtils.MAP_EVENT_REPORT_V11) {
                                        Event evt;
                                        String name = c.getString(cInfo.mContactColName);
                                        String displayName = c.getString(cInfo.mContactColNickname);
                                        String presenceStatus =
                                                c.getString(cInfo.mContactColPresenceText);
                                        int presenceState =
                                                c.getInt(cInfo.mContactColPresenceState);
                                        long lastActivity = c.getLong(cInfo.mContactColLastActive);
                                        int chatState = c.getInt(cInfo.mContactColChatState);
                                        int priority = c.getInt(cInfo.mContactColPriority);
                                        String btUid = c.getString(cInfo.mContactColBtUid);

                                        // Get Conversation information for
                                        // event
//                                        Uri convoUri = Uri
//                                                .parse(mAccount.mBase_uri
//                                                        + "/"
//                                                        + BluetoothMapContract
// .TABLE_CONVERSATION);
//                                        String whereClause = "contacts._id = "
//                                                + convoId;
//                                        Cursor cConvo = mProviderClient
//                                                .query(convoUri,
//                                                       BluetoothMapContract
// .BT_CONVERSATION_PROJECTION,
//                                                       whereClause, null, null);
                                        // TODO: will move out of the loop when merged with CB's
                                        // changes make sure to look up col index out side loop
                                        String convoName = null;
//                                        if (cConvo != null
//                                                && cConvo.moveToFirst()) {
//                                            convoName = cConvo
//                                                    .getString(cConvo
//                                                            .getColumnIndex
// (BluetoothMapContract.ConvoContactColumns.NAME));
//                                        }

                                        contact = new BluetoothMapConvoContactElement(uci, name,
                                                displayName, presenceStatus, presenceState,
                                                lastActivity, chatState, priority, btUid);

                                        contactList.put(uci, contact);

                                        evt = new Event(EVENT_TYPE_CONVERSATION, uci,
                                                mAccount.getType(), name, String.valueOf(priority),
                                                BluetoothMapUtils.getDateTimeString(lastActivity),
                                                convoId, convoName, presenceState, presenceStatus,
                                                chatState);

                                        sendEvent(evt);
                                    }

                                } else {
                                    // Not new - compare updated content
//                                    Uri convoUri = Uri
//                                            .parse(mAccount.mBase_uri
//                                                    + "/"
//                                                    + BluetoothMapContract.TABLE_CONVERSATION);
                                    // TODO: Should be changed to own provider interface name
//                                    String whereClause = "contacts._id = "
//                                            + convoId;
//                                    Cursor cConvo = mProviderClient
//                                            .query(convoUri,
//                                                    BluetoothMapContract
// .BT_CONVERSATION_PROJECTION,
//                                                    whereClause, null, null);
//                                    // TODO: will move out of the loop when merged with CB's
//                                    // changes make sure to look up col index out side loop
                                    String convoName = null;
//                                    if (cConvo != null && cConvo.moveToFirst()) {
//                                        convoName = cConvo
//                                                .getString(cConvo
//                                                        .getColumnIndex(BluetoothMapContract
// .ConvoContactColumns.NAME));
//                                    }

                                    // Check if presence is updated
                                    int presenceState = c.getInt(cInfo.mContactColPresenceState);
                                    String presenceStatus =
                                            c.getString(cInfo.mContactColPresenceText);
                                    String currentPresenceStatus = contact.getPresenceStatus();
                                    if (contact.getPresenceAvailability() != presenceState
                                            || !Objects.equals(currentPresenceStatus,
                                            presenceStatus)) {
                                        long lastOnline = c.getLong(cInfo.mContactColLastOnline);
                                        contact.setPresenceAvailability(presenceState);
                                        contact.setLastActivity(lastOnline);
                                        if (currentPresenceStatus != null
                                                && !currentPresenceStatus.equals(presenceStatus)) {
                                            contact.setPresenceStatus(presenceStatus);
                                        }
                                        Event evt = new Event(EVENT_TYPE_PRESENCE, uci,
                                                mAccount.getType(), contact.getName(),
                                                String.valueOf(contact.getPriority()),
                                                BluetoothMapUtils.getDateTimeString(lastOnline),
                                                convoId, convoName, presenceState, presenceStatus,
                                                0);
                                        sendEvent(evt);
                                    }

                                    // Check if chat state is updated
                                    int chatState = c.getInt(cInfo.mContactColChatState);
                                    if (contact.getChatState() != chatState) {
                                        // Get DB timestamp
                                        long lastActivity = c.getLong(cInfo.mContactColLastActive);
                                        contact.setLastActivity(lastActivity);
                                        contact.setChatState(chatState);
                                        Event evt = new Event(EVENT_TYPE_CHAT_STATE, uci,
                                                mAccount.getType(), contact.getName(),
                                                String.valueOf(contact.getPriority()),
                                                BluetoothMapUtils.getDateTimeString(lastActivity),
                                                convoId, convoName, 0, null, chatState);
                                        sendEvent(evt);
                                    }
                                    contactList.put(uci, contact);
                                }
                            } while (c.moveToNext());
                        }
                        if (getContactList().size() > 0) {
                            // one or more contacts were deleted, hence the conversation listing
                            // version counter should change.
                            listChanged = true;
                        }
                        setContactList(contactList, listChanged);
                    } // end synchronized
                } finally {
                    if (c != null) {
                        c.close();
                    }
                }
            } catch (RemoteException e) {
                mMasInstance.restartObexServerSession();
                Log.w(TAG, "Problems contacting the ContentProvider in mas Instance " + mMasId
                        + " restaring ObexServerSession");
            }

        }
        // TODO: conversation contact updates if IM and SMS(MMS in one instance
    }

    private boolean setEmailMessageStatusDelete(BluetoothMapFolderElement mCurrentFolder,
            String uriStr, long handle, int status) {
        boolean res = false;
        Uri uri = Uri.parse(uriStr + BluetoothMapContract.TABLE_MESSAGE);

        int updateCount = 0;
        ContentValues contentValues = new ContentValues();
        BluetoothMapFolderElement deleteFolder =
                mFolders.getFolderByName(BluetoothMapContract.FOLDER_NAME_DELETED);
        contentValues.put(BluetoothMapContract.MessageColumns._ID, handle);
        synchronized (getMsgListMsg()) {
            Msg msg = getMsgListMsg().get(handle);
            if (status == BluetoothMapAppParams.STATUS_VALUE_YES) {
                /* Set deleted folder id */
                long folderId = -1;
                if (deleteFolder != null) {
                    folderId = deleteFolder.getFolderId();
                }
                contentValues.put(BluetoothMapContract.MessageColumns.FOLDER_ID, folderId);
                updateCount = mResolver.update(uri, contentValues, null, null);
                /* The race between updating the value in our cached values and the database
                 * is handled by the synchronized statement. */
                if (updateCount > 0) {
                    res = true;
                    if (msg != null) {
                        msg.oldFolderId = msg.folderId;
                        /* Update the folder ID to avoid triggering an event for MCE
                         * initiated actions. */
                        msg.folderId = folderId;
                    }
                    if (D) {
                        Log.d(TAG, "Deleted MSG: " + handle + " from folderId: " + folderId);
                    }
                } else {
                    Log.w(TAG, "Msg: " + handle + " - Set delete status " + status
                            + " failed for folderId " + folderId);
                }
            } else if (status == BluetoothMapAppParams.STATUS_VALUE_NO) {
                /* Undelete message. move to old folder if we know it,
                 * else move to inbox - as dictated by the spec. */
                if (msg != null && deleteFolder != null
                        && msg.folderId == deleteFolder.getFolderId()) {
                    /* Only modify messages in the 'Deleted' folder */
                    long folderId = -1;
                    BluetoothMapFolderElement inboxFolder =
                            mCurrentFolder.getFolderByName(BluetoothMapContract.FOLDER_NAME_INBOX);
                    if (msg != null && msg.oldFolderId != -1) {
                        folderId = msg.oldFolderId;
                    } else {
                        if (inboxFolder != null) {
                            folderId = inboxFolder.getFolderId();
                        }
                        if (D) {
                            Log.d(TAG, "We did not delete the message, hence the old folder "
                                    + "is unknown. Moving to inbox.");
                        }
                    }
                    contentValues.put(BluetoothMapContract.MessageColumns.FOLDER_ID, folderId);
                    updateCount = mResolver.update(uri, contentValues, null, null);
                    if (updateCount > 0) {
                        res = true;
                        /* Update the folder ID to avoid triggering an event for MCE
                         * initiated actions. */
                        /* UPDATE: Actually the BT-Spec. states that an undelete is a move of the
                         * message to INBOX - clearified in errata 5591.
                         * Therefore we update the cache to INBOX-folderId - to trigger a message
                         * shift event to the old-folder. */
                        if (inboxFolder != null) {
                            msg.folderId = inboxFolder.getFolderId();
                        } else {
                            msg.folderId = folderId;
                        }
                    } else {
                        if (D) {
                            Log.d(TAG, "We did not delete the message, hence the old folder "
                                    + "is unknown. Moving to inbox.");
                        }
                    }
                }
            }
            if (V) {
                BluetoothMapFolderElement folderElement;
                String folderName = "unknown";
                if (msg != null) {
                    folderElement = mCurrentFolder.getFolderById(msg.folderId);
                    if (folderElement != null) {
                        folderName = folderElement.getName();
                    }
                }
                Log.d(TAG, "setEmailMessageStatusDelete: " + handle + " from " + folderName
                        + " status: " + status);
            }
        }
        if (!res) {
            Log.w(TAG, "Set delete status " + status + " failed.");
        }
        return res;
    }

    private void updateThreadId(Uri uri, String valueString, long threadId) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(valueString, threadId);
        mResolver.update(uri, contentValues, null, null);
    }

    private boolean deleteMessageMms(long handle) {
        boolean res = false;
        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
        Cursor c = mResolver.query(uri, null, null, null, null);
        try {
            if (c != null && c.moveToFirst()) {
                /* Move to deleted folder, or delete if already in deleted folder */
                int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
                if (threadId != DELETED_THREAD_ID) {
                    /* Set deleted thread id */
                    synchronized (getMsgListMms()) {
                        Msg msg = getMsgListMms().get(handle);
                        if (msg != null) { // This will always be the case
                            msg.threadId = DELETED_THREAD_ID;
                        }
                    }
                    updateThreadId(uri, Mms.THREAD_ID, DELETED_THREAD_ID);
                } else {
                    /* Delete from observer message list to avoid delete notifications */
                    synchronized (getMsgListMms()) {
                        getMsgListMms().remove(handle);
                    }
                    /* Delete message */
                    mResolver.delete(uri, null, null);
                }
                res = true;
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }

        return res;
    }

    private boolean unDeleteMessageMms(long handle) {
        boolean res = false;
        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
        Cursor c = mResolver.query(uri, null, null, null, null);
        try {
            if (c != null && c.moveToFirst()) {
                int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
                if (threadId == DELETED_THREAD_ID) {
                    /* Restore thread id from address, or if no thread for address
                     * create new thread by insert and remove of fake message */
                    String address;
                    long id = c.getLong(c.getColumnIndex(Mms._ID));
                    int msgBox = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
                    if (msgBox == Mms.MESSAGE_BOX_INBOX) {
                        address = BluetoothMapContent.getAddressMms(mResolver, id,
                                BluetoothMapContent.MMS_FROM);
                    } else {
                        address = BluetoothMapContent.getAddressMms(mResolver, id,
                                BluetoothMapContent.MMS_TO);
                    }
                    Set<String> recipients = new HashSet<String>();
                    recipients.addAll(Arrays.asList(address));
                    Long oldThreadId = Telephony.Threads.getOrCreateThreadId(mContext, recipients);
                    synchronized (getMsgListMms()) {
                        Msg msg = getMsgListMms().get(handle);
                        if (msg != null) { // This will always be the case
                            msg.threadId = oldThreadId.intValue();
                            // Spec. states that undelete shall shift the message to Inbox.
                            // Hence we need to trigger a message shift from INBOX to old-folder
                            // after undelete.
                            // We do this by changing the cached folder value to being inbox - hence
                            // the event handler will se the update as the message have been shifted
                            // from INBOX to old-folder. (Errata 5591 clearifies this)
                            msg.type = Mms.MESSAGE_BOX_INBOX;
                        }
                    }
                    updateThreadId(uri, Mms.THREAD_ID, oldThreadId);
                } else {
                    Log.d(TAG, "Message not in deleted folder: handle " + handle + " threadId "
                            + threadId);
                }
                res = true;
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return res;
    }

    private boolean deleteMessageSms(long handle) {
        boolean res = false;
        Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
        Cursor c = mResolver.query(uri, null, null, null, null);
        try {
            if (c != null && c.moveToFirst()) {
                /* Move to deleted folder, or delete if already in deleted folder */
                int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
                if (threadId != DELETED_THREAD_ID) {
                    synchronized (getMsgListSms()) {
                        Msg msg = getMsgListSms().get(handle);
                        if (msg != null) { // This will always be the case
                            msg.threadId = DELETED_THREAD_ID;
                        }
                    }
                    /* Set deleted thread id */
                    updateThreadId(uri, Sms.THREAD_ID, DELETED_THREAD_ID);
                } else {
                    /* Delete from observer message list to avoid delete notifications */
                    synchronized (getMsgListSms()) {
                        getMsgListSms().remove(handle);
                    }
                    /* Delete message */
                    mResolver.delete(uri, null, null);
                }
                res = true;
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return res;
    }

    private boolean unDeleteMessageSms(long handle) {
        boolean res = false;
        Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
        Cursor c = mResolver.query(uri, null, null, null, null);
        try {
            if (c != null && c.moveToFirst()) {
                int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
                if (threadId == DELETED_THREAD_ID) {
                    String address = c.getString(c.getColumnIndex(Sms.ADDRESS));
                    Set<String> recipients = new HashSet<String>();
                    recipients.addAll(Arrays.asList(address));
                    Long oldThreadId = Telephony.Threads.getOrCreateThreadId(mContext, recipients);
                    synchronized (getMsgListSms()) {
                        Msg msg = getMsgListSms().get(handle);
                        if (msg != null) {
                            msg.threadId = oldThreadId.intValue();
                            /* This will always be the case
                             * The threadId is specified as an int, so it is safe to truncate
                             * TODO: Test that this will trigger a message-shift from Inbox
                             * to old-folder
                             **/
                            /* Spec. states that undelete shall shift the message to Inbox.
                             * Hence we need to trigger a message shift from INBOX to old-folder
                             * after undelete.
                             * We do this by changing the cached folder value to being inbox - hence
                             * the event handler will se the update as the message have been shifted
                             * from INBOX to old-folder. (Errata 5591 clearifies this)
                             * */
                            msg.type = Sms.MESSAGE_TYPE_INBOX;
                        }
                    }
                    updateThreadId(uri, Sms.THREAD_ID, oldThreadId);
                } else {
                    Log.d(TAG, "Message not in deleted folder: handle " + handle + " threadId "
                            + threadId);
                }
                res = true;
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return res;
    }

    /**
     *
     * @param handle
     * @param type
     * @param mCurrentFolder
     * @param uriStr
     * @param statusValue
     * @return true is success
     */
    public boolean setMessageStatusDeleted(long handle, TYPE type,
            BluetoothMapFolderElement mCurrentFolder, String uriStr, int statusValue) {
        boolean res = false;
        if (D) {
            Log.d(TAG, "setMessageStatusDeleted: handle " + handle + " type " + type + " value "
                    + statusValue);
        }

        if (type == TYPE.EMAIL) {
            res = setEmailMessageStatusDelete(mCurrentFolder, uriStr, handle, statusValue);
        } else if (type == TYPE.IM) {
            // TODO: to do when deleting IM message
            if (D) {
                Log.d(TAG, "setMessageStatusDeleted: IM not handled");
            }
        } else {
            if (statusValue == BluetoothMapAppParams.STATUS_VALUE_YES) {
                if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
                    res = deleteMessageSms(handle);
                } else if (type == TYPE.MMS) {
                    res = deleteMessageMms(handle);
                }
            } else if (statusValue == BluetoothMapAppParams.STATUS_VALUE_NO) {
                if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
                    res = unDeleteMessageSms(handle);
                } else if (type == TYPE.MMS) {
                    res = unDeleteMessageMms(handle);
                }
            }
        }
        return res;
    }

    /**
     *
     * @param handle
     * @param type
     * @param uriStr
     * @param statusValue
     * @return true at success
     */
    public boolean setMessageStatusRead(long handle, TYPE type, String uriStr, int statusValue)
            throws RemoteException {
        int count = 0;

        if (D) {
            Log.d(TAG, "setMessageStatusRead: handle " + handle + " type " + type + " value "
                    + statusValue);
        }

        /* Approved MAP spec errata 3445 states that read status initiated
         * by the MCE shall change the MSE read status. */
        if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
            Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
            ContentValues contentValues = new ContentValues();
            contentValues.put(Sms.READ, statusValue);
            contentValues.put(Sms.SEEN, statusValue);
            String values = contentValues.toString();
            if (D) {
                Log.d(TAG, " -> SMS Uri: " + uri.toString() + " values " + values);
            }
            synchronized (getMsgListSms()) {
                Msg msg = getMsgListSms().get(handle);
                if (msg != null) { // This will always be the case
                    msg.flagRead = statusValue;
                }
            }
            count = mResolver.update(uri, contentValues, null, null);
            if (D) {
                Log.d(TAG, " -> " + count + " rows updated!");
            }

        } else if (type == TYPE.MMS) {
            Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
            if (D) {
                Log.d(TAG, " -> MMS Uri: " + uri.toString());
            }
            ContentValues contentValues = new ContentValues();
            contentValues.put(Mms.READ, statusValue);
            synchronized (getMsgListMms()) {
                Msg msg = getMsgListMms().get(handle);
                if (msg != null) { // This will always be the case
                    msg.flagRead = statusValue;
                }
            }
            count = mResolver.update(uri, contentValues, null, null);
            if (D) {
                Log.d(TAG, " -> " + count + " rows updated!");
            }
        } else if (type == TYPE.EMAIL || type == TYPE.IM) {
            Uri uri = mMessageUri;
            ContentValues contentValues = new ContentValues();
            contentValues.put(BluetoothMapContract.MessageColumns.FLAG_READ, statusValue);
            contentValues.put(BluetoothMapContract.MessageColumns._ID, handle);
            synchronized (getMsgListMsg()) {
                Msg msg = getMsgListMsg().get(handle);
                if (msg != null) { // This will always be the case
                    msg.flagRead = statusValue;
                }
            }
            count = mProviderClient.update(uri, contentValues, null, null);
        }

        return (count > 0);
    }

    private class PushMsgInfo {
        public long id;
        public int transparent;
        public int retry;
        public String phone;
        public Uri uri;
        public long timestamp;
        public int parts;
        public int partsSent;
        public int partsDelivered;
        public boolean resend;
        public boolean sendInProgress;
        public boolean failedSent; // Set to true if a single part sent fail is received.
        public int statusDelivered; // Set to != 0 if a single part deliver fail is received.

        PushMsgInfo(long id, int transparent, int retry, String phone, Uri uri) {
            this.id = id;
            this.transparent = transparent;
            this.retry = retry;
            this.phone = phone;
            this.uri = uri;
            this.resend = false;
            this.sendInProgress = false;
            this.failedSent = false;
            this.statusDelivered = 0; /* Assume success */
            this.timestamp = 0;
        }

        ;
    }

    private Map<Long, PushMsgInfo> mPushMsgList =
            Collections.synchronizedMap(new HashMap<Long, PushMsgInfo>());

    /**
     * Add an SMS to the given URI.
     *
     * @param resolver the content resolver to use
     * @param uri the URI to add the message to
     * @param address the address of the sender
     * @param body the body of the message
     * @param subject the pseudo-subject of the message
     * @param date the timestamp for the message
     * @return the URI for the new message
     */
    private static Uri addMessageToUri(ContentResolver resolver, Uri uri,
                                      String address, String body, String subject,
                                      Long date) {
        ContentValues values = new ContentValues(7);
        final int statusPending = 32;
        final int subId = SubscriptionManager.getDefaultSmsSubscriptionId();
        Log.v(TAG, "Telephony addMessageToUri sub id: " + subId);

        values.put(Telephony.Sms.SUBSCRIPTION_ID, subId);
        values.put(Telephony.Sms.ADDRESS, address);
        if (date != null) {
            values.put(Telephony.Sms.DATE, date);
        }
        values.put(Telephony.Sms.READ, 0);
        values.put(Telephony.Sms.SUBJECT, subject);
        values.put(Telephony.Sms.BODY, body);
        values.put(Telephony.Sms.STATUS, statusPending);
        return resolver.insert(uri, values);
    }

    public long pushMessage(BluetoothMapbMessage msg, BluetoothMapFolderElement folderElement,
            BluetoothMapAppParams ap, String emailBaseUri)
            throws IllegalArgumentException, RemoteException, IOException {
        if (D) {
            Log.d(TAG, "pushMessage");
        }
        ArrayList<BluetoothMapbMessage.VCard> recipientList = msg.getRecipients();
        int transparent = (ap.getTransparent() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) ? 0
                : ap.getTransparent();
        int retry = ap.getRetry();
        int charset = ap.getCharset();
        long handle = -1;
        long folderId = -1;

        if (recipientList == null) {
            if (folderElement.getName().equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_DRAFT)) {
                BluetoothMapbMessage.VCard empty =
                        new BluetoothMapbMessage.VCard("", "", null, null, 0);
                recipientList = new ArrayList<BluetoothMapbMessage.VCard>();
                recipientList.add(empty);
                Log.w(TAG, "Added empty recipient to draft message");
            } else {
                Log.e(TAG, "Trying to send a message with no recipients");
                return -1;
            }
        }

        if (msg.getType().equals(TYPE.EMAIL)) {
            /* Write the message to the database */
            String msgBody = ((BluetoothMapbMessageEmail) msg).getEmailBody();
            if (V) {
                int length = msgBody.length();
                Log.v(TAG, "pushMessage: message string length = " + length);
                String[] messages = msgBody.split("\r\n");
                Log.v(TAG, "pushMessage: messages count=" + messages.length);
                for (int i = 0; i < messages.length; i++) {
                    Log.v(TAG, "part " + i + ":" + messages[i]);
                }
            }
            FileOutputStream os = null;
            ParcelFileDescriptor fdOut = null;
            Uri uriInsert = Uri.parse(emailBaseUri + BluetoothMapContract.TABLE_MESSAGE);
            if (D) {
                Log.d(TAG, "pushMessage - uriInsert= " + uriInsert.toString() + ", intoFolder id="
                        + folderElement.getFolderId());
            }

            synchronized (getMsgListMsg()) {
                // Now insert the empty message into folder
                ContentValues values = new ContentValues();
                folderId = folderElement.getFolderId();
                values.put(BluetoothMapContract.MessageColumns.FOLDER_ID, folderId);
                Uri uriNew = mProviderClient.insert(uriInsert, values);
                if (D) {
                    Log.d(TAG, "pushMessage - uriNew= " + uriNew.toString());
                }
                handle = Long.parseLong(uriNew.getLastPathSegment());

                try {
                    fdOut = mProviderClient.openFile(uriNew, "w");
                    os = new FileOutputStream(fdOut.getFileDescriptor());
                    // Write Email to DB
                    os.write(msgBody.getBytes(), 0, msgBody.getBytes().length);
                } catch (FileNotFoundException e) {
                    Log.w(TAG, e);
                    throw (new IOException("Unable to open file stream"));
                } catch (NullPointerException e) {
                    Log.w(TAG, e);
                    throw (new IllegalArgumentException("Unable to parse message."));
                } finally {
                    try {
                        if (os != null) {
                            os.close();
                        }
                    } catch (IOException e) {
                        Log.w(TAG, e);
                    }
                    try {
                        if (fdOut != null) {
                            fdOut.close();
                        }
                    } catch (IOException e) {
                        Log.w(TAG, e);
                    }
                }

                /* Extract the data for the inserted message, and store in local mirror, to
                 * avoid sending a NewMessage Event. */
                /*TODO: We need to add the new 1.1 parameter as well:-) e.g. read*/
                Msg newMsg = new Msg(handle, folderId, 1); // TODO: Create define for read-state
                newMsg.transparent = transparent == 1;
                if (folderId == folderElement.getFolderByName(
                        BluetoothMapContract.FOLDER_NAME_OUTBOX).getFolderId()) {
                    newMsg.localInitiatedSend = true;
                }
                getMsgListMsg().put(handle, newMsg);
            }
        } else if (msg.getType().equals(TYPE.MMS) && (recipientList.size() > 1)) {
            // Group MMS
            String folder = folderElement.getName();
            ArrayList<String> telNums = new ArrayList<String>();
            for (BluetoothMapbMessage.VCard recipient : recipientList) {
                // Only send the message to the top level recipient
                if (recipient.getEnvLevel() == 0) {
                    // Only send to recipient's first phone number
                    telNums.add(recipient.getFirstPhoneNumber());
                }
            }
            // Send message if folder is outbox else just store in draft
            handle = sendMmsMessage(folder, telNums.toArray(new String[telNums.size()]),
                    (BluetoothMapbMessageMime) msg, transparent, retry);
        } else { // type SMS_* (single or mass text) or single MMS
            for (BluetoothMapbMessage.VCard recipient : recipientList) {
                // Only send the message to the top level recipient
                if (recipient.getEnvLevel() == 0) {
                    /* Only send to first address */
                    String phone = recipient.getFirstPhoneNumber();
                    String email = recipient.getFirstEmail();
                    String folder = folderElement.getName();
                    String msgBody = null;

                    /* If MMS contains text only and the size is less than ten SMS's
                     * then convert the MMS to type SMS and then proceed
                     */
                    if (msg.getType().equals(TYPE.MMS)
                            && (((BluetoothMapbMessageMime) msg).getTextOnly())) {
                        msgBody = ((BluetoothMapbMessageMime) msg).getMessageAsText();
                        SmsManager smsMng = SmsManager.getDefault();
                        ArrayList<String> parts = smsMng.divideMessage(msgBody);
                        int smsParts = parts.size();
                        if (smsParts <= CONVERT_MMS_TO_SMS_PART_COUNT) {
                            if (D) {
                                Log.d(TAG, "pushMessage - converting MMS to SMS, sms parts="
                                        + smsParts);
                            }
                            msg.setType(mSmsType);
                        } else {
                            if (D) {
                                Log.d(TAG, "pushMessage - MMS text only but to big to "
                                        + "convert to SMS");
                            }
                            msgBody = null;
                        }

                    }

                    if (msg.getType().equals(TYPE.MMS)) {
                        /* Send message if folder is outbox else just store in draft*/
                        handle = sendMmsMessage(folder, new String[] {phone},
                                (BluetoothMapbMessageMime) msg, transparent, retry);
                    } else if (msg.getType().equals(TYPE.SMS_GSM) || msg.getType()
                            .equals(TYPE.SMS_CDMA)) {
                        /* Add the message to the database */
                        if (msgBody == null) {
                            msgBody = ((BluetoothMapbMessageSms) msg).getSmsBody();
                        }

                        if (TextUtils.isEmpty(msgBody)) {
                            Log.d(TAG, "PushMsg: Empty msgBody ");
                            /* not allowed to push empty message */
                            throw new IllegalArgumentException("push EMPTY message: Invalid Body");
                        }
                        /* We need to lock the SMS list while updating the database,
                         * to avoid sending events on MCE initiated operation. */
                        Uri contentUri = Uri.parse(Sms.CONTENT_URI + "/" + folder);
                        Uri uri;
                        synchronized (getMsgListSms()) {
                            uri = addMessageToUri(mResolver, contentUri, phone, msgBody, "",
                                    System.currentTimeMillis());

                            if (V) {
                                Log.v(TAG, "Sms.addMessageToUri() returned: " + uri);
                            }
                            if (uri == null) {
                                if (D) {
                                    Log.d(TAG, "pushMessage - failure on add to uri " + contentUri);
                                }
                                return -1;
                            }
                            Cursor c = mResolver.query(uri, SMS_PROJECTION_SHORT, null, null, null);

                            /* Extract the data for the inserted message, and store in local mirror,
                             * to avoid sending a NewMessage Event. */
                            try {
                                if (c != null && c.moveToFirst()) {
                                    long id = c.getLong(c.getColumnIndex(Sms._ID));
                                    int type = c.getInt(c.getColumnIndex(Sms.TYPE));
                                    int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
                                    int readFlag = c.getInt(c.getColumnIndex(Sms.READ));
                                    if (V) {
                                        Log.v(TAG, "add message with id=" + id + " type=" + type
                                                + " threadId=" + threadId + " readFlag=" + readFlag
                                                + "to mMsgListSms");
                                    }
                                    Msg newMsg = new Msg(id, type, threadId, readFlag);
                                    getMsgListSms().put(id, newMsg);
                                    c.close();
                                } else {
                                    Log.w(TAG, "Message: " + uri + " no longer exist!");
                                    /* This can only happen, if the message is deleted
                                     * just as it is added */
                                    return -1;
                                }
                            } finally {
                                if (c != null) {
                                    c.close();
                                }
                            }

                            handle = Long.parseLong(uri.getLastPathSegment());

                            /* Send message if folder is outbox */
                            if (folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX)) {
                                PushMsgInfo msgInfo =
                                        new PushMsgInfo(handle, transparent, retry, phone, uri);
                                mPushMsgList.put(handle, msgInfo);
                                sendMessage(msgInfo, msgBody);
                                if (V) {
                                    Log.v(TAG, "sendMessage returned...");
                                }
                            } /* else just added to draft */

                            /* sendMessage causes the message to be deleted and reinserted,
                             * hence we need to lock the list while this is happening. */
                        }
                    } else {
                        if (D) {
                            Log.d(TAG, "pushMessage - failure on type ");
                        }
                        return -1;
                    }
                }
            }
        }

        /* If multiple recipients return handle of last */
        return handle;
    }

    public long sendMmsMessage(String folder, String[] toAddress, BluetoothMapbMessageMime msg,
            int transparent, int retry) {
        /*
         *strategy:
         *1) parse message into parts
         *if folder is outbox/drafts:
         *2) push message to draft
         *if folder is outbox:
         *3) move message to outbox (to trigger the mms app to add msg to pending_messages list)
         *4) send intent to mms app in order to wake it up.
         *else if folder !outbox:
         *1) push message to folder
         * */
        if (folder != null && (folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX)
                || folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_DRAFT))) {
            long handle = pushMmsToFolder(Mms.MESSAGE_BOX_DRAFTS, toAddress, msg);
            /* if invalid handle (-1) then just return the handle
             * - else continue sending (if folder is outbox) */
            if (BluetoothMapAppParams.INVALID_VALUE_PARAMETER != handle && folder.equalsIgnoreCase(
                    BluetoothMapContract.FOLDER_NAME_OUTBOX)) {
                Uri btMmsUri = MmsFileProvider.CONTENT_URI.buildUpon()
                        .appendPath(Long.toString(handle))
                        .build();
                Intent sentIntent = new Intent(ACTION_MESSAGE_SENT);
                // TODO: update the mmsMsgList <- done in pushMmsToFolder() but check
                sentIntent.setType("message/" + Long.toString(handle));
                sentIntent.putExtra(EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.MMS.ordinal());
                sentIntent.putExtra(EXTRA_MESSAGE_SENT_HANDLE, handle); // needed for notification
                sentIntent.putExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, transparent);
                sentIntent.putExtra(EXTRA_MESSAGE_SENT_RETRY, retry);
                //sentIntent.setDataAndNormalize(btMmsUri);
                PendingIntent pendingSendIntent =
                        PendingIntent.getBroadcast(mContext, 0, sentIntent, 0);
                SmsManager.getDefault()
                        .sendMultimediaMessage(mContext, btMmsUri, null/*locationUrl*/,
                                null/*configOverrides*/,
                                pendingSendIntent);
            }
            return handle;
        } else {
            /* not allowed to push mms to anything but outbox/draft */
            throw new IllegalArgumentException(
                    "Cannot push message to other " + "folders than outbox/draft");
        }
    }

    private void moveDraftToOutbox(long handle) {
        moveMmsToFolder(handle, mResolver, Mms.MESSAGE_BOX_OUTBOX);
    }

    /**
     * Move a MMS to another folder.
     * @param handle the CP handle of the message to move
     * @param resolver the ContentResolver to use
     * @param folder the destination folder - use Mms.MESSAGE_BOX_xxx
     */
    private static void moveMmsToFolder(long handle, ContentResolver resolver, int folder) {
        /*Move message by changing the msg_box value in the content provider database */
        if (handle != -1) {
            String whereClause = " _id= " + handle;
            Uri uri = Mms.CONTENT_URI;
            Cursor queryResult = resolver.query(uri, null, whereClause, null, null);
            try {
                if (queryResult != null) {
                    if (queryResult.getCount() > 0) {
                        queryResult.moveToFirst();
                        ContentValues data = new ContentValues();
                        /* set folder to be outbox */
                        data.put(Mms.MESSAGE_BOX, folder);
                        resolver.update(uri, data, whereClause, null);
                        if (D) {
                            Log.d(TAG, "moved MMS message to " + getMmsFolderName(folder));
                        }
                    }
                } else {
                    Log.w(TAG, "Could not move MMS message to " + getMmsFolderName(folder));
                }
            } finally {
                if (queryResult != null) {
                    queryResult.close();
                }
            }
        }
    }

    private long pushMmsToFolder(int folder, String[] toAddress, BluetoothMapbMessageMime msg) {
        /**
         * strategy:
         * 1) parse msg into parts + header
         * 2) create thread id (abuse the ease of adding an SMS to get id for thread)
         * 3) push parts into content://mms/parts/ table
         * 3)
         */

        ContentValues values = new ContentValues();
        values.put(Mms.MESSAGE_BOX, folder);
        values.put(Mms.READ, 0);
        values.put(Mms.SEEN, 0);
        if (msg.getSubject() != null) {
            values.put(Mms.SUBJECT, msg.getSubject());
        } else {
            values.put(Mms.SUBJECT, "");
        }

        if (msg.getSubject() != null && msg.getSubject().length() > 0) {
            values.put(Mms.SUBJECT_CHARSET, 106);
        }
        values.put(Mms.CONTENT_TYPE, "application/vnd.wap.multipart.related");
        values.put(Mms.EXPIRY, 604800);
        values.put(Mms.MESSAGE_CLASS, PduHeaders.MESSAGE_CLASS_PERSONAL_STR);
        values.put(Mms.MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ);
        values.put(Mms.MMS_VERSION, PduHeaders.CURRENT_MMS_VERSION);
        values.put(Mms.PRIORITY, PduHeaders.PRIORITY_NORMAL);
        values.put(Mms.READ_REPORT, PduHeaders.VALUE_NO);
        values.put(Mms.TRANSACTION_ID, "T" + Long.toHexString(System.currentTimeMillis()));
        values.put(Mms.DELIVERY_REPORT, PduHeaders.VALUE_NO);
        values.put(Mms.LOCKED, 0);
        if (msg.getTextOnly()) {
            values.put(Mms.TEXT_ONLY, true);
        }
        values.put(Mms.MESSAGE_SIZE, msg.getSize());

        // Get thread id
        Set<String> recipients = new HashSet<String>();
        recipients.addAll(Arrays.asList(toAddress));
        values.put(Mms.THREAD_ID, Telephony.Threads.getOrCreateThreadId(mContext, recipients));
        Uri uri = Mms.CONTENT_URI;

        synchronized (getMsgListMms()) {

            uri = mResolver.insert(uri, values);

            if (uri == null) {
                // unable to insert MMS
                Log.e(TAG, "Unabled to insert MMS " + values + "Uri: " + uri);
                return -1;
            }
            /* As we already have all the values we need, we could skip the query, but
               doing the query ensures we get any changes made by the content provider
               at insert. */
            Cursor c = mResolver.query(uri, MMS_PROJECTION_SHORT, null, null, null);
            try {
                if (c != null && c.moveToFirst()) {
                    long id = c.getLong(c.getColumnIndex(Mms._ID));
                    int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
                    int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
                    int readStatus = c.getInt(c.getColumnIndex(Mms.READ));

                    /* We must filter out any actions made by the MCE. Add the new message to
                     * the list of known messages. */

                    Msg newMsg = new Msg(id, type, threadId, readStatus);
                    newMsg.localInitiatedSend = true;
                    getMsgListMms().put(id, newMsg);
                    c.close();
                }
            } finally {
                if (c != null) {
                    c.close();
                }
            }
        } // Done adding changes, unlock access to mMsgListMms to allow sending MMS events again

        long handle = Long.parseLong(uri.getLastPathSegment());
        if (V) {
            Log.v(TAG, " NEW URI " + uri.toString());
        }

        try {
            if (msg.getMimeParts() == null) {
                /* Perhaps this message have been deleted, and no longer have any content,
                 * but only headers */
                Log.w(TAG, "No MMS parts present...");
            } else {
                if (V) {
                    Log.v(TAG, "Adding " + msg.getMimeParts().size() + " parts to the data base.");
                }
                for (MimePart part : msg.getMimeParts()) {
                    int count = 0;
                    count++;
                    values.clear();
                    if (part.mContentType != null && part.mContentType.toUpperCase()
                            .contains("TEXT")) {
                        values.put(Mms.Part.CONTENT_TYPE, "text/plain");
                        values.put(Mms.Part.CHARSET, 106);
                        if (part.mPartName != null) {
                            values.put(Mms.Part.FILENAME, part.mPartName);
                            values.put(Mms.Part.NAME, part.mPartName);
                        } else {
                            values.put(Mms.Part.FILENAME, "text_" + count + ".txt");
                            values.put(Mms.Part.NAME, "text_" + count + ".txt");
                        }
                        // Ensure we have "ci" set
                        if (part.mContentId != null) {
                            values.put(Mms.Part.CONTENT_ID, part.mContentId);
                        } else {
                            if (part.mPartName != null) {
                                values.put(Mms.Part.CONTENT_ID, "<" + part.mPartName + ">");
                            } else {
                                values.put(Mms.Part.CONTENT_ID, "<text_" + count + ">");
                            }
                        }
                        // Ensure we have "cl" set
                        if (part.mContentLocation != null) {
                            values.put(Mms.Part.CONTENT_LOCATION, part.mContentLocation);
                        } else {
                            if (part.mPartName != null) {
                                values.put(Mms.Part.CONTENT_LOCATION, part.mPartName + ".txt");
                            } else {
                                values.put(Mms.Part.CONTENT_LOCATION, "text_" + count + ".txt");
                            }
                        }

                        if (part.mContentDisposition != null) {
                            values.put(Mms.Part.CONTENT_DISPOSITION, part.mContentDisposition);
                        }
                        values.put(Mms.Part.TEXT, part.getDataAsString());
                        uri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/part");
                        uri = mResolver.insert(uri, values);
                        if (V) {
                            Log.v(TAG, "Added TEXT part");
                        }

                    } else if (part.mContentType != null && part.mContentType.toUpperCase()
                            .contains("SMIL")) {
                        values.put(Mms.Part.SEQ, -1);
                        values.put(Mms.Part.CONTENT_TYPE, "application/smil");
                        if (part.mContentId != null) {
                            values.put(Mms.Part.CONTENT_ID, part.mContentId);
                        } else {
                            values.put(Mms.Part.CONTENT_ID, "<smil_" + count + ">");
                        }
                        if (part.mContentLocation != null) {
                            values.put(Mms.Part.CONTENT_LOCATION, part.mContentLocation);
                        } else {
                            values.put(Mms.Part.CONTENT_LOCATION, "smil_" + count + ".xml");
                        }

                        if (part.mContentDisposition != null) {
                            values.put(Mms.Part.CONTENT_DISPOSITION, part.mContentDisposition);
                        }
                        values.put(Mms.Part.FILENAME, "smil.xml");
                        values.put(Mms.Part.NAME, "smil.xml");
                        values.put(Mms.Part.TEXT, new String(part.mData, "UTF-8"));

                        uri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/part");
                        uri = mResolver.insert(uri, values);
                        if (V) {
                            Log.v(TAG, "Added SMIL part");
                        }

                    } else /*VIDEO/AUDIO/IMAGE*/ {
                        writeMmsDataPart(handle, part, count);
                        if (V) {
                            Log.v(TAG, "Added OTHER part");
                        }
                    }
                    if (uri != null) {
                        if (V) {
                            Log.v(TAG, "Added part with content-type: " + part.mContentType
                                    + " to Uri: " + uri.toString());
                        }
                    }
                }
            }
        } catch (UnsupportedEncodingException e) {
            Log.w(TAG, e);
        } catch (IOException e) {
            Log.w(TAG, e);
        }

        values.clear();
        values.put(Mms.Addr.CONTACT_ID, "null");
        values.put(Mms.Addr.ADDRESS, "insert-address-token");
        values.put(Mms.Addr.TYPE, BluetoothMapContent.MMS_FROM);
        values.put(Mms.Addr.CHARSET, 106);

        uri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/addr");
        uri = mResolver.insert(uri, values);
        if (uri != null && V) {
            Log.v(TAG, " NEW URI " + uri.toString());
        }

        values.clear();
        values.put(Mms.Addr.CONTACT_ID, "null");
        values.put(Mms.Addr.ADDRESS, String.join(",", toAddress));
        values.put(Mms.Addr.TYPE, BluetoothMapContent.MMS_TO);
        values.put(Mms.Addr.CHARSET, 106);

        uri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/addr");
        uri = mResolver.insert(uri, values);
        if (uri != null && V) {
            Log.v(TAG, " NEW URI " + uri.toString());
        }
        return handle;
    }


    private void writeMmsDataPart(long handle, MimePart part, int count) throws IOException {
        ContentValues values = new ContentValues();
        values.put(Mms.Part.MSG_ID, handle);
        if (part.mContentType != null) {
            values.put(Mms.Part.CONTENT_TYPE, part.mContentType);
        } else {
            Log.w(TAG, "MMS has no CONTENT_TYPE for part " + count);
        }
        if (part.mContentId != null) {
            values.put(Mms.Part.CONTENT_ID, part.mContentId);
        } else {
            if (part.mPartName != null) {
                values.put(Mms.Part.CONTENT_ID, "<" + part.mPartName + ">");
            } else {
                values.put(Mms.Part.CONTENT_ID, "<part_" + count + ">");
            }
        }

        if (part.mContentLocation != null) {
            values.put(Mms.Part.CONTENT_LOCATION, part.mContentLocation);
        } else {
            if (part.mPartName != null) {
                values.put(Mms.Part.CONTENT_LOCATION, part.mPartName + ".dat");
            } else {
                values.put(Mms.Part.CONTENT_LOCATION, "part_" + count + ".dat");
            }
        }
        if (part.mContentDisposition != null) {
            values.put(Mms.Part.CONTENT_DISPOSITION, part.mContentDisposition);
        }
        if (part.mPartName != null) {
            values.put(Mms.Part.FILENAME, part.mPartName);
            values.put(Mms.Part.NAME, part.mPartName);
        } else {
            /* We must set at least one part identifier */
            values.put(Mms.Part.FILENAME, "part_" + count + ".dat");
            values.put(Mms.Part.NAME, "part_" + count + ".dat");
        }
        Uri partUri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/part");
        Uri res = mResolver.insert(partUri, values);

        // Add data to part
        OutputStream os = mResolver.openOutputStream(res);
        os.write(part.mData);
        os.close();
    }


    public void sendMessage(PushMsgInfo msgInfo, String msgBody) {

        SmsManager smsMng = SmsManager.getDefault();
        ArrayList<String> parts = smsMng.divideMessage(msgBody);
        msgInfo.parts = parts.size();
        // We add a time stamp to differentiate delivery reports from each other for resent messages
        msgInfo.timestamp = Calendar.getInstance().getTime().getTime();
        msgInfo.partsDelivered = 0;
        msgInfo.partsSent = 0;

        ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>(msgInfo.parts);
        ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(msgInfo.parts);

        /*       We handle the SENT intent in the MAP service, as this object
         *       is destroyed at disconnect, hence if a disconnect occur while sending
         *       a message, there is no intent handler to move the message from outbox
         *       to the correct folder.
         *       The correct solution would be to create a service that will start based on
         *       the intent, if BT is turned off. */

        if (parts != null && parts.size() > 0) {
            for (int i = 0; i < msgInfo.parts; i++) {
                Intent intentDelivery, intentSent;

                intentDelivery = new Intent(ACTION_MESSAGE_DELIVERY, null);
                /* Add msgId and part number to ensure the intents are different, and we
                 * thereby get an intent for each msg part.
                 * setType is needed to create different intents for each message id/ time stamp,
                 * as the extras are not used when comparing. */
                intentDelivery.setType(
                        "message/" + Long.toString(msgInfo.id) + msgInfo.timestamp + i);
                intentDelivery.putExtra(EXTRA_MESSAGE_SENT_HANDLE, msgInfo.id);
                intentDelivery.putExtra(EXTRA_MESSAGE_SENT_TIMESTAMP, msgInfo.timestamp);
                PendingIntent pendingIntentDelivery =
                        PendingIntent.getBroadcast(mContext, 0, intentDelivery,
                                PendingIntent.FLAG_UPDATE_CURRENT);

                intentSent = new Intent(ACTION_MESSAGE_SENT, null);
                /* Add msgId and part number to ensure the intents are different, and we
                 * thereby get an intent for each msg part.
                 * setType is needed to create different intents for each message id/ time stamp,
                 * as the extras are not used when comparing. */
                intentSent.setType("message/" + Long.toString(msgInfo.id) + msgInfo.timestamp + i);
                intentSent.putExtra(EXTRA_MESSAGE_SENT_HANDLE, msgInfo.id);
                intentSent.putExtra(EXTRA_MESSAGE_SENT_URI, msgInfo.uri.toString());
                intentSent.putExtra(EXTRA_MESSAGE_SENT_RETRY, msgInfo.retry);
                intentSent.putExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, msgInfo.transparent);

                PendingIntent pendingIntentSent =
                        PendingIntent.getBroadcast(mContext, 0, intentSent,
                                PendingIntent.FLAG_UPDATE_CURRENT);

                // We use the same pending intent for all parts, but do not set the one shot flag.
                deliveryIntents.add(pendingIntentDelivery);
                sentIntents.add(pendingIntentSent);
            }

            Log.d(TAG, "sendMessage to " + msgInfo.phone);

            if (parts.size() == 1) {
                smsMng.sendTextMessageWithoutPersisting(msgInfo.phone, null, parts.get(0),
                        sentIntents.get(0), deliveryIntents.get(0));
            } else {
                smsMng.sendMultipartTextMessageWithoutPersisting(msgInfo.phone, null, parts,
                        sentIntents, deliveryIntents);
            }
        }
    }

    private static final String[] ID_PROJECTION = new String[]{Sms._ID};
    private static final Uri UPDATE_STATUS_URI = Uri.withAppendedPath(Sms.CONTENT_URI, "/status");

    private class SmsBroadcastReceiver extends BroadcastReceiver {
        public void register() {
            Handler handler = new Handler(Looper.getMainLooper());

            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(ACTION_MESSAGE_DELIVERY);
            try {
                intentFilter.addDataType("message/*");
            } catch (MalformedMimeTypeException e) {
                Log.e(TAG, "Wrong mime type!!!", e);
            }

            mContext.registerReceiver(this, intentFilter, null, handler);
        }

        public void unregister() {
            try {
                mContext.unregisterReceiver(this);
            } catch (IllegalArgumentException e) {
                /* do nothing */
            }
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            long handle = intent.getLongExtra(EXTRA_MESSAGE_SENT_HANDLE, -1);
            PushMsgInfo msgInfo = mPushMsgList.get(handle);

            Log.d(TAG, "onReceive: action" + action);

            if (msgInfo == null) {
                Log.d(TAG, "onReceive: no msgInfo found for handle " + handle);
                return;
            }

            if (action.equals(ACTION_MESSAGE_SENT)) {
                int result =
                        intent.getIntExtra(EXTRA_MESSAGE_SENT_RESULT, Activity.RESULT_CANCELED);
                msgInfo.partsSent++;
                if (result != Activity.RESULT_OK) {
                    /* If just one of the parts in the message fails, we need to send the
                     * entire message again
                     */
                    msgInfo.failedSent = true;
                }
                if (D) {
                    Log.d(TAG, "onReceive: msgInfo.partsSent = " + msgInfo.partsSent
                            + ", msgInfo.parts = " + msgInfo.parts + " result = " + result);
                }

                if (msgInfo.partsSent == msgInfo.parts) {
                    actionMessageSent(context, intent, msgInfo, handle);
                }
            } else if (action.equals(ACTION_MESSAGE_DELIVERY)) {
                long timestamp = intent.getLongExtra(EXTRA_MESSAGE_SENT_TIMESTAMP, 0);
                int status = -1;
                if (msgInfo.timestamp == timestamp) {
                    msgInfo.partsDelivered++;
                }
            } else {
                Log.d(TAG, "onReceive: Unknown action " + action);
            }
        }

        private void actionMessageSent(
                Context context, Intent intent, PushMsgInfo msgInfo, long handle) {
            /* As the MESSAGE_SENT intent is forwarded from the MAP service, we use the intent
             * to carry the result, as getResult() will not return the correct value.
             */
            boolean delete = false;

            if (D) {
                Log.d(TAG, "actionMessageSent(): msgInfo.failedSent = " + msgInfo.failedSent);
            }

            msgInfo.sendInProgress = false;

            if (!msgInfo.failedSent) {
                if (D) {
                    Log.d(TAG, "actionMessageSent: result OK");
                }
                if (msgInfo.transparent == 0) {
                    if (!Utils.moveMessageToFolder(context, msgInfo.uri, true)) {
                        Log.w(TAG, "Failed to move " + msgInfo.uri + " to SENT");
                    }
                } else {
                    delete = true;
                }

                Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, msgInfo.id,
                        getSmsFolderName(Sms.MESSAGE_TYPE_SENT), null, mSmsType);
                sendEvent(evt);

            } else {
                if (msgInfo.retry == 1) {
                    /* Notify failure, but keep message in outbox for resending */
                    msgInfo.resend = true;
                    msgInfo.partsSent = 0; // Reset counter for the retry
                    msgInfo.failedSent = false;
                    Event evt = new Event(EVENT_TYPE_SENDING_FAILURE, msgInfo.id,
                            getSmsFolderName(Sms.MESSAGE_TYPE_OUTBOX), null, mSmsType);
                    sendEvent(evt);
                } else {
                    if (msgInfo.transparent == 0) {
                        if (!Utils.moveMessageToFolder(context, msgInfo.uri, false)) {
                            Log.w(TAG, "Failed to move " + msgInfo.uri + " to FAILED");
                        }
                    } else {
                        delete = true;
                    }

                    Event evt = new Event(EVENT_TYPE_SENDING_FAILURE, msgInfo.id,
                            getSmsFolderName(Sms.MESSAGE_TYPE_FAILED), null, mSmsType);
                    sendEvent(evt);
                }
            }

            if (delete) {
                /* Delete from Observer message list to avoid delete notifications */
                synchronized (getMsgListSms()) {
                    getMsgListSms().remove(msgInfo.id);
                }

                /* Delete from DB */
                Uri msgUri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
                int nRows = mResolver.delete(msgUri, null, null);
                if (V && nRows > 0) Log.v(TAG, "Deleted message with Uri = " + msgUri);
            }
        }

        private void actionMessageDelivery(Context context, Intent intent, PushMsgInfo msgInfo) {
            Uri messageUri = intent.getData();
            msgInfo.sendInProgress = false;

            Cursor cursor = mResolver.query(msgInfo.uri, ID_PROJECTION, null, null, null);

            try {
                if (cursor.moveToFirst()) {
                    int messageId = cursor.getInt(0);

                    Uri updateUri = ContentUris.withAppendedId(UPDATE_STATUS_URI, messageId);

                    if (D) {
                        Log.d(TAG, "actionMessageDelivery: uri=" + messageUri + ", status="
                                + msgInfo.statusDelivered);
                    }

                    ContentValues contentValues = new ContentValues(2);

                    contentValues.put(Sms.STATUS, msgInfo.statusDelivered);
                    contentValues.put(Inbox.DATE_SENT, System.currentTimeMillis());
                    mResolver.update(updateUri, contentValues, null, null);
                } else {
                    Log.d(TAG, "Can't find message for status update: " + messageUri);
                }
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }

            if (msgInfo.statusDelivered == 0) {
                Event evt = new Event(EVENT_TYPE_DELEVERY_SUCCESS, msgInfo.id,
                        getSmsFolderName(Sms.MESSAGE_TYPE_SENT), null, mSmsType);
                sendEvent(evt);
            } else {
                Event evt = new Event(EVENT_TYPE_DELIVERY_FAILURE, msgInfo.id,
                        getSmsFolderName(Sms.MESSAGE_TYPE_SENT), null, mSmsType);
                sendEvent(evt);
            }

            mPushMsgList.remove(msgInfo.id);
        }
    }

    private class CeBroadcastReceiver extends BroadcastReceiver {
        public void register() {
            UserManager manager = UserManager.get(mContext);
            if (manager == null || manager.isUserUnlocked()) {
                mStorageUnlocked = true;
                return;
            }

            Handler handler = new Handler(Looper.getMainLooper());
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
            mContext.registerReceiver(this, intentFilter, null, handler);
        }

        public void unregister() {
            try {
                mContext.unregisterReceiver(this);
            } catch (IllegalArgumentException e) {
                /* do nothing */
            }
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG, "onReceive: action" + action);

            if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
                try {
                    initMsgList();
                } catch (RemoteException e) {
                    Log.e(TAG, "Error initializing SMS/MMS message lists.");
                }

                for (String folder : FOLDER_SMS_MAP.values()) {
                    Event evt = new Event(EVENT_TYPE_NEW, -1, folder, mSmsType);
                    sendEvent(evt);
                }
                mStorageUnlocked = true;
                /* After unlock this BroadcastReceiver is never needed */
                unregister();
            } else {
                Log.d(TAG, "onReceive: Unknown action " + action);
            }
        }
    }

    /**
     * Handle MMS sent intents in disconnected(MNS) state, where we do not need to send any
     * notifications.
     * @param context The context to use for provider operations
     * @param intent The intent received
     * @param result The result
     */
    public static void actionMmsSent(Context context, Intent intent, int result,
            Map<Long, Msg> mmsMsgList) {
        /*
         * if transparent:
         *   delete message and send notification(regardless of result)
         * else
         *   Result == Success:
         *     move to sent folder (will trigger notification)
         *   Result == Fail:
         *     move to outbox (send delivery fail notification)
         */
        if (D) {
            Log.d(TAG, "actionMmsSent()");
        }
        int transparent = intent.getIntExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, 0);
        long handle = intent.getLongExtra(EXTRA_MESSAGE_SENT_HANDLE, -1);
        if (handle < 0) {
            Log.w(TAG, "Intent received for an invalid handle");
            return;
        }
        ContentResolver resolver = context.getContentResolver();
        if (transparent == 1) {
            /* The specification is a bit unclear about the transparent flag. If it is set
             * no copy of the message shall be kept in the send folder after the message
             * was send, but in the case of a send error, it is unclear what to do.
             * As it will not be transparent if we keep the message in any folder,
             * we delete the message regardless of the result.
             * If we however do have a MNS connection we need to send a notification. */
            Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
            /* Delete from observer message list to avoid delete notifications */
            if (mmsMsgList != null) {
                synchronized (mmsMsgList) {
                    mmsMsgList.remove(handle);
                }
            }
            /* Delete message */
            if (D) {
                Log.d(TAG, "Transparent in use - delete");
            }
            resolver.delete(uri, null, null);
        } else if (result == Activity.RESULT_OK) {
            /* This will trigger a notification */
            moveMmsToFolder(handle, resolver, Mms.MESSAGE_BOX_SENT);
        } else {
            if (mmsMsgList != null) {
                synchronized (mmsMsgList) {
                    Msg msg = mmsMsgList.get(handle);
                    if (msg != null) {
                        msg.type = Mms.MESSAGE_BOX_OUTBOX;
                    }
                }
            }
            /* Hand further retries over to the MMS application */
            moveMmsToFolder(handle, resolver, Mms.MESSAGE_BOX_OUTBOX);
        }
    }

    public static void actionMessageSentDisconnected(Context context, Intent intent, int result) {
        TYPE type = TYPE.fromOrdinal(
                intent.getIntExtra(EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.NONE.ordinal()));
        if (type == TYPE.MMS) {
            actionMmsSent(context, intent, result, null);
        } else {
            actionSmsSentDisconnected(context, intent, result);
        }
    }

    public static void actionSmsSentDisconnected(Context context, Intent intent, int result) {
        /* Check permission for message deletion. */
        if ((Binder.getCallingPid() != Process.myPid()) || (
                context.checkCallingOrSelfPermission("android.Manifest.permission.WRITE_SMS")
                        != PackageManager.PERMISSION_GRANTED)) {
            Log.w(TAG, "actionSmsSentDisconnected: Not allowed to delete SMS/MMS messages");
            return;
        }

        boolean delete = false;
        //int retry = intent.getIntExtra(EXTRA_MESSAGE_SENT_RETRY, 0);
        int transparent = intent.getIntExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, 0);
        String uriString = intent.getStringExtra(EXTRA_MESSAGE_SENT_URI);
        if (uriString == null) {
            // Nothing we can do about it, just bail out
            return;
        }
        Uri uri = Uri.parse(uriString);

        if (result == Activity.RESULT_OK) {
            Log.d(TAG, "actionMessageSentDisconnected: result OK");
            if (transparent == 0) {
                if (!Utils.moveMessageToFolder(context, uri, true)) {
                    Log.d(TAG, "Failed to move " + uri + " to SENT");
                }
            } else {
                delete = true;
            }
        } else {
            /*if (retry == 1) {
                 The retry feature only works while connected, else we fail the send,
             * and move the message to failed, to let the user/app resend manually later.
            } else */
            {
                if (transparent == 0) {
                    if (!Utils.moveMessageToFolder(context, uri, false)) {
                        Log.d(TAG, "Failed to move " + uri + " to FAILED");
                    }
                } else {
                    delete = true;
                }
            }
        }

        if (delete) {
            /* Delete from DB */
            ContentResolver resolver = context.getContentResolver();
            if (resolver != null) {
                resolver.delete(uri, null, null);
            } else {
                Log.w(TAG, "Unable to get resolver");
            }
        }
    }

    private void registerPhoneServiceStateListener() {
        TelephonyManager tm =
                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        tm.listen(mPhoneListener, PhoneStateListener.LISTEN_SERVICE_STATE);
    }

    private void unRegisterPhoneServiceStateListener() {
        TelephonyManager tm =
                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        tm.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE);
    }

    private void resendPendingMessages() {
        /* Send pending messages in outbox */
        String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX;
        UserManager manager = UserManager.get(mContext);
        if (manager == null || !manager.isUserUnlocked()) {
            return;
        }
        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null, null);
        try {
            if (c != null && c.moveToFirst()) {
                do {
                    long id = c.getLong(c.getColumnIndex(Sms._ID));
                    String msgBody = c.getString(c.getColumnIndex(Sms.BODY));
                    PushMsgInfo msgInfo = mPushMsgList.get(id);
                    if (msgInfo == null || !msgInfo.resend || msgInfo.sendInProgress) {
                        continue;
                    }
                    msgInfo.sendInProgress = true;
                    sendMessage(msgInfo, msgBody);
                } while (c.moveToNext());
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }


    }

    private void failPendingMessages() {
        /* Move pending messages from outbox to failed */
        String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX;
        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null, null);
        try {
            if (c != null && c.moveToFirst()) {
                do {
                    long id = c.getLong(c.getColumnIndex(Sms._ID));
                    String msgBody = c.getString(c.getColumnIndex(Sms.BODY));
                    PushMsgInfo msgInfo = mPushMsgList.get(id);
                    if (msgInfo == null || !msgInfo.resend) {
                        continue;
                    }
                    Utils.moveMessageToFolder(mContext, msgInfo.uri, false);
                } while (c.moveToNext());
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }

    }

    private void removeDeletedMessages() {
        /* Remove messages from virtual "deleted" folder (thread_id -1) */
        mResolver.delete(Sms.CONTENT_URI, "thread_id = " + DELETED_THREAD_ID, null);
    }

    private PhoneStateListener mPhoneListener = new PhoneStateListener() {
        @Override
        public void onServiceStateChanged(ServiceState serviceState) {
            Log.d(TAG, "Phone service state change: " + serviceState.getState());
            if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
                resendPendingMessages();
            }
        }
    };

    public void init() {
        if (mSmsBroadcastReceiver != null) {
            mSmsBroadcastReceiver.register();
        }

        if (mCeBroadcastReceiver != null) {
            mCeBroadcastReceiver.register();
        }

        registerPhoneServiceStateListener();
        mInitialized = true;
    }

    public void deinit() {
        mInitialized = false;
        unregisterObserver();
        if (mSmsBroadcastReceiver != null) {
            mSmsBroadcastReceiver.unregister();
        }
        unRegisterPhoneServiceStateListener();
        if (UserManager.get(mContext).isUserUnlocked()) {
            failPendingMessages();
            removeDeletedMessages();
        }
    }

    public boolean handleSmsSendIntent(Context context, Intent intent) {
        TYPE type = TYPE.fromOrdinal(
                intent.getIntExtra(EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.NONE.ordinal()));
        if (type == TYPE.MMS) {
            return handleMmsSendIntent(context, intent);
        } else {
            if (mInitialized) {
                mSmsBroadcastReceiver.onReceive(context, intent);
                return true;
            }
        }
        return false;
    }

    public boolean handleMmsSendIntent(Context context, Intent intent) {
        if (D) {
            Log.w(TAG, "handleMmsSendIntent()");
        }
        if (!mMnsClient.isConnected()) {
            // No need to handle notifications, just use default handling
            if (D) {
                Log.w(TAG, "MNS not connected - use static handling");
            }
            return false;
        }
        long handle = intent.getLongExtra(EXTRA_MESSAGE_SENT_HANDLE, -1);
        int result = intent.getIntExtra(EXTRA_MESSAGE_SENT_RESULT, Activity.RESULT_CANCELED);
        actionMmsSent(context, intent, result, getMsgListMms());
        if (handle < 0) {
            Log.w(TAG, "Intent received for an invalid handle");
            return true;
        }
        if (result != Activity.RESULT_OK) {
            if (mObserverRegistered) {
                Event evt = new Event(EVENT_TYPE_SENDING_FAILURE, handle,
                        getMmsFolderName(Mms.MESSAGE_BOX_OUTBOX), null, TYPE.MMS);
                sendEvent(evt);
            }
        } else {
            int transparent = intent.getIntExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, 0);
            if (transparent != 0) {
                if (mObserverRegistered) {
                    Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, handle,
                            getMmsFolderName(Mms.MESSAGE_BOX_OUTBOX), null, TYPE.MMS);
                    sendEvent(evt);
                }
            }
        }
        return true;
    }

}
