diff --git a/Android.mk b/Android.mk
index 147141b..7ae59ea 100644
--- a/Android.mk
+++ b/Android.mk
@@ -8,6 +8,12 @@
 
 LOCAL_PACKAGE_NAME := BluetoothExt
 LOCAL_CERTIFICATE := platform
+LOCAL_JAVA_LIBRARIES := javax.obex
+LOCAL_JAVA_LIBRARIES += mms-common
+LOCAL_JAVA_LIBRARIES += telephony-common
+LOCAL_STATIC_JAVA_LIBRARIES := com.android.vcard
+
+LOCAL_REQUIRED_MODULES := libbluetooth_jni bluetooth.default
 
 LOCAL_PROGUARD_ENABLED := disabled
 
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7519746..63229db 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -40,7 +40,16 @@
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
     <uses-permission android:name="android.permission.BLUETOOTH_STACK" />
+    <uses-permission android:name="android.permission.READ_SMS"></uses-permission>
+    <uses-permission android:name="android.permission.WRITE_SMS"></uses-permission>
+    <uses-permission android:name="android.permission.BROADCAST_SMS"></uses-permission>
+    <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
+    <uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
+    <uses-permission android:name="android.permission.MMS_PUSH"></uses-permission>
+    <uses-permission android:name="com.android.email.permission.ACCESS_PROVIDER"/>
+    <uses-permission android:name="com.android.email.permission.READ_ATTACHMENT"/>
     <application>
+        <uses-library android:name="javax.obex" />
         <service
             android:name = ".btcservice.BTCService">
         </service>
@@ -60,5 +69,29 @@
                 <action android:name="android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED" />
             </intent-filter>
         </receiver>
+ <activity android:name=".map.BluetoothMasActivity"
+            android:process="@string/process"
+            android:excludeFromRecents="true"
+            android:enabled="@bool/profile_supported_map"
+            android:theme="@*android:style/Theme.Holo.Dialog.Alert">
+            <intent-filter>
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <service
+            android:process="@string/process"
+            android:enabled="@bool/profile_supported_map"
+            android:name=".map.BluetoothMasService" >
+        </service>
+        <receiver
+            android:process="@string/process"
+            android:enabled="@bool/profile_supported_map"
+            android:name=".map.BluetoothMasReceiver">
+            <intent-filter>
+                <action android:name="android.bluetooth.adapter.action.STATE_CHANGED"/>
+                <action android:name="android.bluetooth.device.action.BOND_STATE_CHANGED"/>
+                <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED"/>
+            </intent-filter>
+        </receiver>
     </application>
 </manifest>
diff --git a/res/layout/auth.xml b/res/layout/auth.xml
new file mode 100644
index 0000000..7d1a200
--- /dev/null
+++ b/res/layout/auth.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, The Android Open Source Project
+**
+** 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.
+*/
+-->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent">
+
+    <LinearLayout
+    android:layout_height="match_parent"
+    android:layout_width="match_parent"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/message"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="20dip"
+        android:layout_marginRight="20dip"
+        android:gravity="center_horizontal"
+        android:textAppearance="?android:attr/textAppearanceMedium" />
+
+    <EditText
+        android:id="@+id/text"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dip"
+        android:layout_marginLeft="20dip"
+        android:layout_marginRight="20dip"
+        android:singleLine="true" />
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/res/layout/bluetooth_access.xml b/res/layout/bluetooth_access.xml
new file mode 100644
index 0000000..d81305b
--- /dev/null
+++ b/res/layout/bluetooth_access.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, The Android Open Source Project
+**
+** 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.
+*/
+-->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent">
+
+    <LinearLayout
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="20dip"
+            android:layout_marginEnd="20dip"
+            android:gravity="center_horizontal"
+            android:textAppearance="?android:attr/textAppearanceMedium" />
+
+        <CheckBox android:id="@+id/alwaysallowed"
+            style="?android:attr/textAppearanceMedium"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="2dip"
+            android:text="@string/bluetooth_remember_choice" />
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/res/values/config.xml b/res/values/config.xml
new file mode 100644
index 0000000..247f362
--- /dev/null
+++ b/res/values/config.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009-2012 Broadcom Corporation
+   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.
+-->
+<resources>
+    <bool name="profile_supported_map">true</bool>
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..7c01009
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="defaultname">Carkit</string>
+    <!-- Do not translate. android:process of this application. -->
+    <string name="process" translate="false"><xliff:g id="x" /></string>
+
+    <!-- Bluetooth FTP or MAP permission Alert Activity checkbox text [CHAR LIMIT=none] -->
+    <string name="bluetooth_remember_choice">Always Allow</string>
+
+</resources>
diff --git a/res/values/strings_map.xml b/res/values/strings_map.xml
new file mode 100644
index 0000000..5ed01c7
--- /dev/null
+++ b/res/values/strings_map.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_acceptance_dialog_title">%1$s would like to access your phone folders. Give access to %2$s?</string>
+    <string name="map_acceptance_dialog_header">Phone Folder Access</string>
+    <string name="map_session_key_dialog_title">Type session key for %1$s</string>
+    <string name="map_session_key_dialog_header">Bluetooth session key required</string>
+    <string name="map_acceptance_timeout_message">There was time out to accept connection with %1$s</string>
+    <string name="map_authentication_timeout_message">There was time out to input session key with %1$s</string>
+    <string name="map_notif_ticker">Bluetooth connection request</string>
+    <!-- Notification title when a Bluetooth device wants to pair with us -->
+    <string name="map_notif_title">Session Key Request for MAP</string>
+    <!-- Notification message when a Bluetooth device wants to pair with us -->
+    <string name="map_notif_message">"Touch to connect to \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022."</string>
+    <string name="map_alert_conn_failed_message">Bluetooth MAP connection failed.</string>
+    <!-- Activity label of BluetoothMasPermissionActivity, also used as Strings in the permission dialog [CHAR LIMIT=none] -->
+    <string name="bluetooth_mas_request">"Message Access request"</string>
+    <!-- Bluetooth MAS permission Alert Activity text [CHAR LIMIT=none] -->
+    <string name="bluetooth_mas_acceptance_dialog_text">%1$s would like to access your messages. Give access to %2$s?</string>
+
+</resources>
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMapAuthenticator.java b/src/org/codeaurora/bluetooth/map/BluetoothMapAuthenticator.java
new file mode 100644
index 0000000..314536e
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMapAuthenticator.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.codeaurora.bluetooth.map;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import javax.obex.Authenticator;
+import javax.obex.PasswordAuthentication;
+
+/**
+ * BluetoothMapAuthenticator is a used by BluetoothObexServer for obex
+ * authentication procedure.
+ */
+public class BluetoothMapAuthenticator implements Authenticator {
+    private static final String TAG = "BluetoothMapAuthenticator";
+
+    private boolean mChallenged;
+
+    private boolean mAuthCancelled;
+
+    private String mSessionKey;
+
+    private Handler mCallback;
+
+    public BluetoothMapAuthenticator(final Handler callback) {
+        mCallback = callback;
+        mChallenged = false;
+        mAuthCancelled = false;
+        mSessionKey = null;
+    }
+
+    public final synchronized void setChallenged(final boolean bool) {
+        mChallenged = bool;
+    }
+
+    public final synchronized void setCancelled(final boolean bool) {
+        mAuthCancelled = bool;
+    }
+
+    public final synchronized void setSessionKey(final String string) {
+        mSessionKey = string;
+    }
+
+    private void waitUserConfirmation() {
+        Message msg = Message.obtain(mCallback);
+        msg.what = BluetoothMasService.MSG_OBEX_AUTH_CHALL;
+        msg.sendToTarget();
+        synchronized (this) {
+            while (!mChallenged && !mAuthCancelled) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "Interrupted while waiting on isChalled");
+                }
+            }
+        }
+    }
+
+      public PasswordAuthentication onAuthenticationChallenge(final String description,
+            final boolean isUserIdRequired, final boolean isFullAccess) {
+        waitUserConfirmation();
+        if (mSessionKey.trim().length() != 0) {
+            PasswordAuthentication pa = new PasswordAuthentication(null, mSessionKey.getBytes());
+            return pa;
+        }
+        return null;
+    }
+
+    // TODO: Reserved for future use only, in case PSE challenge PCE
+    public byte[] onAuthenticationResponse(final byte[] userName) {
+        return null;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMapRfcommTransport.java b/src/org/codeaurora/bluetooth/map/BluetoothMapRfcommTransport.java
new file mode 100644
index 0000000..154ecb0
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMapRfcommTransport.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.bluetooth.BluetoothSocket;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.obex.ObexTransport;
+
+public class BluetoothMapRfcommTransport implements ObexTransport {
+    private BluetoothSocket mSocket = null;
+
+    public BluetoothMapRfcommTransport(BluetoothSocket rfs) {
+        super();
+        this.mSocket = rfs;
+    }
+
+    public void close() throws IOException {
+        mSocket.close();
+    }
+
+    public DataInputStream openDataInputStream() throws IOException {
+        return new DataInputStream(openInputStream());
+    }
+
+    public DataOutputStream openDataOutputStream() throws IOException {
+        return new DataOutputStream(openOutputStream());
+    }
+
+    public InputStream openInputStream() throws IOException {
+        return mSocket.getInputStream();
+    }
+
+    public OutputStream openOutputStream() throws IOException {
+        return mSocket.getOutputStream();
+    }
+
+    public void connect() throws IOException {
+    }
+
+    public void create() throws IOException {
+    }
+
+    public void disconnect() throws IOException {
+    }
+
+    public void listen() throws IOException {
+    }
+
+    public boolean isConnected() throws IOException {
+        return true;
+    }
+
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasActivity.java b/src/org/codeaurora/bluetooth/map/BluetoothMasActivity.java
new file mode 100644
index 0000000..011641c
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasActivity.java
@@ -0,0 +1,313 @@
+ /*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.Preference;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+
+import org.codeaurora.bluetooth.R;
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+
+/**
+ * MapActivity shows dialogues for accepting incoming map request
+ * with a  remote Bluetooth device.
+  */
+public class BluetoothMasActivity extends AlertActivity implements
+        DialogInterface.OnClickListener, Preference.OnPreferenceChangeListener, TextWatcher {
+    private static final String TAG = "BluetoothMasActivity";
+
+    private static final boolean V = BluetoothMasService.VERBOSE;
+
+    private static final int BLUETOOTH_OBEX_AUTHKEY_MAX_LENGTH = 16;
+
+    private static final int DIALOG_YES_NO_CONNECT = 1;
+
+    private static final String KEY_USER_TIMEOUT = "user_timeout";
+
+    private View mView;
+
+    private EditText mKeyView;
+
+    private TextView messageView;
+
+    private String mSessionKey = "";
+
+    private int mCurrentDialog;
+
+    private Button mOkButton;
+
+    private CheckBox mAlwaysAllowed;
+
+    private boolean mTimeout = false;
+
+    private boolean mAlwaysAllowedValue = false;
+
+    private static final int DISMISS_TIMEOUT_DIALOG = 0;
+
+    private static final int DISMISS_TIMEOUT_DIALOG_VALUE = 2000;
+
+    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!BluetoothMasService.USER_CONFIRM_TIMEOUT_ACTION.equals(intent.getAction())) {
+                return;
+            }
+            onTimeout();
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent i = getIntent();
+        String action = i.getAction();
+        if (BluetoothMasService.ACCESS_REQUEST_ACTION.equals(action)) {
+            showMapDialog(DIALOG_YES_NO_CONNECT);
+            mCurrentDialog = DIALOG_YES_NO_CONNECT;
+        }
+        else {
+            Log.e(TAG, "Error: this activity may be started only with intent "
+                    + "MAP_ACCESS_REQUEST");
+            finish();
+        }
+        registerReceiver(mReceiver, new IntentFilter(
+                BluetoothMasService.USER_CONFIRM_TIMEOUT_ACTION));
+    }
+
+    private void showMapDialog(int id) {
+        final AlertController.AlertParams p = mAlertParams;
+        switch (id) {
+            case DIALOG_YES_NO_CONNECT:
+                p.mIconId = android.R.drawable.ic_dialog_info;
+                p.mTitle = getString(R.string.bluetooth_mas_request);
+                p.mView = createView(DIALOG_YES_NO_CONNECT);
+                p.mPositiveButtonText = getString(android.R.string.yes);
+                p.mPositiveButtonListener = this;
+                p.mNegativeButtonText = getString(android.R.string.no);
+                p.mNegativeButtonListener = this;
+                mOkButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
+                setupAlert();
+                break;
+            default:
+                break;
+        }
+    }
+
+    private String getRemoteDeviceName() {
+        String remoteDeviceName = null;
+        Intent intent = getIntent();
+        if (intent.hasExtra(BluetoothMasService.EXTRA_BLUETOOTH_DEVICE)) {
+            BluetoothDevice device = intent.getParcelableExtra(BluetoothMasService.EXTRA_BLUETOOTH_DEVICE);
+            if (device != null) {
+                remoteDeviceName = device.getName();
+            }
+        }
+
+        return (remoteDeviceName != null) ? remoteDeviceName : getString(R.string.defaultname);
+    }
+
+    private String createDisplayText(final int id) {
+        String mRemoteName = getRemoteDeviceName();
+        switch (id) {
+        case DIALOG_YES_NO_CONNECT:
+            String mMessage1 = getString(R.string.bluetooth_mas_acceptance_dialog_text, mRemoteName,
+                    mRemoteName);
+            return mMessage1;
+        default:
+            return null;
+        }
+    }
+
+    private View createView(final int id) {
+        switch (id) {
+            case DIALOG_YES_NO_CONNECT:
+                mView = getLayoutInflater().inflate(R.layout.bluetooth_access, null);
+                messageView = (TextView)mView.findViewById(R.id.message);
+                messageView.setText(createDisplayText(id));
+                mAlwaysAllowed = (CheckBox)mView.findViewById(R.id.alwaysallowed);
+                mAlwaysAllowed.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                        if (isChecked) {
+                            mAlwaysAllowedValue = true;
+                        } else {
+                            mAlwaysAllowedValue = false;
+                        }
+                    }
+                });
+                return mView;
+            default:
+                return null;
+        }
+    }
+
+    private void onPositive() {
+        if (!mTimeout) {
+            if (mCurrentDialog == DIALOG_YES_NO_CONNECT) {
+                sendIntentToReceiver(BluetoothMasService.ACCESS_ALLOWED_ACTION,
+                        BluetoothMasService.EXTRA_ALWAYS_ALLOWED, mAlwaysAllowedValue);
+            }
+        }
+        mTimeout = false;
+        finish();
+    }
+
+    private void onNegative() {
+        if (mCurrentDialog == DIALOG_YES_NO_CONNECT) {
+            sendIntentToReceiver(BluetoothMasService.ACCESS_DISALLOWED_ACTION, null, null);
+        }
+        finish();
+    }
+
+    private void sendIntentToReceiver(final String intentName, final String extraName,
+            final String extraValue) {
+        Intent intent = new Intent(intentName);
+        intent.setClassName(BluetoothMasService.THIS_PACKAGE_NAME, BluetoothMasReceiver.class
+                .getName());
+        if (extraName != null) {
+            intent.putExtra(extraName, extraValue);
+        }
+        sendBroadcast(intent);
+    }
+
+    private void sendIntentToReceiver(final String intentName, final String extraName,
+            final boolean extraValue) {
+        Intent intent = new Intent(intentName);
+        intent.setClassName(BluetoothMasService.THIS_PACKAGE_NAME, BluetoothMasReceiver.class
+                .getName());
+        if (extraName != null) {
+            intent.putExtra(extraName, extraValue);
+        }
+        Intent i = getIntent();
+        if (i.hasExtra(BluetoothMasService.EXTRA_BLUETOOTH_DEVICE)) {
+            intent.putExtra(BluetoothMasService.EXTRA_BLUETOOTH_DEVICE, i.getParcelableExtra(BluetoothMasService.EXTRA_BLUETOOTH_DEVICE));
+        }
+        sendBroadcast(intent);
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        switch (which) {
+            case DialogInterface.BUTTON_POSITIVE:
+                onPositive();
+                break;
+
+            case DialogInterface.BUTTON_NEGATIVE:
+                onNegative();
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void onTimeout() {
+        mTimeout = true;
+        if (mCurrentDialog == DIALOG_YES_NO_CONNECT) {
+            if(mView != null) {
+                messageView.setText(getString(R.string.map_acceptance_timeout_message,
+                        getRemoteDeviceName()));
+                mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE);
+                mAlwaysAllowed.setVisibility(View.GONE);
+                mAlwaysAllowed.clearFocus();
+            }
+        }
+
+        mTimeoutHandler.sendMessageDelayed(mTimeoutHandler.obtainMessage(DISMISS_TIMEOUT_DIALOG),
+                DISMISS_TIMEOUT_DIALOG_VALUE);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        mTimeout = savedInstanceState.getBoolean(KEY_USER_TIMEOUT);
+        if (V) Log.v(TAG, "onRestoreInstanceState() mTimeout: " + mTimeout);
+
+        if (mTimeout) {
+            onTimeout();
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(KEY_USER_TIMEOUT, mTimeout);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        unregisterReceiver(mReceiver);
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        return true;
+    }
+
+    public void beforeTextChanged(CharSequence s, int start, int before, int after) {
+    }
+
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    }
+
+    public void afterTextChanged(android.text.Editable s) {
+        if (s.length() > 0) {
+            mOkButton.setEnabled(true);
+        }
+    }
+    private final Handler mTimeoutHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case DISMISS_TIMEOUT_DIALOG:
+                    if (V) Log.v(TAG, "Received DISMISS_TIMEOUT_DIALOG msg.");
+                    finish();
+                    break;
+                default:
+                    break;
+            }
+        }
+    };
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasAppEmail.java b/src/org/codeaurora/bluetooth/map/BluetoothMasAppEmail.java
new file mode 100644
index 0000000..f827205
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasAppEmail.java
@@ -0,0 +1,800 @@
+/*
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Handler;
+import android.text.format.Time;
+import android.util.Log;
+
+import org.codeaurora.bluetooth.map.MapUtils.BmessageConsts;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils;
+import org.codeaurora.bluetooth.map.MapUtils.EmailUtils;
+import org.codeaurora.bluetooth.map.MapUtils.MapUtils;
+import org.codeaurora.bluetooth.map.MapUtils.MsgListingConsts;
+import org.codeaurora.bluetooth.map.MapUtils.SqlHelper;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageListingRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasPushMsgRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMsgListRsp;
+import org.codeaurora.bluetooth.map.MapUtils.MapUtils.BadRequestException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.obex.ResponseCodes;
+
+import static org.codeaurora.bluetooth.map.BluetoothMasService.MSG_SERVERSESSION_CLOSE;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.TYPE_DELETED;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.TYPE_DRAFT;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.TYPE_INBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.TYPE_OUTBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.TYPE_SENT;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.DELETED;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.DRAFT;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.DRAFTS;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.INBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.OUTBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.SENT;
+
+public class BluetoothMasAppEmail extends BluetoothMasAppIf {
+    public final String TAG = "BluetoothMasAppEmail";
+    public final boolean V = BluetoothMasService.VERBOSE;
+
+    private ContentObserver mObserver;
+    private static final int[] SPECIAL_MAILBOX_TYPES
+            = {TYPE_DELETED, TYPE_DRAFT, TYPE_INBOX, TYPE_OUTBOX, TYPE_SENT};
+    private static final String[] SPECIAL_MAILBOX_MAP_NAME
+            = {DELETED, DRAFT, INBOX, OUTBOX, SENT};
+    private HashMap<Integer, String> mSpecialMailboxName = new HashMap<Integer, String>();
+
+    public BluetoothMasAppEmail(Context context, Handler handler, BluetoothMns mnsClient,
+            int masId, String remoteDeviceName) {
+        super(context, handler, MESSAGE_TYPE_EMAIL, mnsClient, masId, remoteDeviceName);
+
+        mObserver = new ContentObserver(null) {
+            @Override
+            public void onChange(boolean selfChange) {
+                long id = EmailUtils.getAccountId(mMasId);
+                if (!EmailUtils.hasEmailAccount(mContext, id)) {
+                    // Email account removed, disconnect
+                    // TODO: inform the user
+                    disconnect();
+                }
+                super.onChange(selfChange);
+            }
+        };
+
+        loadSpecialMailboxName();
+        if (V) Log.v(TAG, "BluetoothMasAppEmail Constructor called");
+    }
+
+    private void loadSpecialMailboxName() {
+        mSpecialMailboxName.clear();
+        long id = EmailUtils.getAccountId(mMasId);
+        final String where = EmailUtils.ACCOUNT_KEY + "=" + id + " AND " + EmailUtils.TYPE + "=";
+        String name;
+        for (int i = 0; i < SPECIAL_MAILBOX_TYPES.length; i ++) {
+            name = SqlHelper.getFirstValueForColumn(mContext, EmailUtils.EMAIL_BOX_URI,
+                    EmailUtils.DISPLAY_NAME, where + SPECIAL_MAILBOX_TYPES[i], null);
+            if (name.length() > 0) {
+                mSpecialMailboxName.put(i, name);
+            }
+        }
+    }
+
+    /**
+     * Start an MNS obex client session and push notification whenever available
+     */
+    public void startMnsSession(BluetoothDevice remoteDevice) {
+        if (V) Log.v(TAG, "Start MNS Client");
+        mMnsClient.getHandler().obtainMessage(BluetoothMns.MNS_CONNECT, mMasId,
+                -1, remoteDevice).sendToTarget();
+    }
+
+    /**
+     * Stop pushing notifications and disconnect MNS obex session
+     */
+    public void stopMnsSession(BluetoothDevice remoteDevice) {
+        if (V) Log.v(TAG, "Stop MNS Client");
+        mMnsClient.getHandler().obtainMessage(BluetoothMns.MNS_DISCONNECT, mMasId,
+                -1, remoteDevice).sendToTarget();
+    }
+
+    @Override
+    protected List<String> getCompleteFolderList() {
+        if (V) Log.v(TAG, "getCompleteFolderList mCurrentPath: " + mCurrentPath);
+        long id = EmailUtils.getAccountId(mMasId);
+        List<String> list;
+        String splitStrings[] = mCurrentPath.split("/");
+        ArrayList<String> finalList = new ArrayList<String>();
+        String name;
+        int type;
+        int curType;
+        int len =splitStrings.length;
+        if (V) Log.v(TAG, "getCompleteFolderList splitStrings.len = " + splitStrings.length);
+        //Get Default List at "/telecom/msg/"
+        if(len < 3 &&  (mCurrentPath.equalsIgnoreCase("telecom") ||
+                mCurrentPath.equalsIgnoreCase("telecom/msg"))) {
+            list = EmailUtils.getEmailFolderListAtPath(mContext, id, "");
+            for (int i = 0; i < SPECIAL_MAILBOX_TYPES.length; i ++) {
+                curType = SPECIAL_MAILBOX_TYPES[i];
+                if (V) Log.v(TAG, " getCompleteFolderList: Current Type: " + curType);
+                for (String str : list) {
+                    type = EmailUtils.getTypeForFolder(mContext, id, str);
+                    if (V) Log.v(TAG, " getCompleteFolderList: type: " + type);
+                    if (type == curType) {
+                        if (V) Log.v(TAG, " getCompleteFolderList: removing folder : " + str);
+                        list.remove(str);
+                        break;
+                   }
+                }
+                if (!list.contains(SPECIAL_MAILBOX_MAP_NAME[i])) {
+                    if (V) Log.v(TAG, " getCompleteFolderList: adding default folder : "
+                        + SPECIAL_MAILBOX_MAP_NAME[i]);
+                    list.add(SPECIAL_MAILBOX_MAP_NAME[i]);
+                }
+            }
+            for (String str : list) {
+                type = EmailUtils.getTypeForFolder(mContext, id, str);
+                if (type <= ((EmailUtils.TYPE_DELETED) + 1)) {
+                    if (V) Log.v(TAG, " getCompleteFolderList: Adding a valid folder:" + str);
+                    finalList.add(str);
+                }
+            }
+        }
+        else {
+            //Remove length of "telecom/msg" -> 11 from mCurrentPath , Get folders and subfodlers
+            String path = mCurrentPath.substring(12);
+            list = EmailUtils.getEmailFolderListAtPath(mContext, id, path);
+            for (String str : list) {
+                if (V) Log.v(TAG, " getCompleteFolderList: Processing SerId: " + str);
+                String folderStr = str.substring(path.length()+ 1);
+                String folder[] = folderStr.split("/");
+                if(folder.length == 1){
+                    type = EmailUtils.getTypeForFolder(mContext, id, folder[0]);
+                    if (V) Log.v(TAG, " getCompleteFolderList: Add Folder:" + folder[0]);
+                    finalList.add(folder[0]);
+                }
+            }
+        }
+        if (V) Log.v(TAG, "Returning from CompleteFolderList");
+        return finalList;
+    }
+
+    public boolean checkPrecondition() {
+        long id = EmailUtils.getAccountId(mMasId);
+        if (id == -1) {
+            return false;
+        }
+        return true;
+    }
+
+    public void onConnect() {
+        if (V) Log.v(TAG, "onConnect() registering email account content observer");
+        mContext.getContentResolver().registerContentObserver(
+                EmailUtils.EMAIL_ACCOUNT_URI, true, mObserver);
+    }
+
+    public void onDisconnect() {
+        if (V) Log.v(TAG, "onDisconnect() unregistering email account content observer");
+        mContext.getContentResolver().unregisterContentObserver(mObserver);
+    }
+
+    private void disconnect() {
+        if (V) Log.v(TAG, "disconnect() sending serversession close.");
+        mHandler.obtainMessage(MSG_SERVERSESSION_CLOSE, mMasId, -1).sendToTarget();
+    }
+
+    /*
+     * Email specific methods
+     */
+    @Override
+    protected BluetoothMsgListRsp msgListingSpecific(List<MsgListingConsts> msgList, String name,
+            BluetoothMasMessageListingRsp rsp, BluetoothMasAppParams appParams) {
+        BluetoothMsgListRsp bmlr = new BluetoothMsgListRsp();
+        String fullPath = (name == null || name.length() == 0) ? mCurrentPath :
+                CommonUtils.getFullPath(name, mContext, getCompleteFolderList(), mCurrentPath);
+        if (fullPath == null) {
+            // Child folder not present
+            rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            bmlr.rsp = rsp;
+            return bmlr;
+        }
+
+        if (V) {
+            Log.v(TAG, "appParams.FilterMessageType ::"+ appParams.FilterMessageType);
+            Log.v(TAG, "Condition result:"+ (appParams.FilterMessageType & 0x04));
+        }
+        String splitStrings[] = fullPath.split("/");
+        int len = splitStrings.length;
+        //Add folders and subfolders
+        if (len >= 3) {
+            if (CommonUtils.validateFilterPeriods(appParams) == 0) {
+                rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+                bmlr.rsp = rsp;
+                return bmlr;
+            }
+            if (appParams.FilterReadStatus > 0x02) {
+                rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+                bmlr.rsp = rsp;
+                return bmlr;
+            }
+
+            if (appParams.FilterPriority == 0 || appParams.FilterPriority == 0x02) {
+                if((appParams.FilterMessageType & 0x04) == 0) {
+                    String folderName;
+                    if (splitStrings.length < 3) {
+                        Log.e(TAG, "The folder path is invalid.");
+                        rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;;
+                        bmlr.rsp = rsp;
+                        return bmlr;
+                    }
+                    if (V) Log.v(TAG, "splitStrings[len-1] = " + splitStrings[len-1]);
+
+                    folderName = EmailUtils.getFolderName(splitStrings);
+                    int index = 0;
+                    long accountId = EmailUtils.getAccountId(mMasId);
+                    for (; index < SPECIAL_MAILBOX_MAP_NAME.length; index ++) {
+                        if (SPECIAL_MAILBOX_MAP_NAME[index].equalsIgnoreCase(folderName)) {
+                            List<String> folders = EmailUtils.getFoldersForType(mContext,
+                                    accountId, SPECIAL_MAILBOX_TYPES[index]);
+                            List<MsgListingConsts> list = null;
+                            for (String folder : folders) {
+                                list = getListEmailFromFolder(folder, rsp, appParams);
+                                if (list.size() > 0) {
+                                    msgList.addAll(list);
+                                }
+                            }
+                            break;
+                        }
+                    }
+                    //Add NON SPECIAL FOLDERS
+                    if (index >= SPECIAL_MAILBOX_MAP_NAME.length) {
+                        msgList = getListEmailFromFolder(folderName, rsp, appParams);
+                    }
+                    rsp.rsp = ResponseCodes.OBEX_HTTP_OK;
+                    bmlr.messageListingSize = rsp.msgListingSize;
+                    bmlr.rsp = rsp;
+                    bmlr.msgList = msgList;
+                    return bmlr;
+                }
+                else {
+                    if (V) Log.v(TAG, "Invalid Message Filter, returning empty list");
+                    rsp.rsp = ResponseCodes.OBEX_HTTP_OK;
+                    bmlr.rsp = rsp;
+                    return bmlr;
+                }
+            } else {
+                if (appParams.FilterPriority > 0x02) {
+                    rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+                    bmlr.rsp = rsp;
+                    return bmlr;
+                }
+            }
+        }
+        rsp.rsp = ResponseCodes.OBEX_HTTP_OK;
+        bmlr.rsp = rsp;
+        return bmlr;
+    }
+
+    @Override
+    protected BluetoothMasMessageRsp getMessageSpecific(long msgHandle,
+            BluetoothMasMessageRsp rsp, BluetoothMasAppParams bluetoothMasAppParams) {
+        /*
+         * Spec 5.6.4 says MSE shall reject request with value native
+         * for MMS and Email
+         */
+        if ((int)bluetoothMasAppParams.Charset == 0) {
+            rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            return rsp;
+        }
+
+        long emailMsgID = msgHandle - OFFSET_START;
+        String str = EmailUtils.bldEmailBmsg(emailMsgID, rsp, mContext, mRemoteDeviceName);
+        if (V) Log.v(TAG, "\n" + str + "\n");
+        if (str != null && (str.length() > 0)) {
+            final String FILENAME = "message" + getMasId();
+            FileOutputStream bos = null;
+            File file = new File(mContext.getFilesDir() + "/" + FILENAME);
+            file.delete();
+
+            try {
+                bos = mContext.openFileOutput(FILENAME, Context.MODE_PRIVATE);
+                bos.write(str.getBytes());
+                bos.flush();
+                bos.close();
+            } catch (FileNotFoundException e) {
+                Log.e(TAG, "Unable to write " + FILENAME, e);
+            } catch (IOException e) {
+                Log.e(TAG, "Unable to write " + FILENAME, e);
+            }
+
+            File fileR = new File(mContext.getFilesDir() + "/" + FILENAME);
+            if (fileR.exists() == true) {
+                rsp.file = fileR;
+                rsp.fractionDeliver = 1;
+            } else {
+                rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            }
+        }
+        return rsp;
+    }
+
+    /**
+     * Push a outgoing message from MAS Client to the network
+     *
+     * @return Response to push command
+     */
+    public BluetoothMasPushMsgRsp pushMsg(String name, File file,
+            BluetoothMasAppParams bluetoothMasAppParams) throws BadRequestException {
+        BluetoothMasPushMsgRsp rsp = new BluetoothMasPushMsgRsp();
+        rsp.response = ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+        rsp.msgHandle = null;
+        if((int)bluetoothMasAppParams.Charset == 0) {
+            rsp.response = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            return rsp;
+        }
+        if(!checkPath(false, name, false) ||
+                mCurrentPath == null ||
+                mCurrentPath.equals("telecom") ||
+                (mCurrentPath.equals("telecom/msg") && (name == null || name.length() == 0))) {
+            rsp.response = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            return rsp;
+        }
+        byte[] readBytes = null;
+        FileInputStream fis = null;
+        try {
+            fis = new FileInputStream(file);
+            if(file.length() > EMAIL_MAX_PUSHMSG_SIZE){
+                rsp.response = ResponseCodes.OBEX_HTTP_ENTITY_TOO_LARGE;
+                rsp.msgHandle = null;
+                Log.d(TAG,"Message body is larger than the max length allowed");
+                return rsp;
+            } else {
+                readBytes = new byte[(int) file.length()];
+                fis.read(readBytes);
+            }
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, e.getMessage());
+            return rsp;
+        } catch (IOException e) {
+            Log.e(TAG, e.getMessage());
+            return rsp;
+        } catch (SecurityException e) {
+            Log.e(TAG, e.getMessage());
+            return rsp;
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException ei) {
+                    Log.e(TAG, "Error while closing stream"+ ei.toString());
+                }
+            }
+        }
+
+        String readStr = "";
+        String type = "";
+        try {
+            readStr = new String(readBytes);
+            type = MapUtils.fetchType(readStr);
+        } catch (Exception e) {
+            throw new BadRequestException(e.getMessage());
+        }
+        if (type != null && type.equalsIgnoreCase("EMAIL")) {
+            rsp = pushMessageEmail(rsp, readStr, name);
+            return rsp;
+        }
+        rsp.response = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        return rsp;
+    }
+
+    /**
+     * Sets the message status (read/unread, delete)
+     *
+     * @return Obex response code
+     */
+    public int msgStatus(String msgHandle, BluetoothMasAppParams bluetoothMasAppParams) {
+        if ((bluetoothMasAppParams.StatusIndicator != 0)
+                && (bluetoothMasAppParams.StatusIndicator != 1)) {
+            return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
+        }
+        if ((bluetoothMasAppParams.StatusValue != 0)
+                && (bluetoothMasAppParams.StatusValue != 1)) {
+            return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
+        }
+        final long handle = Long.valueOf(msgHandle);
+        if (handle < OFFSET_START && handle > OFFSET_END) {
+            return ResponseCodes.OBEX_HTTP_NOT_FOUND;
+        }
+        return setMsgStatusEmail(handle, bluetoothMasAppParams);
+    }
+
+    /**
+     * Sets the message update
+     *
+     * @return Obex response code
+     */
+    public int msgUpdate() {
+        if (V) Log.v(TAG, "Message Update");
+        long accountId = EmailUtils.getAccountId(mMasId);
+        if (V) Log.v(TAG, " Account id for Inbox Update: " +accountId);
+
+        Intent emailIn = new Intent();
+
+        emailIn.setAction("com.android.email.intent.action.MAIL_SERVICE_WAKEUP");
+        emailIn.putExtra("com.android.email.intent.extra.ACCOUNT", accountId);
+        mContext.startService(emailIn);
+
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    /**
+     * Adds an Email to the Email ContentProvider
+     */
+    private String addToEmailFolder(String folder, String address, String text, String subject,
+            String OrigEmail, String OrigName) {
+        if (V) {
+            Log.v(TAG, "-------------");
+            Log.v(TAG, "address " + address);
+            Log.v(TAG, "TEXT " + text);
+        }
+        // TODO: need to insert a row in the body table and update the mailbox table
+        // with the no of messages unread
+        Cursor cr;
+        int folderId = -1;
+        long accountId = -1;
+        Time timeObj = new Time();
+        timeObj.setToNow();
+
+        Cursor cr1;
+        String whereClause1 = "UPPER(emailAddress) LIKE  '"+OrigEmail.toUpperCase().trim()+"'";
+        cr1 = mContext.getContentResolver().query(
+                Uri.parse("content://com.android.email.provider/account"),
+                null, whereClause1, null, null);
+        if (cr1 != null) {
+            if (cr1.getCount() > 0) {
+                cr1.moveToFirst();
+                accountId = cr1.getInt(cr1.getColumnIndex("_id"));
+            }
+            cr1.close();
+        }
+        if (accountId == -1) {
+            accountId = EmailUtils.getAccountId(mMasId);
+        }
+        if (DRAFT.equalsIgnoreCase(folder)) {
+            List<String> folders = EmailUtils.getFoldersForType(mContext, accountId,
+                    EmailUtils.TYPE_DRAFT);
+            if (V) Log.v(TAG, "DRAFT folders: " + folders.toString());
+            if (folders.size() == 0) {
+                // no draft folder
+                return INTERNAL_ERROR;
+            }
+            if (folders.contains(DRAFTS)) {
+                folder = DRAFTS;
+            } else {
+                folder = folders.get(0);
+            }
+        }
+
+        String whereClause = "UPPER(displayName) = '"+folder.toUpperCase().trim()+"'";
+        cr = mContext.getContentResolver().query(
+                Uri.parse("content://com.android.email.provider/mailbox"),
+                null, whereClause, null, null);
+        if (cr != null) {
+            if (cr.getCount() > 0) {
+                cr.moveToFirst();
+                folderId = cr.getInt(cr.getColumnIndex("_id"));
+            }
+            cr.close();
+        }
+        if (folderId == -1) {
+            return INTERNAL_ERROR;
+        }
+
+        if (V){
+            Log.v(TAG, "-------------");
+            Log.v(TAG, "To address " + address);
+            Log.v(TAG, "Text " + text);
+            Log.v(TAG, "Originator email address:: " + OrigEmail);
+            Log.v(TAG, "Originator email name:: " + OrigName);
+            Log.v(TAG, "Time Stamp:: " + timeObj.toMillis(false));
+            Log.v(TAG, "Account Key:: " + accountId);
+            Log.v(TAG, "Folder Id:: " + folderId);
+            Log.v(TAG, "Folder Name:: " + folder);
+            Log.v(TAG, "Subject" + subject);
+        }
+        ContentValues values = new ContentValues();
+        values.put("syncServerTimeStamp", 0);
+        values.put("syncServerId", "5:65");
+        values.put("displayName", OrigName.trim());
+        values.put("timeStamp", timeObj.toMillis(false));
+        values.put("subject", subject.trim());
+        values.put("flagLoaded", "1");
+        values.put("flagFavorite", "0");
+        values.put("flagAttachment", "0");
+        values.put("flags", "0");
+
+        values.put("accountKey", accountId);
+        values.put("fromList", OrigEmail.trim());
+
+        values.put("mailboxKey", folderId);
+        values.put("toList", address.trim());
+        values.put("flagRead", 0);
+
+        Uri uri = mContext.getContentResolver().insert(
+                Uri.parse("content://com.android.email.provider/message"), values);
+        if (V){
+            Log.v(TAG, " NEW URI " + (uri == null ? "null" : uri.toString()));
+        }
+
+        if (uri == null) {
+            return INTERNAL_ERROR;
+        }
+        String str = uri.toString();
+        String[] splitStr = str.split("/");
+        if (splitStr.length < 5) {
+            return INTERNAL_ERROR;
+        }
+        if (V){
+            Log.v(TAG, " NEW HANDLE " + splitStr[4]);
+        }
+
+        // TODO: need to insert into the body table
+        // --seems like body table gets updated automatically
+        ContentValues valuesBody = new ContentValues();
+        valuesBody.put("messageKey", splitStr[4]);
+        valuesBody.put("textContent", text);
+
+        mContext.getContentResolver().insert(
+                Uri.parse("content://com.android.email.provider/body"), valuesBody);
+        long virtualMsgId;
+        virtualMsgId = Long.valueOf(splitStr[4]) + OFFSET_START;
+        return Long.toString(virtualMsgId);
+    }
+
+    private List<MsgListingConsts> getListEmailFromFolder(String folderName,
+            BluetoothMasMessageListingRsp rsp, BluetoothMasAppParams appParams) {
+        List<MsgListingConsts> msgList = new ArrayList<MsgListingConsts>();
+        String urlEmail = "content://com.android.email.provider/message";
+        Uri uriEmail = Uri.parse(urlEmail);
+        ContentResolver crEmail = mContext.getContentResolver();
+
+        String whereClauseEmail  = EmailUtils.getConditionString(folderName, mContext, appParams,
+                mMasId);
+
+        if (V){
+                Log.v(TAG, "## whereClauseEmail ##:" + whereClauseEmail);
+        }
+        Cursor cursor = crEmail.query(uriEmail, null, whereClauseEmail, null, "timeStamp desc");
+
+        if (cursor != null && V){
+                Log.v(TAG, "move to First" + cursor.moveToFirst());
+        }
+        if (cursor != null && V){
+                Log.v(TAG, "move to Liststartoffset"
+                    + cursor.moveToPosition(appParams.ListStartOffset));
+        }
+        if (cursor != null && cursor.moveToFirst()) {
+            int idInd = cursor.getColumnIndex("_id");
+            int displayNameIndex = cursor.getColumnIndex("displayName");
+            int fromIndex = cursor.getColumnIndex("fromList");
+            int toIndex = cursor.getColumnIndex("toList");
+            int dateInd = cursor.getColumnIndex("timeStamp");
+            int readInd = cursor.getColumnIndex("flagRead");
+            int subjectInd = cursor.getColumnIndex("subject");
+            int replyToInd = cursor.getColumnIndex("replyToList");
+
+            do {
+                /*
+                 * Apply remaining filters
+                 */
+
+                if (V) Log.v(TAG, " msgListSize " + rsp.msgListingSize);
+                rsp.msgListingSize++;
+
+                String subject = cursor.getString(subjectInd);
+                String timestamp = cursor.getString(dateInd);
+                String senderName = cursor.getString(displayNameIndex);
+                String senderAddressing = cursor.getString(fromIndex);
+                String recipientName = cursor.getString(toIndex);
+                String recipientAddressing = cursor.getString(toIndex);
+                String msgId = cursor.getString(idInd);
+                String readStatus = cursor.getString(readInd);
+                String replyToStr = cursor.getString(replyToInd);
+
+                /*
+                 * Don't want the listing; just send the listing size after
+                 * applying all the filters.
+                 */
+
+                /*
+                 * TODO: Skip the first ListStartOffset record(s). Don't write
+                 * more than MaxListCount record(s).
+                 */
+
+                MsgListingConsts emailMsg = new MsgListingConsts();
+                emailMsg = EmailUtils.bldEmailMsgLstItem(mContext, folderName, appParams,
+                        subject, timestamp, senderName, senderAddressing,
+                        recipientName, recipientAddressing,
+                        msgId, readStatus, replyToStr, OFFSET_START);
+
+                // New Message?
+                if ((rsp.newMessage == 0) && (cursor.getInt(readInd) == 0)) {
+                    rsp.newMessage = 1;
+                }
+                msgList.add(emailMsg);
+            } while (cursor.moveToNext());
+        }
+        if (cursor != null) {
+            cursor.close();
+        }
+        return msgList;
+    }
+
+    private boolean isAllowedEmailFolderForPush(String folderName) {
+        if (DRAFT.equalsIgnoreCase(folderName) || OUTBOX.equalsIgnoreCase(folderName)) {
+            return true;
+        }
+        long id = EmailUtils.getAccountId(mMasId);
+        int type = EmailUtils.getTypeForFolder(mContext, id, folderName);
+        if (type == EmailUtils.TYPE_DRAFT || type == EmailUtils.TYPE_OUTBOX) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private BluetoothMasPushMsgRsp pushMessageEmail(BluetoothMasPushMsgRsp rsp,
+                String readStr, String name) throws BadRequestException {
+        if (V) Log.v(TAG, " Before fromBmessageemail method:: "+readStr);
+
+        BmessageConsts bMsg = MapUtils.fromBmessageEmail(mContext,readStr,mMasId);
+        String address = bMsg.getRecipientVcard_email();
+        String text = bMsg.getBody_msg();
+        String subject = bMsg.getSubject();
+        String originator = bMsg.getOriginatorVcard_email();
+        String origName = bMsg.getOriginatorVcard_name();
+
+        String fullPath = (name == null || name.length() == 0)
+                ? mCurrentPath : mCurrentPath + "/" + name;
+        String splitStrings[] = fullPath.split("/");
+        mMnsClient.addMceInitiatedOperation("+");
+        int tmp = splitStrings.length;
+        String folderName;
+        if (name != null) {
+            if (name.length() == 0) {
+                folderName = splitStrings[tmp - 1];
+            } else {
+                folderName = name;
+            }
+        } else {
+            folderName = splitStrings[tmp - 1];
+        }
+        if (!isAllowedEmailFolderForPush(folderName)) {
+            rsp.msgHandle = null;
+            rsp.response = ResponseCodes.OBEX_HTTP_FORBIDDEN;
+            return rsp;
+        }
+        String handle = addToEmailFolder(folderName, address, text, subject, originator, origName);
+        if (INTERNAL_ERROR == handle) { // == comparison valid here
+            rsp.msgHandle = null;
+            rsp.response = ResponseCodes.OBEX_HTTP_NOT_FOUND;
+            return rsp;
+        }
+        rsp.msgHandle = handle;
+        rsp.response = ResponseCodes.OBEX_HTTP_OK;
+
+        long accountId = EmailUtils.getAccountId(mMasId);
+        if (V) Log.v(TAG, " Account id before Mail service:: " + accountId);
+
+        Intent emailIn = new Intent();
+        emailIn.setAction("com.android.email.intent.action.MAIL_SERVICE_SEND_PENDING");
+        emailIn.putExtra("com.android.email.intent.extra.ACCOUNT", accountId);
+        mContext.startService(emailIn);
+        return rsp;
+    }
+
+    private int setMsgStatusEmail(long handle,
+            BluetoothMasAppParams bluetoothMasAppParams){
+        //Query the mailbox table to get the id values for Inbox and Trash folder
+        Uri uri1 = Uri.parse("content://com.android.email.provider/mailbox");
+        Cursor cr1 = mContext.getContentResolver().query(uri1, null,
+                "(UPPER(displayName) = 'INBOX' OR UPPER(displayName) LIKE '%TRASH%')", null, null);
+        int inboxFolderId = 0;
+        int deletedFolderId = 0;
+        int msgFolderId = 0;
+        String folderName;
+        if (cr1 != null && cr1.moveToFirst()) {
+            do {
+                folderName = cr1.getString(cr1.getColumnIndex("displayName"));
+                if(folderName.equalsIgnoreCase("INBOX")){
+                    inboxFolderId = cr1.getInt(cr1.getColumnIndex("_id"));
+                } else {
+                    deletedFolderId = cr1.getInt(cr1.getColumnIndex("_id"));
+                }
+            } while (cr1.moveToNext());
+        }
+        if (cr1 != null) {
+            cr1.close();
+        }
+
+        //Query the message table for the given message id
+        long emailMsgId = handle - 0;
+        emailMsgId = handle - OFFSET_START;
+        Uri uri2 = Uri.parse("content://com.android.email.provider/message/"+emailMsgId);
+        Cursor crEmail = mContext.getContentResolver().query(uri2, null, null, null, null);
+        if (crEmail != null && crEmail.moveToFirst()) {
+            if (bluetoothMasAppParams.StatusIndicator == 0) {
+                /* Read Status */
+                ContentValues values = new ContentValues();
+                values.put("flagRead", bluetoothMasAppParams.StatusValue);
+                mContext.getContentResolver().update(uri2, values, null, null);
+            } else {
+                if (bluetoothMasAppParams.StatusValue == 1) { //if the email is deleted
+                    msgFolderId = crEmail.getInt(crEmail.getColumnIndex("mailboxKey"));
+                    if(msgFolderId == deletedFolderId){
+                        // TODO: need to add notification for deleted email here
+                        mMnsClient.addMceInitiatedOperation(Long.toString(handle));
+                        mContext.getContentResolver().delete(
+                                Uri.parse("content://com.android.email.provider/message/"
+                                + emailMsgId), null, null);
+                    } else {
+                        ContentValues values = new ContentValues();
+                        values.put("mailboxKey", deletedFolderId);
+                        mContext.getContentResolver().update(uri2, values, null, null);
+                    }
+                } else { // if the email is undeleted
+                    // TODO: restore it to original folder
+                    ContentValues values = new ContentValues();
+                    values.put("mailboxKey", inboxFolderId);
+                    mContext.getContentResolver().update(uri2, values, null, null);
+                }
+            }
+        }
+        if (crEmail != null) {
+            crEmail.close();
+        }
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasAppIf.java b/src/org/codeaurora/bluetooth/map/BluetoothMasAppIf.java
new file mode 100644
index 0000000..90afe68
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasAppIf.java
@@ -0,0 +1,615 @@
+/*
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.PhoneLookup;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.codeaurora.bluetooth.map.MapUtils.MapUtils;
+import org.codeaurora.bluetooth.map.MapUtils.MsgListingConsts;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageListingRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMsgListRsp;
+import org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.VcardContent;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.obex.ResponseCodes;
+
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.DELETED;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.DRAFT;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.INBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.OUTBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.SENT;
+
+/**
+ * This class provides the application interface for MAS Server It interacts
+ * with the SMS repository using Sms Content Provider to service the MAS
+ * requests. It also initializes BluetoothMns thread which is used for MNS
+ * connection.
+ */
+
+public abstract class BluetoothMasAppIf implements IBluetoothMasApp {
+    public static final String TAG = "BluetoothMasAppIf";
+    public static final boolean D = BluetoothMasService.DEBUG;
+    public static final boolean V = BluetoothMasService.VERBOSE;
+
+    protected static final String INTERNAL_ERROR = "ERROR";
+
+    // IOP work around for BMW carkit
+    // The connection is dropped by the carkit When GetMessagesListing results empty list
+    // So, we ignore improper filtering request by messageType.
+    protected static final String BMW = "BMW";
+
+    protected Context mContext;
+    protected int mSupportedMessageTypes;
+    protected int mMasId;
+    protected String mRemoteDeviceName;
+
+    protected String mCurrentPath = null;
+    protected BluetoothMns mMnsClient;
+    protected Handler mHandler = null;
+
+    protected final long OFFSET_START;
+    protected final long OFFSET_END;
+
+    public BluetoothMasAppIf(Context context, Handler handler, int supportedMessageTypes,
+            BluetoothMns mnsClient, int masId, String remoteDeviceName) {
+        mContext = context;
+        mSupportedMessageTypes = supportedMessageTypes;
+        mMasId = masId;
+        mHandler = handler;
+        mMnsClient = mnsClient;
+        mRemoteDeviceName = remoteDeviceName;
+
+        OFFSET_START = HANDLE_OFFSET[masId];
+        OFFSET_END = HANDLE_OFFSET[masId + 1] - 1;
+
+        if (V) Log.v(TAG, "Constructor called");
+    }
+
+    /**
+     * This must be overridden
+     * @return folder list for corresponding MAS
+     */
+    protected abstract List<String> getCompleteFolderList();
+
+    /**
+     * Check the path to a given folder. If setPathFlag is set,
+     * set the path to the new value. Else, just check if the path
+     * exists and don't change the current path.
+     *
+     * @return true if the path exists, and could be accessed.
+     */
+    public boolean checkPath(boolean up, String name, boolean setPathFlag) {
+        if (V) Log.v(TAG, "setPath called");
+        if (V) {
+            Log.v(TAG, "mCurrentPath::"+mCurrentPath);
+            Log.v(TAG, "name::"+name);
+        }
+        if (up == false) {
+            if (name == null || name.length() == 0) {
+                mCurrentPath = (setPathFlag) ? null : mCurrentPath;
+                return true;
+            }
+        } else {
+            if (mCurrentPath == null) {
+                // Can't go above root
+                return false;
+            } else {
+                int LastIndex;
+                if (mCurrentPath.toUpperCase().contains("GMAIL")) {
+                    LastIndex = mCurrentPath.lastIndexOf('/');
+                    mCurrentPath = mCurrentPath.substring(0, LastIndex);
+                    LastIndex = mCurrentPath.lastIndexOf('/');
+                } else {
+                    LastIndex = mCurrentPath.lastIndexOf('/');
+                }
+                if (LastIndex < 0) {
+                    // Reaches root
+                    mCurrentPath = null;
+                } else {
+                    mCurrentPath = mCurrentPath.substring(0, LastIndex);
+                }
+            }
+            if (name == null || name.length() == 0) {
+                // Only going up by one
+                return true;
+            }
+        }
+
+        if (mCurrentPath == null) {
+            if (TELECOM.equals(name)) {
+                mCurrentPath = (setPathFlag) ? TELECOM : mCurrentPath;
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        String splitStrings[] = mCurrentPath.split("/");
+
+        boolean Result = false;
+        switch (splitStrings.length) {
+        case 0:
+            Result=false;
+            break;
+        case 1:
+            if (name.equals(MSG)) {
+                mCurrentPath += (setPathFlag) ? ("/" + name) : "";
+                Result = true;
+            }
+            break;
+        //Handle folders and subfolders
+        default:
+            List<String> completeFolderList = getCompleteFolderList();
+            for (String FolderName : completeFolderList) {
+                //added second condition for gmail sent folder
+                if (FolderName.equalsIgnoreCase(name)) {
+                    mCurrentPath += (setPathFlag) ? ("/" + name) : "";
+                    Result = true;
+                    break;
+                }
+            }
+            break;
+        }
+        return Result;
+    }
+
+    /**
+     * Set the path to a given folder.
+     *
+     * @return true if the path exists, and could be accessed.
+     */
+    public boolean setPath(boolean up, String name) {
+        return checkPath(up, name, true);
+    }
+
+    /**
+     * Get the number of messages in the folder
+     *
+     * @return number of messages; -1 if error
+     */
+    public int folderListingSize() {
+        if (V) Log.v(TAG, "folderListingSize called, current path " + mCurrentPath);
+
+        if (mCurrentPath == null) {
+            // at root, only telecom folder should be present
+            return 1;
+        }
+
+        if (mCurrentPath.equals(TELECOM)) {
+            // at root -> telecom, only msg folder should be present
+            return 1;
+        }
+        //Add folders and subfolders
+        List<String> completeFolderList = getCompleteFolderList();
+        return completeFolderList.size();
+
+    }
+
+    /**
+     * Get the XML listing of the folders at CurrenthPath
+     *
+     * @return XML listing of the folders
+     */
+    public String folderListing(BluetoothMasAppParams appParam) {
+        if (V) Log.v(TAG, "folderListing called, current path " + mCurrentPath);
+
+        List<String> list = new ArrayList<String>();
+
+        if (mCurrentPath == null) {
+            // at root, only telecom folder should be present
+            if (appParam.ListStartOffset == 0) {
+                list.add(TELECOM);
+            }
+        }else  if (mCurrentPath.equals(TELECOM)) {
+            // at root -> telecom, only msg folder should be present
+            if (appParam.ListStartOffset == 0) {
+                list.add(MSG);
+            }
+        } else  if (!(mCurrentPath.equals(TELECOM + "/" + MSG + "/" + INBOX) ||
+                mCurrentPath.equals(TELECOM + "/" + MSG + "/" + OUTBOX) ||
+                mCurrentPath.equals(TELECOM + "/" + MSG + "/" + DRAFT) ||
+                mCurrentPath.equals(TELECOM + "/" + MSG + "/" + DELETED) ||
+                mCurrentPath.equals(TELECOM + "/" + MSG + "/" + SENT))) {
+            //Add folders and subfolders NOT for SPECIAL FOLDERS
+            int offset = 0;
+            int added = 0;
+            List<String> completeFolderList = getCompleteFolderList();
+            for (String Folder : completeFolderList) {
+                offset++;
+                if ((offset > appParam.ListStartOffset)
+                        && (added < appParam.MaxListCount)) {
+                    list.add(Folder);
+                    if (V) Log.v(TAG, "folderListing AddFolder " + Folder);
+                    added++;
+                }
+            }
+        }
+
+        return MapUtils.folderListingXML(list);
+
+    }
+
+    static final int PHONELOOKUP_ID_COLUMN_INDEX = 0;
+    static final int PHONELOOKUP_LOOKUP_KEY_COLUMN_INDEX = 1;
+    static final int PHONELOOKUP_DISPLAY_NAME_COLUMN_INDEX = 2;
+
+    static final int EMAIL_DATA_COLUMN_INDEX = 0;
+
+    private List<VcardContent> mVcardList = new ArrayList<VcardContent>();;
+    protected VcardListContentObserver mVcardListObserver = new VcardListContentObserver();
+    protected VcardContent getVcardContent(String phoneAddress) {
+        VcardContent vCard = new VcardContent();
+        vCard.tel = phoneAddress;
+
+        Uri uriContacts = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
+                Uri.encode(phoneAddress));
+        Cursor cursorContacts = mContext.getContentResolver().query(
+                uriContacts,
+                new String[] { PhoneLookup._ID, PhoneLookup.LOOKUP_KEY,
+                        PhoneLookup.DISPLAY_NAME }, null, null, null);
+        if (cursorContacts == null) {
+            return vCard;
+        }
+        cursorContacts.moveToFirst();
+        if (cursorContacts.getCount() > 0) {
+            long contactId = cursorContacts
+                    .getLong(PHONELOOKUP_ID_COLUMN_INDEX);
+            String lookupKey = cursorContacts
+                    .getString(PHONELOOKUP_LOOKUP_KEY_COLUMN_INDEX);
+            vCard.name = cursorContacts
+                    .getString(PHONELOOKUP_DISPLAY_NAME_COLUMN_INDEX);
+
+            Uri lookUpUri = Contacts.getLookupUri(contactId, lookupKey);
+            String Id = lookUpUri.getLastPathSegment();
+
+            Cursor crEm = mContext.getContentResolver().query(Email.CONTENT_URI,
+                    new String[] { Email.DATA }, Email.CONTACT_ID + "=?",
+                    new String[] { Id }, null);
+            if (crEm != null) {
+                if (crEm.moveToFirst()) {
+                    vCard.email = "";
+                    if (crEm.moveToFirst()) {
+                        do {
+                            vCard.email += crEm.getString(EMAIL_DATA_COLUMN_INDEX) + ";";
+                        } while (crEm.moveToNext());
+                    }
+                }
+                crEm.close();
+            }
+        }
+        cursorContacts.close();
+        return vCard;
+    }
+    public final class VcardListContentObserver extends ContentObserver {
+        public VcardListContentObserver() {
+            super(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            Log.v(TAG, "Clear VcardList");
+            if(!mVcardList.isEmpty())
+              mVcardList.clear();
+        }
+   }
+
+
+    /**
+     * Check if the entry is not to be filtered out (allowed)
+     */
+    protected boolean allowEntry(String phoneAddress, String filterString) {
+        boolean found = false;
+        VcardContent foundEntry = null;
+        for (VcardContent elem : mVcardList) {
+            if (elem.tel.contains(phoneAddress)) {
+                found = true;
+                foundEntry = elem;
+            }
+        }
+        if (found == false) {
+            VcardContent vCard = getVcardContent(phoneAddress);
+            if (vCard != null) {
+                mVcardList.add(vCard);
+                found = true;
+                foundEntry = vCard;
+                if (V) {
+                    Log.v(TAG, " NEW VCARD ADDED " + vCard.tel + vCard.name
+                            + vCard.email);
+                }
+            } else {
+                if (V) Log.v(TAG, "VCARD NOT FOUND ERROR");
+            }
+        }
+
+        if (found == true) {
+            String regExp = filterString.replace("*", ".*[0-9A-Za-z].*");
+            if ((foundEntry.tel.matches(".*"+regExp+".*"))
+                    || (foundEntry.name.matches(".*"+regExp+".*"))
+                    || (foundEntry.email.matches(".*"+regExp+".*"))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the contact name for the given phone number
+     */
+    protected String getContactName(String phoneNumber) {
+        boolean found = false;
+        VcardContent foundEntry = null;
+        if(phoneNumber == null){
+            return null;
+        }
+        if(V) Log.v(TAG, "getContactName " + phoneNumber);
+        for (VcardContent elem : mVcardList) {
+            if (elem.tel == null){
+                continue;
+            }
+            if (elem.tel.contains(phoneNumber)) {
+                found = true;
+                foundEntry = elem;
+                break;
+            }
+        }
+        if (found == false) {
+            foundEntry = getVcardContent(phoneNumber);
+            if (foundEntry != null) {
+                mVcardList.add(foundEntry);
+                found = true;
+            }
+        }
+        if (found == true) {
+            return foundEntry.name;
+        }
+
+        return null;
+    }
+
+    protected class OwnerInfo {
+        public String Name;
+        public String Number;
+    }
+
+    protected OwnerInfo getOwnerInfo() {
+        OwnerInfo info = new OwnerInfo();
+        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        if (tm != null) {
+            String localPhoneNum = tm.getLine1Number();
+            String localPhoneName = tm.getLine1AlphaTag();
+
+            if (TextUtils.isEmpty(localPhoneNum)) {
+                localPhoneNum = "";
+            }
+            if (TextUtils.isEmpty(localPhoneName)) {
+                localPhoneName = mContext.getString(android.R.string.unknownName);
+            }
+            info.Name = localPhoneName;
+            info.Number = localPhoneNum;
+        }
+        return info;
+    }
+
+    private OwnerInfo ownerInfo = null;
+
+    /**
+     * Get the owners name
+     */
+    protected String getOwnerName() {
+        if (ownerInfo == null) {
+            ownerInfo = getOwnerInfo();
+        }
+        return ownerInfo.Name;
+    }
+
+    /**
+     * Get the owners phone number
+     */
+    protected String getOwnerNumber() {
+        if (ownerInfo == null) {
+            ownerInfo = getOwnerInfo();
+        }
+        return ownerInfo.Number;
+    }
+
+    /**
+     * Get the list of message in the given folder.
+     * It must be implemented for MessageType specific
+     * @param msgList
+     * @param name
+     * @param rsp
+     * @param appParams
+     * @return
+     */
+    protected abstract BluetoothMsgListRsp msgListingSpecific(List<MsgListingConsts> msgList,
+            String name, BluetoothMasMessageListingRsp rsp, BluetoothMasAppParams appParams);
+
+    /**
+     * Get the list of messages in the given folder
+     *
+     * @return Listing of messages in MAP-msg-listing format
+     */
+    public BluetoothMasMessageListingRsp msgListing(String name, BluetoothMasAppParams appParams) {
+        BluetoothMasMessageListingRsp rsp = new BluetoothMasMessageListingRsp();
+        boolean fileGenerated = false;
+        final String FILENAME = "msglist" + getMasId();
+
+        List<MsgListingConsts> msgList = new ArrayList<MsgListingConsts>();
+
+        if (appParams == null) {
+            return null;
+        }
+
+        BluetoothMsgListRsp specificRsp = msgListingSpecific(msgList, name, rsp, appParams);
+        rsp = specificRsp.rsp;
+
+        if (rsp.rsp != ResponseCodes.OBEX_HTTP_OK) {
+            return rsp;
+        }
+        msgList = specificRsp.msgList;
+        // Process the list based on MaxListCount and list offset
+        String str = null;
+        int numOfItems = msgList.size();
+        int msgDelta = numOfItems - appParams.ListStartOffset;
+        int startIdx = appParams.ListStartOffset;
+        int stopIdx = 0;
+        if (msgDelta <= 0) {
+            List<MsgListingConsts> msgSubList = new ArrayList<MsgListingConsts>();;
+            str = MapUtils.messageListingXML(msgSubList);
+        } else {
+            if (msgDelta <= appParams.MaxListCount) {
+                stopIdx = startIdx + msgDelta;
+            } else {
+                stopIdx = startIdx + appParams.MaxListCount;
+            }
+            List<MsgListingConsts> msgSubList = msgList.subList(startIdx,
+                    stopIdx);
+            str = MapUtils.messageListingXML(msgSubList);
+        }
+        if (str == null) {
+            rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            return rsp;
+        }
+
+        // String str = "this is a test for the data file";
+        try {
+            FileOutputStream bos = mContext.openFileOutput(FILENAME, Context.MODE_PRIVATE);
+            bos.write(str.getBytes());
+            bos.flush();
+            bos.close();
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        msgList.clear();
+
+        if (V) {
+            Log.v(TAG, "");
+            Log.v(TAG, " MESSAGE LISTING FULL ( total length)" + str.length());
+            Log.v(TAG, str);
+        }
+
+        try {
+            FileInputStream fis = new FileInputStream(mContext.getFilesDir()
+                    + "/" + FILENAME);
+            fis.close();
+            fileGenerated = true;
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        if (fileGenerated == true) {
+            File file = new File(mContext.getFilesDir() + "/" + FILENAME);
+            rsp.file = file;
+        }
+        rsp.rsp = ResponseCodes.OBEX_HTTP_OK;
+        return rsp;
+    }
+
+    protected abstract BluetoothMasMessageRsp getMessageSpecific(long msgHandle,
+            BluetoothMasMessageRsp rsp, BluetoothMasAppParams bluetoothMasAppParams);
+
+    /**
+     * Get the message for the given message handle
+     *
+     * @return BMSG object
+     */
+    public BluetoothMasMessageRsp msg(String msgHandle,
+            BluetoothMasAppParams bluetoothMasAppParams) {
+        BluetoothMasMessageRsp rsp = new BluetoothMasMessageRsp();
+        if (msgHandle == null || msgHandle.length() == 0) {
+            rsp.file = null;
+            rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            return rsp;
+        }
+        final long handle = Long.valueOf(msgHandle);
+        if (handle < OFFSET_START && handle > OFFSET_END) {
+            rsp.rsp = ResponseCodes.OBEX_HTTP_NOT_FOUND;
+            return rsp;
+        }
+
+        return getMessageSpecific(handle, rsp, bluetoothMasAppParams);
+    }
+
+    /**
+     * Enable/disable notification
+     *
+     * @return Obex response code
+     */
+    public int notification(BluetoothDevice remoteDevice,
+            BluetoothMasAppParams bluetoothMasAppParams) {
+        if (bluetoothMasAppParams.Notification == 1) {
+            startMnsSession(remoteDevice);
+            return ResponseCodes.OBEX_HTTP_OK;
+        } else if (bluetoothMasAppParams.Notification == 0) {
+            stopMnsSession(remoteDevice);
+            return ResponseCodes.OBEX_HTTP_OK;
+        }
+
+        return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
+    }
+
+    /**
+     * Start an MNS obex client session and push notification whenever available
+     */
+    public abstract void startMnsSession(BluetoothDevice remoteDevice);
+
+    /**
+     * Stop pushing notifications and disconnect MNS obex session
+     */
+    public abstract void stopMnsSession(BluetoothDevice remoteDevice);
+
+    public int getMasId() {
+        return mMasId;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasAppParams.java b/src/org/codeaurora/bluetooth/map/BluetoothMasAppParams.java
new file mode 100644
index 0000000..4514d4b
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasAppParams.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+public final class BluetoothMasAppParams {
+
+    public int MaxListCount;
+    public int ListStartOffset;
+    public short SubjectLength;
+    public long ParameterMask;
+    public byte FilterMessageType;
+    public byte FilterReadStatus;
+    public byte FilterPriority;
+    public String FilterPeriodBegin;
+    public String FilterPeriodEnd;
+    public String FilterRecipient;
+    public String FilterOriginator;
+    public byte FractionRequest;
+    public byte Charset;
+    public byte Attachment;
+    public byte Retry;
+    public byte Transparent;
+    public byte StatusIndicator;
+    public byte StatusValue;
+    public byte Notification;
+
+};
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasAppSmsMms.java b/src/org/codeaurora/bluetooth/map/BluetoothMasAppSmsMms.java
new file mode 100644
index 0000000..69fe818
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasAppSmsMms.java
@@ -0,0 +1,2569 @@
+/*
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.codeaurora.bluetooth.map;
+
+import android.app.ActivityManager;
+import android.bluetooth.BluetoothDevice;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Handler;
+import android.telephony.SmsManager;
+import android.telephony.SmsMessage;
+import android.telephony.TelephonyManager;
+import android.text.format.Time;
+import android.util.Log;
+import android.util.TimeFormatException;
+
+import org.codeaurora.bluetooth.map.MapUtils.BmessageConsts;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils;
+import org.codeaurora.bluetooth.map.MapUtils.MapUtils;
+import org.codeaurora.bluetooth.map.MapUtils.MsgListingConsts;
+import org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils;
+import org.codeaurora.bluetooth.map.MapUtils.SortMsgListByDate;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageListingRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasPushMsgRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMsgListRsp;
+import org.codeaurora.bluetooth.map.MapUtils.MapUtils.BadRequestException;
+import org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.VcardContent;
+import android.provider.ContactsContract.PhoneLookup;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Random;
+
+import javax.obex.ResponseCodes;
+
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.DELETED;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.DRAFT;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.DRAFTS;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.INBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.OUTBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.QUEUED;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.SENT;
+
+public class BluetoothMasAppSmsMms extends BluetoothMasAppIf {
+    public final String TAG = "BluetoothMasAppSmsMms";
+
+    private final long SMS_OFFSET_START;
+    private final long MMS_OFFSET_START;
+
+    private static final String SMS_GSM = "SMS_GSM";
+    private static final String SMS_CDMA = "SMS_CDMA";
+    private static final String MMS = "MMS";
+    // OMA-TS-MMS-ENC defined many types in X-Mms-Message-Type.
+    // Only m-send-req (128) m-retrieve-conf (132), m-notification-ind (130)
+    // are interested by user
+    private static final String INTERESTED_MESSAGE_TYPE_CLAUSE =
+                "(m_type = 128 OR m_type = 132 OR m_type = 130)";
+
+    public BluetoothMasAppSmsMms(Context context, Handler handler, BluetoothMns mnsClient,
+            int masId, String remoteDeviceName) {
+        super(context, handler, MESSAGE_TYPE_SMS_MMS, mnsClient, masId, remoteDeviceName);
+        SMS_OFFSET_START = OFFSET_START;
+        MMS_OFFSET_START = OFFSET_START + ((OFFSET_END - OFFSET_START) / 2);
+
+        // Clear out deleted items from database
+        cleanUp();
+
+        if (V) Log.v(TAG, "BluetoothMasAppSmsMms Constructor called");
+    }
+
+    /**
+     * Start an MNS obex client session and push notification whenever available
+     */
+    public void startMnsSession(BluetoothDevice remoteDevice) {
+        if (V) Log.v(TAG, "Start MNS Client");
+        mMnsClient.getHandler()
+                .obtainMessage(BluetoothMns.MNS_CONNECT, 0, -1, remoteDevice)
+                .sendToTarget();
+    }
+
+    /**
+     * Stop pushing notifications and disconnect MNS obex session
+     */
+    public void stopMnsSession(BluetoothDevice remoteDevice) {
+        if (V) Log.v(TAG, "Stop MNS Client");
+        mMnsClient.getHandler()
+                .obtainMessage(BluetoothMns.MNS_DISCONNECT, 0, -1,
+                remoteDevice).sendToTarget();
+    }
+
+    @Override
+    protected List<String> getCompleteFolderList() {
+        return SmsMmsUtils.FORLDER_LIST_SMS_MMS;
+    }
+
+    private void cleanUp() {
+        // Remove the deleted item entries
+        mContext.getContentResolver().delete(Uri.parse("content://mms-sms/conversations/"),
+                "thread_id = " + DELETED_THREAD_ID, null);
+        if(V) Log.v(TAG, "Unregister PhoneLookUP observer");
+        mContext.getContentResolver().unregisterContentObserver(mVcardListObserver);
+    }
+
+    public boolean checkPrecondition() {
+        // TODO: Add any precondition check routine for this MAS instance
+        return true;
+    }
+
+    public void onConnect() {
+        // TODO: Add any routine to be run when OBEX connection established
+        if(V) Log.v(TAG, "Register PhoneLookUP observer");
+        mContext.getContentResolver().registerContentObserver(PhoneLookup.CONTENT_FILTER_URI, true,
+                mVcardListObserver);
+    }
+
+    public void onDisconnect() {
+        cleanUp();
+    }
+
+    @Override
+    protected BluetoothMsgListRsp msgListingSpecific(List<MsgListingConsts> msgList, String name,
+            BluetoothMasMessageListingRsp rsp, BluetoothMasAppParams appParams) {
+        BluetoothMsgListRsp bmlr = new BluetoothMsgListRsp();
+        boolean validFilter = false;
+        String fullPath = (name == null || name.length() == 0) ? mCurrentPath :
+                CommonUtils.getFullPath(name, mContext, getCompleteFolderList(), mCurrentPath);
+        if (fullPath == null) {
+            // Child folder not present
+            rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            bmlr.rsp = rsp;
+            return bmlr;
+        }
+
+        if (V) {
+            Log.v(TAG, "appParams.FilterMessageType ::"+ appParams.FilterMessageType);
+            Log.v(TAG, "Condition result::"+ (appParams.FilterMessageType & 0x0B));
+        }
+        String splitStrings[] = fullPath.split("/");
+        if (splitStrings.length == 3) {
+            String folderName = splitStrings[2];
+            if (V) Log.v(TAG, "folderName: " + folderName);
+            if (CommonUtils.validateFilterPeriods(appParams) == 0) {
+                rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+                bmlr.rsp = rsp;
+                return bmlr;
+            }
+            if (appParams.FilterReadStatus > 0x02) {
+                rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+                bmlr.rsp = rsp;
+                return bmlr;
+            }
+
+            // TODO: Filter priority?
+            /*
+             * There is no support for FilterPriority in SMS/MMS. So, we will
+             * assume Filter Priority is always non-high which makes sense for
+             * SMS/MMS.We check the content provider only if the Filter Priority
+             * is "unfiltered" or "non-high". Else, simply return an empty
+             * string. If the Filter priority is greater than 2, return a bad
+             * request.
+             */
+
+            if (appParams.FilterPriority == 0 || appParams.FilterPriority == 0x02) {
+                final int phoneType = TelephonyManager.getDefault().getPhoneType();
+                if ((appParams.FilterMessageType & 0x03) == 0 ||
+                        ((appParams.FilterMessageType & 0x01) == 0 &&
+                                phoneType == TelephonyManager.PHONE_TYPE_GSM) ||
+                        ((appParams.FilterMessageType & 0x02) == 0 &&
+                                phoneType == TelephonyManager.PHONE_TYPE_CDMA)) {
+                    validFilter = true;
+                    BluetoothMsgListRsp bmlrSms = msgListSms(msgList, folderName,
+                            rsp, appParams);
+                    bmlr.msgList = bmlrSms.msgList;
+                    bmlr.rsp = bmlrSms.rsp;
+                }
+                // Now that all of the SMS messages have been listed. Look for
+                // any
+                // MMS messages and provide them
+                if((appParams.FilterMessageType & 0x08) == 0) {
+                    Log.v(TAG, "About to retrieve msgListMms ");
+                    // MMS draft folder is called //mms/drafts not //mms/draft like
+                    // SMS
+                    validFilter = true;
+                    if (DRAFT.equalsIgnoreCase(folderName)) {
+                        folderName = DRAFTS;
+                    }
+                    BluetoothMsgListRsp bmlrMms = msgListMms(msgList, folderName, rsp, appParams);
+                    bmlr.msgList = bmlrMms.msgList;
+                    bmlr.rsp = bmlrMms.rsp;
+                }
+                if (validFilter != true) {
+                    if (V) Log.v(TAG, "Invalid message filter, returning empty-list");
+                    rsp.rsp = ResponseCodes.OBEX_HTTP_OK;
+                    bmlr.rsp = rsp;
+                    return bmlr;
+                }
+            } else {
+                if (appParams.FilterPriority > 0x02) {
+                    rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+                    bmlr.rsp = rsp;
+                    return bmlr;
+                }
+            }
+        }
+
+        // Now that the message list exists, we can sort the list by date
+        Collections.sort(bmlr.msgList, new SortMsgListByDate());
+        rsp.rsp = ResponseCodes.OBEX_HTTP_OK;
+        bmlr.rsp = rsp;
+        return bmlr;
+    }
+
+    @Override
+    protected BluetoothMasMessageRsp getMessageSpecific(long msgHandle, BluetoothMasMessageRsp rsp,
+            BluetoothMasAppParams bluetoothMasAppParams) {
+        final long handle = Long.valueOf(msgHandle);
+
+        if (handle >= MMS_OFFSET_START) { // MMS
+            /*
+             * Spec 5.6.4 says MSE shall reject request with value native
+             * for MMS and Email
+             */
+            if ((int)bluetoothMasAppParams.Charset == 0) {
+                rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+                return rsp;
+            }
+            return getMessageMms(msgHandle, rsp);
+        } else { // SMS
+            return getMessageSms(msgHandle, mContext, rsp, bluetoothMasAppParams);
+        }
+    }
+
+    /**
+     * Push a outgoing message from MAS Client to the network
+     *
+     * @return Response to push command
+     */
+    public BluetoothMasPushMsgRsp pushMsg(String name, File file,
+            BluetoothMasAppParams bluetoothMasAppParams) throws BadRequestException {
+        BluetoothMasPushMsgRsp rsp = new BluetoothMasPushMsgRsp();
+        rsp.response = ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+        rsp.msgHandle = null;
+
+        if(!checkPath(false, name, false) ||
+                mCurrentPath == null ||
+                mCurrentPath.equals("telecom") ||
+                (mCurrentPath.equals("telecom/msg") && (name == null || name.length() == 0))) {
+            rsp.response = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            return rsp;
+        }
+
+        ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
+        am.getMemoryInfo(outInfo);
+        final long allowedMem = outInfo.availMem - outInfo.threshold;
+
+        byte[] readBytes = null;
+        FileInputStream fis = null;
+        try {
+            fis = new FileInputStream(file);
+            if(file.length() > allowedMem){
+                rsp.response = ResponseCodes.OBEX_HTTP_ENTITY_TOO_LARGE;
+                rsp.msgHandle = null;
+                Log.d(TAG,"Message body is larger than the max length allowed");
+                return rsp;
+            } else {
+                readBytes = new byte[(int) file.length()];
+                fis.read(readBytes);
+            }
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, e.getMessage());
+            return rsp;
+        } catch (IOException e) {
+            Log.e(TAG, e.getMessage());
+            return rsp;
+        } catch (SecurityException e) {
+            Log.e(TAG, e.getMessage());
+            return rsp;
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    Log.e(TAG, "Error while closing stream"+ e.toString());
+                }
+            }
+        }
+
+        String readStr = "";
+        String type = "";
+        try {
+            readStr = new String(readBytes);
+            type = MapUtils.fetchType(readStr);
+        } catch (Exception e) {
+            throw new BadRequestException(e.getMessage());
+        }
+        if (type == null) {
+            rsp.response = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            return rsp;
+        }
+        if (SMS_GSM.equalsIgnoreCase(type) || SMS_CDMA.equalsIgnoreCase(type)) {
+            return pushMessageSms(rsp, readStr, name, bluetoothMasAppParams);
+        } else if (MMS.equals(type) && ((int)bluetoothMasAppParams.Charset != 0)) {
+            // If the message to be pushed is an MMS message, extract any text,
+            // discard
+            // any attachments and convert the message to an SMS
+            if (type.equalsIgnoreCase("MMS")) {
+                /*
+                 * The pair of calls below is used to send the MMS message out to
+                 * the network.You need to first move the message to the drafts
+                 * folder and then move the message from drafts to the outbox
+                 * folder. This action causes the message to also be added to the
+                 * pending_msgs table in the database. The transaction service will
+                 * then send the message out to the network the next time it is
+                 * scheduled to run
+                 */
+                rsp = pushMessageMms(rsp, readStr, name);
+                return rsp;
+            }
+        }
+        rsp.response = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        return rsp;
+    }
+
+    /**
+     * Sets the message status (read/unread, delete)
+     *
+     * @return Obex response code
+     */
+    public int msgStatus(String msgHandle, BluetoothMasAppParams bluetoothMasAppParams) {
+        if ((bluetoothMasAppParams.StatusIndicator != 0)
+                && (bluetoothMasAppParams.StatusIndicator != 1)) {
+            return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
+        }
+        if ((bluetoothMasAppParams.StatusValue != 0)
+                && (bluetoothMasAppParams.StatusValue != 1)) {
+            return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
+        }
+        final long handle = Long.valueOf(msgHandle);
+        if (handle < OFFSET_START && handle > OFFSET_END) {
+            return ResponseCodes.OBEX_HTTP_NOT_FOUND;
+        }
+        if (handle >= MMS_OFFSET_START) { // MMS
+            return setMsgStatusMms(handle, bluetoothMasAppParams);
+        } else { // SMS
+            return setMsgStatusSms(handle, bluetoothMasAppParams);
+        }
+    }
+
+    /**
+     * Sets the message update
+     *
+     * @return Obex response code
+     */
+    public int msgUpdate() {
+        if (V) Log.v(TAG, "Message Update");
+        // UpdateInbox for MMS/SMS is not supported
+        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
+    }
+
+    private boolean isOutgoingSMSMessage(int type) {
+        if (type == 1) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Get the folder name (MAP representation) based on the folder type value
+     * in SMS database
+     */
+    private String getMAPFolder(String type, String threadId) {
+        String folder = null;
+        if (type == null || threadId == null){
+            if (V) Log.v(TAG, "getMapFolder cannot parse folder type");
+            return null;
+        }
+
+        if (Integer.valueOf(threadId) == DELETED_THREAD_ID) {
+            folder = DELETED;
+        } else {
+            switch (Integer.valueOf(type)) {
+            case 1:
+                folder = INBOX;
+                break;
+            case 2:
+                folder = SENT;
+                break;
+            case 3:
+                folder = DRAFT;
+                break;
+            case 4:
+            case 5:
+            case 6:
+                folder = OUTBOX;
+                break;
+            default:
+                break;
+            }
+        }
+        return folder;
+    }
+
+    /**
+     * Get the folder name (MAP representation) based on the message Handle
+     */
+    private String getContainingFolder(long msgHandle) {
+        String folder = null;
+        Cursor cr = mContext.getContentResolver().query(
+                Uri.parse("content://sms/" + msgHandle),
+                new String[] { "_id", "type", "thread_id"}, null, null, null);
+        if (cr != null) {
+            if (cr.getCount() > 0) {
+                cr.moveToFirst();
+                folder = getMAPFolder(cr.getString(cr.getColumnIndex("type")),
+                        cr.getString(cr.getColumnIndex("thread_id")));
+            }
+            cr.close();
+        }
+        return folder;
+    }
+
+    /**
+     * Get the SMS Deliver PDU for the given SMS
+     */
+    private String getSMSDeliverPdu(String smsBody, String dateTime, String address) {
+        Time time = new Time();
+        time.set(Long.valueOf(dateTime));
+
+        String timeStr = time.format3339(false);
+
+        // Extract the YY, MM, DD, HH, MM, SS from time
+        String tempTimeStr = timeStr.substring(2,4) + timeStr.substring(5, 7)
+                + timeStr.substring(8, 10) + timeStr.substring(11, 13) +
+                timeStr.substring(14, 16) + timeStr.substring(17, 19);
+
+        /* Calculate the time zone offset
+         * An offset of 1 indicates 15 min difference between local
+         * time and GMT. MSB of 1 in offset indicates it is negative
+         */
+        String tZoneStr = timeStr.substring(timeStr.length()- 6);
+        int tempInt = Integer.valueOf(tZoneStr.substring(tZoneStr.length()-2));
+        int tZone15offset = tempInt / 15;
+
+        tZone15offset += (Integer.valueOf(tZoneStr.substring(tZoneStr.length()-5,
+                tZoneStr.length()-3)) * 4);
+        if (timeStr.charAt(timeStr.length()-6) == '-'){
+            tZone15offset = tZone15offset | 0x80;
+        }
+
+        String tZone15OffsetHexStr = "";
+
+        // Add 0 as prefix for single digit offset
+        if(((int) tZone15offset & 0xff) < 0x10){
+            tZone15OffsetHexStr += "0";
+        }
+        tZone15OffsetHexStr += Integer.toHexString(tZone15offset);
+
+        tempTimeStr += tZone15OffsetHexStr;
+
+        // Swap the nibble
+        String encodedTimeStr = "";
+        for (int i=0; i<tempTimeStr.length(); i=i+2){
+            encodedTimeStr += tempTimeStr.substring(i+1, i+2);
+            encodedTimeStr += tempTimeStr.substring(i, i+1);
+        }
+
+        byte[] byteAddress = address.getBytes();
+
+        // Let the service center number be 0000000000
+        String smsPdu = "0681000000000004";
+
+        // Extract only digits out of the phone address
+        StringBuffer strbufAddress = new StringBuffer(address.length() + 1);
+        for (int i=0; i<address.length(); i++){
+            if (V){
+                Log.v(TAG, " VAL " + address.substring(i, i+1));
+            }
+            if (byteAddress[i] >= 48 && byteAddress[i] <= 57){
+                strbufAddress.append(Integer.parseInt(address.substring(i, i+1)));
+            }
+        }
+
+        int addressLength = strbufAddress.length();
+
+        String addressLengthStr = "";
+
+        if(((int) addressLength & 0xff) < 0x10)
+            addressLengthStr += "0";
+        addressLengthStr += Integer.toHexString(addressLength);
+
+        smsPdu = smsPdu + addressLengthStr;
+        smsPdu = smsPdu + "81";
+
+        String strAddress = new String(strbufAddress);
+
+        // Use getSubmitPdu only to obtain the encoded msg and encoded address
+        byte[] msg = SmsMessage.getSubmitPdu(null, strAddress, smsBody, false).encodedMessage;
+
+        int addLength = Integer.valueOf(msg[2]);
+        if (addLength %2 != 0){
+            addLength++;
+        }
+        addLength = addLength / 2;
+
+        // Extract the message from the SubmitPdu
+        int msgOffset = 7 + addLength;
+        int msgLength = msg.length - msgOffset;
+
+        StringBuffer strbufMessage = new StringBuffer(msgLength * 2);
+
+        // Convert from byte to Hex String
+        for (int i=msgOffset; i<msgLength + msgOffset; i++) {
+            if (((int) msg[i] & 0xff) < 0x10) {
+                strbufMessage.append("0");
+            }
+            strbufMessage.append((Long.toString((int) msg[i] & 0xff, 16)));
+        }
+
+        int encodedAddressLength = strAddress.length() / 2;
+        if (strAddress.length() % 2 != 0) {
+            encodedAddressLength++;
+        }
+
+        StringBuffer strbufAddress1 = new StringBuffer(msgLength * 2);
+
+        // Convert from byte to Hex String
+        for(int i=4; i<encodedAddressLength + 4; i++)
+        {
+            if(((int) msg[i] & 0xff) < 0x10)
+                strbufAddress1.append("0");
+            strbufAddress1.append((Long.toString((int) msg[i] & 0xff, 16)));
+        }
+
+        smsPdu += strbufAddress1;
+        smsPdu += "0000";
+        smsPdu += encodedTimeStr;
+
+        int smsBodyLength = smsBody.length();
+        String smsMessageTextLengthStr = "";
+
+        if(((int) smsBodyLength & 0xff) < 0x10){
+            smsMessageTextLengthStr += "0";
+        }
+        smsMessageTextLengthStr += Integer.toHexString(smsBodyLength);
+
+        smsPdu += smsMessageTextLengthStr;
+        smsPdu += strbufMessage;
+        smsPdu = smsPdu.toUpperCase();
+        return smsPdu;
+    }
+
+    /**
+     * Adds a SMS to the Sms ContentProvider
+     */
+    private String addToSmsFolder(String folder, String address, String text) {
+        ContentValues values = new ContentValues();
+        // thread_id is handled by SmsProvider
+        values.put("body", text);
+        values.put("address", address);
+        values.put("read", 0);
+        values.put("seen", 0);
+        /*
+         * status none -1 complete 0 pending 64 failed 128
+         */
+        values.put("status", -1);
+        /*
+         * outbox 4 queued 6
+         */
+        values.put("locked", 0);
+        values.put("error_code", 0);
+        Uri uri = mContext.getContentResolver().insert(
+                Uri.parse("content://sms/" + folder), values);
+        if (V){
+            Log.v(TAG, " NEW URI " + ((uri == null) ? "null" : uri.toString()));
+        }
+
+        if (uri == null) {
+            return INTERNAL_ERROR;
+        }
+        String str = uri.toString();
+        String[] splitStr = str.split("/");
+        if (splitStr.length < 4) {
+            return INTERNAL_ERROR;
+        }
+        if (V){
+            Log.v(TAG, " NEW HANDLE " + splitStr[3]);
+        }
+        return splitStr[3];
+    }
+
+    private void updateMMSThreadId(long handle, int threadId) {
+        ContentValues values = new ContentValues();
+        values.put("thread_id", threadId);
+        mContext.getContentResolver().update(Uri.parse("content://mms/" + handle),
+                values, null, null);
+    }
+
+    private void deleteMMS(long handle) {
+        Cursor cr = mContext.getContentResolver().query(Uri.parse("content://mms/" + handle),
+                null, null, null, null);
+        if (cr != null && cr.moveToFirst()){
+            int threadId = cr.getInt(cr.getColumnIndex(("thread_id")));
+            if (threadId != DELETED_THREAD_ID){
+                // Move to deleted folder
+                updateMMSThreadId(handle, Integer.valueOf(DELETED_THREAD_ID));
+            } else {
+                // Delete the message permanently
+                long msgId = handle + MMS_OFFSET_START;
+                mMnsClient.addMceInitiatedOperation(Long.toString(msgId));
+                mContext.getContentResolver().delete(Uri.parse("content://mms/" + handle),
+                        null, null);
+            }
+        }
+        if (cr != null) {
+            cr.close();
+        }
+    }
+
+    private void unDeleteMMS(long msgHandle) {
+        Cursor cr = mContext.getContentResolver().query(Uri.parse("content://mms/" + msgHandle),
+                null, null, null, null );
+        if (cr == null) {
+            if (V){
+                Log.v(TAG, "unable to query content://mms/" + msgHandle);
+            }
+            return;
+        }
+        if (cr.moveToFirst()){
+            // Make sure that the message is in delete folder
+            String currentThreadId = cr.getString(cr.getColumnIndex("thread_id"));
+            if (currentThreadId != null && Integer.valueOf(currentThreadId) != -1){
+                if (V){
+                    Log.v(TAG, " Not in delete folder");
+                }
+                return;
+            }
+
+            // Fetch the address of the deleted message
+            String address = getMmsMsgAddress(msgHandle);
+
+            // Search the database for the given message ID
+            Cursor crThreadId = mContext.getContentResolver().query(Uri.parse("content://mms/"),
+                    null,"_id = " + msgHandle + " AND thread_id != -1", null, null);
+            if (crThreadId != null && crThreadId.moveToFirst()) {
+                // A thread for the given message ID exists in the database
+                String threadIdStr = crThreadId.getString(crThreadId.getColumnIndex("thread_id"));
+                if (V){
+                    Log.v(TAG, " THREAD ID " + threadIdStr);
+                }
+                updateMMSThreadId(msgHandle, Integer.valueOf(threadIdStr));
+            } else {
+                /* No thread for the given address
+                 * Create a fake message to obtain the thread, use that thread_id
+                 * and then delete the fake message
+                 */
+                ContentValues tempValue = new ContentValues();
+                tempValue.put("address", address);
+                tempValue.put("type", "20");
+                Uri tempUri = mContext.getContentResolver().insert( Uri.parse("content://sms/"),
+                        tempValue);
+
+                if (tempUri != null) {
+                    Cursor tempCr = mContext.getContentResolver().query(tempUri, null, null, null,
+                            null);
+                    if (tempCr != null) {
+                        tempCr.moveToFirst();
+                        String newThreadIdStr = tempCr.getString(
+                                tempCr.getColumnIndex("thread_id"));
+                        tempCr.close();
+                        updateMMSThreadId(msgHandle, Integer.valueOf(newThreadIdStr));
+                    }
+                    mContext.getContentResolver().delete(tempUri, null, null);
+                } else {
+                    Log.e(TAG, "Error in undelete");
+                }
+            }
+            if (crThreadId != null) {
+                crThreadId.close();
+            }
+        } else {
+            if (V) {
+                Log.v(TAG, "msgHandle not found");
+            }
+        }
+        cr.close();
+    }
+
+    private void updateSMSThreadId(long msgHandle, int threadId) {
+        ContentValues values = new ContentValues();
+        values.put("thread_id", threadId);
+        mContext.getContentResolver().update(Uri.parse("content://sms/" + msgHandle),
+                values, null, null);
+    }
+
+    private void deleteSMS(long handle) {
+        Cursor cr = mContext.getContentResolver().query(Uri.parse("content://sms/" + handle),
+                null, null, null, null);
+        if (cr != null && cr.moveToFirst()){
+            int threadId = cr.getInt(cr.getColumnIndex(("thread_id")));
+            if (threadId != DELETED_THREAD_ID){
+                // Move to deleted folder
+                updateSMSThreadId(handle, Integer.valueOf(DELETED_THREAD_ID));
+            } else {
+                // Delete the message permanently
+                long msgHandle = handle + SMS_OFFSET_START;
+                mMnsClient.addMceInitiatedOperation(Long.toString(msgHandle));
+                mContext.getContentResolver().delete(Uri.parse("content://sms/" + handle),
+                        null, null);
+            }
+        }
+        if (cr != null) {
+            cr.close();
+        }
+    }
+
+    private void unDeleteSMS(long msgHandle){
+        Cursor cr = mContext.getContentResolver().query(Uri.parse("content://sms/" + msgHandle),
+                null, null, null, null );
+        if (cr == null) {
+            return;
+        }
+
+        if (cr.moveToFirst()){
+            // Make sure that the message is in delete folder
+            String currentThreadId = cr.getString(cr.getColumnIndex("thread_id"));
+            if (currentThreadId != null && Integer.valueOf(currentThreadId) != -1){
+                if (V){
+                    Log.v(TAG, " Not in delete folder");
+                }
+                return;
+            }
+
+            // Fetch the address of the deleted message
+            String address = cr.getString(cr.getColumnIndex("address"));
+
+            // Search the database for the given address
+            Cursor crThreadId = mContext.getContentResolver().query(Uri.parse("content://sms/"),
+                    null, "address = " + address + " AND thread_id != -1", null, null);
+            if (crThreadId != null && crThreadId.moveToFirst()) {
+                // A thread for the given address exists in the database
+                String threadIdStr = crThreadId.getString(crThreadId.getColumnIndex("thread_id"));
+                if (V){
+                    Log.v(TAG, " THREAD ID " + threadIdStr);
+                }
+                updateSMSThreadId(msgHandle, Integer.valueOf(threadIdStr));
+            } else {
+                /* No thread for the given address
+                 * Create a fake message to obtain the thread, use that thread_id
+                 * and then delete the fake message
+                 */
+                ContentValues tempValue = new ContentValues();
+                tempValue.put("address", address);
+                tempValue.put("type", "20");
+                Uri tempUri = mContext.getContentResolver().insert( Uri.parse("content://sms/"),
+                        tempValue);
+
+                if (tempUri != null) {
+                    Cursor tempCr = mContext.getContentResolver().query(tempUri, null, null, null,
+                            null);
+                    if (tempCr != null) {
+                        tempCr.moveToFirst();
+                        String newThreadIdStr = tempCr.getString(
+                                tempCr.getColumnIndex("thread_id"));
+                        tempCr.close();
+                        updateSMSThreadId(msgHandle, Integer.valueOf(newThreadIdStr));
+                    }
+
+                    mContext.getContentResolver().delete(tempUri, null, null);
+                }
+            }
+            if (crThreadId != null) {
+                crThreadId.close();
+            }
+        } else {
+            if (V) {
+                Log.v(TAG, "msgHandle not found");
+            }
+        }
+        cr.close();
+    }
+
+    /**
+     * Obtain the number of MMS messages
+     */
+    private int getNumMmsMsgs(String name) {
+        int msgCount = 0;
+
+        if ( name.equalsIgnoreCase(DELETED)){
+            Uri uri = Uri.parse("content://mms/");
+            ContentResolver cr = mContext.getContentResolver();
+            Cursor cursor = cr.query(uri, null, "thread_id = " + DELETED_THREAD_ID
+                    + " AND " + INTERESTED_MESSAGE_TYPE_CLAUSE, null, null);
+            if(cursor != null){
+                msgCount = cursor.getCount();
+                cursor.close();
+            }
+        } else {
+            Uri uri = Uri.parse("content://mms/" + name);
+            ContentResolver cr = mContext.getContentResolver();
+            Cursor cursor = cr.query(uri, null, "thread_id <> " + DELETED_THREAD_ID
+                    + " AND " + INTERESTED_MESSAGE_TYPE_CLAUSE, null, null);
+            if(cursor != null){
+                msgCount = cursor.getCount();
+                cursor.close();
+            }
+        }
+        return msgCount;
+    }
+
+    /**
+     * Obtain the MMS message ID from Handle
+     */
+    private Long getMmsMsgHndToID(long msgHandle) {
+        long msgID = -1;
+        String whereClause = " mid= " + (msgHandle - MMS_OFFSET_START);
+        Uri uri = Uri.parse("content://mms/part");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null) {
+            if (cursor.getCount() > 0) {
+                cursor.moveToFirst();
+                int handleInd = cursor.getColumnIndex("mid");
+                msgID = cursor.getLong(handleInd);
+            }
+            cursor.close();
+        }
+        return msgID;
+    }
+
+    /**
+     * Obtain the MMS message MID list
+     */
+    private List<Integer> getMmsMsgMIDs(String whereClause) {
+        List<Integer> idList = new ArrayList<Integer>();
+        Uri uri = Uri.parse("content://mms");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor crID = cr.query(uri, null, whereClause, null, null);
+        if (crID != null) {
+            int idInd = crID.getColumnIndex("_id");
+            if (crID.getCount() != 0) {
+                crID.moveToFirst();
+                do {
+                    idList.add(Integer.valueOf(crID.getInt(idInd)));
+                } while (crID.moveToNext());
+            }
+            crID.close();
+        }
+        return idList;
+    }
+
+    /**
+     * Build a whereclause for MMS filtering
+     */
+    private String bldMmsWhereClause(BluetoothMasAppParams appParams, int foldertype) {
+        String whereClause = "";
+        if ( foldertype != -1) {
+            // Inbox, Outbox, Sent, Draft folders
+            whereClause = "msg_box=" + foldertype + " AND thread_id <> " + DELETED_THREAD_ID
+                    + " AND " + INTERESTED_MESSAGE_TYPE_CLAUSE;
+        } else {
+            // Deleted folder
+            whereClause =  "thread_id = " + DELETED_THREAD_ID + " AND "
+                    + INTERESTED_MESSAGE_TYPE_CLAUSE;
+        }
+
+        /* Filter readstatus: 0 no filtering, 0x01 get unread, 0x10 get read */
+        if (appParams.FilterReadStatus != 0) {
+            if ((appParams.FilterReadStatus & 0x1) != 0) {
+                if (whereClause.length() != 0) {
+                    whereClause += " AND ";
+                }
+                whereClause += " read=0 ";
+            }
+            if ((appParams.FilterReadStatus & 0x02) != 0) {
+                if (whereClause.length() != 0) {
+                    whereClause += " AND ";
+                }
+                whereClause += " read=1 ";
+            }
+        }
+
+        /* Filter Period Begin */
+        if ((appParams.FilterPeriodBegin != null)
+                && (appParams.FilterPeriodBegin.length() > 0)) {
+            Time time = new Time();
+            try {
+                time.parse(appParams.FilterPeriodBegin.trim());
+                if (whereClause.length() != 0) {
+                    whereClause += " AND ";
+                }
+                whereClause += "date >= " + (time.toMillis(false))/1000;
+            } catch (TimeFormatException e) {
+                Log.d(TAG, "Bad formatted FilterPeriodBegin "
+                        + appParams.FilterPeriodBegin);
+            }
+        }
+
+        /* Filter Period End */
+        if ((appParams.FilterPeriodEnd != null)
+                && (appParams.FilterPeriodEnd.length() > 0)) {
+            Time time = new Time();
+            try {
+                time.parse(appParams.FilterPeriodEnd.trim());
+                if (whereClause.length() != 0) {
+                    whereClause += " AND ";
+                }
+                whereClause += "date < " + (time.toMillis(false))/1000;
+            } catch (TimeFormatException e) {
+                Log.d(TAG, "Bad formatted FilterPeriodEnd "
+                        + appParams.FilterPeriodEnd);
+            }
+        }
+        //Delivery report check
+        if (whereClause.length() != 0) {
+            whereClause += " AND ";
+        }
+        whereClause += "d_rpt > 0";
+
+        return whereClause;
+    }
+
+    /**
+     * Obtain the MMS msg_box id
+     */
+    private int getMmsMsgBox(long msgID) {
+        int val = -1;
+        String whereClause = " _id= " + msgID;
+        Uri uri = Uri.parse("content://mms/");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null) {
+            if (cursor.getCount() > 0) {
+                cursor.moveToFirst();
+                int msgBoxInd = cursor.getColumnIndex("msg_box");
+                val = cursor.getInt(msgBoxInd);
+            }
+            cursor.close();
+        }
+        return val;
+    }
+
+    /**
+     * Obtain MMS message text
+     */
+    private String getMmsMsgTxt(long msgID) {
+        String text = null;
+        String whereClause = " mid= " + msgID + " AND ct=\"text/plain\"";
+        Uri uri = Uri.parse("content://mms/part");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null) {
+            if (cursor.getCount() > 0) {
+                cursor.moveToFirst();
+                int textInd = cursor.getColumnIndex("text");
+                text = cursor.getString(textInd);
+            }
+            cursor.close();
+        }
+        return text;
+    }
+
+    /**
+     * Obtain the MMS message Subject
+     */
+    private String getMmsMsgSubject(long msgID) {
+        String text = null;
+        String whereClause = " _id= " + msgID;
+        Uri uri = Uri.parse("content://mms/");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null) {
+            if (cursor.getCount() > 0) {
+                cursor.moveToFirst();
+                int subjectInd = cursor.getColumnIndex("sub");
+                text = cursor.getString(subjectInd);
+            }
+            cursor.close();
+        }
+        return text;
+    }
+
+    /**
+     * Obtain the MMS message Date
+     */
+    private Date getMmsMsgDate(long msgID) {
+        long  date = 0;
+        String whereClause = " _id= " + msgID;
+        Uri uri = Uri.parse("content://mms/");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null) {
+            if (cursor.moveToFirst()) {
+                int dateInd = cursor.getColumnIndex("date");
+                date = 1000 * cursor.getLong(dateInd);
+            }
+            cursor.close();
+        }
+        if (V) Log.v(TAG, "DATE:millisces "+ date);
+        return new Date(date);
+
+    }
+
+    /**
+     * Obtain the MMS attachment size
+     */
+    private int getMmsMsgAttachSize(long msgID) {
+        int attachSize = 0;
+        String whereClause = " _id= " + msgID;
+        Uri uri = Uri.parse("content://mms/");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null) {
+            if (cursor.getCount() > 0) {
+                cursor.moveToFirst();
+                int sizeInd = cursor.getColumnIndex("m_size");
+                attachSize = cursor.getInt(sizeInd);
+            }
+            cursor.close();
+        }
+        return attachSize;
+
+    }
+
+    /**
+     * Obtain the MMS message read status
+     */
+    private String getMmsMsgReadStatus(long msgID) {
+        String text = null;
+        String whereClause = " _id= " + msgID;
+        Uri uri = Uri.parse("content://mms/");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null) {
+            if (cursor.getCount() > 0) {
+                cursor.moveToFirst();
+                int readInd = cursor.getColumnIndex("read");
+                if (cursor.getInt(readInd) == 0) {
+                    text = "no";
+                } else {
+                    text = "yes";
+                }
+            }
+            cursor.close();
+        }
+        return text;
+    }
+
+    /**
+     * Obtain the MMS message read sent
+     */
+    private String getMmsMsgReadSent(long msgID) {
+        String text = null;
+        if ( getMmsMsgBox(msgID) == 2 ) {
+            // Sent folder
+            text = "yes";
+        } else {
+            text = "no";
+        }
+        return text;
+    }
+
+    /**
+     * Obtain the MMS message priority
+     */
+    private String getMmsMsgPriority(long msgID) {
+        final int PRIORITY_LOW = 0X80;
+        final int PRIORITY_NORMAL = 0X81;
+        final int PRIORITY_HIGH = 0X82;
+
+        String text = null;
+        String whereClause = " _id= " + msgID;
+        Uri uri = Uri.parse("content://mms/");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null && cursor.getCount() > 0) {
+            cursor.moveToFirst();
+            int priInd = cursor.getColumnIndex("pri");
+
+            switch (cursor.getInt(priInd)) {
+            case PRIORITY_LOW:
+                text = "no";
+                break;
+            case PRIORITY_NORMAL:
+                text = "no";
+                break;
+            case PRIORITY_HIGH:
+                text = "yes";
+                break;
+
+            default:
+                text = "no";
+                break;
+            }
+        }
+        if (cursor != null) {
+            cursor.close();
+        }
+        return text;
+    }
+
+    /**
+     * Obtain the MMS message read protected
+     */
+    private String getMmsMsgProtected(long msgID) {
+        String text = null;
+        String whereClause = " _id= " + msgID;
+        Uri uri = Uri.parse("content://mms/");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null) {
+            if (cursor.getCount() > 0) {
+                cursor.moveToFirst();
+                int readInd = cursor.getColumnIndex("locked");
+                if (cursor.getInt(readInd) == 0) {
+                    text = "no";
+                } else {
+                    text = "yes";
+                }
+            }
+            cursor.close();
+        }
+        return text;
+
+    }
+
+    /**
+     * Obtain MMS message address
+     * When Multiple addresses are present return the addresses separated by semicolon
+     */
+    private String getMmsMsgAddress(long msgID) {
+        String text = "";
+        String whereClause = " address != \"insert-address-token\"";
+        Uri uri = Uri.parse("content://mms/" + msgID + "/addr");
+        //FOR INCOMING MMS ONLY "FROM" ADDRESS IS REQUIRED
+        if (isOutgoingMMSMessage(msgID) == false)
+            whereClause = " address != \"insert-address-token\" AND type=137";
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null) {
+            if (V) Log.v(TAG, "cursor.getCount(): " + cursor.getCount());
+            if (cursor.getCount() == 1) {
+                cursor.moveToFirst();
+                int addressInd = cursor.getColumnIndex("address");
+                text = cursor.getString(addressInd);
+            }
+            else if (cursor.getCount() > 1) {
+                cursor.moveToFirst();
+                int addressInd = 0;
+                do {
+                    addressInd = cursor.getColumnIndex("address");
+                    text = text.concat(cursor.getString(addressInd) + ";");
+                    if (V) Log.v(TAG, "address: " + cursor.getString(cursor.getColumnIndex("address")));
+                } while (cursor.moveToNext());
+
+            }
+            cursor.close();
+        }
+        if (V) Log.v(TAG, "final MMS address: " + text);
+        return text;
+    }
+
+    /**
+     * Get the folder name (MAP representation) based on the message Handle
+     */
+    private int getMmsContainingFolder(long msgID) {
+        int folderNum = 0;
+        String whereClause = " _id= " + msgID;
+        Uri uri = Uri.parse("content://mms/");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor cursor = cr.query(uri, null, whereClause, null, null);
+        if (cursor != null) {
+            if (cursor.getCount() > 0) {
+                cursor.moveToFirst();
+                int msgboxInd = cursor.getColumnIndex("msg_box");
+                String thread_id = cursor.getString(cursor.getColumnIndex("thread_id"));
+                if ( Integer.valueOf(thread_id) == DELETED_THREAD_ID) {
+                    // Deleted folder
+                    folderNum = 0;
+                } else {
+                    folderNum = cursor.getInt(msgboxInd);
+                }
+            }
+            cursor.close();
+        }
+        return folderNum;
+    }
+
+    /**
+     * Get MMS folder name based on value Inbox = 1 Sent = 2 Drafts = 3 Outbox =
+     * 4 Queued = 6
+     *
+     */
+    private String getMmsMapVirtualFolderName(int type) {
+        String folderName = null;
+
+        switch (type) {
+        case 0:
+            folderName = DELETED;
+            break;
+        case 1:
+            folderName = INBOX;
+            break;
+        case 2:
+            folderName = SENT;
+            break;
+        case 3:
+            folderName = DRAFT;
+            break;
+        case 4: // outbox
+        case 5: // failed
+        case 6: // queued
+            folderName = OUTBOX;
+            break;
+
+        default:
+            break;
+        }
+        return folderName;
+    }
+
+    /**
+     * Build an MMS bMessage when given a message handle
+     */
+    private BluetoothMasMessageRsp bldMmsBmsg(long msgID, BluetoothMasMessageRsp rsp) {
+        Cursor cr = null;
+        Uri uri = Uri.parse("content://mms/");
+        String whereClause = " _id = " + msgID;
+        String address = null;
+        String addressTokens[] = null;
+        cr = mContext.getContentResolver().query(uri, null, whereClause, null,
+                null);
+        if (cr == null) {
+            rsp.rsp = ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+            return rsp;
+        }
+        if (cr.getCount() > 0) {
+            cr.moveToFirst();
+            String containingFolder = getMmsMapVirtualFolderName((getMmsContainingFolder(msgID)));
+            BmessageConsts bmsg = new BmessageConsts();
+
+            // Create a bMessage
+            bmsg.setType("MMS");
+
+            bmsg.setBmsg_version("1.0");
+            if (cr.getString(cr.getColumnIndex("read")).equalsIgnoreCase("1")) {
+                bmsg.setStatus("READ");
+            } else {
+                bmsg.setStatus("UNREAD");
+            }
+
+            bmsg.setFolder(TELECOM + "/" + MSG + "/" + containingFolder);
+
+            bmsg.setVcard_version("2.1");
+            address = getMmsMsgAddress(msgID);
+            if ((address != null) && address.contains(";")) {
+                addressTokens = address.split(";");
+                String name = "";
+                String tel = "";
+                VcardContent vcardInternal;
+                for (int i=0; i < addressTokens.length; i++) {
+                    vcardInternal = getVcardContent(addressTokens[i]);
+                    if ((vcardInternal.name == null) || (vcardInternal.name.length() == 0)) {
+                        name = name.concat(" " + ";");
+                        if(V) Log.v (TAG, "name not present: ");
+                    } else {
+                        if(V) Log.v (TAG, "name present");
+                        name = name.concat(vcardInternal.name + ";");
+                    }
+                    tel = tel.concat(vcardInternal.tel + ";");
+                }
+                String type = cr.getString(cr.getColumnIndex("msg_box"));
+                // Inbox is type 1.
+                if (type.equalsIgnoreCase("1")) {
+                    bmsg.setOriginatorVcard_name(name);
+                    bmsg.setOriginatorVcard_phone_number(tel);
+                    bmsg.setRecipientVcard_name(getOwnerName());
+                    bmsg.setRecipientVcard_phone_number(getOwnerNumber());
+                } else {
+                    bmsg.setRecipientVcard_name(name);
+                    bmsg.setRecipientVcard_phone_number(tel);
+                    bmsg.setOriginatorVcard_name(getOwnerName());
+                    bmsg.setOriginatorVcard_phone_number(getOwnerNumber());
+                }
+            }
+            else {
+                VcardContent vcard = getVcardContent(address);
+                String type = cr.getString(cr.getColumnIndex("msg_box"));
+                // Inbox is type 1.
+                if (type.equalsIgnoreCase("1")) {
+                    bmsg.setOriginatorVcard_name(vcard.name);
+                    bmsg.setOriginatorVcard_phone_number(vcard.tel);
+                    bmsg.setRecipientVcard_name(getOwnerName());
+                    bmsg.setRecipientVcard_phone_number(getOwnerNumber());
+                } else {
+                    bmsg.setRecipientVcard_name(vcard.name);
+                    bmsg.setRecipientVcard_phone_number(vcard.tel);
+                    bmsg.setOriginatorVcard_name(getOwnerName());
+                    bmsg.setOriginatorVcard_phone_number(getOwnerNumber());
+                }
+            }
+            StringBuilder sb = new StringBuilder();
+            sb.append("Date: ").append(getMmsMsgDate(msgID).toString()).append("\r\n");
+
+            boolean MIME = true;
+            boolean msgFormat = MIME;
+            sb.append(bldMMSBody(bmsg, msgFormat, msgID));
+            bmsg.setBody_msg(sb.toString());
+            bmsg.setBody_length(sb.length() + 22);
+            bmsg.setBody_encoding("8BIT");
+            // Send a bMessage
+            String str = MapUtils.toBmessageMMS(bmsg);
+            if (V) Log.v(TAG, str);
+            if (str != null && (str.length() > 0)) {
+                final String FILENAME = "message" + getMasId();
+                FileOutputStream bos = null;
+                File file = new File(mContext.getFilesDir() + "/" + FILENAME);
+                file.delete();
+
+                try {
+                    bos = mContext.openFileOutput(FILENAME, Context.MODE_PRIVATE);
+                    bos.write(str.getBytes());
+                    bos.flush();
+                    bos.close();
+                } catch (FileNotFoundException e) {
+                    Log.e(TAG, "Unable to write " + FILENAME, e);
+                } catch (IOException e) {
+                    Log.e(TAG, "Unable to write " + FILENAME, e);
+                }
+
+                File fileR = new File(mContext.getFilesDir() + "/" + FILENAME);
+                if (fileR.exists() == true) {
+                    rsp.file = fileR;
+                    rsp.fractionDeliver = 1;
+                }
+            }
+        }
+        cr.close();
+        return rsp;
+    }
+
+    private boolean isOutgoingMMSMessage(long mmsMsgID) {
+        if (getMmsMsgBox(mmsMsgID) == 1) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * This method constructs an MMS message that is added to the message list
+     * which is used to construct a message listing
+     */
+    private MsgListingConsts bldMmsMsgLstItem(long mmsMsgID, BluetoothMasAppParams appParams,
+            String folderName, String datetimeStr) {
+
+        MsgListingConsts ml = new MsgListingConsts();
+        String address = getMmsMsgAddress(mmsMsgID);
+        boolean isMultipleAddress = false;
+        String addressTokens[] = null;
+        if ((address != null) && address.contains(";")) {
+            isMultipleAddress = true;
+            addressTokens = address.split(";");
+            for (int i=0; i < addressTokens.length; i++) {
+                if (V) Log.v ( TAG, "addressTokens[" + i + "] = " + addressTokens[i]);
+            }
+            if (V) Log.v (TAG, "addressTokens.length: " + addressTokens.length);
+        }
+        if (V) Log.v (TAG, "isMultipleAddress: " + isMultipleAddress);
+
+
+        // Set the message handle
+        ml.setMsg_handle(mmsMsgID + MMS_OFFSET_START);
+
+        // Set the message subject
+        if ((appParams.ParameterMask & BIT_SUBJECT) != 0) {
+            ml.setSubject(getMmsMsgSubject(mmsMsgID));
+            ml.sendSubject = true;
+        }
+
+        // Construct datetime value
+        if ((appParams.ParameterMask & BIT_DATETIME) != 0) {
+            ml.setDatetime(datetimeStr);
+        }
+
+        // Construct msg body
+        if ((appParams.ParameterMask & BIT_TEXT) != 0) {
+            if ((getMmsMsgTxt(mmsMsgID) != null)) {
+                ml.setContains_text("yes");
+            } else {
+                ml.setContains_text("no");
+            }
+
+        }
+
+        // Set text size
+        if ((appParams.ParameterMask & BIT_SIZE) != 0) {
+            final String mmsMsgTxt = getMmsMsgTxt(mmsMsgID);
+            ml.setSize(mmsMsgTxt == null ? 0 : mmsMsgTxt.length());
+        }
+
+        // Set message type
+        if ((appParams.ParameterMask & BIT_TYPE) != 0) {
+            ml.setType("MMS");
+        }
+
+        if ((appParams.ParameterMask & BIT_RECIPIENT_NAME) != 0) {
+            String recipientName = "";
+            if (isOutgoingMMSMessage(mmsMsgID) == false) {
+                recipientName = getOwnerName();
+            } else {
+                if(!isMultipleAddress) {
+                    recipientName = getContactName(getMmsMsgAddress(mmsMsgID));
+                } else {
+                    for (int i=0; i < addressTokens.length; i++) {
+                        recipientName = recipientName.concat(getContactName(addressTokens[i]) + ";");
+                        if (V) Log.v ( TAG, "recipientName: " + recipientName);
+                    }
+                }
+            }
+            ml.setRecepient_name(recipientName);
+        }
+
+        if ((appParams.ParameterMask & BIT_RECIPIENT_ADDRESSING) != 0) {
+            // TODO: In case of a SMS this is the recipient's phone number
+            // in canonical form (chapter 2.4.1 of [5])
+            String recipientAddressing = null;
+            if (isOutgoingMMSMessage(mmsMsgID) == false) {
+                recipientAddressing = getOwnerNumber();
+            } else {
+                recipientAddressing = getMmsMsgAddress(mmsMsgID);
+            }
+            ml.setRecepient_addressing(recipientAddressing);
+            ml.setSendRecipient_addressing(true);
+        }
+
+        if ((appParams.ParameterMask & BIT_SENDER_NAME) != 0) {
+            String senderName = "";
+            if (isOutgoingMMSMessage(mmsMsgID) == true) {
+                senderName = getOwnerName();
+            } else {
+                if(!isMultipleAddress) {
+                    senderName = getContactName(getMmsMsgAddress(mmsMsgID));
+                } else {
+                    for (int i=0; i < addressTokens.length; i++) {
+                        senderName = senderName.concat(getContactName(addressTokens[i]) + ";");
+                        if (V) Log.v ( TAG, "senderName: " + senderName);
+                    }
+                }
+            }
+            ml.setSender_name(senderName);
+        }
+
+        if ((appParams.ParameterMask & BIT_SENDER_ADDRESSING) != 0) {
+            String senderAddressing = null;
+            if (isOutgoingMMSMessage(mmsMsgID) == true) {
+                senderAddressing = getOwnerNumber();
+            } else {
+                senderAddressing = getMmsMsgAddress(mmsMsgID);
+            }
+            ml.setSender_addressing(senderAddressing);
+        }
+
+        // Set read status
+        if ((appParams.ParameterMask & BIT_READ) != 0) {
+            final String mmsMsgStatus = getMmsMsgReadStatus(mmsMsgID);
+            if (mmsMsgStatus != null && mmsMsgStatus.equalsIgnoreCase("yes")) {
+                ml.setRead("yes");
+            } else {
+                ml.setRead("no");
+            }
+        }
+
+        // Set priority
+        if ((appParams.ParameterMask & BIT_PRIORITY) != 0) {
+            ml.setPriority(getMmsMsgPriority(mmsMsgID));
+        }
+
+        // Set Protected
+        if ((appParams.ParameterMask & BIT_PROTECTED) != 0) {
+            ml.setMsg_protected(getMmsMsgProtected(mmsMsgID));
+        }
+
+        // Set sent
+        if ((appParams.ParameterMask & BIT_SENT) != 0) {
+            ml.setSent(getMmsMsgReadSent(mmsMsgID));
+        }
+
+        // Set reception status
+        if ((appParams.ParameterMask & BIT_RECEPTION_STATUS) != 0) {
+            ml.setReception_status("complete");
+        }
+
+        // Set attachment size
+        if ((appParams.ParameterMask & BIT_ATTACHMENT_SIZE) != 0) {
+            ml.setAttachment_size(getMmsMsgAttachSize(mmsMsgID));
+        }
+
+        return ml;
+    }
+
+    /**
+     * This method is used to take an MMS in the drafts folder and move it to
+     * the outbox This action is required to add the MMS to the pending_msgs
+     * table which is used to send the MMS out to the network
+     */
+    private void moveMMSfromDraftstoOutbox() {
+
+        String handle = null;
+
+        // scan drafts folder for an MMS to send
+        // fetch the message handle
+        Uri uri = Uri.parse("content://mms/drafts");
+        ContentResolver cr = mContext.getContentResolver();
+        Cursor crID = cr.query(uri, null, null, null, null);
+        if (crID != null) {
+            if (crID.getCount() > 0) {
+                crID.moveToFirst();
+                int msgIDInd = crID.getColumnIndex("_id");
+                handle = crID.getString(msgIDInd);
+            }
+            crID.close();
+        }
+
+        if (handle != null) {
+            String whereClause = " _id= " + handle;
+            uri = Uri.parse("content://mms");
+            crID = cr.query(uri, null, whereClause, null, null);
+            if (crID != null) {
+                if (crID.getCount() > 0) {
+                    crID.moveToFirst();
+                    ContentValues values = new ContentValues();
+                    values.put("msg_box", 4);
+                    cr.update(uri, values, whereClause, null);
+                }
+                crID.close();
+            }
+        }
+    }
+
+    /**
+     * This method is used to take a Bmessage that was pushed and move it to the
+     * folder
+     */
+    private String addToMmsFolder(String folderName, String mmsMsg) throws BadRequestException {
+        if (folderName == null) {
+            return null;
+        }
+        if (folderName.equalsIgnoreCase(DRAFT)) {
+            folderName = DRAFTS;
+        }
+        int folderType = SmsMmsUtils.getFolderTypeMms(folderName);
+        BmessageConsts bMsg = MapUtils.fromBmessageMMS(mmsMsg);
+        String address = bMsg.getRecipientVcard_phone_number();
+        String mmsText = bMsg.getBody_msg();
+
+        /**
+         * The PTS tester does not contain the same message format as CE4A This
+         * code /* looks at the pushed message and checks for the message boundary. If
+         * it does not /* find it then it then it assumes PTS tester format
+         */
+        mmsText = MapUtils.fetchBodyEmail(mmsText);
+        ContentValues values = new ContentValues();
+        values.put("msg_box", folderType);
+
+        if (folderName.equalsIgnoreCase(DELETED)) {
+            values.put("thread_id", -1);
+        } else {
+            values.put("thread_id", createMMSThread(address));
+        }
+
+        // function that creates a thread ID
+        values.put("read", 0);
+        values.put("seen", 0);
+        values.put("sub_cs", 106);
+        values.put("ct_t", "application/vnd.wap.multipart.related");
+        values.put("exp", 604800);
+        values.put("m_cls", "personal");
+        values.put("m_type", 128);
+        values.put("v", 18);
+        values.put("pri", 129);
+        values.put("rr", 129);
+        values.put("tr_id", "T12dc2e87182");
+        values.put("d_rpt", 129);
+        values.put("locked", 0);
+
+        Uri uri;
+        if (folderName.equalsIgnoreCase(DELETED)) {
+            uri = Uri.parse("content://mms/inbox");
+        } else {
+            uri = Uri.parse("content://mms/" + folderName);
+        }
+        ContentResolver cr = mContext.getContentResolver();
+        uri = cr.insert(uri, values);
+
+        if (uri == null) {
+            // unable to insert MMS
+            Log.e(TAG, "Unabled to insert MMS " + values);
+            return INTERNAL_ERROR;
+        }
+        String msgNum = uri.getLastPathSegment();
+        long msgID = Long.parseLong(msgNum);
+        if (V){
+            Log.v(TAG, " NEW URI " + uri.toString());
+        }
+        long virtualMsgId = (msgID + MMS_OFFSET_START);
+
+        // Build the \mms\part portion
+        values.clear();
+
+        values.put("seq", -1);
+        values.put("ct", "application/smil");
+        values.put("cid", "<smil>");
+        values.put("cl", "smil.xml");
+        values.put("text", "<smil><head><layout><root-layout width=\"320px\" height=\"480px\"/>" +
+                "<region id=\"Text\" left=\"0\" top=\"320\" width=\"320px\" height=\"160px\"" +
+                " fit=\"meet\"/></layout></head><body><par dur=\"5000ms\">" +
+                "<text src=\"text_0.txt\" region=\"Text\"/></par></body></smil>");
+
+        uri = Uri.parse("content://mms/" + msgID + "/part");
+        uri = cr.insert(uri, values);
+        if (uri != null && V){
+            Log.v(TAG, " NEW URI " + uri.toString());
+        }
+
+        values.clear();
+        values.put("seq", 0);
+        values.put("ct", "text/plain");
+        values.put("name", "null");
+        values.put("chset", 106);
+        values.put("cd", "null");
+        values.put("fn", "null");
+        values.put("cid", "<smil>");
+        values.put("cl", "text_0.txt");
+        values.put("ctt_s", "null");
+        values.put("ctt_t", "null");
+        values.put("_data", "null");
+        values.put("text", mmsText);
+
+        uri = Uri.parse("content://mms/" + msgID + "/part");
+        uri = cr.insert(uri, values);
+        if (uri != null && V){
+            Log.v(TAG, " NEW URI " + uri.toString());
+        }
+
+        values.clear();
+        values.put("contact_id", "null");
+        values.put("address", "insert-address-token");
+        values.put("type", 137);
+        values.put("charset", 106);
+
+        uri = Uri.parse("content://mms/" + msgID + "/addr");
+        uri = cr.insert(uri, values);
+        if (uri != null && V){
+            Log.v(TAG, " NEW URI " + uri.toString());
+        }
+
+        values.clear();
+        values.put("contact_id", "null");
+        values.put("address", address);
+        values.put("type", 151);
+        values.put("charset", 106);
+
+        uri = Uri.parse("content://mms/" + msgID + "/addr");
+        uri = cr.insert(uri, values);
+        if (uri != null && V){
+            Log.v(TAG, " NEW URI " + uri.toString());
+        }
+
+        String virtualMsgIdStr = String.valueOf(virtualMsgId);
+        String whereClause = "address LIKE '" + address + "' AND type = 125";
+        if (!folderName.equalsIgnoreCase("deleted")) {
+            mContext.getContentResolver().delete(Uri.parse("content://sms/"), whereClause, null);
+        }
+        return virtualMsgIdStr;
+    }
+
+    /**
+     * Method to construct body of bmessage using either MIME or no MIME
+     *
+     */
+    private String bldMMSBody(BmessageConsts bMsg, boolean msgType, long msgID) {
+        boolean MIME = true;
+        StringBuilder sb = new StringBuilder();
+
+        if (msgType == MIME) {
+            Random randomGenerator = new Random();
+            int randomInt = randomGenerator.nextInt(1000);
+            String boundary = "MessageBoundary."+randomInt;
+            final String mmsMsgTxt = getMmsMsgTxt(msgID);
+            if(mmsMsgTxt != null){
+                while(mmsMsgTxt.contains(boundary)){
+                    randomInt = randomGenerator.nextInt(1000);
+                    boundary = "MessageBoundary."+randomInt;
+                }
+            }
+            sb.append("To:").append(bMsg.recipient_vcard_phone_number)
+                    .append("\r\n");
+            sb.append("Mime-Version: 1.0").append("\r\n");
+            sb.append(
+                    "Content-Type: multipart/mixed; boundary=\""+boundary+"\"")
+                    .append("\r\n");
+            sb.append("Content-Transfer-Encoding: 7bit").append("\r\n")
+                    .append("\r\n");
+            sb.append("MIME Message").append("\r\n");
+            sb.append("--"+boundary).append("\r\n");
+            sb.append("Content-Type: text/plain").append("\r\n");
+            sb.append("Content-Transfer-Encoding: 8bit").append("\r\n");
+            sb.append("Content-Disposition:inline").append("\r\n")
+                    .append("\r\n");
+            sb.append(getMmsMsgTxt(msgID)).append("\r\n");
+            sb.append("--"+boundary+"--").append("\r\n")
+                    .append("\r\n");
+        } else {
+            sb.append("Subject:").append("Not Implemented").append("\r\n");
+            sb.append("From:").append(bMsg.originator_vcard_phone_number)
+                    .append("\r\n");
+            sb.append(getMmsMsgTxt(msgID)).append("\r\n").append("\r\n");
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Method to create a thread for a pushed MMS message
+     *
+     */
+    private int createMMSThread(String address) {
+        int returnValue = 0;
+        if (address != null) {
+            if (V){
+                Log.v(TAG, "Inside adress not null");
+            }
+            ContentValues tempValue = new ContentValues();
+            tempValue.put("address", address);
+            tempValue.put("type", 125);
+            Uri tempUri = mContext.getContentResolver().insert(
+                    Uri.parse("content://sms/"), tempValue);
+
+            if (tempUri != null) {
+                Cursor tempCr = mContext.getContentResolver().query(tempUri, null,
+                        null, null, null);
+                if (tempCr != null) {
+                    tempCr.moveToFirst();
+                    String newThreadIdStr = tempCr.getString(tempCr
+                            .getColumnIndex("thread_id"));
+                    tempCr.close();
+                    returnValue = Integer.valueOf(newThreadIdStr);
+                }
+                if (V){
+                    Log.v(TAG, "Thread ID::"+returnValue);
+                }
+            }
+        }
+
+        return returnValue;
+    }
+
+    private String bldSmsBmsg(long msgHandle, Context context, Cursor cr,
+                BluetoothMasAppParams bluetoothMasAppParams) {
+        String str = null;
+        int body_length = 0;
+        if (cr.getCount() > 0) {
+            cr.moveToFirst();
+            String containingFolder = getContainingFolder(msgHandle);
+            BmessageConsts bmsg = new BmessageConsts();
+
+            // Create a bMessage
+
+            if (TelephonyManager.getDefault().getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
+                bmsg.setType("SMS_CDMA");
+            } else {
+                bmsg.setType("SMS_GSM");
+            }
+
+            bmsg.setBmsg_version("1.0");
+            if (cr.getString(cr.getColumnIndex("read")).equalsIgnoreCase("1")) {
+                bmsg.setStatus("READ");
+            } else {
+                bmsg.setStatus("UNREAD");
+            }
+
+            bmsg.setFolder(TELECOM + "/" + MSG + "/" + containingFolder);
+
+            bmsg.setVcard_version("2.1");
+            VcardContent vcard = getVcardContent(cr.getString(cr
+                    .getColumnIndex("address")));
+
+            String type = cr.getString(cr.getColumnIndex("type"));
+            if (type.equalsIgnoreCase("1")) {
+                // The address in database is of originator
+                bmsg.setOriginatorVcard_name(vcard.name);
+                bmsg.setOriginatorVcard_phone_number(vcard.tel);
+                bmsg.setRecipientVcard_name(getOwnerName());
+                bmsg.setRecipientVcard_phone_number(getOwnerNumber());
+            } else {
+                bmsg.setRecipientVcard_name(vcard.name);
+                bmsg.setRecipientVcard_phone_number(vcard.tel);
+                bmsg.setOriginatorVcard_name(getOwnerName());
+                bmsg.setOriginatorVcard_phone_number(getOwnerNumber());
+            }
+
+            String smsBody = " ";
+
+            if ( (int)bluetoothMasAppParams.Charset == 1){
+                bmsg.setBody_charset("UTF-8");
+                smsBody = cr.getString(cr.getColumnIndex("body"));
+            }
+
+            if ( (int)bluetoothMasAppParams.Charset == 0){
+                bmsg.setBody_encoding("G-7BIT");
+                String smsBodyUnicode = cr.getString(cr.getColumnIndex("body"));
+                smsBody = getSMSDeliverPdu(smsBodyUnicode, cr.getString(cr.getColumnIndex("date")),
+                        vcard.tel);
+            }
+            if (V) {
+              Log.v(TAG, "Unicode String Length :: " + smsBody.length());
+            }
+            try {
+               switch ((int)bluetoothMasAppParams.Charset) {
+               case 1:
+                   byte[] b = smsBody.getBytes("UTF-8");
+                   body_length = b.length;
+                   break;
+               case 0:
+               default:
+                   body_length = smsBody.length();
+                   break;
+               }
+            }catch (Exception e) {
+               if (V) {
+                   Log.v(TAG, "Exception::Getting String UTF-8 Length:: " + smsBody.length());
+               }
+               body_length = smsBody.length();
+            }
+            if (V) {
+               Log.v(TAG, "BT SMS Total length :: 22 + " + body_length);
+            }
+            bmsg.setBody_length(22 + body_length);
+            bmsg.setBody_msg(smsBody);
+            cr.close();
+            // Send a bMessage
+           if (V){
+               Log.v(TAG, "bMessageSMS test\n");
+               Log.v(TAG, "=======================\n\n");
+            }
+            str = MapUtils.toBmessageSMS(bmsg);
+        }
+        return str;
+    }
+
+    private MsgListingConsts bldSmsMsgLstItem(BluetoothMasAppParams appParams,
+                String subject, String timestamp, String address, String msgId,
+                String readStatus, int msgType) {
+        MsgListingConsts ml = new MsgListingConsts();
+        ml.setMsg_handle(Integer.valueOf(msgId));
+
+        Time time = new Time();
+        time.set(Long.valueOf(timestamp));
+
+        String datetimeStr = time.toString().substring(0, 15);
+
+        ml.msgInfo.setDateTime(datetimeStr);
+
+        if ((appParams.ParameterMask & BIT_SUBJECT) != 0) {
+            /* SMS doesn't have subject. Append Body
+             * so that remote client doesn't have to do
+             * GetMessage
+             */
+            ml.setSendSubject(true);
+            if (subject == null) {
+                subject = "";
+            } else if (subject != null && subject.length() > appParams.SubjectLength ) {
+                subject = subject.substring(0,
+                        appParams.SubjectLength);
+            }
+            ml.setSubject(subject);
+        }
+
+        if ((appParams.ParameterMask & BIT_DATETIME) != 0) {
+            ml.setDatetime(datetimeStr);
+        }
+
+        if ((appParams.ParameterMask & BIT_SENDER_NAME) != 0) {
+            // TODO: Query the Contacts database
+            String senderName = null;
+            if (isOutgoingSMSMessage(msgType) == true) {
+                senderName = getOwnerName();
+            } else {
+                senderName = getContactName(address);
+            }
+            ml.setSender_name(senderName);
+        }
+
+        if ((appParams.ParameterMask & BIT_SENDER_ADDRESSING) != 0) {
+            // TODO: In case of a SMS this is the sender's phone number in canonical form
+            // (chapter 2.4.1 of [5]).
+            String senderAddressing = null;
+            if (isOutgoingSMSMessage(msgType) == true) {
+                senderAddressing = getOwnerNumber();
+            } else {
+                senderAddressing = address;
+            }
+            ml.setSender_addressing(senderAddressing);
+        }
+
+        if ((appParams.ParameterMask & BIT_RECIPIENT_NAME) != 0) {
+            // TODO: "recipient_name" is the name of the recipient of
+            // the message, when it is known by the MSE device.
+            String recipientName = null;
+            if (isOutgoingSMSMessage(msgType) == false) {
+                recipientName = getOwnerName();
+            } else {
+                recipientName = getContactName(address);
+            }
+            ml.setRecepient_name(recipientName);
+        }
+
+        if ((appParams.ParameterMask & BIT_RECIPIENT_ADDRESSING) != 0) {
+            // TODO: In case of a SMS this is the recipient's phone
+            // number in canonical form (chapter 2.4.1 of [5])
+            String recipientAddressing = null;
+            if (isOutgoingSMSMessage(msgType) == false) {
+                recipientAddressing = getOwnerNumber();
+            } else {
+                recipientAddressing = address;
+            }
+            ml.setRecepient_addressing(recipientAddressing);
+            ml.setSendRecipient_addressing(true);
+        }
+
+        if ((appParams.ParameterMask & BIT_TYPE) != 0) {
+            final int phoneType = TelephonyManager.getDefault().getPhoneType();
+            if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
+                ml.setType("SMS_CDMA");
+            } else {
+                ml.setType("SMS_GSM");
+            }
+        }
+
+        if ((appParams.ParameterMask & BIT_SIZE) != 0) {
+            ml.setSize(subject.length());
+        }
+
+        if ((appParams.ParameterMask & BIT_RECEPTION_STATUS) != 0) {
+            ml.setReception_status("complete");
+        }
+
+        if ((appParams.ParameterMask & BIT_TEXT) != 0) {
+            // TODO: Set text to "yes"
+            ml.setContains_text("yes");
+        }
+
+        if ((appParams.ParameterMask & BIT_ATTACHMENT_SIZE) != 0) {
+            ml.setAttachment_size(0);
+        }
+
+        if ((appParams.ParameterMask & BIT_PRIORITY) != 0) {
+            // TODO: Get correct priority
+            ml.setPriority("no");
+        }
+
+        if ((appParams.ParameterMask & BIT_READ) != 0) {
+            if (readStatus.equalsIgnoreCase("1")) {
+                ml.setRead("yes");
+            } else {
+                ml.setRead("no");
+            }
+        }
+
+        if ((appParams.ParameterMask & BIT_SENT) != 0) {
+            // TODO: Get sent status?
+            if (msgType == 2) {
+                ml.setSent("yes");
+            } else {
+                ml.setSent("no");
+            }
+        }
+
+        if ((appParams.ParameterMask & BIT_PROTECTED) != 0) {
+            ml.setMsg_protected("no");
+        }
+
+        return ml;
+    }
+    private BluetoothMsgListRsp msgListSms(List<MsgListingConsts> msgList, String folder,
+            BluetoothMasMessageListingRsp rsp, BluetoothMasAppParams appParams) {
+        BluetoothMsgListRsp bmlr = new BluetoothMsgListRsp();
+        String url = "content://sms/";
+        Uri uri = Uri.parse(url);
+        ContentResolver cr = mContext.getContentResolver();
+        String whereClause  = SmsMmsUtils.getConditionStringSms(folder, appParams);
+
+        Cursor cursor = cr.query(uri, null, whereClause, null,
+                "date desc");
+
+        if (cursor != null && V) {
+                Log.v(TAG, "move to First" + cursor.moveToFirst());
+        }
+        if (cursor != null && V) {
+                Log.v(TAG, "move to Liststartoffset"
+                    + cursor.moveToPosition(appParams.ListStartOffset));
+        }
+        if (cursor != null && cursor.moveToFirst()) {
+            int idInd = cursor.getColumnIndex("_id");
+            int addressInd = cursor.getColumnIndex("address");
+            int personInd = cursor.getColumnIndex("person");
+            int dateInd = cursor.getColumnIndex("date");
+            int readInd = cursor.getColumnIndex("read");
+            int statusInd = cursor.getColumnIndex("status");
+            int subjectInd = cursor.getColumnIndex("subject");
+            int typeInd = cursor.getColumnIndex("type");
+            int bodyInd = cursor.getColumnIndex("body");
+
+            do {
+                /*
+                 * Apply remaining filters
+                 */
+
+                /*
+                 * For incoming message, originator is the remote
+                 * contact For outgoing message, originator is the
+                 * owner.
+                 */
+                String filterString = null;
+                String oname = getOwnerName();
+                if (oname == null) {
+                    oname = "";
+                }
+                String onumber = getOwnerNumber();
+                if (onumber == null) {
+                    onumber = "";
+                }
+
+                int msgType = cursor.getInt(typeInd);
+                String regExpOrig = null;
+                String regExpRecipient = null;
+                if (appParams.FilterOriginator != null) {
+                    regExpOrig = appParams.FilterOriginator.replace("*", ".*[0-9A-Za-z].*");
+                }
+                if (appParams.FilterRecipient != null) {
+                    regExpRecipient = appParams.FilterRecipient.replace("*", ".*[0-9A-Za-z].*");
+                }
+                if (isOutgoingSMSMessage(msgType) == true) {
+                    if ((appParams.FilterOriginator != null)
+                            && (appParams.FilterOriginator.length() != 0)
+                            && !(oname.matches(".*"+regExpOrig+".*"))
+                            && !(onumber.matches(".*"+regExpOrig+".*"))) {
+                        continue;
+                    }
+                    if ((appParams.FilterRecipient != null)
+                            && (appParams.FilterRecipient.length() != 0)) {
+                        filterString = appParams.FilterRecipient.trim();
+                        if (V){
+                                Log.v(TAG, "appParams.FilterRecipient"
+                                    + appParams.FilterRecipient);
+                        }
+                    }
+                }
+                if (isOutgoingSMSMessage(msgType) == false) {
+                    if ((appParams.FilterRecipient != null)
+                            && (appParams.FilterRecipient.length() != 0)
+                            && !(oname.matches(".*"+regExpRecipient+".*"))
+                            && !(onumber.matches(".*"+regExpRecipient+".*"))) {
+                        continue;
+                    }
+                    if ((appParams.FilterOriginator != null)
+                            && (appParams.FilterOriginator.length() != 0)) {
+                        filterString = appParams.FilterOriginator.trim();
+                        if (V){
+                                Log.v(TAG, "appParams.FilterOriginator"
+                                    + appParams.FilterOriginator);
+                        }
+                    }
+                }
+
+                if (filterString != null) {
+                    if (V){
+                        Log.v(TAG, "filterString = " + filterString);
+                    }
+                    if (allowEntry(cursor.getString(addressInd),
+                            filterString) == true) {
+                        if (V){
+                                Log.v(TAG,
+                                    " ALLOWED : "
+                                    + cursor.getString(addressInd)
+                                    + " - " + cursor.getPosition());
+                        }
+                    } else {
+                        if (V){
+                                Log.v(TAG,
+                                    " DENIED : "
+                                    + cursor.getString(addressInd)
+                                    + " - " + cursor.getPosition());
+                        }
+                        continue;
+                    }
+                }
+                if (V) Log.v(TAG, " msgListSize " + rsp.msgListingSize);
+                rsp.msgListingSize++;
+
+                /*
+                 * Don't want the listing; just send the listing size
+                 * after applying all the filters.
+                 */
+                if (appParams.MaxListCount == 0) {
+                    continue;
+                }
+                String msgIdSms = cursor.getString(idInd);
+                String subjectSms = cursor.getString(bodyInd);
+                String timestampSms = cursor.getString(dateInd);
+                String addressSms = cursor.getString(addressInd);
+                String readStatusSms = cursor.getString(readInd);
+
+                MsgListingConsts ml = bldSmsMsgLstItem(appParams, subjectSms,
+                                timestampSms, addressSms, msgIdSms,
+                                readStatusSms, msgType);
+
+                // New Message?
+                if ((rsp.newMessage == 0)
+                        && (cursor.getInt(readInd) == 0)) {
+                    rsp.newMessage = 1;
+                }
+
+                msgList.add(ml);
+            } while (cursor.moveToNext());
+        }
+        if (cursor != null) {
+            cursor.close();
+        }
+        rsp.rsp = ResponseCodes.OBEX_HTTP_OK;
+        bmlr.messageListingSize = rsp.msgListingSize;
+        bmlr.rsp = rsp;
+        bmlr.msgList = msgList;
+        return bmlr;
+    }
+
+    private BluetoothMsgListRsp msgListMms(List<MsgListingConsts> msgList, String name,
+            BluetoothMasMessageListingRsp rsp, BluetoothMasAppParams appParams) {
+        BluetoothMsgListRsp bmlr = new BluetoothMsgListRsp();
+        String filterString = null;
+
+        String oname = getOwnerName();
+        if (oname == null) {
+            oname = "";
+        }
+
+        String onumber = getOwnerNumber();
+        if (onumber == null) {
+            onumber = "";
+        }
+
+        Log.v(TAG, "oname = " + oname + "onumber = " + onumber);
+
+        String regExpOrig = null;
+        String regExpRecipient = null;
+
+        if (appParams.FilterOriginator != null) {
+            regExpOrig = appParams.FilterOriginator.replace("*", ".*[0-9A-Za-z].*");
+        }
+
+        if (appParams.FilterRecipient != null) {
+            regExpRecipient = appParams.FilterRecipient.replace("*", ".*[0-9A-Za-z].*");
+        }
+
+        Log.v(TAG, " regExpOrig = " + regExpOrig + " regExpRecipient = " + regExpRecipient);
+
+        if (getNumMmsMsgs(name) != 0) {
+            List<Integer> list = getMmsMsgMIDs(bldMmsWhereClause(
+                    appParams, SmsMmsUtils.getFolderTypeMms(name)));
+            for (int msgId : list) {
+                if (V){
+                        Log.v(TAG, "\n MMS Text message ==> "
+                            + getMmsMsgTxt(msgId));
+                }
+                if (V){
+                        Log.v(TAG, "\n MMS message subject ==> "
+                            + getMmsMsgSubject(msgId));
+                }
+                if (isOutgoingMMSMessage(msgId) == false) {
+                    if ((appParams.FilterRecipient != null)
+                        && (appParams.FilterRecipient.length() != 0)
+                        && !(oname.matches(".*"+regExpRecipient+".*"))
+                        && !(onumber.matches(".*"+regExpRecipient+".*"))) {
+                            continue;
+                        }
+                    if ((appParams.FilterOriginator != null)
+                        && (appParams.FilterOriginator.length() != 0)) {
+                        filterString = appParams.FilterOriginator.trim();
+                        if (V){
+                            Log.v(TAG, " appParams.FilterOriginator"
+                                + appParams.FilterOriginator);
+                        }
+                    }
+                }
+
+                if (isOutgoingMMSMessage(msgId) == true) {
+                    if ((appParams.FilterOriginator != null)
+                        && (appParams.FilterOriginator.length() != 0)
+                        && !(oname.matches(".*"+regExpOrig+".*"))
+                        && !(onumber.matches(".*"+regExpOrig+".*"))) {
+                        continue;
+                    }
+
+                    if ((appParams.FilterRecipient != null)
+                        && (appParams.FilterRecipient.length() != 0)) {
+                        filterString = appParams.FilterRecipient.trim();
+                        if (V){
+                            Log.v(TAG, " appParams.FilterRecipient"
+                                + appParams.FilterRecipient);
+                        }
+                    }
+                }
+
+                if (filterString != null) {
+                    if (V){
+                        Log.v(TAG, " filterString = " + filterString);
+                    }
+                    String ContactName = null;
+                    String ContactNum = null;
+
+                    ContactName = getContactName(getMmsMsgAddress(msgId));
+                    ContactNum = getMmsMsgAddress(msgId);
+
+                    if (ContactName.matches(filterString) || ContactNum.matches(filterString)) {
+                        if (V){
+                            Log.v(TAG, " ALLOWED : "
+                                + ContactName + " - " + ContactNum );
+                        }
+                    } else {
+                        if (V){
+                            Log.v(TAG, " DENIED : "
+                                + ContactName + " - " + ContactNum );
+                        }
+                        continue;
+                    }
+                }
+
+                Time time = new Time();
+                time.set(getMmsMsgDate(msgId).getTime());
+
+                String datetimeStr = time.toString().substring(0, 15);
+
+                MsgListingConsts mmsl = bldMmsMsgLstItem(msgId, appParams, name, datetimeStr);
+                mmsl.msgInfo.setDateTime(datetimeStr);
+
+                if ((rsp.newMessage == 0)
+                        && "no".equalsIgnoreCase(getMmsMsgReadStatus(msgId))) {
+                    rsp.newMessage = 1;
+                }
+
+                msgList.add(mmsl);
+                rsp.msgListingSize++;
+            }
+        }
+        rsp.rsp = ResponseCodes.OBEX_HTTP_OK;
+        bmlr.messageListingSize = rsp.msgListingSize;
+        bmlr.rsp = rsp;
+        bmlr.msgList = msgList;
+        return bmlr;
+    }
+
+    private BluetoothMasMessageRsp getMessageSms(long msgHandle, Context context,
+            BluetoothMasMessageRsp rsp, BluetoothMasAppParams bluetoothMasAppParams) {
+        long smsHandle = msgHandle - SMS_OFFSET_START;
+        Cursor cr = null;
+        Uri uri = Uri.parse("content://sms/");
+        String whereClause = " _id = " + smsHandle;
+        try {
+            cr = context.getContentResolver().query(uri, null, whereClause, null,
+                    null);
+        } catch (Exception e){
+            rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            return rsp;
+        }
+        if (cr == null) {
+            rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            return rsp;
+        }
+        String strSms = bldSmsBmsg(smsHandle, context, cr, bluetoothMasAppParams);
+        cr.close();
+        if (V) Log.v(TAG, strSms);
+
+        if (strSms != null && (strSms.length() > 0)) {
+            final String FILENAME = "message" + getMasId();
+            FileOutputStream bos = null;
+            File file = new File(context.getFilesDir() + "/" + FILENAME);
+            file.delete();
+
+            try {
+                bos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
+                bos.write(strSms.getBytes());
+                bos.flush();
+                bos.close();
+            } catch (FileNotFoundException e) {
+                Log.e(TAG, "Unable to write " + FILENAME, e);
+            } catch (IOException e) {
+                Log.e(TAG, "Unable to write " + FILENAME, e);
+            }
+
+            File fileR = new File(context.getFilesDir() + "/" + FILENAME);
+            if (fileR.exists() == true) {
+                rsp.file = fileR;
+                rsp.fractionDeliver = 1;
+            }
+        }
+        return rsp;
+    }
+
+    private BluetoothMasMessageRsp getMessageMms(long msgHandle, BluetoothMasMessageRsp rsp) {
+        long mmsMsgID = 0;
+        try {
+            mmsMsgID = getMmsMsgHndToID(msgHandle);
+        } catch (Exception e) {
+            rsp.rsp = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            return rsp;
+        }
+        if (mmsMsgID > 0) {
+            rsp = bldMmsBmsg(mmsMsgID, rsp);
+        }
+        return rsp;
+    }
+
+    private BluetoothMasPushMsgRsp pushMessageMms(BluetoothMasPushMsgRsp rsp,
+            String readStr, String name) throws BadRequestException {
+        String fullPath = (name == null || name.length() == 0) ? mCurrentPath : mCurrentPath + "/" + name;
+        if (fullPath.equalsIgnoreCase("telecom/msg/outbox")) {
+            String handle = addToMmsFolder(DRAFTS, readStr);
+            if (INTERNAL_ERROR == handle) {  // == comparison valid here
+                rsp.response = ResponseCodes.OBEX_HTTP_NOT_FOUND;
+                return rsp;
+            }
+            moveMMSfromDraftstoOutbox();
+            if (V) Log.v(TAG, "\nBroadcasting Intent to MmsSystemEventReceiver\n ");
+            Intent sendIntent = new Intent("android.intent.action.MMS_PUSH");
+            mContext.sendBroadcast(sendIntent);
+            rsp.msgHandle = handle;
+            rsp.response = ResponseCodes.OBEX_HTTP_OK;
+            return rsp;
+        } else {
+            String splitStrings[] = mCurrentPath.split("/");
+            mMnsClient.addMceInitiatedOperation("+");
+            int tmp = splitStrings.length;
+            String folderName;
+            if (name != null) {
+                if (name.length() == 0) {
+                    folderName = splitStrings[tmp - 1];
+                } else {
+                    folderName = name;
+                }
+            } else {
+                folderName = splitStrings[tmp - 1];
+            }
+            if (folderName != null && folderName.equalsIgnoreCase(DRAFT)){
+                String handle = addToMmsFolder(folderName, readStr);
+                if (INTERNAL_ERROR == handle) {  // == comparison valid here
+                    rsp.msgHandle = null;
+                    rsp.response = ResponseCodes.OBEX_HTTP_NOT_FOUND;
+                    return rsp;
+                }
+                rsp.msgHandle = handle;
+                rsp.response = ResponseCodes.OBEX_HTTP_OK;
+                return rsp;
+            } else {
+                rsp.msgHandle = null;
+                rsp.response = ResponseCodes.OBEX_HTTP_FORBIDDEN;
+                return rsp;
+            }
+        }
+    }
+
+    private static int toByte(char c) throws BadRequestException{
+        if (c >= '0' && c <= '9') return (c - '0');
+        if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
+        if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
+        throw new BadRequestException ("Invalid hex char '" + c + "'");
+    }
+
+    private static byte[] hexStringToByteArray(String hexString) throws BadRequestException{
+        int length = hexString.length();
+        if((length % 2) != 0)
+            throw new BadRequestException ("HexString must be even number of characters");
+
+        byte[] buffer = new byte[length / 2];
+
+        for (int i = 0 ; i < length ; i += 2) {
+           buffer[i / 2] =  (byte)((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i+1)));
+        }
+        return buffer;
+    }
+
+    private String parseSMSDeliverPdu(String pdu)throws BadRequestException{
+        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        return sms.getMessageBody();
+    }
+
+    private BluetoothMasPushMsgRsp pushMessageSms(BluetoothMasPushMsgRsp rsp, String readStr,
+            String name, BluetoothMasAppParams bluetoothMasAppParams) throws BadRequestException {
+        BmessageConsts bMsg = MapUtils.fromBmessageSMS(readStr);
+        String address = bMsg.getRecipientVcard_phone_number();
+        String smsText;
+        if((int)bluetoothMasAppParams.Charset == 0)
+            smsText = parseSMSDeliverPdu(bMsg.getBody_msg());
+        else
+            smsText = bMsg.getBody_msg();
+        String fullPath = (name == null || name.length() == 0) ? mCurrentPath : mCurrentPath + "/" + name;
+        if(!"telecom/msg/outbox".equalsIgnoreCase(fullPath)) {
+            String splitStrings[] = mCurrentPath.split("/");
+            mMnsClient.addMceInitiatedOperation("+");
+            int tmp = splitStrings.length;
+            String folderName;
+            if (name != null) {
+                if (name.length() == 0){
+                    folderName = splitStrings[tmp - 1];
+                } else {
+                    folderName = name;
+                }
+            } else {
+                folderName = splitStrings[tmp - 1];
+            }
+            if (folderName != null && folderName.equalsIgnoreCase(DRAFT)) {
+                String handle = addToSmsFolder(folderName, address, smsText);
+                if (INTERNAL_ERROR == handle) {  // == comparison valid here
+                    rsp.msgHandle = null;
+                    rsp.response = ResponseCodes.OBEX_HTTP_NOT_FOUND;
+                    return rsp;
+                }
+                rsp.msgHandle = handle;
+                rsp.response = ResponseCodes.OBEX_HTTP_OK;
+                return rsp;
+            } else {
+                rsp.msgHandle = null;
+                rsp.response = ResponseCodes.OBEX_HTTP_FORBIDDEN;
+                return rsp;
+            }
+        }
+        rsp.msgHandle = "";
+        if (bluetoothMasAppParams.Transparent == 0) {
+            mMnsClient.addMceInitiatedOperation("+");
+            String handle = addToSmsFolder(QUEUED, address, smsText);
+            if (INTERNAL_ERROR == handle) {  // == comparison valid here
+                rsp.msgHandle = null;
+                rsp.response = ResponseCodes.OBEX_HTTP_NOT_FOUND;
+                return rsp;
+            }
+            rsp.msgHandle = handle;
+            rsp.response = ResponseCodes.OBEX_HTTP_OK;
+        } else if (bluetoothMasAppParams.Transparent == 1) {
+            ArrayList<String> parts = new ArrayList<String>();
+            SmsManager sms = SmsManager.getDefault();
+            parts = sms.divideMessage(smsText);
+
+            mMnsClient.addMceInitiatedOperation("+");
+            sms.sendMultipartTextMessage(address, null, parts, null, null);
+            rsp.msgHandle = "-1";
+            rsp.response = ResponseCodes.OBEX_HTTP_OK;
+            return rsp;
+        }
+
+        if (V) {
+            Log.v(TAG, " Trying to send SMS ");
+            Log.v(TAG, " Text " + smsText + " address " + address);
+        }
+
+        try {
+            Intent sendIntentSms = new Intent("com.android.mms.transaction.SEND_MESSAGE");
+            sendIntentSms.putExtra(android.content.Intent.EXTRA_PHONE_NUMBER, address);
+            sendIntentSms.putExtra(android.content.Intent.EXTRA_TEXT, smsText);
+            mContext.sendBroadcast(sendIntentSms);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return rsp;
+    }
+
+    private int setMsgStatusSms(long msgHandle, BluetoothMasAppParams bluetoothMasAppParams){
+        long handle = msgHandle - SMS_OFFSET_START;
+        Uri uri = Uri.parse("content://sms/" + handle);
+        Cursor cr = mContext.getContentResolver().query(uri, null, null, null, null);
+        if (cr != null && cr.moveToFirst()) {
+            if (bluetoothMasAppParams.StatusIndicator == 0) {
+                /* Read Status */
+                ContentValues values = new ContentValues();
+                values.put("read", bluetoothMasAppParams.StatusValue);
+                mContext.getContentResolver().update(uri, values, null, null);
+            } else {
+                if (bluetoothMasAppParams.StatusValue == 1) {
+                    deleteSMS(handle);
+                } else if (bluetoothMasAppParams.StatusValue == 0) {
+                    unDeleteSMS(handle);
+                }
+            }
+        }
+        if (cr != null) {
+            cr.close();
+        }
+        // Do we need to return ResponseCodes.OBEX_HTTP_BAD_REQUEST when cr == null?
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    private int setMsgStatusMms(long msgHandle, BluetoothMasAppParams bluetoothMasAppParams){
+        long handle = getMmsMsgHndToID(msgHandle);
+        String whereClause = " _id= " + handle;
+        Uri uri = Uri.parse("content://mms/");
+        if(handle > 0){
+            Cursor cr = mContext.getContentResolver().query(uri, null, null, null, null);
+            if (cr != null) {
+                if (cr.getCount() > 0) {
+                    cr.moveToFirst();
+                    if (bluetoothMasAppParams.StatusIndicator == 0) {
+                        /* Read Status */
+                        ContentValues values = new ContentValues();
+                        values.put("read", bluetoothMasAppParams.StatusValue);
+                        int rowUpdate = mContext.getContentResolver().update(uri,
+                                values, whereClause, null);
+                        if (V){
+                                Log.v(TAG, "\nRows updated => " + Integer.toString(rowUpdate));
+                        }
+                        return ResponseCodes.OBEX_HTTP_OK;
+                    } else {
+                        if (bluetoothMasAppParams.StatusValue == 1) {
+                            deleteMMS(handle);
+                        } else if (bluetoothMasAppParams.StatusValue == 0) {
+                            unDeleteMMS(handle);
+                        }
+                        return ResponseCodes.OBEX_HTTP_OK;
+                    }
+                }
+                cr.close();
+            }
+        }
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasMsg.java b/src/org/codeaurora/bluetooth/map/BluetoothMasMsg.java
new file mode 100644
index 0000000..81248f5
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasMsg.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import java.io.File;
+
+public class BluetoothMasMsg {
+
+    byte fractionDeliver;
+    File file;
+
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasObexServer.java b/src/org/codeaurora/bluetooth/map/BluetoothMasObexServer.java
new file mode 100644
index 0000000..c2accc3
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasObexServer.java
@@ -0,0 +1,1320 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.text.format.Time;
+import android.util.Log;
+
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageListingRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasPushMsgRsp;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+
+import javax.obex.ApplicationParameter;
+import javax.obex.HeaderSet;
+import javax.obex.Operation;
+import javax.obex.ResponseCodes;
+import javax.obex.ServerOperation;
+import javax.obex.ServerRequestHandler;
+
+import org.codeaurora.bluetooth.map.MapUtils.MapUtils.BadRequestException;
+
+public class BluetoothMasObexServer extends ServerRequestHandler {
+
+    private static final String TAG = "BluetoothMasObexServer";
+
+    private static final boolean D = BluetoothMasService.DEBUG;
+
+    private static final boolean V = BluetoothMasService.VERBOSE;
+
+    private static final int UUID_LENGTH = 16;
+
+    // type for list folder contents
+    private static final String TYPE_LISTING = "x-obex/folder-listing";
+    private static final String TYPE_MESSAGE_LISTING = "x-bt/MAP-msg-listing";
+    private static final String TYPE_MESSAGE = "x-bt/message";
+    private static final String TYPE_MESSAGE_STATUS = "x-bt/messageStatus";
+    private static final String TYPE_MESSAGE_UPDATE = "x-bt/MAP-messageUpdate";
+    private static final String TYPE_MESSAGE_NOTIFICATION = "x-bt/MAP-NotificationRegistration";
+
+    public long mConnectionId;
+
+    private Handler mCallback = null;
+
+    public Context mContext;
+
+    public static boolean sIsAborted = false;
+
+    private PowerManager.WakeLock mWakeLock = null;
+
+    public enum MasState {
+        MAS_SERVER_CONNECTING,
+        MAS_SERVER_DISCONNECTING,
+        MAS_SERVER_CONNECTED,
+        MAS_SERVER_DISCONNECTED,
+        MAS_SERVER_SET_FOLDER,
+        MAS_SERVER_GET_FILE_PENDING,
+        MAS_SERVER_BROWSE_FOLDER_PENDING,
+        MAS_SERVER_BROWSE_FOLDER,
+        MAS_SERVER_GET_MSG_LIST_PENDING,
+        MAS_SERVER_GET_MSG_LIST,
+        MAS_SERVER_GET_MSG_PENDING,
+        MAS_SERVER_GET_MSG,
+        MAS_SERVER_SET_MSG_STATUS,
+        MAS_SERVER_SET_NOTIFICATION_REG,
+        MAS_SERVER_UPDATE_INBOX,
+        MAS_SERVER_PUSH_MESSAGE
+    };
+    private MasState mState = MasState.MAS_SERVER_DISCONNECTED;
+
+     // 128 bit UUID for MAS
+    private static final byte[] MAS_TARGET = new byte[] {
+        (byte)0xbb, (byte)0x58, (byte)0x2b, (byte)0x40, (byte)0x42, (byte)0x0c, (byte)0x11, (byte)0xdb,
+        (byte)0xb0, (byte)0xde, (byte)0x08, (byte)0x00, (byte)0x20, (byte)0x0c, (byte)0x9a, (byte)0x66
+    };
+
+    private IBluetoothMasApp mAppIf;
+
+    private BluetoothDevice mRemoteDevice;
+
+    private class MasAppParamsStore {
+
+        private BluetoothMasAppParams appParams = null;
+
+        public final void clear() {
+            if (D) Log.d(TAG, "Clear AppParams : Enter");
+            appParams.MaxListCount = BluetoothMasSpecParams.MAS_DEFAULT_MAX_LIST_COUNT;
+            appParams.ListStartOffset = 0;
+            appParams.SubjectLength = BluetoothMasSpecParams.MAS_DEFAULT_SUBJECT_LENGTH;
+            appParams.ParameterMask = BluetoothMasSpecParams.MAS_DEFAULT_PARAMETER_MASK;
+            appParams.FilterMessageType = 0;
+            appParams.FilterReadStatus = 0;
+            appParams.FilterPriority = 0;
+            appParams.FilterPeriodBegin = null;
+            appParams.FilterPeriodEnd = null;
+            appParams.FilterRecipient = null;
+            appParams.FilterOriginator = null;
+            appParams.Retry = 1;
+            appParams.Transparent = 0;
+            appParams.FractionRequest = BluetoothMasSpecParams.MAS_FRACTION_REQUEST_NOT_SET;
+            appParams.Charset = 0x01;
+        }
+
+        public MasAppParamsStore() {
+            super();
+            appParams = new BluetoothMasAppParams();
+            clear();
+        }
+
+        public final BluetoothMasAppParams get() {
+            if (D) Log.d(TAG, "Create MasAppParams struct for service : Enter");
+            BluetoothMasAppParams tmp = new BluetoothMasAppParams();
+
+            tmp.MaxListCount = appParams.MaxListCount;
+            tmp.ListStartOffset = appParams.ListStartOffset;
+            tmp.SubjectLength = appParams.SubjectLength;
+            tmp.ParameterMask = appParams.ParameterMask;
+
+            tmp.Attachment = appParams.Attachment;
+            tmp.Charset = appParams.Charset;
+
+            tmp.StatusIndicator = appParams.StatusIndicator;
+            tmp.StatusValue = appParams.StatusValue;
+            tmp.Retry = appParams.Retry;
+
+            tmp.FilterMessageType = appParams.FilterMessageType;
+            tmp.FilterReadStatus = appParams.FilterReadStatus;
+            tmp.FilterPriority = appParams.FilterPriority;
+
+            tmp.FilterPeriodBegin = (appParams.FilterPeriodBegin == null) ? null : new String(appParams.FilterPeriodBegin);
+            tmp.FilterPeriodEnd = (appParams.FilterPeriodEnd == null) ? null : new String(appParams.FilterPeriodEnd);
+            tmp.FilterRecipient = (appParams.FilterRecipient == null) ? null : new String(appParams.FilterRecipient);
+            tmp.FilterOriginator = (appParams.FilterOriginator == null) ? null : new String(appParams.FilterOriginator);
+            tmp.Retry = appParams.Retry;
+            tmp.Transparent = appParams.Transparent;
+            tmp.FractionRequest = appParams.FractionRequest;
+            tmp.Notification = appParams.Notification;
+
+            return tmp;
+        }
+
+        public final boolean isMaxListCountZero() {
+
+            return (appParams.MaxListCount == 0) ? true : false;
+
+        }
+
+        private final int getUint16BigEndian(byte b1, byte b2) {
+            int retVal;
+            retVal = (int) ((0x0000FF00 & (int) (b1 << 0x8)) | (0x000000FF & (int) b2));
+            return retVal;
+        }
+
+        private final long getUint32BigEndian(byte b1, byte b2, byte b3, byte b4) {
+            long retVal;
+            retVal = (long) ((0xFF000000 & (long) (b1 << 0x24))
+                    | (0x00FF0000 & (long) (b2 << 0x16))
+                    | (0x0000FF00 & (long) (b3 << 0x8)) | (0x000000FF & (long) b4));
+            return retVal;
+        }
+
+        private final boolean validateTag(long tagVal, long tagLen, long tagMinVal, long tagMaxVal, long tagActualLen) {
+
+            if (tagLen != tagActualLen) {
+                return false;
+            }
+
+            if ( tagVal < tagMinVal || tagVal > tagMaxVal){
+                return false;
+            }
+            return true;
+        }
+
+        public final boolean parse(byte[] params) {
+            int i = 0;
+
+
+            if (D) Log.d(TAG, "Parse App. Params: Enter");
+
+            if (params == null){
+                if (D) Log.d(TAG, "No App. Params to parse: Exit");
+                return true;
+            }
+
+            while (i < params.length) {
+                switch (params[i]) {
+                case BluetoothMasSpecParams.MAS_TAG_MAX_LIST_COUNT:
+                    i += 2;
+                    appParams.MaxListCount = getUint16BigEndian(params[i], params[i + 1]);
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " params i+1"
+                                + params[i + 1] + " maxlistcount "
+                                + appParams.MaxListCount);
+                    }
+                    if(validateTag((long)appParams.MaxListCount, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_MAX_LIST_COUNT_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_MAX_LIST_COUNT_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_MAX_LIST_COUNT_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_MAX_LIST_COUNT_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_LIST_START_OFFSET:
+                    i += 2;
+                    appParams.ListStartOffset = getUint16BigEndian(params[i],
+                            params[i + 1]);
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " params i+1"
+                                + params[i + 1] + " maxlistcount "
+                                + appParams.ListStartOffset);
+                    }
+                    if(validateTag((long)appParams.ListStartOffset, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_LIST_START_OFFSET_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_LIST_START_OFFSET_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_LIST_START_OFFSET_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_LIST_START_OFFSET_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_FILTER_PERIOD_BEGIN:
+                    i += 1;
+                    appParams.FilterPeriodBegin = new String("");
+                    for (int j = 1; j <= params[i]; j++) {
+                        appParams.FilterPeriodBegin += (char) params[i + j];
+                    }
+                    if (V){
+                        Log.v(TAG, "FilterPeriodBegin "
+                                + appParams.FilterPeriodBegin);
+                    }
+                    i += params[i];
+                    i += 1;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_FILTER_PERIOD_END:
+                    i += 1;
+                    appParams.FilterPeriodEnd = new String("");
+                    for (int j = 1; j <= params[i]; j++) {
+                        appParams.FilterPeriodEnd += (char) params[i + j];
+                    }
+                    if (V){
+                        Log.v(TAG, "FilterPeriodEnd " + appParams.FilterPeriodEnd);
+                    }
+                    i += params[i];
+                    i += 1;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_FILTER_RECIPIENT:
+                    i += 1;
+                    appParams.FilterRecipient = new String("");
+                    for (int j = 1; j <= params[i]; j++) {
+                        appParams.FilterRecipient += (char)params[i + j];
+
+                    }
+                    if (V){
+                        Log.v(TAG, "FilterPeriodRecipient "
+                                + appParams.FilterRecipient);
+                    }
+                    i += params[i];
+                    i += 1;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_FILTER_ORIGINATOR:
+                    i += 1;
+                    appParams.FilterOriginator = new String("");
+                    for (int j = 1; j <= params[i]; j++) {
+                        appParams.FilterOriginator += (char) params[i+ j];
+                    }
+                    if (V){
+                        Log.v(TAG, "FilterPeriodOriginator "
+                                + appParams.FilterOriginator);
+                    }
+                    i += params[i];
+                    i += 1;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_FILTER_MESSAGE_TYPE:
+                    i += 2;
+                    appParams.FilterMessageType = params[i];
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " FilterMessageType "
+                                + appParams.FilterMessageType);
+                    }
+                    if(validateTag((long)appParams.FilterMessageType, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FILTER_MESSAGE_TYPE_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FILTER_MESSAGE_TYPE_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FILTER_MESSAGE_TYPE_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_FILTER_MESSAGE_TYPE_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_FILTER_READ_STATUS:
+                    i += 2;
+                    appParams.FilterReadStatus = params[i];
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " FilterReadStatus "
+                                + appParams.FilterReadStatus);
+                    }
+                    if(validateTag((long)appParams.FilterReadStatus, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FILTER_READ_STATUS_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FILTER_READ_STATUS_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FILTER_READ_STATUS_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_FILTER_READ_STATUS_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_FILTER_PRIORITY:
+                    i += 2;
+                    appParams.FilterPriority = params[i];
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " FilterPriority "
+                                + appParams.FilterPriority);
+                    }
+                    if(validateTag((long)appParams.FilterPriority, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FILTER_PRIORITY_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FILTER_PRIORITY_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FILTER_PRIORITY_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_FILTER_PRIORITY_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_STATUS_INDICATOR:
+                    i += 2;
+                    appParams.StatusIndicator = params[i];
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " StatusIndicator "
+                                + appParams.StatusIndicator);
+                    }
+                    if(validateTag((long)appParams.StatusIndicator, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_STATUS_INDICATOR_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_STATUS_INDICATOR_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_STATUS_INDICATOR_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_STATUS_INDICATOR_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_STATUS_VALUE:
+                    i += 2;
+                    appParams.StatusValue = params[i];
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " StatusValue "
+                                + appParams.StatusValue);
+                    }
+                    if(validateTag((long)appParams.StatusValue, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_STATUS_VALUE_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_STATUS_VALUE_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_STATUS_VALUE_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_STATUS_VALUE_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_SUBJECT_LENGTH:
+                    i += 2;
+                    appParams.SubjectLength = (short)(params[i] & 0x00FF);
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " SubjectLen "
+                                + appParams.SubjectLength);
+                    }
+                    if(validateTag((long)appParams.SubjectLength, (long) params[i-1],
+                                         (long) BluetoothMasSpecParams.MAS_TAG_SUBJECT_LENGTH_MIN_VAL,
+                                         (long) BluetoothMasSpecParams.MAS_TAG_SUBJECT_LENGTH_MAX_VAL,
+                                         (long) BluetoothMasSpecParams.MAS_TAG_SUBJECT_LENGTH_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_SUBJECT_LENGTH_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_PARAMETER_MASK:
+                    i += 2;
+                    appParams.ParameterMask = getUint32BigEndian(params[i],
+                            params[i + 1], params[i + 2], params[i + 3]);
+                    if ( appParams.ParameterMask == 0 ){
+                        // If it is 0, send all parameters
+                        appParams.ParameterMask = BluetoothMasSpecParams.MAS_DEFAULT_PARAMETER_MASK;
+                    }
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " params i+1"
+                                + params[i + 1] + "params[i+2]" + params[i + 2]
+                                + "params[i+3" + params[i + 3] + " ParameterMask "
+                                + appParams.ParameterMask);
+                    }
+                    if(validateTag((long)appParams.ParameterMask, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_PARAMETER_MASK_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_PARAMETER_MASK_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_PARAMETER_MASK_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_PARAMETER_MASK_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_CHARSET:
+                    i += 2;
+                    appParams.Charset = params[i];
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " Charset "
+                                + appParams.Charset);
+                    }
+                    if(validateTag((long)appParams.Charset, (long) params[i-1],
+                                          (long) BluetoothMasSpecParams.MAS_TAG_CHARSET_MIN_VAL,
+                                          (long) BluetoothMasSpecParams.MAS_TAG_CHARSET_MAX_VAL,
+                                          (long) BluetoothMasSpecParams.MAS_TAG_CHARSET_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_CHARSET_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_TRANSPARENT:
+                    i += 2;
+                    appParams.Transparent = params[i];
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " Transparent "
+                                + appParams.Transparent);
+                    }
+                    if(validateTag((long)appParams.Transparent, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_TRANSPARENT_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_TRANSPARENT_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_TRANSPARENT_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_TRANSPARENT_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_RETRY:
+                    i += 2;
+                    appParams.Retry = params[i];
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " Retry "
+                                + appParams.Retry);
+                    }
+                    if(validateTag((long)appParams.Retry, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_RETRY_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_RETRY_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_RETRY_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_RETRY_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_ATTACHMENT:
+                    i += 2;
+                    appParams.Attachment = params[i];
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " Attachment "
+                                + appParams.Attachment);
+                    }
+                    if(validateTag((long)appParams.Attachment, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_ATTACHMENT_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_ATTACHMENT_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_ATTACHMENT_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_ATTACHMENT_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_FRACTION_REQUEST:
+                    i += 2;
+                    appParams.FractionRequest = params[i];
+                    if (V){
+                        Log.v(TAG, " params i " + params[i] + " Fraction Request "
+                                + appParams.FractionRequest);
+                    }
+                    if(validateTag((long)appParams.FractionRequest, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FRACTION_REQUEST_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FRACTION_REQUEST_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_FRACTION_REQUEST_LEN ) == false){
+                        return false;
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_FRACTION_REQUEST_LEN;
+                    break;
+
+                case BluetoothMasSpecParams.MAS_TAG_NOTIFICATION_STATUS:
+                    i += 2;
+                    appParams.Notification = params[i];
+                    if(validateTag((long)appParams.MaxListCount, (long) params[i-1],
+                                   (long) BluetoothMasSpecParams.MAS_TAG_NOTIFICATION_STATUS_MIN_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_NOTIFICATION_STATUS_MAX_VAL,
+                                   (long) BluetoothMasSpecParams.MAS_TAG_NOTIFICATION_STATUS_LEN ) == false){
+                        return false;
+
+                    }
+                    i += BluetoothMasSpecParams.MAS_TAG_NOTIFICATION_STATUS_LEN;
+                    break;
+                default:
+                    break;
+
+                }
+            }
+            return true;
+        }
+    }
+
+    private MasAppParamsStore masAppParams = new MasAppParamsStore();
+
+    public BluetoothMasObexServer(Handler callback, BluetoothDevice remoteDevice,
+            Context context, IBluetoothMasApp appIf) {
+        super();
+        mAppIf = appIf;
+
+        mConnectionId = -1;
+        mCallback = callback;
+        mContext = context;
+        mRemoteDevice = remoteDevice;
+        if (V){
+            Log.v(TAG, "BlueoothMasObexServer const called");
+        }
+        // set initial value when ObexServer created
+        if (D) Log.d(TAG, "Initialize MasObexServer");
+    }
+
+    @Override
+    public int onConnect(final HeaderSet request, HeaderSet reply) {
+        if (V) Log.v(TAG, "BluetoothMasObexServer: onConnect");
+        acquireMasLock();
+        int retVal = onConnectInternal(request, reply);
+        if (V) Log.v(TAG, "BluetoothMasObexServer: exiting from onConnect");
+        releaseMasLock();
+        return retVal;
+    }
+
+    private int onConnectInternal(final HeaderSet request, HeaderSet reply) {
+        if (D) Log.d(TAG, "onConnect()");
+        try {
+            byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
+            if (uuid == null) {
+                Log.w(TAG, "Null UUID ");
+                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+            }
+            if (D)
+                Log.d(TAG, "onConnect(): uuid=" + Arrays.toString(uuid));
+
+            if (uuid.length != UUID_LENGTH) {
+                Log.w(TAG, "Wrong UUID length");
+                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+            }
+            for (int i = 0; i < UUID_LENGTH; i++) {
+                if (uuid[i] != MAS_TARGET[i]) {
+                    Log.w(TAG, "Wrong UUID");
+                    return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+                }
+            }
+            if (!mAppIf.checkPrecondition()) {
+                return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+            }
+            reply.setHeader(HeaderSet.WHO, uuid);
+        } catch (IOException e) {
+            Log.e(TAG, e.toString());
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, e.toString());
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        try {
+            byte[] remote = (byte[]) request.getHeader(HeaderSet.WHO);
+            if (remote != null) {
+                if (D) Log.d(TAG, "onConnect(): remote=" + Arrays.toString(remote));
+                reply.setHeader(HeaderSet.TARGET, remote);
+            }
+        } catch (IOException e) {
+            Log.e(TAG, e.toString());
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+
+        if (V) Log.v(TAG, "onConnect(): uuid is ok, will send out "
+            + "MSG_SESSION_ESTABLISHED msg.");
+
+        Message msg = Message.obtain(mCallback);
+        msg.what = BluetoothMasService.MSG_SESSION_ESTABLISHED;
+        msg.sendToTarget();
+
+        mState = MasState.MAS_SERVER_CONNECTED;
+        if (D) Log.d(TAG, "Connect(): Success");
+        mAppIf.onConnect();
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    @Override
+    public void onDisconnect(final HeaderSet req, final HeaderSet resp) {
+        if (V) Log.v(TAG, "BluetoothMasObexServer: onDisconnect");
+        acquireMasLock();
+        onDisconnectInternal(req, resp);
+        if (V) Log.v(TAG, "BluetoothMasObexServer: exiting from onDisconnect");
+        releaseMasLock();
+    }
+
+    private void onDisconnectInternal(final HeaderSet req, final HeaderSet resp) {
+        if (D) Log.d(TAG, "onDisconnect(): enter");
+        mAppIf.onDisconnect();
+
+        resp.responseCode = ResponseCodes.OBEX_HTTP_OK;
+        if (mCallback != null) {
+            Message msg = Message.obtain(mCallback);
+            msg.what = BluetoothMasService.MSG_SESSION_DISCONNECTED;
+            msg.sendToTarget();
+            if (V) Log.v(TAG,"onDisconnect(): msg MSG_SESSION_DISCONNECTED sent out.");
+        }
+
+        // MNS Service
+        mAppIf.stopMnsSession(mRemoteDevice);
+        mState = MasState.MAS_SERVER_DISCONNECTED;
+    }
+
+    @Override
+    public int onAbort(HeaderSet request, HeaderSet reply) {
+        if (D) Log.d(TAG, "onAbort(): enter.");
+        sIsAborted = true;
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    @Override
+    public int onSetPath(final HeaderSet request, final HeaderSet reply,
+            final boolean backup, final boolean create) {
+        if (V) Log.v(TAG, "BluetoothMasObexServer: onSetPath");
+        acquireMasLock();
+        int retVal = onSetPathInternal(request, reply, backup, create);
+        if (V) Log.v(TAG, "BluetoothMasObexServer: exiting from onSetPath");
+        releaseMasLock();
+        return retVal;
+    }
+
+    private int onSetPathInternal(final HeaderSet request, final HeaderSet reply,
+            final boolean backup, final boolean create) {
+
+        if (D) Log.d(TAG, "onSetPath(): supports SetPath request.");
+
+        String tmpPath = null;
+        boolean retVal = false;
+        boolean tmpBackup = backup;
+
+        if (tmpBackup && create) {
+            tmpBackup = true;
+        } else {
+            tmpBackup = false;
+        }
+        if (mState != MasState.MAS_SERVER_CONNECTED) {
+            if (D)
+                Log.e(TAG, "onSetPath() Failed: Mas Server not connected");
+            return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+        }
+        mState = MasState.MAS_SERVER_SET_FOLDER;
+
+        try {
+            tmpPath = (String) request.getHeader(HeaderSet.NAME);
+        } catch (IOException e) {
+            Log.e(TAG, "Get name header fail: " + e);
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Get name header fail: " + e);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+        if (D)
+            Log.d(TAG, "backup=" + backup + " create=" + create + " name="
+                    + tmpPath);
+
+        retVal = mAppIf.setPath(backup, tmpPath);
+        mState = MasState.MAS_SERVER_CONNECTED;
+        if (retVal == true) {
+            if (V)
+                Log.v(TAG, "SetPath to" + tmpPath + "SUCCESS");
+            return ResponseCodes.OBEX_HTTP_OK;
+        } else {
+            Log.e(TAG, "Path not found");
+            return ResponseCodes.OBEX_HTTP_NOT_FOUND;
+        }
+    }
+
+    @Override
+    public void onClose() {
+        if (V) Log.v(TAG, "BluetoothMasObexServer: onClose");
+        acquireMasLock();
+        onCloseInternal();
+        if (V) Log.v(TAG, "BluetoothMasObexServer: exiting from onClose");
+        releaseMasLock();
+    }
+
+    public void onCloseInternal() {
+        mAppIf.stopMnsSession(mRemoteDevice);
+
+        if (mCallback != null) {
+            Message msg = Message.obtain(mCallback);
+            msg.what = BluetoothMasService.MSG_SERVERSESSION_CLOSE;
+            msg.arg1 = mAppIf.getMasId();
+            msg.sendToTarget();
+            if (D) Log.d(TAG, "onClose(): msg MSG_SERVERSESSION_CLOSE sent out.");
+        }
+    }
+
+    @Override
+    public int onGet(Operation op) {
+        if (V) Log.v(TAG, "BluetoothMasObexServer: onGet");
+        acquireMasLock();
+        int retVal = onGetInternal(op);
+        if (V) Log.v(TAG, "BluetoothMasObexServer: exiting from onGet");
+        releaseMasLock();
+        return retVal;
+    }
+
+    private int onGetInternal(Operation op) {
+
+        byte[] appParams = null;
+        boolean retVal = true;
+
+        if (D) Log.d(TAG, "onGet(): support GET request.");
+
+        sIsAborted = false;
+        HeaderSet request = null;
+        String type = "";
+        String name = "";
+
+        // TBD - IncompleteGet handling
+        try {
+            request = op.getReceivedHeader();
+            type = (String) request.getHeader(HeaderSet.TYPE);
+            name = (String) request.getHeader(HeaderSet.NAME);
+            appParams = (byte[])request.getHeader(HeaderSet.APPLICATION_PARAMETER);
+        } catch (IOException e) {
+            Log.e(TAG, "request headers error: " + e);
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "request headers error: " + e);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        masAppParams.clear();
+        retVal = masAppParams.parse(appParams);
+
+        if (type == null || (retVal == false) ) {
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        if (V) Log.v(TAG, "type = " + type);
+
+        if (type.equals(TYPE_LISTING)) {
+            return sendFolderListing(op);
+        }
+        if (type.equals(TYPE_MESSAGE_LISTING)) {
+            return sendMsgListing(op, name);
+        }
+        if (type.equals(TYPE_MESSAGE)) {
+            return sendMsg(op, name);
+        }
+
+        if (V) Log.v(TAG, "get returns HTTP_BAD_REQUEST");
+        return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+
+    }
+
+    private final int pushMsg(Operation op, String name) {
+        // TBD - Need to do this on a per masinstance basis
+        String fileName = "PushMsg" + mAppIf.getMasId();
+        int outputBufferSize = op.getMaxPacketSize();
+        int readLength = 0;
+        long timestamp = 0;
+        int position = 0;
+        byte[] b = new byte[outputBufferSize];
+        BufferedOutputStream bos = null;
+        InputStream is = null;
+        boolean error = false;
+        File file = null;
+        BluetoothMasPushMsgRsp pMsg = new BluetoothMasPushMsgRsp();;
+
+        file = new File(mContext.getFilesDir() + "/" + fileName);
+
+        try {
+            is = op.openInputStream();
+        } catch (IOException e1) {
+            Log.e(TAG, "Error while opening InputStream");
+            error = true;
+        }
+
+        if (error != true) {
+            try {
+
+                FileOutputStream fos = mContext.openFileOutput(fileName,
+                        Context.MODE_PRIVATE);
+
+                bos = new BufferedOutputStream(fos);
+            } catch (FileNotFoundException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+
+        if (error != true) {
+            try {
+                while (true) {
+                    if (V) {
+                        timestamp = System.currentTimeMillis();
+                    }
+                    readLength = is.read(b);
+                    if (readLength == -1) {
+                        if (D) {
+                            Log.d(TAG, "Receive file reached stream end at position" + position);
+                        }
+                        break;
+                    }
+                    bos.write(b, 0, readLength);
+                    position += readLength;
+                    if (V) {
+                        Log.v(TAG, "Receive file position = " + position
+                                + " readLength " + readLength + " bytes took "
+                                + (System.currentTimeMillis() - timestamp)
+                                + " ms");
+                    }
+                }
+            } catch (IOException e1) {
+                Log.e(TAG, "Error when receiving file");
+                error = true;
+            }
+        }
+
+        if (bos != null) {
+            try {
+                bos.close();
+            } catch (IOException e) {
+                Log.e(TAG, "Error when closing stream after send");
+                error = true;
+            }
+        }
+
+        if (error != true) {
+            try {
+                pMsg = mAppIf.pushMsg(name, file, masAppParams.get());
+            } catch (BadRequestException e) {
+                if (V) Log.v(TAG, "BadRequestException:" + e.getMessage(), e);
+                return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            }
+
+            if ((pMsg.msgHandle != null)
+                    && (pMsg.response == ResponseCodes.OBEX_HTTP_OK)) {
+                HeaderSet reply;
+                reply = new HeaderSet();
+                reply.setHeader(HeaderSet.NAME, pMsg.msgHandle);
+                return pushHeader(op, reply);
+            } else {
+                return pMsg.response;
+            }
+        } else {
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+    }
+
+    private final int msgStatus(Operation op, String name) {
+        if (D) Log.d(TAG, "msgStatus: Enter");
+        if (name == null || name.length() == 0) {
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+        return mAppIf.msgStatus(name, masAppParams.get());
+    }
+
+    private final int msgUpdate(Operation op) {
+        if (D) Log.d(TAG, "msgUpdate: Enter");
+        return mAppIf.msgUpdate();
+    }
+
+    private final int notification(Operation op) {
+        return mAppIf.notification(mRemoteDevice, masAppParams.get());
+    }
+
+    @Override
+    public int onPut(Operation op) {
+        if (V) Log.v(TAG, "BluetoothMasObexServer: onPut");
+        acquireMasLock();
+        int retVal = onPutInternal(op);
+        if (V) Log.v(TAG, "BluetoothMasObexServer: exiting from onPut");
+        releaseMasLock();
+        return retVal;
+    }
+
+    private int onPutInternal(Operation op) {
+
+        byte[] appParams = null;
+        boolean retVal = true;
+        BluetoothMasAppParams tmp;
+        InputStream inputStream = null;
+        byte[] readByte = new byte[10];
+
+        if (D) Log.d(TAG, "onPut(): support PUT request.");
+
+        sIsAborted = false;
+        HeaderSet request = null;
+        String type = "";
+        String name = "";
+
+        // TBD - IncompleteGet handling
+        try {
+            request = op.getReceivedHeader();
+            type = (String) request.getHeader(HeaderSet.TYPE);
+            name = (String) request.getHeader(HeaderSet.NAME);
+            appParams = (byte[])request.getHeader(HeaderSet.APPLICATION_PARAMETER);
+        } catch (IOException e) {
+            Log.e(TAG, "request headers error: " + e);
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "request headers error: " + e);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+        masAppParams.clear();
+        if ( appParams != null ){
+            masAppParams.parse(appParams);
+        }
+        if(type == null || retVal == false) {
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        tmp = masAppParams.get();
+
+        if (V) Log.v(TAG, "type = " + type);
+
+        if (type.equals(TYPE_MESSAGE)) {
+            return pushMsg(op, name);
+        }
+        if (type.equals(TYPE_MESSAGE_STATUS)) {
+            return msgStatus(op, name);
+        }
+        if (type.equals(TYPE_MESSAGE_UPDATE)) {
+            return msgUpdate(op);
+        }
+        if (type.equals(TYPE_MESSAGE_NOTIFICATION)) {
+            if (V) Log.v(TAG, "entered TYPE_MESSAGE_NOTIFICATION");
+            // Following section of code ensures if the Body/EOB
+            // payload is not present in the same Obex packet
+            // Containing headers, but is pushed in the continuation
+            // packet, then we take the corresponding action only
+            // after reading the complete obex packet.
+            // And as the Body / EOB payload contains dummy body as
+            // '0' [0x30 (48)], hence we discard the same.
+            if (!(((ServerOperation) op).finalBitSet)) {
+                if (V) Log.v(TAG, "Not the final Obex packet");
+                try {
+                    inputStream = op.openInputStream();
+                    int readLength = -1;
+                    while(true) {
+                        if (V) Log.v(TAG, "Inside while loop: TYPE_MESSAGE_NOTIFICATION");
+                        readLength = inputStream.read(readByte);
+                        if (readLength == -1) {
+                            if (V) Log.v(TAG, "Complete Obex packet read, Proceeding");
+                            break;
+                        } else {
+                            if (V) Log.v(TAG, "readLength: " + readLength);
+                            if (V) Log.v(TAG, "readByte[0]: " + readByte[0]);
+                            // Compare first byte to check if '0' is received as Body/ EOB
+                            // And Length of the Body Payload is 1, If not, print Error
+                            if ((readByte[0] == 0x30) && (readLength == 1)) {
+                                if (V) Log.v(TAG, "Body / EOB contains '0'");
+                            } else {
+                                Log.e(TAG, "Body / EOB does not contain '0'");
+                            }
+                        }
+                    }
+                } catch (IOException ioException) {
+                    Log.e(TAG, "Error while opening InputStream");
+                } finally {
+                    try {
+                        if (inputStream != null) {
+                            inputStream.close();
+                        }
+                    } catch (IOException ioException) {
+                        Log.e(TAG, "Error when closing stream");
+                    }
+                }
+            }
+            return notification(op);
+        }
+        if (V) Log.v(TAG, "put returns HTTP_BAD_REQUEST");
+        return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+
+    }
+
+    /**
+    */
+    private final int pushHeader(final Operation op, final HeaderSet reply) {
+
+        if (D) Log.d(TAG, "Push Header");
+        if (D) Log.d(TAG, reply.toString());
+
+        int pushResult = ResponseCodes.OBEX_HTTP_OK;
+        try {
+            op.sendHeaders(reply);
+        } catch (IOException e) {
+            Log.e(TAG, e.toString());
+            pushResult = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, e.toString());
+            pushResult = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+        if (D) Log.d(TAG, "Push Header: Exit : RetVal " + pushResult);
+        return pushResult;
+    }
+
+    /** Function to send folder data to client */
+    private final int sendFolderListingBody(Operation op,
+            final String folderlistString) {
+
+        if (folderlistString == null) {
+            Log.e(TAG, "folderlistString is null!");
+            return ResponseCodes.OBEX_HTTP_OK;
+        }
+
+        int folderlistStringLen = folderlistString.length();
+        if (D) Log.d(TAG, "Send Folder Listing Body: len=" + folderlistStringLen);
+
+        OutputStream outputStream = null;
+        int pushResult = ResponseCodes.OBEX_HTTP_OK;
+        try {
+            outputStream = op.openOutputStream();
+        } catch (IOException e) {
+            Log.e(TAG, "open outputstrem failed" + e.toString());
+            return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+        }
+
+        int position = 0;
+        long timestamp = 0;
+        int outputBufferSize = op.getMaxPacketSize();
+        if (V) Log.v(TAG, "outputBufferSize = " + outputBufferSize);
+        while (position != folderlistStringLen) {
+            if (sIsAborted) {
+                ((ServerOperation) op).isAborted = true;
+                sIsAborted = false;
+                break;
+            }
+            if (V) timestamp = System.currentTimeMillis();
+            int readLength = outputBufferSize;
+            if (folderlistStringLen - position < outputBufferSize) {
+                readLength = folderlistStringLen - position;
+            }
+            String subStr = folderlistString.substring(position, position + readLength);
+            try {
+                outputStream.write(subStr.getBytes(), 0, readLength);
+            } catch (IOException e) {
+                Log.e(TAG, "write outputstream failed" + e.toString());
+                pushResult = ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+                break;
+            }
+            if (V) {
+                Log.d(TAG, "Sending folderlist String position = " + position
+                        + " readLength " + readLength + " bytes took "
+                        + (System.currentTimeMillis() - timestamp) + " ms");
+            }
+            position += readLength;
+        }
+
+        if (V) Log.v(TAG, "Send Data complete!");
+
+        if (!closeStream(outputStream, op)) {
+            Log.e(TAG,"Send Folder Listing Body - Close output stream error! ");
+            pushResult = ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+        }
+        if (V) Log.v(TAG, "Send Folder Listing Body complete! result = " + pushResult);
+        return pushResult;
+    }
+
+    private final int sendBody(Operation op, File fileinfo) {
+        if (V) Log.v(TAG, "sendFile = " + fileinfo.getName());
+        int position = 0;
+        int readLength = 0;
+        int outputBufferSize = op.getMaxPacketSize();
+        long timestamp = 0;
+        FileInputStream fileInputStream = null;
+        OutputStream outputStream;
+        BufferedInputStream bis;
+
+        if (D) Log.d(TAG, "Send Body: Enter");
+        try {
+            byte[] buffer = new byte[outputBufferSize];
+            fileInputStream = new FileInputStream(fileinfo);
+            outputStream = op.openOutputStream();
+            bis = new BufferedInputStream(fileInputStream, 0x4000);
+            while ((position != fileinfo.length())) {
+                timestamp = System.currentTimeMillis();
+                if (position != fileinfo.length()) {
+                    readLength = bis.read(buffer, 0, outputBufferSize);
+                }
+                outputStream.write(buffer, 0, readLength);
+                position += readLength;
+                if (V) {
+                    Log.v(TAG, "Sending file position = " + position
+                            + " readLength " + readLength + " bytes took "
+                            + (System.currentTimeMillis() - timestamp) + " ms");
+                }
+            }
+        } catch (IOException e) {
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        } finally {
+            if (fileInputStream != null) {
+                try {
+                    fileInputStream.close();
+                } catch (IOException ei) {
+                    Log.e(TAG, "Error while closing stream"+ ei.toString());
+                }
+            }
+        }
+        if (position == fileinfo.length()) {
+            if (D) Log.d(TAG, "SendBody : Exit: OK");
+            return ResponseCodes.OBEX_HTTP_OK;
+        }
+        else {
+            if (D) Log.d(TAG, "SendBody : Exit: CONTINUE");
+            return ResponseCodes.OBEX_HTTP_CONTINUE;
+        }
+    }
+
+    /** Send a bMessage to client */
+    private final int sendMsg(Operation op, String name) {
+        BluetoothMasMessageRsp msg = new BluetoothMasMessageRsp();
+        byte[] val = new byte[1];
+
+        if (D) Log.d(TAG, "SendMsg : Enter");
+        msg = mAppIf.msg(name, masAppParams.get());
+        if(msg == null || msg.rsp != ResponseCodes.OBEX_HTTP_OK) {
+            return msg.rsp;
+        }
+
+        if(masAppParams.get().FractionRequest == 1){
+            HeaderSet reply;
+            val[0] = msg.fractionDeliver;
+            ApplicationParameter ap = new ApplicationParameter();
+            ap.addAPPHeader(
+                (byte) BluetoothMasSpecParams.MAS_TAG_FRACTION_DELIVER,
+                (byte) BluetoothMasSpecParams.MAS_TAG_FRACTION_DELIVER_LEN,
+                 val);
+
+            reply = new HeaderSet();
+            reply.setHeader(HeaderSet.APPLICATION_PARAMETER, ap.getAPPparam());
+
+            int retVal;
+            retVal = pushHeader(op, reply);
+            if (retVal != ResponseCodes.OBEX_HTTP_OK) {
+                if (D) Log.d(TAG, "SendMsg : FAILED: RetVal " + retVal);
+                 return retVal;
+            }
+        }
+        if (D) Log.d(TAG, "SendMsg : SUCCESS");
+        return sendBody(op, msg.file);
+    }
+
+    /** Send an XML format String to client for Folder listing */
+    private final int sendFolderListing(Operation op) {
+        int folderListSize = 0;
+        if (D) Log.d(TAG, "SendFolderListing : Enter");
+        folderListSize = mAppIf.folderListingSize();
+        byte[] size = new byte[2];
+        size[0] = (byte) ((folderListSize / 0x100) & 0xff);
+        size[1] = (byte) ((folderListSize % 0x100) & 0xff);
+
+        HeaderSet reply;
+        ApplicationParameter ap = new ApplicationParameter();
+        ap.addAPPHeader(
+            (byte) BluetoothMasSpecParams.MAS_TAG_FOLDER_LISTING_SIZE,
+            (byte) BluetoothMasSpecParams.MAS_TAG_FOLDER_LISTING_SIZE_LEN,
+            size);
+        reply = new HeaderSet();
+        reply.setHeader(HeaderSet.APPLICATION_PARAMETER, ap.getAPPparam());
+
+        if (!masAppParams.isMaxListCountZero()) {
+            int retVal;
+            retVal = pushHeader(op, reply);
+            if (retVal != ResponseCodes.OBEX_HTTP_OK) {
+                if (D) Log.d(TAG, "SendFolderListing : FAILED : RetVal" + retVal);
+                return retVal;
+            }
+            return sendFolderListingBody(op, mAppIf.folderListing(masAppParams.get()));
+        } else {
+            op.noEndofBody();
+            return pushHeader(op, reply);
+        }
+    }
+
+    /** Send an XML format String to client for Message listing */
+    private final int sendMsgListing(Operation op, String name) {
+
+        byte[] val = new byte[2];
+        BluetoothMasMessageListingRsp appIfMsgListRsp = new BluetoothMasMessageListingRsp();
+        if (D) Log.d(TAG, "SendMsgListing : Enter");
+        appIfMsgListRsp = mAppIf.msgListing(name, masAppParams.get());
+
+        if(appIfMsgListRsp == null || appIfMsgListRsp.rsp != ResponseCodes.OBEX_HTTP_OK) {
+            return appIfMsgListRsp.rsp;
+        }
+
+        Time time = new Time();
+        time.setToNow();
+
+        String time3339 = time.format3339(false);
+        int timeStrLength = time3339.length();
+
+        String datetimeStr = time.toString().substring(0, 15) +
+                time3339.substring(timeStrLength - 6, timeStrLength - 3) +
+                time3339.substring(timeStrLength - 2, timeStrLength);
+
+        byte[] MSETime = datetimeStr.getBytes();
+
+        HeaderSet reply;
+        ApplicationParameter ap = new ApplicationParameter();
+        ap.addAPPHeader((byte) BluetoothMasSpecParams.MAS_TAG_MSE_TIME,
+                (byte) BluetoothMasSpecParams.MAS_TAG_MSE_TIME_LEN, MSETime);
+        val[0] = appIfMsgListRsp.newMessage;
+        ap.addAPPHeader((byte) BluetoothMasSpecParams.MAS_TAG_NEW_MESSAGE,
+                (byte) BluetoothMasSpecParams.MAS_TAG_NEW_MESSAGE_LEN, val);
+
+        val[0] = (byte) ((appIfMsgListRsp.msgListingSize / 0x100) & 0xff);
+        val[1] = (byte) ((appIfMsgListRsp.msgListingSize % 0x100) & 0xff);
+
+        ap.addAPPHeader(
+                (byte) BluetoothMasSpecParams.MAS_TAG_MESSAGE_LISTING_SIZE,
+                (byte) BluetoothMasSpecParams.MAS_TAG_MESSAGE_LISTING_SIZE_LEN,
+                val);
+
+        reply = new HeaderSet();
+        reply.setHeader(HeaderSet.APPLICATION_PARAMETER, ap.getAPPparam());
+
+        if (!masAppParams.isMaxListCountZero()) {
+            int retVal;
+            retVal = pushHeader(op, reply);
+            if (retVal != ResponseCodes.OBEX_HTTP_OK) {
+                if (D) Log.d(TAG, "SendMsgListing : Failed : RetVal " + retVal);
+                return retVal;
+            }
+            return sendBody(op, appIfMsgListRsp.file);
+        } else {
+            return pushHeader(op, reply);
+        }
+    }
+
+    public static boolean closeStream(final OutputStream out, final Operation op) {
+        boolean returnvalue = true;
+        try {
+            if (out != null) {
+                out.close();
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "outputStream close failed" + e.toString());
+            returnvalue = false;
+        }
+        try {
+            if (op != null) {
+                op.close();
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "operation close failed" + e.toString());
+            returnvalue = false;
+        }
+        return returnvalue;
+    }
+
+    private void acquireMasLock() {
+        if (V) Log.v(TAG, "About to acquire Mas:mWakeLock");
+        if (mWakeLock == null) {
+            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MasPartialWakeLock");
+            mWakeLock.setReferenceCounted(false);
+            mWakeLock.acquire();
+            if (V) Log.v(TAG, "Mas:mWakeLock acquired");
+        }
+        else
+        {
+            Log.e(TAG, "Mas:mWakeLock already acquired");
+        }
+    }
+
+    private void releaseMasLock() {
+        if (V) Log.v(TAG, "About to release Mas:mWakeLock");
+        if (mWakeLock != null) {
+            if (mWakeLock.isHeld()) {
+                mWakeLock.release();
+                if (V) Log.v(TAG, "Mas:mWakeLock released");
+            } else {
+                if (V) Log.v(TAG, "Mas:mWakeLock already released");
+            }
+            mWakeLock = null;
+        }
+    }
+};
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasReceiver.java b/src/org/codeaurora/bluetooth/map/BluetoothMasReceiver.java
new file mode 100644
index 0000000..ce29570
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasReceiver.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+public class BluetoothMasReceiver extends BroadcastReceiver {
+    private static final String TAG = "BluetoothMasReceiver";
+    private static final boolean V = BluetoothMasService.VERBOSE;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (V) Log.v(TAG, "BluetoothMasReceiver onReceive :" + intent.getAction());
+
+        Intent in = new Intent();
+        in.putExtras(intent);
+        in.setClass(context, BluetoothMasService.class);
+        String action = intent.getAction();
+        in.putExtra("action", action);
+        boolean startService = true;
+        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
+            int state = in.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                    BluetoothAdapter.ERROR);
+            in.putExtra(BluetoothAdapter.EXTRA_STATE, state);
+            /*
+             * Other than Tranistioning state, start the MAP service whenever BT
+             * transitioned to OFF/ON, or Adapter returns error
+             */
+            Log.d(TAG, "Bluetooth STATE CHANGED to " + state);
+
+            if ((state == BluetoothAdapter.STATE_TURNING_ON)
+                    || (state == BluetoothAdapter.STATE_TURNING_OFF)) {
+                startService = false;
+            }
+            if (state == BluetoothAdapter.ERROR) {
+                Log.d(TAG, " BluetoothAdapter returns ERROR");
+            }
+
+            if ((state == BluetoothAdapter.STATE_OFF)) {
+
+                startService = false;
+                // Stop MAS service
+                context.stopService(in);
+
+                // TODO - Stop MNS service?
+            }
+
+        } else if (action.equals(Intent.ACTION_MEDIA_EJECT)
+                || action.equals(Intent.ACTION_MEDIA_MOUNTED))
+            startService = true;
+
+        if (startService) {
+            context.startService(in);
+        }
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasService.java b/src/org/codeaurora/bluetooth/map/BluetoothMasService.java
new file mode 100644
index 0000000..e53c2f3
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasService.java
@@ -0,0 +1,982 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc. All rights reserved.
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothSocket;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.text.TextUtils;
+import android.os.ParcelUuid;
+import android.util.Log;
+import android.bluetooth.BluetoothUuid;
+
+import org.codeaurora.bluetooth.R;
+import org.codeaurora.bluetooth.map.BluetoothMns.MnsClient;
+import org.codeaurora.bluetooth.map.MapUtils.EmailUtils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashSet;
+import java.io.FileInputStream;
+import java.io.DataInputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.FileNotFoundException;
+import javax.obex.ServerSession;
+
+import static org.codeaurora.bluetooth.map.IBluetoothMasApp.MESSAGE_TYPE_EMAIL;
+import static org.codeaurora.bluetooth.map.IBluetoothMasApp.MESSAGE_TYPE_MMS;
+import static org.codeaurora.bluetooth.map.IBluetoothMasApp.MESSAGE_TYPE_SMS;
+import static org.codeaurora.bluetooth.map.IBluetoothMasApp.MESSAGE_TYPE_SMS_MMS;
+
+public class BluetoothMasService extends Service {
+    private static final String TAG = "BluetoothMasService";
+
+    /**
+     * To enable MAP DEBUG/VERBOSE logging - run below cmd in adb shell, and
+     * restart com.android.bluetooth process. only enable DEBUG log:
+     * "setprop log.tag.BluetoothMapService DEBUG"; enable both VERBOSE and
+     * DEBUG log: "setprop log.tag.BluetoothMapService VERBOSE"
+     */
+    public static final boolean DEBUG = true;
+    public static final boolean VERBOSE = true;
+  //  public static final boolean DEBUG = false;
+    //public static final boolean VERBOSE = false;
+
+    /**
+     * Intent indicating incoming connection request which is sent to
+     * BluetoothMasActivity
+     */
+    public static final String ACCESS_REQUEST_ACTION = "org.codeaurora.bluetooth.map.accessrequest";
+
+    /**
+     * Intent indicating incoming connection request accepted by user which is
+     * sent from BluetoothMasActivity
+     */
+    public static final String ACCESS_ALLOWED_ACTION = "org.codeaurora.bluetooth.map.accessallowed";
+
+    /**
+     * Intent indicating incoming connection request denied by user which is
+     * sent from BluetoothMasActivity
+     */
+    public static final String ACCESS_DISALLOWED_ACTION = "org.codeaurora.bluetooth.map.accessdisallowed";
+
+    /**
+     * Intent indicating incoming obex authentication request which is from
+     * PCE(Carkit)
+     */
+    public static final String AUTH_CHALL_ACTION = "org.codeaurora.bluetooth.map.authchall";
+
+    /**
+     * Intent indicating obex session key input complete by user which is sent
+     * from BluetoothMasActivity
+     */
+    public static final String AUTH_RESPONSE_ACTION = "org.codeaurora.bluetooth.map.authresponse";
+
+    /**
+     * Intent indicating user canceled obex authentication session key input
+     * which is sent from BluetoothMasActivity
+     */
+    public static final String AUTH_CANCELLED_ACTION = "org.codeaurora.bluetooth.map.authcancelled";
+
+    /**
+     * Intent indicating timeout for user confirmation, which is sent to
+     * BluetoothMasActivity
+     */
+    public static final String USER_CONFIRM_TIMEOUT_ACTION = "org.codeaurora.bluetooth.map.userconfirmtimeout";
+
+    public static final String THIS_PACKAGE_NAME = "org.codeaurora.bluetooth";
+
+    /**
+     * Intent Extra name indicating always allowed which is sent from
+     * BluetoothMasActivity
+     */
+    public static final String EXTRA_ALWAYS_ALLOWED = "org.codeaurora.bluetooth.map.alwaysallowed";
+
+    /**
+     * Intent Extra name indicating session key which is sent from
+     * BluetoothMasActivity
+     */
+    public static final String EXTRA_SESSION_KEY = "org.codeaurora.bluetooth.map.sessionkey";
+
+    /**
+     * Intent Extra name indicating BluetoothDevice which is sent to
+     * BluetoothMasActivity
+     */
+    public static final String EXTRA_BLUETOOTH_DEVICE = "org.codeaurora.bluetooth.map.bluetoothdevice";
+
+    private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
+
+    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
+
+    public static final int MSG_SERVERSESSION_CLOSE = 5004;
+
+    public static final int MSG_SESSION_ESTABLISHED = 5005;
+
+    public static final int MSG_SESSION_DISCONNECTED = 5006;
+
+    public static final int MSG_OBEX_AUTH_CHALL = 5007;
+
+    private static final int MSG_INTERNAL_START_LISTENER = 1;
+
+    private static final int MSG_INTERNAL_USER_TIMEOUT = 2;
+
+    private static final int USER_CONFIRM_TIMEOUT_VALUE = 30000;
+
+    public static final int MAS0_PORT_NUM = 16;
+
+    public static final int MAS1_PORT_NUM = 17;
+
+    public static final ParcelUuid MessageAccessServer =
+            ParcelUuid.fromString("00001132-0000-1000-8000-00805f9b34fb");
+
+    public static final ParcelUuid MessageNotificationServer =
+            ParcelUuid.fromString("00001133-0000-1000-8000-00805f9b34fb");
+
+    // Ensure not conflict with Opp notification ID
+    private static final int NOTIFICATION_ID_ACCESS = -1000005;
+
+    private BluetoothAdapter mAdapter;
+
+    private Object mAuthSync = new Object();
+
+    private BluetoothMapAuthenticator mAuth = null;
+
+    BluetoothMasObexConnectionManager mConnectionManager = null;
+
+    BluetoothMns mnsClient;
+    private static BluetoothDevice mRemoteDevice = null;
+    private static HashSet<BluetoothDevice> trustDevices = new HashSet<BluetoothDevice>();
+
+    private boolean mHasStarted = false;
+    private int mStartId = -1;
+
+    private boolean mIsEmailEnabled = true;
+
+    /**
+     * The flag indicating MAP request has been notified.
+     * This is set on when initiate notification and set off after accept/time out
+     */
+    private volatile boolean mIsRequestBeingNotified = false;
+
+
+    public static class MasInstanceInfo {
+        int mSupportedMessageTypes;
+        Class<? extends MnsClient> mMnsClientClass;
+        int mRfcommPort;
+
+        public MasInstanceInfo(int smt, Class<? extends MnsClient> _class, int port) {
+            mSupportedMessageTypes = smt;
+            mMnsClientClass = _class;
+            mRfcommPort = port;
+        }
+    }
+
+    public static final int MAX_INSTANCES = 2;
+    public static final int EMAIL_MAS_START = 1;
+    public static final int EMAIL_MAS_END = 1;
+    public static final MasInstanceInfo MAS_INS_INFO[] = new MasInstanceInfo[MAX_INSTANCES];
+
+    // The following information must match with corresponding
+    // SDP records supported message types and port number
+    // Please refer sdptool.c, BluetoothService.java, & init.qcom.rc
+    static {
+        MAS_INS_INFO[0] = new MasInstanceInfo(MESSAGE_TYPE_SMS_MMS, BluetoothMnsSmsMms.class, MAS0_PORT_NUM);
+        MAS_INS_INFO[1] = new MasInstanceInfo(MESSAGE_TYPE_EMAIL, BluetoothMnsEmail.class, MAS1_PORT_NUM);
+    }
+
+    private ContentObserver mEmailAccountObserver;
+
+    private static final String CONF_FILE_PATH =
+            "/etc/bluetooth/main.conf";
+
+    public void CheckEmailEnabled() {
+        if (VERBOSE)
+            Log.v(TAG, " CheckEmailEnabled: Loading from conf");
+        FileInputStream fstream = null;
+        try {
+            fstream = new FileInputStream(CONF_FILE_PATH);
+            DataInputStream in = new DataInputStream(fstream);
+            BufferedReader file = new BufferedReader(new InputStreamReader(in));
+            String line;
+            while((line = file.readLine()) != null) {
+                line = line.trim();
+                if (line.length() == 0 || line.startsWith("#")) continue;
+                String[] value = line.split(" = ");
+                if (value != null && value.length == 2) {
+                    if (value[0].equalsIgnoreCase("BluetoothMapEmailEnabled")) {
+                        if (value[1].equalsIgnoreCase("false")) {
+                            mIsEmailEnabled = false;
+                        }
+                        else {
+                            mIsEmailEnabled = true;
+                        }
+                        Log.v(TAG, "CheckEmailEnabled: IsEmailEnabled: " + mIsEmailEnabled);
+                    }
+                }
+            }
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, "Main.conf File Not found");
+        } catch (IOException e) {
+            Log.e(TAG, "IOException: read Main.conf File " + e);
+        } finally {
+            if (fstream != null) {
+                try {
+                    fstream.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    private void updateEmailAccount() {
+        if (VERBOSE) Log.v(TAG, "updateEmailAccount()");
+        List<Long> list = EmailUtils.getEmailAccountIdList(this);
+        ArrayList<Long> notAssigned = new ArrayList<Long>();
+        EmailUtils.removeMasIdIfNotPresent(list);
+        for (Long id : list) {
+            int masId = EmailUtils.getMasId(id);
+            if (masId == -1) {
+                notAssigned.add(id);
+            }
+        }
+        for (int i = EMAIL_MAS_START; i <= EMAIL_MAS_END; i ++) {
+            long accountId = EmailUtils.getAccountId(i);
+            if (accountId == -1 && notAssigned.size() > 0) {
+                EmailUtils.updateMapTable(notAssigned.remove(0), i);
+            }
+        }
+    }
+
+    public BluetoothMasService() {
+        CheckEmailEnabled();
+        mConnectionManager = new BluetoothMasObexConnectionManager();
+        if (VERBOSE)
+           Log.v(TAG, "BluetoothMasService: mIsEmailEnabled: " + mIsEmailEnabled);
+        if(mIsEmailEnabled) {
+            mEmailAccountObserver = new ContentObserver(null) {
+                @Override
+                public void onChange(boolean selfChange) {
+                    updateEmailAccount();
+                }
+            };
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        if (VERBOSE)
+            Log.v(TAG, "Map Service onCreate");
+
+        mConnectionManager.init();
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+
+        if (!mHasStarted) {
+            mHasStarted = true;
+            if (VERBOSE) Log.v(TAG, "Starting MAS instances");
+
+            int state = mAdapter.getState();
+            if (state == BluetoothAdapter.STATE_ON) {
+                mSessionStatusHandler.sendEmptyMessage(MSG_INTERNAL_START_LISTENER);
+            } else if (VERBOSE) {
+                Log.v(TAG, "BT is not ON, no start");
+            }
+        }
+        Log.v(TAG, "onCreate: mIsEmailEnabled: " + mIsEmailEnabled);
+        if(mIsEmailEnabled) {
+            getContentResolver().registerContentObserver(
+                EmailUtils.EMAIL_ACCOUNT_URI, true, mEmailAccountObserver);
+        }
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        if (VERBOSE)
+            Log.v(TAG, "Map Service onStartCommand");
+        int retCode = super.onStartCommand(intent, flags, startId);
+        if (retCode == START_STICKY) {
+            mStartId = startId;
+            if (mAdapter == null) {
+                Log.w(TAG, "Stopping BluetoothMasService: "
+                        + "device does not have BT or device is not ready");
+                // Release all resources
+                closeService();
+            } else {
+                // No need to handle the null intent case, because we have
+                // all restart work done in onCreate()
+                if (intent != null) {
+                    parseIntent(intent);
+                }
+            }
+        }
+        return retCode;
+    }
+
+    // process the intent from receiver
+    private void parseIntent(final Intent intent) {
+        String action = intent.getStringExtra("action");
+        if (VERBOSE)
+            Log.v(TAG, "action: " + action);
+
+        int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                BluetoothAdapter.ERROR);
+        boolean removeTimeoutMsg = true;
+        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
+            if (state == BluetoothAdapter.STATE_TURNING_OFF) {
+                // Release all resources
+                closeService();
+            } else {
+                removeTimeoutMsg = false;
+                Log.v(TAG, "parseIntent 1: mIsEmailEnabled: " + mIsEmailEnabled);
+                if(mIsEmailEnabled) {
+                    if (state == BluetoothAdapter.STATE_ON) {
+                        updateEmailAccount();
+                    }
+                }
+            }
+        } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) &&
+                                 mIsRequestBeingNotified) {
+            if (mRemoteDevice == null) {
+               Log.e(TAG, "Unexpected error!");
+               return;
+            }
+            if (mSessionStatusHandler != null) {
+               /* Let the user timeout handle this case as well */
+               mSessionStatusHandler.sendMessage(mSessionStatusHandler
+                   .obtainMessage(MSG_INTERNAL_USER_TIMEOUT));
+               removeTimeoutMsg = false;
+            }
+        } else if (action.equals(ACCESS_ALLOWED_ACTION)) {
+            if (mRemoteDevice == null) {
+               Log.e(TAG, "Unexpected error!");
+               return;
+            }
+            if (intent.getBooleanExtra(BluetoothMasService.EXTRA_ALWAYS_ALLOWED, false) == true) {
+                   trustDevices.add(mRemoteDevice);
+                  Log.v(TAG, "setTrust() TRUE " + mRemoteDevice.getName());
+            }
+            Log.v(TAG, "parseIntent 2: mIsEmailEnabled: " + mIsEmailEnabled);
+            if(mIsEmailEnabled) {
+                  updateEmailAccount();
+            }
+            mConnectionManager.initiateObexServerSession(mRemoteDevice);
+        }  else if (action.equals(ACCESS_DISALLOWED_ACTION)) {
+            mIsRequestBeingNotified = false;
+            mConnectionManager.stopObexServerSessionWaiting();
+        } else if (AUTH_RESPONSE_ACTION.equals(action)) {
+            String sessionkey = intent.getStringExtra(EXTRA_SESSION_KEY);
+            notifyAuthKeyInput(sessionkey);
+        } else if (AUTH_CANCELLED_ACTION.equals(action)) {
+            notifyAuthCancelled();
+        } else if ( BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
+
+            if (intent.hasExtra(BluetoothDevice.EXTRA_DEVICE)) {
+               BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                if(device != null)
+                    Log.d(TAG,"device: "+ device.getName());
+                if(mRemoteDevice != null)
+                    Log.d(TAG," Remtedevie: "+mRemoteDevice.getName());
+               if (device != null && trustDevices.contains(device) &&
+                     intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE) == BluetoothDevice.BOND_NONE) {
+                   Log.d(TAG,"BOND_STATE_CHANGED REFRESH trustDevices"+ device.getName());
+                   trustDevices.remove(device);
+               }
+            }
+
+        } else {
+            removeTimeoutMsg = false;
+        }
+
+        if (removeTimeoutMsg) {
+            mSessionStatusHandler.removeMessages(MSG_INTERNAL_USER_TIMEOUT);
+            if (VERBOSE) Log.v(TAG, "MAS access request notification flag off");
+            mIsRequestBeingNotified = false;
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        if (VERBOSE)
+            Log.v(TAG, "Map Service onDestroy");
+
+        super.onDestroy();
+        Log.v(TAG, "onDestroy: mIsEmailEnabled: " + mIsEmailEnabled);
+        if(mIsEmailEnabled) {
+            getContentResolver().unregisterContentObserver(mEmailAccountObserver);
+            EmailUtils.clearMapTable();
+        }
+        closeService();
+    }
+
+    private final void closeService() {
+        if (VERBOSE) Log.v(TAG, "MNS_BT: inside closeService");
+        try {
+            if(mnsClient!=null) {
+                if (VERBOSE) Log.v(TAG, "MNS_BT: about to send MNS_BLUETOOTH_OFF");
+                mnsClient.getHandler().sendEmptyMessage(BluetoothMns.MNS_BLUETOOTH_OFF);
+                mnsClient = null;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "MNS_BT: exception while sending MNS_BLUETOOTH_OFF");
+        } finally {
+            if (VERBOSE) Log.v(TAG, "MNS_BT: successfully sent MNS_BLUETOOTH_OFF");
+            mConnectionManager.closeAll();
+            mHasStarted = false;
+            if (stopSelfResult(mStartId)) {
+                if (VERBOSE) Log.v(TAG, "successfully stopped map service");
+            }
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (VERBOSE) Log.v(TAG, "Map Service onBind");
+        return null;
+    }
+
+    private final Handler mSessionStatusHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            if (VERBOSE) Log.v(TAG, "Handler(): got msg=" + msg.what);
+            Context context = getApplicationContext();
+            if (mnsClient == null) {
+                Log.v(TAG, "handleMessage: mIsEmailEnabled" + mIsEmailEnabled);
+                mnsClient = new BluetoothMns(context, mIsEmailEnabled);
+            }
+
+            switch (msg.what) {
+                case MSG_INTERNAL_START_LISTENER:
+                    if (mAdapter.isEnabled()) {
+                        mConnectionManager.startAll();
+                    } else {
+                        closeService();
+                    }
+                    break;
+                case MSG_INTERNAL_USER_TIMEOUT:
+                    Intent intent = new Intent(USER_CONFIRM_TIMEOUT_ACTION);
+                    intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice);
+                    sendBroadcast(intent);
+                    removeMapNotification(NOTIFICATION_ID_ACCESS);
+                    if (VERBOSE) Log.v(TAG, "MAS access request notification flag off");
+                    mIsRequestBeingNotified = false;
+                    mConnectionManager.stopObexServerSessionWaiting();
+                    break;
+                case MSG_SERVERSESSION_CLOSE:
+                {
+                    final int masId = msg.arg1;
+                    mConnectionManager.stopObexServerSession(masId);
+                    break;
+                }
+                case MSG_SESSION_ESTABLISHED:
+                    break;
+                case MSG_SESSION_DISCONNECTED:
+                    break;
+                default:
+                    break;
+            }
+        }
+    };
+
+    private void createMapNotification(BluetoothDevice device) {
+        if (VERBOSE) Log.v(TAG, "Creating MAS access notification");
+        mIsRequestBeingNotified = true;
+
+        NotificationManager nm = (NotificationManager)
+                getSystemService(Context.NOTIFICATION_SERVICE);
+
+        // Create an intent triggered by clicking on the status icon.
+        Intent clickIntent = new Intent();
+        clickIntent.setClass(this, BluetoothMasActivity.class);
+        clickIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        clickIntent.setAction(ACCESS_REQUEST_ACTION);
+        clickIntent.putExtra(EXTRA_BLUETOOTH_DEVICE, device);
+
+        // Create an intent triggered by clicking on the
+        // "Clear All Notifications" button
+        Intent deleteIntent = new Intent();
+        deleteIntent.setClass(this, BluetoothMasReceiver.class);
+
+        Notification notification = null;
+        String name = device.getName();
+        if (TextUtils.isEmpty(name)) {
+            name = getString(R.string.defaultname);
+        }
+
+        deleteIntent.setAction(ACCESS_DISALLOWED_ACTION);
+        notification = new Notification(android.R.drawable.stat_sys_data_bluetooth,
+            getString(R.string.map_notif_ticker), System.currentTimeMillis());
+        notification.setLatestEventInfo(this, getString(R.string.map_notif_ticker),
+                getString(R.string.map_notif_message, name), PendingIntent
+                        .getActivity(this, 0, clickIntent, 0));
+
+        notification.flags |= Notification.FLAG_AUTO_CANCEL;
+        notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
+        notification.defaults = Notification.DEFAULT_SOUND;
+        notification.deleteIntent = PendingIntent.getBroadcast(this, 0, deleteIntent, 0);
+        nm.notify(NOTIFICATION_ID_ACCESS, notification);
+
+
+        if (VERBOSE) Log.v(TAG, "Awaiting Authorization : MAS Connection : " + device.getName());
+
+    }
+
+    private void removeMapNotification(int id) {
+        Context context = getApplicationContext();
+        NotificationManager nm = (NotificationManager) context
+                .getSystemService(Context.NOTIFICATION_SERVICE);
+        nm.cancel(id);
+    }
+
+    private void notifyAuthKeyInput(final String key) {
+        synchronized (mAuthSync) {
+            if (key != null) {
+                mAuth.setSessionKey(key);
+            }
+            mAuth.setChallenged(true);
+            mAuth.notify();
+        }
+    }
+
+    private void notifyAuthCancelled() {
+        synchronized (mAuthSync) {
+            mAuth.setCancelled(true);
+            mAuth.notify();
+        }
+    }
+
+    class BluetoothMasObexConnectionManager {
+        private ArrayList<BluetoothMasObexConnection> mConnections =
+                new ArrayList<BluetoothMasObexConnection>();
+
+        public BluetoothMasObexConnectionManager() {
+            int numberOfSupportedInstances = MAX_INSTANCES;
+            Log.e(TAG, "BluetoothMasObexConnectionManager: mIsEmailEnabled: " + mIsEmailEnabled);
+            if(!mIsEmailEnabled) {
+                numberOfSupportedInstances = 1; /*Email instance not supported*/
+            }
+            for (int i = 0; i < numberOfSupportedInstances; i ++) {
+                mConnections.add(new BluetoothMasObexConnection(
+                        MAS_INS_INFO[i].mSupportedMessageTypes, i, MAS_INS_INFO[i].mRfcommPort));
+            }
+        }
+
+        public void initiateObexServerSession(BluetoothDevice device) {
+            try {
+                for (BluetoothMasObexConnection connection : mConnections) {
+                    if (connection.mConnSocket != null && connection.mWaitingForConfirmation) {
+                        connection.mWaitingForConfirmation = false;
+                        connection.startObexServerSession(device, mnsClient);
+                    }
+                }
+            } catch (IOException ex) {
+                Log.e(TAG, "Caught the error: " + ex.toString());
+            }
+        }
+
+        public void setWaitingForConfirmation(int masId) {
+            if (masId < mConnections.size()) {
+                final BluetoothMasObexConnection connect = mConnections.get(masId);
+                connect.mWaitingForConfirmation = true;
+            } else {
+                Log.e(TAG, "Attempt to set waiting for user confirmation for MAS id: " + masId);
+                Log.e(TAG, "out of index");
+            }
+        }
+
+        public void stopObexServerSession(int masId) {
+            if (masId < mConnections.size()) {
+                final BluetoothMasObexConnection connect = mConnections.get(masId);
+                if (connect.mConnSocket != null) {
+                    connect.stopObexServerSession();
+                } else {
+                    Log.w(TAG, "Attempt to stop OBEX Server session for MAS id: " + masId);
+                    Log.w(TAG, "when there is no connected socket");
+                }
+            } else {
+                Log.e(TAG, "Attempt to stop OBEX Server session for MAS id: " + masId);
+                Log.e(TAG, "out of index");
+            }
+        }
+
+        public void stopObexServerSessionWaiting() {
+            for (BluetoothMasObexConnection connection : mConnections) {
+                if (connection.mConnSocket != null && connection.mWaitingForConfirmation) {
+                    connection.mWaitingForConfirmation = false;
+                    connection.stopObexServerSession();
+                }
+            }
+        }
+
+        public void stopObexServerSessionAll() {
+            for (BluetoothMasObexConnection connection : mConnections) {
+                if (connection.mConnSocket != null) {
+                    connection.stopObexServerSession();
+                }
+            }
+        }
+
+        public void closeAll() {
+            for (BluetoothMasObexConnection connection : mConnections) {
+                // Stop the possible trying to init serverSocket
+                connection.mInterrupted = true;
+                connection.closeConnection();
+            }
+        }
+
+        public void startAll() {
+            for (BluetoothMasObexConnection connection : mConnections) {
+                connection.startRfcommSocketListener(mnsClient);
+            }
+        }
+
+        public void init() {
+            for (BluetoothMasObexConnection connection: mConnections) {
+                connection.mInterrupted = false;
+            }
+        }
+
+        public boolean isAllowedConnection(BluetoothDevice remoteDevice) {
+            String remoteAddress = remoteDevice.getAddress();
+            if (remoteAddress == null) {
+                if (VERBOSE) Log.v(TAG, "Connection request from unknown device");
+                return false;
+            }
+            final int size = mConnections.size();
+            for (int i = 0; i < size; i ++) {
+                final BluetoothMasObexConnection connection = mConnections.get(i);
+                BluetoothSocket socket = connection.mConnSocket;
+                if (socket != null) {
+                    BluetoothDevice device = socket.getRemoteDevice();
+                    if (device != null) {
+                        String address = device.getAddress();
+                        if (address != null) {
+                            if (remoteAddress.equalsIgnoreCase(address)) {
+                                if (VERBOSE) {
+                                    Log.v(TAG, "Connection request from " + remoteAddress);
+                                    Log.v(TAG, "when MAS id:" + i + " is connected to " + address);
+                                }
+                                return true;
+                            } else {
+                                if (VERBOSE) {
+                                    Log.v(TAG, "Connection request from " + remoteAddress);
+                                    Log.v(TAG, "when MAS id:" + i + " is connected to " + address);
+                                }
+                                return false;
+                            }
+                        } else {
+                            // shall not happen, connected device must has address
+                            // just for null pointer dereference
+                            Log.w(TAG, "Connected device has no address!");
+                        }
+                    }
+                }
+            }
+
+            if (VERBOSE) {
+                Log.v(TAG, "Connection request from " + remoteAddress);
+                Log.v(TAG, "when no MAS instance is connected.");
+            }
+            return true;
+        }
+    }
+
+    private class BluetoothMasObexConnection {
+        private volatile boolean mInterrupted;
+        private BluetoothServerSocket mServerSocket = null;
+        private SocketAcceptThread mAcceptThread = null;
+        private BluetoothSocket mConnSocket = null;
+        private ServerSession mServerSession = null;
+        private BluetoothMasObexServer mMapServer = null;
+
+        private int mSupportedMessageTypes;
+        private int mPortNum;
+        private int mMasId;
+        boolean mWaitingForConfirmation = false;
+
+        public BluetoothMasObexConnection(int supportedMessageTypes, int masId, int portNumber) {
+                mSupportedMessageTypes = supportedMessageTypes;
+                mMasId = masId;
+                mPortNum = portNumber;
+        }
+
+        private void startRfcommSocketListener(BluetoothMns mnsClient) {
+            if (VERBOSE)
+                Log.v(TAG, "Map Service startRfcommSocketListener");
+
+            if (mServerSocket == null) {
+                if (!initSocket()) {
+                    closeService();
+                    return;
+                }
+            }
+            if (mAcceptThread == null) {
+                mAcceptThread = new SocketAcceptThread(mnsClient, mMasId);
+                mAcceptThread.setName("BluetoothMapAcceptThread " + mPortNum);
+                mAcceptThread.start();
+            }
+        }
+
+        private final boolean initSocket() {
+            if (VERBOSE)
+                Log.v(TAG, "Map Service initSocket");
+
+            boolean initSocketOK = false;
+            final int CREATE_RETRY_TIME = 10;
+
+            // It's possible that create will fail in some cases. retry for 10 times
+            for (int i = 0; i < CREATE_RETRY_TIME && !mInterrupted; i++) {
+                try {
+                    //mServerSocket = mAdapter.listenUsingRfcommOn(mPortNum);
+                    if(mPortNum == MAS1_PORT_NUM)
+                       mServerSocket  = mAdapter.listenUsingRfcommWithServiceRecord("Email Message Access", MessageAccessServer.getUuid());
+                    else
+                       mServerSocket  = mAdapter.listenUsingRfcommWithServiceRecord("SMS/MMS Message Access", MessageAccessServer.getUuid());
+                    initSocketOK = true;
+                } catch (IOException e) {
+                    Log.e(TAG, "Error create RfcommServerSocket " + e.toString());
+                    initSocketOK = false;
+                }
+
+                if (!initSocketOK) {
+                    synchronized (this) {
+                        try {
+                            if (VERBOSE) Log.v(TAG, "wait 3 seconds");
+                            Thread.sleep(3000);
+                        } catch (InterruptedException e) {
+                            Log.e(TAG, "socketAcceptThread thread was interrupted (3)");
+                            mInterrupted = true;
+                        }
+                    }
+                } else {
+                    break;
+                }
+            }
+
+            if (initSocketOK) {
+                if (VERBOSE)
+                    Log.v(TAG, "Succeed to create listening socket on channel "
+                            + mPortNum);
+            } else {
+                Log.e(TAG, "Error to create listening socket after "
+                        + CREATE_RETRY_TIME + " try");
+            }
+            return initSocketOK;
+        }
+
+        private final void closeSocket() throws IOException {
+            if (mConnSocket != null) {
+                mConnSocket.close();
+                mConnSocket = null;
+            }
+        }
+
+        public void closeConnection() {
+            if (VERBOSE) Log.v(TAG, "Mas connection closing");
+
+            if (mAcceptThread != null) {
+                try {
+                    mAcceptThread.shutdown();
+                    mAcceptThread.join();
+                } catch (InterruptedException ex) {
+                    Log.w(TAG, "mAcceptThread  close error" + ex);
+                } finally {
+                    mAcceptThread = null;
+                }
+            }
+
+            if (mServerSession != null) {
+                mServerSession.close();
+                mServerSession = null;
+            }
+
+            try {
+                closeSocket();
+            } catch (IOException ex) {
+                Log.e(TAG, "CloseSocket error: " + ex);
+            }
+            if (VERBOSE) Log.v(TAG, "Mas connection closed");
+        }
+
+        private final void startObexServerSession(BluetoothDevice device, BluetoothMns mnsClient)
+                        throws IOException {
+            if (VERBOSE)
+                Log.v(TAG, "Map Service startObexServerSession ");
+
+            Context context = getApplicationContext();
+
+            IBluetoothMasApp appIf = null;
+            if (((mSupportedMessageTypes & ~MESSAGE_TYPE_SMS_MMS) == 0x00) &&
+                    ((mSupportedMessageTypes & MESSAGE_TYPE_SMS) != 0x00) &&
+                    ((mSupportedMessageTypes & MESSAGE_TYPE_MMS) != 0x00)) {
+                // BluetoothMasAppZero if and only if both SMS and MMS
+                appIf = new BluetoothMasAppSmsMms(context, mSessionStatusHandler, mnsClient,
+                        mMasId, device.getName());
+            } else if (((mSupportedMessageTypes & ~MESSAGE_TYPE_EMAIL) == 0x0) &&
+                    ((mSupportedMessageTypes & MESSAGE_TYPE_EMAIL) != 0x0)) {
+                // BluetoothMasAppOne if and only if email
+                appIf = new BluetoothMasAppEmail(context, mSessionStatusHandler, mnsClient,
+                        mMasId, device.getName());
+            }
+
+            mMapServer = new BluetoothMasObexServer(mSessionStatusHandler,
+                    device, context, appIf);
+            synchronized (mAuthSync) {
+                mAuth = new BluetoothMapAuthenticator(mSessionStatusHandler);
+                mAuth.setChallenged(false);
+                mAuth.setCancelled(false);
+            }
+            BluetoothMapRfcommTransport transport = new BluetoothMapRfcommTransport(
+                    mConnSocket);
+            mServerSession = new ServerSession(transport, mMapServer, mAuth);
+
+            if (VERBOSE) Log.v(TAG, "startObexServerSession() success!");
+        }
+
+        private void stopObexServerSession() {
+            if (VERBOSE) Log.v(TAG, "Map Service stopObexServerSession ");
+
+            closeConnection();
+
+            // Last obex transaction is finished, we start to listen for incoming
+            // connection again
+            if (mAdapter.isEnabled()) {
+                startRfcommSocketListener(mnsClient);
+            }
+        }
+
+        /**
+         * A thread that runs in the background waiting for remote rfcomm
+         * connect.Once a remote socket connected, this thread shall be
+         * shutdown.When the remote disconnect,this thread shall run again waiting
+         * for next request.
+         */
+        private class SocketAcceptThread extends Thread {
+            private boolean stopped = false;
+            private BluetoothMns mnsObj;
+            private int mMasId;
+
+            public SocketAcceptThread(BluetoothMns mnsClient, int masId) {
+                mnsObj = mnsClient;
+                mMasId = masId;
+            }
+
+            @Override
+            public void run() {
+                while (!stopped) {
+                    try {
+                        BluetoothSocket connSocket = mServerSocket.accept();
+
+                        BluetoothDevice device = connSocket.getRemoteDevice();
+                        mRemoteDevice = device;
+                        if (device == null) {
+                            Log.i(TAG, "getRemoteDevice() = null");
+                            break;
+                        }
+                        String remoteDeviceName = device.getName();
+                        // In case getRemoteName failed and return null
+                        if (TextUtils.isEmpty(remoteDeviceName)) {
+                            remoteDeviceName = getString(R.string.defaultname);
+                        }
+
+                        if (!mConnectionManager.isAllowedConnection(device)) {
+                            connSocket.close();
+                            continue;
+                        }
+                        mConnSocket = connSocket;
+                        boolean trust = false;
+                        if (trustDevices != null)
+                           trust = trustDevices.contains(device);
+                        if (VERBOSE) Log.v(TAG, "GetTrustState() = " + trust);
+                        if (mIsRequestBeingNotified) {
+                            if (VERBOSE) Log.v(TAG, "Request notification is still on going.");
+                            mConnectionManager.setWaitingForConfirmation(mMasId);
+                            break;
+                        } else if (trust) {
+                            if (VERBOSE) {
+                                Log.v(TAG, "trust is true::");
+                                Log.v(TAG, "incomming connection accepted from: "
+                                        + remoteDeviceName + " automatically as trusted device");
+                            }
+                            try {
+                                startObexServerSession(device, mnsObj);
+                            } catch (IOException ex) {
+                                Log.e(TAG, "catch exception starting obex server session"
+                                    + ex.toString());
+                            }
+                        } else {
+                            if (VERBOSE) Log.v(TAG, "trust is false.");
+                            mConnectionManager.setWaitingForConfirmation(mMasId);
+                            createMapNotification(device);
+                            if (VERBOSE) Log.v(TAG, "incomming connection accepted from: "
+                                + remoteDeviceName);
+                            mSessionStatusHandler.sendMessageDelayed(
+                                mSessionStatusHandler.obtainMessage(MSG_INTERNAL_USER_TIMEOUT),
+                                    USER_CONFIRM_TIMEOUT_VALUE);
+                        }
+                        stopped = true; // job done ,close this thread;
+                    } catch (IOException ex) {
+                        if (stopped) {
+                            break;
+                        }
+                        if (VERBOSE)
+                            Log.v(TAG, "Accept exception: " + ex.toString());
+                    }
+                }
+            }
+
+            void shutdown() {
+                if (VERBOSE) Log.v(TAG, "AcceptThread shutdown for MAS id: " + mMasId);
+                stopped = true;
+                interrupt();
+                if (mServerSocket != null) {
+                    try {
+                        mServerSocket.close();
+                        mServerSocket = null;
+                    } catch (IOException e) {
+                        Log.e(TAG, "Failed to close socket", e);
+                    }
+                }
+            }
+        }
+    }
+};
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasSpecParams.java b/src/org/codeaurora/bluetooth/map/BluetoothMasSpecParams.java
new file mode 100644
index 0000000..d6b874b
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasSpecParams.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+public final class BluetoothMasSpecParams {
+
+    public static final int MAS_TAG_MAX_LIST_COUNT            = 0x01;
+    public static final int MAS_TAG_LIST_START_OFFSET         = 0x02;
+    public static final int MAS_TAG_FILTER_MESSAGE_TYPE       = 0x03;
+    public static final int MAS_TAG_FILTER_PERIOD_BEGIN       = 0x04;
+    public static final int MAS_TAG_FILTER_PERIOD_END         = 0x05;
+    public static final int MAS_TAG_FILTER_READ_STATUS        = 0x06;
+    public static final int MAS_TAG_FILTER_RECIPIENT          = 0x07;
+    public static final int MAS_TAG_FILTER_ORIGINATOR         = 0x08;
+    public static final int MAS_TAG_FILTER_PRIORITY           = 0x09;
+    public static final int MAS_TAG_ATTACHMENT                = 0x0A;
+    public static final int MAS_TAG_TRANSPARENT               = 0x0B;
+    public static final int MAS_TAG_RETRY                     = 0x0C;
+    public static final int MAS_TAG_NEW_MESSAGE               = 0x0D;
+    public static final int MAS_TAG_NOTIFICATION_STATUS       = 0x0E;
+    public static final int MAS_TAG_MAS_INSTANCE_ID           = 0x0F;
+    public static final int MAS_TAG_PARAMETER_MASK            = 0x10;
+    public static final int MAS_TAG_FOLDER_LISTING_SIZE       = 0x11;
+    public static final int MAS_TAG_MESSAGE_LISTING_SIZE     = 0x12;
+    public static final int MAS_TAG_SUBJECT_LENGTH            = 0x13;
+    public static final int MAS_TAG_CHARSET                   = 0x14;
+    public static final int MAS_TAG_FRACTION_REQUEST          = 0x15;
+    public static final int MAS_TAG_FRACTION_DELIVER          = 0x16;
+    public static final int MAS_TAG_STATUS_INDICATOR          = 0x17;
+    public static final int MAS_TAG_STATUS_VALUE              = 0x18;
+    public static final int MAS_TAG_MSE_TIME                  = 0x19;
+
+    public static final int MAS_TAG_MAX_LIST_COUNT_LEN            = 0x02;
+    public static final int MAS_TAG_LIST_START_OFFSET_LEN         = 0x02;
+    public static final int MAS_TAG_SUBJECT_LENGTH_LEN            = 0x01;
+    public static final int MAS_TAG_FILTER_MESSAGE_TYPE_LEN       = 0x01;
+    public static final int MAS_TAG_FILTER_READ_STATUS_LEN        = 0x01;
+    public static final int MAS_TAG_FILTER_PRIORITY_LEN           = 0x01;
+    public static final int MAS_TAG_PARAMETER_MASK_LEN            = 0x04;
+    public static final int MAS_TAG_ATTACHMENT_LEN                = 0x01;
+    public static final int MAS_TAG_TRANSPARENT_LEN               = 0x01;
+    public static final int MAS_TAG_RETRY_LEN                     = 0x01;
+    public static final int MAS_TAG_NEW_MESSAGE_LEN               = 0x01;
+    public static final int MAS_TAG_NOTIFICATION_STATUS_LEN       = 0x01;
+    public static final int MAS_TAG_MAS_INSTANCE_ID_LEN           = 0x01;
+    public static final int MAS_TAG_FOLDER_LISTING_SIZE_LEN       = 0x02;
+    public static final int MAS_TAG_MESSAGE_LISTING_SIZE_LEN     = 0x02;
+    public static final int MAS_TAG_CHARSET_LEN                   = 0x01;
+    public static final int MAS_TAG_FRACTION_REQUEST_LEN         = 0x01;
+    public static final int MAS_TAG_FRACTION_DELIVER_LEN          = 0x01;
+    public static final int MAS_TAG_STATUS_INDICATOR_LEN          = 0x01;
+    public static final int MAS_TAG_STATUS_VALUE_LEN              = 0x01;
+    public static final int MAS_TAG_MSE_TIME_LEN                  = 0x14;
+
+    public static final int MAS_DEFAULT_MAX_LIST_COUNT = 1024;
+    public static final int MAS_DEFAULT_SUBJECT_LENGTH = 255;
+    public static final int MAS_DEFAULT_PARAMETER_MASK = 0xFFFF;
+
+    public static final int MAS_FRACTION_REQUEST_NOT_SET = 0x02;
+
+    public static final int MAS_TAG_MAX_LIST_COUNT_MIN_VAL        = 0x0;
+    public static final int MAS_TAG_MAX_LIST_COUNT_MAX_VAL        = 0xFFFF;
+    public static final int MAS_TAG_LIST_START_OFFSET_MIN_VAL     = 0x00;
+    public static final int MAS_TAG_LIST_START_OFFSET_MAX_VAL     = 0xFFFF;
+    public static final int MAS_TAG_SUBJECT_LENGTH_MIN_VAL        = 0x01;
+    public static final int MAS_TAG_SUBJECT_LENGTH_MAX_VAL        = 0xFF;
+    public static final int MAS_TAG_FILTER_MESSAGE_TYPE_MIN_VAL   = 0x00;
+    public static final int MAS_TAG_FILTER_MESSAGE_TYPE_MAX_VAL   = 0x0F;
+    public static final int MAS_TAG_FILTER_READ_STATUS_MIN_VAL    = 0x00;
+    public static final int MAS_TAG_FILTER_READ_STATUS_MAX_VAL    = 0x02;
+    public static final int MAS_TAG_FILTER_PRIORITY_MIN_VAL       = 0x00;
+    public static final int MAS_TAG_FILTER_PRIORITY_MAX_VAL       = 0x02;
+    public static final int MAS_TAG_PARAMETER_MASK_MIN_VAL        = 0x0;
+    public static final int MAS_TAG_PARAMETER_MASK_MAX_VAL        = 0xFFFF;
+    public static final int MAS_TAG_ATTACHMENT_MIN_VAL            = 0x00;
+    public static final int MAS_TAG_ATTACHMENT_MAX_VAL            = 0x01;
+    public static final int MAS_TAG_TRANSPARENT_MIN_VAL           = 0x00;
+    public static final int MAS_TAG_TRANSPARENT_MAX_VAL           = 0x01;
+    public static final int MAS_TAG_RETRY_MIN_VAL                 = 0x00;
+    public static final int MAS_TAG_RETRY_MAX_VAL                 = 0x01;
+    public static final int MAS_TAG_NEW_MESSAGE_MIN_VAL           = 0x00;
+    public static final int MAS_TAG_NEW_MESSAGE_MAX_VAL           = 0x01;
+    public static final int MAS_TAG_NOTIFICATION_STATUS_MIN_VAL   = 0x00;
+    public static final int MAS_TAG_NOTIFICATION_STATUS_MAX_VAL   = 0x01;
+    public static final int MAS_TAG_MAS_INSTANCE_ID_MIN_VAL       = 0x00;
+    public static final int MAS_TAG_MAS_INSTANCE_ID_MAX_VAL       = 0xFF;
+    public static final int MAS_TAG_FOLDER_LISTING_SIZE_MIN_VAL   = 0x00;
+    public static final int MAS_TAG_FOLDER_LISTING_SIZE_MAX_VAL   = 0xFFFF;
+    public static final int MAS_TAG_MESSAGE_LISTING_SIZE_MIN_VAL  = 0x00;
+    public static final int MAS_TAG_MESSAGE_LISTING_SIZE_MAX_VAL  = 0xFFFF;
+    public static final int MAS_TAG_CHARSET_MIN_VAL               = 0x00;
+    public static final int MAS_TAG_CHARSET_MAX_VAL               = 0x01;
+    public static final int MAS_TAG_FRACTION_REQUEST_MIN_VAL      = 0x00;
+    public static final int MAS_TAG_FRACTION_REQUEST_MAX_VAL      = 0x01;
+    public static final int MAS_TAG_FRACTION_DELIVER_MIN_VAL      = 0x00;
+    public static final int MAS_TAG_FRACTION_DELIVER_MAX_VAL      = 0x01;
+    public static final int MAS_TAG_STATUS_INDICATOR_MIN_VAL      = 0x00;
+    public static final int MAS_TAG_STATUS_INDICATOR_MAX_VAL      = 0x01;
+    public static final int MAS_TAG_STATUS_VALUE_MIN_VAL          = 0x00;
+    public static final int MAS_TAG_STATUS_VALUE_MAX_VAL          = 0x01;
+};
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMasTestActivity.java b/src/org/codeaurora/bluetooth/map/BluetoothMasTestActivity.java
new file mode 100644
index 0000000..708e5be
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMasTestActivity.java
@@ -0,0 +1,306 @@
+ /*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.app.Activity;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.Preference;
+import android.text.InputFilter;
+import android.text.TextWatcher;
+import android.text.InputFilter.LengthFilter;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+
+import org.codeaurora.bluetooth.R;
+
+import static org.codeaurora.bluetooth.map.BluetoothMasService.EXTRA_BLUETOOTH_DEVICE;
+
+/**
+ * MapActivity shows two dialogues: One for accepting incoming map request and
+ * the other prompts the user to enter a session key for authentication with a
+ * remote Bluetooth device.
+ */
+public class BluetoothMasTestActivity extends Activity implements
+        DialogInterface.OnClickListener, Preference.OnPreferenceChangeListener, TextWatcher {
+    private static final String TAG = "BluetoothMasActivity";
+
+    private static final boolean V = BluetoothMasService.VERBOSE;
+
+    private static final int BLUETOOTH_OBEX_AUTHKEY_MAX_LENGTH = 16;
+
+    private static final int DIALOG_YES_NO_CONNECT = 1;
+
+    private static final int DIALOG_YES_NO_AUTH = 2;
+
+    private static final String KEY_USER_TIMEOUT = "user_timeout";
+
+    private View mView;
+
+    private EditText mKeyView;
+
+    private TextView messageView;
+
+    private String mSessionKey = "";
+
+    private int mCurrentDialog;
+
+    private Button mOkButton;
+
+    private CheckBox mAlwaysAllowed;
+
+    private boolean mTimeout = false;
+
+    private boolean mAlwaysAllowedValue = true;
+
+    private static final int DISMISS_TIMEOUT_DIALOG = 0;
+
+    private static final int DISMISS_TIMEOUT_DIALOG_VALUE = 2000;
+
+    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!BluetoothMasService.USER_CONFIRM_TIMEOUT_ACTION.equals(intent.getAction())) {
+                return;
+            }
+            onTimeout();
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent i = getIntent();
+        String action = i.getAction();
+        if (action.equals(BluetoothMasService.ACCESS_REQUEST_ACTION)) {
+            showMapDialog(DIALOG_YES_NO_CONNECT);
+            mCurrentDialog = DIALOG_YES_NO_CONNECT;
+        } else if (action.equals(BluetoothMasService.AUTH_CHALL_ACTION)) {
+            showMapDialog(DIALOG_YES_NO_AUTH);
+            mCurrentDialog = DIALOG_YES_NO_AUTH;
+        } else {
+            Log.e(TAG, "Error: this activity may be started only with intent "
+                    + "MAP_ACCESS_REQUEST");
+            finish();
+        }
+        registerReceiver(mReceiver, new IntentFilter(
+                BluetoothMasService.USER_CONFIRM_TIMEOUT_ACTION));
+    }
+
+    private void showMapDialog(int id) {
+    }
+
+    private String getRemoteDeviceName() {
+        String remoteDeviceName = null;
+        Intent intent = getIntent();
+        if (intent.hasExtra(EXTRA_BLUETOOTH_DEVICE)) {
+            BluetoothDevice device = intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE);
+            if (device != null) {
+                remoteDeviceName = device.getName();
+            }
+        }
+
+        return (remoteDeviceName != null) ? remoteDeviceName : getString(R.string.defaultname);
+    }
+
+    private String createDisplayText(final int id) {
+        String mRemoteName = getRemoteDeviceName();
+        return null;
+    }
+
+    private View createView(final int id) {
+        switch (id) {
+            case DIALOG_YES_NO_CONNECT:
+                //mView = getLayoutInflater().inflate(R.layout.access, null);
+                messageView = (TextView)mView.findViewById(R.id.message);
+                messageView.setText(createDisplayText(id));
+                //mAlwaysAllowed = (CheckBox)mView.findViewById(R.id.alwaysallowed);
+                mAlwaysAllowed.setChecked(true);
+                mAlwaysAllowed.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                        if (isChecked) {
+                            mAlwaysAllowedValue = true;
+                        } else {
+                            mAlwaysAllowedValue = false;
+                        }
+                    }
+                });
+                return mView;
+            case DIALOG_YES_NO_AUTH:
+                mView = getLayoutInflater().inflate(R.layout.auth, null);
+                messageView = (TextView)mView.findViewById(R.id.message);
+                messageView.setText(createDisplayText(id));
+                mKeyView = (EditText)mView.findViewById(R.id.text);
+                mKeyView.addTextChangedListener(this);
+                mKeyView.setFilters(new InputFilter[] {
+                    new LengthFilter(BLUETOOTH_OBEX_AUTHKEY_MAX_LENGTH)
+                });
+                return mView;
+            default:
+                return null;
+        }
+    }
+
+    private void onPositive() {
+        if (!mTimeout) {
+            if (mCurrentDialog == DIALOG_YES_NO_CONNECT) {
+                sendIntentToReceiver(BluetoothMasService.ACCESS_ALLOWED_ACTION,
+                        BluetoothMasService.EXTRA_ALWAYS_ALLOWED, mAlwaysAllowedValue);
+            } else if (mCurrentDialog == DIALOG_YES_NO_AUTH) {
+                sendIntentToReceiver(BluetoothMasService.AUTH_RESPONSE_ACTION,
+                        BluetoothMasService.EXTRA_SESSION_KEY, mSessionKey);
+                mKeyView.removeTextChangedListener(this);
+            }
+        }
+        mTimeout = false;
+        finish();
+    }
+
+    private void onNegative() {
+        if (mCurrentDialog == DIALOG_YES_NO_CONNECT) {
+            sendIntentToReceiver(BluetoothMasService.ACCESS_DISALLOWED_ACTION, null, null);
+        } else if (mCurrentDialog == DIALOG_YES_NO_AUTH) {
+            sendIntentToReceiver(BluetoothMasService.AUTH_CANCELLED_ACTION, null, null);
+            mKeyView.removeTextChangedListener(this);
+        }
+        finish();
+    }
+
+    private void sendIntentToReceiver(final String intentName, final String extraName,
+            final String extraValue) {
+        Intent intent = new Intent(intentName);
+        intent.setClassName(BluetoothMasService.THIS_PACKAGE_NAME, BluetoothMasReceiver.class
+                .getName());
+        if (extraName != null) {
+            intent.putExtra(extraName, extraValue);
+        }
+        sendBroadcast(intent);
+    }
+
+    private void sendIntentToReceiver(final String intentName, final String extraName,
+            final boolean extraValue) {
+        Intent intent = new Intent(intentName);
+        intent.setClassName(BluetoothMasService.THIS_PACKAGE_NAME, BluetoothMasReceiver.class
+                .getName());
+        if (extraName != null) {
+            intent.putExtra(extraName, extraValue);
+        }
+        sendBroadcast(intent);
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        switch (which) {
+            case DialogInterface.BUTTON_POSITIVE:
+                if (mCurrentDialog == DIALOG_YES_NO_AUTH) {
+                    mSessionKey = mKeyView.getText().toString();
+                }
+                onPositive();
+                break;
+
+            case DialogInterface.BUTTON_NEGATIVE:
+                onNegative();
+                break;
+            default:
+                break;
+        }
+    }
+
+
+    private void onTimeout() {
+        // TODO - Implement appropriate timeout function
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        mTimeout = savedInstanceState.getBoolean(KEY_USER_TIMEOUT);
+        if (V) Log.e(TAG, "onRestoreInstanceState() mTimeout: " + mTimeout);
+
+        if (mTimeout) {
+            onTimeout();
+        }
+
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(KEY_USER_TIMEOUT, mTimeout);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        unregisterReceiver(mReceiver);
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        return true;
+    }
+
+    public void beforeTextChanged(CharSequence s, int start, int before, int after) {
+    }
+
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    }
+
+    public void afterTextChanged(android.text.Editable s) {
+        if (s.length() > 0) {
+            mOkButton.setEnabled(true);
+        }
+    }
+
+    private final Handler mTimeoutHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case DISMISS_TIMEOUT_DIALOG:
+                    if (V) Log.e(TAG, "Received DISMISS_TIMEOUT_DIALOG msg.");
+                    finish();
+                    break;
+                default:
+                    break;
+            }
+        }
+    };
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMns.java b/src/org/codeaurora/bluetooth/map/BluetoothMns.java
new file mode 100644
index 0000000..41c794b
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMns.java
@@ -0,0 +1,784 @@
+/*
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSocket;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.os.Message;
+import android.os.ParcelUuid;
+import android.text.format.Time;
+import android.util.Log;
+import android.util.Pair;
+
+import org.codeaurora.bluetooth.map.IBluetoothMasApp.MessageNotificationListener;
+import org.codeaurora.bluetooth.map.IBluetoothMasApp.MnsRegister;
+import org.codeaurora.bluetooth.map.MapUtils.MapUtils;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import javax.obex.ObexTransport;
+
+import static org.codeaurora.bluetooth.map.BluetoothMasService.MAS_INS_INFO;
+import static org.codeaurora.bluetooth.map.BluetoothMasService.MAX_INSTANCES;
+import static org.codeaurora.bluetooth.map.IBluetoothMasApp.HANDLE_OFFSET;
+import static org.codeaurora.bluetooth.map.IBluetoothMasApp.MSG;
+import static org.codeaurora.bluetooth.map.IBluetoothMasApp.TELECOM;
+
+/**
+ * This class run an MNS session.
+ */
+public class BluetoothMns implements MessageNotificationListener {
+    private static final String TAG = "BtMns";
+
+    private static final boolean V = BluetoothMasService.VERBOSE;
+
+    public static final int RFCOMM_ERROR = 10;
+
+    public static final int RFCOMM_CONNECTED = 11;
+
+    public static final int MNS_CONNECT = 13;
+
+    public static final int MNS_DISCONNECT = 14;
+
+    public static final int MNS_SEND_EVENT = 15;
+
+    public static final int MNS_SEND_EVENT_DONE = 16;
+
+    public static final int MNS_SEND_TIMEOUT = 17;
+
+    public static final int MNS_BLUETOOTH_OFF = 18;
+
+    public static final int MNS_SEND_TIMEOUT_DURATION = 30000; // 30 secs
+
+    private static final short MNS_UUID16 = 0x1133;
+
+    public static final String NEW_MESSAGE = "NewMessage";
+
+    public static final String DELIVERY_SUCCESS = "DeliverySuccess";
+
+    public static final String SENDING_SUCCESS = "SendingSuccess";
+
+    public static final String DELIVERY_FAILURE = "DeliveryFailure";
+
+    public static final String SENDING_FAILURE = "SendingFailure";
+
+    public static final String MEMORY_FULL = "MemoryFull";
+
+    public static final String MEMORY_AVAILABLE = "MemoryAvailable";
+
+    public static final String MESSAGE_DELETED = "MessageDeleted";
+
+    public static final String MESSAGE_SHIFT = "MessageShift";
+
+    private Context mContext;
+
+    private BluetoothAdapter mAdapter;
+
+    private BluetoothMnsObexSession mSession;
+
+    private EventHandler mSessionHandler;
+
+    private List<MnsClient> mMnsClients = new ArrayList<MnsClient>();
+    public static final ParcelUuid BluetoothUuid_ObexMns = ParcelUuid
+            .fromString("00001133-0000-1000-8000-00805F9B34FB");
+
+    private HashSet<Integer> mWaitingMasId = new HashSet<Integer>();
+    private final Queue<Pair<Integer, String>> mEventQueue = new ConcurrentLinkedQueue<Pair<Integer, String>>();
+    private boolean mSendingEvent = false;
+
+
+    public BluetoothMns(Context context, boolean isEmailEnabled) {
+        /* check Bluetooth enable status */
+        /*
+         * normally it's impossible to reach here if BT is disabled. Just check
+         * for safety
+         */
+
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        mContext = context;
+        int numOfSupportedInstances = MAX_INSTANCES;
+        Log.v(TAG, "BluetoothMns: isEmailEnabled: " + isEmailEnabled);
+        if(!isEmailEnabled) {
+            numOfSupportedInstances = 1; /*Email is not supported*/
+        }
+        for (int i = 0; i < numOfSupportedInstances; i ++) {
+            try {
+                // TODO: must be updated when Class<? extends MnsClient>'s constructor is changed
+                Constructor<? extends MnsClient> constructor;
+                constructor = MAS_INS_INFO[i].mMnsClientClass.getConstructor(Context.class,
+                        Integer.class);
+                mMnsClients.add(constructor.newInstance(mContext, i));
+            } catch (IllegalArgumentException e) {
+                Log.e(TAG, "The " + MAS_INS_INFO[i].mMnsClientClass.getName()
+                        + "'s constructor arguments mismatch", e);
+            } catch (InstantiationException e) {
+                Log.e(TAG, "The " + MAS_INS_INFO[i].mMnsClientClass.getName()
+                        + " cannot be instantiated", e);
+            } catch (IllegalAccessException e) {
+                Log.e(TAG, "The " + MAS_INS_INFO[i].mMnsClientClass.getName()
+                        + " cannot be instantiated", e);
+            } catch (InvocationTargetException e) {
+                Log.e(TAG, "Exception during " + MAS_INS_INFO[i].mMnsClientClass.getName()
+                        + "'s constructor invocation", e);
+            } catch (SecurityException e) {
+                Log.e(TAG, MAS_INS_INFO[i].mMnsClientClass.getName()
+                        + "'s constructor is not accessible", e);
+            } catch (NoSuchMethodException e) {
+                Log.e(TAG, MAS_INS_INFO[i].mMnsClientClass.getName()
+                        + " has no matched constructor", e);
+            }
+        }
+
+        if (!mAdapter.isEnabled()) {
+            Log.e(TAG, "Can't send event when Bluetooth is disabled ");
+            return;
+        }
+
+        mSessionHandler = new EventHandler();
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW);
+        filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
+        mContext.registerReceiver(mStorageStatusReceiver, filter);
+    }
+
+    public Handler getHandler() {
+        return mSessionHandler;
+    }
+
+    /**
+     * Asserting masId
+     * @param masId
+     * @return true if MnsClient is created for masId; otherwise false.
+     */
+    private boolean assertMasid(final int masId) {
+        final int size = mMnsClients.size();
+        if (masId < 0 || masId >= size) {
+            Log.e(TAG, "MAS id: " + masId + " is out of maximum number of MAS instances: " + size);
+            return false;
+        }
+        return true;
+    }
+
+    private boolean register(final int masId) {
+        if (!assertMasid(masId)) {
+            Log.e(TAG, "Attempt to register MAS id: " + masId);
+            return false;
+        }
+        final MnsClient client = mMnsClients.get(masId);
+        if (!client.isRegistered()) {
+            try {
+                client.register(BluetoothMns.this);
+            } catch (Exception e) {
+                Log.e(TAG, "Exception occured while register MNS for MAS id: " + masId, e);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private synchronized boolean canDisconnect() {
+        for (MnsClient client : mMnsClients) {
+            if (client.isRegistered()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void deregister(final int masId) {
+        if (!assertMasid(masId)) {
+            Log.e(TAG, "Attempt to register MAS id: " + masId);
+            return;
+        }
+        final MnsClient client = mMnsClients.get(masId);
+        if (client.isRegistered()) {
+            client.register(null);
+        }
+    }
+
+    private void deregisterAll() {
+        for (MnsClient client : mMnsClients) {
+            if (client.isRegistered()) {
+                client.register(null);
+            }
+        }
+    }
+
+    private void mnsCleanupInstances() {
+        if (V) Log.v(TAG, "MNS_BT: entered mnsCleanupInstances");
+        if(mStorageStatusReceiver != null) {
+            mContext.unregisterReceiver(mStorageStatusReceiver);
+            mStorageStatusReceiver = null;
+        }
+        for (MnsClient client : mMnsClients) {
+            if (V) Log.v(TAG, "MNS_BT: mnsCleanupInstances: inside for loop");
+            if (client.isRegistered()) {
+                if (V) Log.v(TAG, "MNS_BT: mnsCleanupInstances: Attempt to deregister MnsClient");
+                client.register(null);
+                client = null;
+                if (V) Log.v(TAG, "MNS_BT: mnsCleanupInstances: made client = null");
+            }
+        }
+        if (V) Log.v(TAG, "Relase MNS lock during MNS close service");
+        if(mSession != null) {
+            mSession.releaseMnsLock();
+        }
+    }
+
+    /*
+     * Receives events from mConnectThread & mSession back in the main thread.
+     */
+    private class EventHandler extends Handler {
+        public EventHandler() {
+            super();
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (V){
+                Log.v(TAG, " Handle Message " + msg.what);
+            }
+            switch (msg.what) {
+                case MNS_CONNECT:
+                {
+                    final int masId = msg.arg1;
+                    final BluetoothDevice device = (BluetoothDevice)msg.obj;
+                    if (mSession != null) {
+                        if (V) Log.v(TAG, "is MNS session connected? " + mSession.isConnected());
+                        if (mSession.isConnected()) {
+                            if (!register(masId)) {
+                                // failed to register, disconnect
+                                obtainMessage(MNS_DISCONNECT, masId, -1).sendToTarget();
+                            }
+                            break;
+                        }
+                    }
+                    if (mWaitingMasId.isEmpty()) {
+                        mWaitingMasId.add(masId);
+                        mConnectThread = new SocketConnectThread(device);
+                        mConnectThread.start();
+                    } else {
+                        mWaitingMasId.add(masId);
+                    }
+                    break;
+                }
+                case MNS_DISCONNECT:
+                {
+                    final int masId = msg.arg1;
+                    new Thread(new Runnable() {
+                        public void run() {
+                            deregister(masId);
+                            if (canDisconnect()) {
+                                stop();
+                            }
+                        }
+                    }).start();
+                    break;
+                }
+                case MNS_BLUETOOTH_OFF:
+                    if (V) Log.v(TAG, "MNS_BT: receive MNS_BLUETOOTH_OFF msg");
+                    new Thread(new Runnable() {
+                        public void run() {
+                            if (V) Log.v(TAG, "MNS_BT: Started Deregister Thread");
+                            if (canDisconnect()) {
+                                stop();
+                            }
+                            mnsCleanupInstances();
+                        }
+                    }).start();
+                    break;
+                /*
+                 * RFCOMM connect fail is for outbound share only! Mark batch
+                 * failed, and all shares in batch failed
+                 */
+                case RFCOMM_ERROR:
+                    if (V) Log.v(TAG, "receive RFCOMM_ERROR msg");
+                    deregisterAll();
+                    if (canDisconnect()) {
+                        stop();
+                    }
+                    break;
+                /*
+                 * RFCOMM connected. Do an OBEX connect by starting the session
+                 */
+                case RFCOMM_CONNECTED:
+                {
+                    if (V) Log.v(TAG, "Transfer receive RFCOMM_CONNECTED msg");
+                    ObexTransport transport = (ObexTransport) msg.obj;
+                    try {
+                        startObexSession(transport);
+                    } catch (NullPointerException ne) {
+                        sendEmptyMessage(RFCOMM_ERROR);
+                        return;
+                    }
+                    for (int masId : mWaitingMasId) {
+                        register(masId);
+                    }
+                    mWaitingMasId.clear();
+                    break;
+                }
+                /* Handle the error state of an Obex session */
+                case BluetoothMnsObexSession.MSG_SESSION_ERROR:
+                    if (V) Log.v(TAG, "receive MSG_SESSION_ERROR");
+                    deregisterAll();
+                    stop();
+                    break;
+                case MNS_SEND_EVENT:
+                {
+                    final String xml = (String)msg.obj;
+                    final int masId = msg.arg1;
+                    if (mSendingEvent) {
+                        mEventQueue.add(new Pair<Integer, String>(masId, xml));
+                    } else {
+                        mSendingEvent = true;
+                        new Thread(new SendEventTask(xml, masId)).start();
+                    }
+                    break;
+                }
+                case MNS_SEND_EVENT_DONE:
+                    if (mEventQueue.isEmpty()) {
+                        mSendingEvent = false;
+                    } else {
+                        final Pair<Integer, String> p = mEventQueue.remove();
+                        final int masId = p.first;
+                        final String xml = p.second;
+                        new Thread(new SendEventTask(xml, masId)).start();
+                    }
+                    break;
+                case MNS_SEND_TIMEOUT:
+                {
+                    if (V) Log.v(TAG, "MNS_SEND_TIMEOUT disconnecting.");
+                    deregisterAll();
+                    stop();
+                    break;
+                }
+            }
+        }
+
+        private void setTimeout(int masId) {
+            if (V) Log.v(TAG, "setTimeout MNS_SEND_TIMEOUT for instance " + masId);
+            sendMessageDelayed(obtainMessage(MNS_SEND_TIMEOUT, masId, -1),
+                    MNS_SEND_TIMEOUT_DURATION);
+        }
+
+        private void removeTimeout() {
+            if (hasMessages(MNS_SEND_TIMEOUT)) {
+                removeMessages(MNS_SEND_TIMEOUT);
+                sendEventDone();
+            }
+        }
+
+        private void sendEventDone() {
+            if (V) Log.v(TAG, "post MNS_SEND_EVENT_DONE");
+            obtainMessage(MNS_SEND_EVENT_DONE).sendToTarget();
+        }
+
+        class SendEventTask implements Runnable {
+            final String mXml;
+            final int mMasId;
+            SendEventTask (String xml, int masId) {
+                mXml = xml;
+                mMasId = masId;
+            }
+
+            public void run() {
+                if (V) Log.v(TAG, "MNS_SEND_EVENT started");
+                setTimeout(mMasId);
+                sendEvent(mXml, mMasId);
+                removeTimeout();
+                if (V) Log.v(TAG, "MNS_SEND_EVENT finished");
+            }
+        }
+    }
+
+    /*
+     * Class to hold message handle for MCE Initiated operation
+     */
+    public class BluetoothMnsMsgHndlMceInitOp {
+        public String msgHandle;
+        Time time;
+    }
+
+    /*
+     * Keep track of Message Handles on which the operation was
+     * initiated by MCE
+     */
+    List<BluetoothMnsMsgHndlMceInitOp> opList = new ArrayList<BluetoothMnsMsgHndlMceInitOp>();
+
+    /*
+     * Adds the Message Handle to the list for tracking
+     * MCE initiated operation
+     */
+    public void addMceInitiatedOperation(String msgHandle) {
+        BluetoothMnsMsgHndlMceInitOp op = new BluetoothMnsMsgHndlMceInitOp();
+        op.msgHandle = msgHandle;
+        op.time = new Time();
+        op.time.setToNow();
+        opList.add(op);
+    }
+    /*
+     * Removes the Message Handle from the list for tracking
+     * MCE initiated operation
+     */
+    public void removeMceInitiatedOperation(int location) {
+        opList.remove(location);
+    }
+
+    /*
+     * Finds the location in the list of the given msgHandle, if
+     * available. "+" indicates the next (any) operation
+     */
+    public int findLocationMceInitiatedOperation( String msgHandle) {
+        int location = -1;
+
+        Time currentTime = new Time();
+        currentTime.setToNow();
+
+        if (V) Log.v(TAG, "findLocationMceInitiatedOperation " + msgHandle);
+
+        List<BluetoothMnsMsgHndlMceInitOp> staleOpList = new ArrayList<BluetoothMnsMsgHndlMceInitOp>();
+        for (BluetoothMnsMsgHndlMceInitOp op: opList) {
+            if (currentTime.toMillis(false) - op.time.toMillis(false) > 10000) {
+                // add stale entries
+                staleOpList.add(op);
+            }
+        }
+        if (!staleOpList.isEmpty()) {
+            for (BluetoothMnsMsgHndlMceInitOp op: staleOpList) {
+                // Remove stale entries
+                opList.remove(op);
+            }
+        }
+
+        for (BluetoothMnsMsgHndlMceInitOp op: opList) {
+            if (op.msgHandle.equalsIgnoreCase(msgHandle)){
+                location = opList.indexOf(op);
+                break;
+            }
+        }
+
+        if (location == -1) {
+            for (BluetoothMnsMsgHndlMceInitOp op: opList) {
+                if (op.msgHandle.equalsIgnoreCase("+")) {
+                    location = opList.indexOf(op);
+                    break;
+                }
+            }
+        }
+        if (V) Log.v(TAG, "findLocationMce loc" + location);
+        return location;
+    }
+
+
+    /**
+     * Post a MNS Event to the MNS thread
+     */
+    public void sendMnsEvent(int masId, String msg, String handle, String folder,
+            String old_folder, String msgType) {
+        if (V) {
+            Log.v(TAG, "sendMnsEvent()");
+            Log.v(TAG, "msg: " + msg);
+            Log.v(TAG, "handle: " + handle);
+            Log.v(TAG, "folder: " + folder);
+            Log.v(TAG, "old_folder: " + old_folder);
+            Log.v(TAG, "msgType: " + msgType);
+        }
+        int location = -1;
+
+        /* Send the notification, only if it was not initiated
+         * by MCE. MEMORY_FULL and MEMORY_AVAILABLE cannot be
+         * MCE initiated
+         */
+        if (msg.equals(MEMORY_AVAILABLE) || msg.equals(MEMORY_FULL)) {
+            location = -1;
+        } else {
+            /* Consider SENDING_SUCESS as non MCE Initiated operation and remove
+             * message handle from MCE Initiated OpList when MmsContentObserver
+             * is not triggered for both OUTBOX and SENT folder even though
+             * message is pushed sucessfully.
+             */
+            location = findLocationMceInitiatedOperation(handle);
+            if (location != -1 && msg.equals(SENDING_SUCCESS)) {
+               if (V) Log.v(TAG, "Handle Pending MCE Initiated list " + location);
+               removeMceInitiatedOperation(location);
+               location = -1;
+            }
+        }
+
+        if (location == -1) {
+            String str = MapUtils.mapEventReportXML(msg, handle, folder, old_folder, msgType);
+            if (V) Log.v(TAG, "Notification to MAS " + masId + ", msgType = " + msgType);
+            mSessionHandler.obtainMessage(MNS_SEND_EVENT, masId, -1, str).sendToTarget();
+        } else {
+            if (V) Log.v(TAG, "REMOVE location" + location);
+            removeMceInitiatedOperation(location);
+        }
+    }
+
+    /**
+     * Push the message over Obex client session
+     */
+    private void sendEvent(String str, int masId) {
+        if (str != null && (str.length() > 0)) {
+            if (V){
+                Log.v(TAG, "--------------");
+                Log.v(TAG, " CONTENT OF EVENT REPORT FILE: " + str);
+            }
+
+            final String FILENAME = "EventReport" + masId;
+            FileOutputStream fos = null;
+            File file = new File(mContext.getFilesDir() + "/" + FILENAME);
+            file.delete();
+            try {
+                fos = mContext.openFileOutput(FILENAME, Context.MODE_PRIVATE);
+                fos.write(str.getBytes());
+                fos.flush();
+                fos.close();
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+            File fileR = new File(mContext.getFilesDir() + "/" + FILENAME);
+            if (fileR.exists() == true) {
+                if (V) {
+                    Log.v(TAG, " Sending event report file for Mas " + masId);
+                }
+                try {
+                    if (mSession != null) {
+                        mSession.sendEvent(fileR, (byte) masId);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            } else {
+                if (V){
+                    Log.v(TAG, " ERROR IN CREATING SEND EVENT OBJ FILE");
+                }
+            }
+        } else if (V) {
+            Log.v(TAG, "sendEvent(null, " + masId + ")");
+        }
+    }
+
+    private BroadcastReceiver mStorageStatusReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent != null && mSession != null) {
+                final String action = intent.getAction();
+                if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) {
+                    Log.d(TAG, " Memory Full ");
+                    sendMnsEventMemory(MEMORY_FULL);
+                } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
+                    Log.d(TAG, " Memory Available ");
+                    sendMnsEventMemory(MEMORY_AVAILABLE);
+                }
+            }
+        }
+    };
+
+    /**
+     * Stop the transfer
+     */
+    public synchronized void stop() {
+        if (V) Log.v(TAG, "stop");
+            if (mSession != null) {
+                if (V) Log.v(TAG, "Stop mSession");
+                mSession.disconnect();
+                mSession = null;
+            }
+    }
+
+    /**
+     * Connect the MNS Obex client to remote server
+     */
+    private void startObexSession(ObexTransport transport) throws NullPointerException {
+        if (V) Log.v(TAG, "Create Client session with transport " + transport.toString());
+        mSession = new BluetoothMnsObexSession(mContext, transport);
+        mSession.connect();
+    }
+
+    private SocketConnectThread mConnectThread;
+    /**
+     * This thread is used to establish rfcomm connection to
+     * remote device
+     */
+    private class SocketConnectThread extends Thread {
+        private final BluetoothDevice device;
+
+        private long timestamp;
+
+        /* create a Rfcomm Socket */
+        public SocketConnectThread(BluetoothDevice device) {
+            super("Socket Connect Thread");
+            this.device = device;
+        }
+
+        public void interrupt() {
+        }
+
+        @Override
+        public void run() {
+            timestamp = System.currentTimeMillis();
+
+            BluetoothSocket btSocket = null;
+            try {
+                btSocket = device.createInsecureRfcommSocketToServiceRecord(
+                        BluetoothUuid_ObexMns.getUuid());
+                btSocket.connect();
+            } catch (IOException e) {
+                Log.e(TAG, "BtSocket Connect error " + e.getMessage(), e);
+                markConnectionFailed(btSocket);
+                return;
+            }
+
+            if (V) Log.v(TAG, "Rfcomm socket connection attempt took "
+                    + (System.currentTimeMillis() - timestamp) + " ms");
+            ObexTransport transport;
+            transport = new BluetoothMnsRfcommTransport(btSocket);
+            if (V) Log.v(TAG, "Send transport message " + transport.toString());
+
+            mSessionHandler.obtainMessage(RFCOMM_CONNECTED, transport).sendToTarget();
+        }
+
+        /**
+         * RFCOMM connection failed
+         */
+        private void markConnectionFailed(BluetoothSocket s) {
+            try {
+                if (s != null) {
+                    s.close();
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error when close socket");
+            }
+            mSessionHandler.obtainMessage(RFCOMM_ERROR).sendToTarget();
+            return;
+        }
+    }
+
+    public void sendMnsEventMemory(String msg) {
+        // Sending "MemoryFull" or "MemoryAvailable" to all registered Mas Instances
+        for (MnsClient client : mMnsClients) {
+            if (client.isRegistered()) {
+                sendMnsEvent(client.getMasId(), msg, null, null, null, null);
+            }
+        }
+    }
+
+    public void onDeliveryFailure(int masId, String handle, String folder, String msgType) {
+        sendMnsEvent(masId, DELIVERY_FAILURE, handle, folder, null, msgType);
+    }
+
+    public void onDeliverySuccess(int masId, String handle, String folder, String msgType) {
+        sendMnsEvent(masId, DELIVERY_SUCCESS, handle, folder, null, msgType);
+    }
+
+    public void onMessageShift(int masId, String handle, String toFolder,
+            String fromFolder, String msgType) {
+        sendMnsEvent(masId, MESSAGE_SHIFT, handle, toFolder, fromFolder, msgType);
+    }
+
+    public void onNewMessage(int masId, String handle, String folder, String msgType) {
+        sendMnsEvent(masId, NEW_MESSAGE, handle, folder, null, msgType);
+    }
+
+    public void onSendingFailure(int masId, String handle, String folder, String msgType) {
+        sendMnsEvent(masId, SENDING_FAILURE, handle, folder, null, msgType);
+    }
+
+    public void onSendingSuccess(int masId, String handle, String folder, String msgType) {
+        sendMnsEvent(masId, SENDING_SUCCESS, handle, folder, null, msgType);
+    }
+
+    public void onMessageDeleted(int masId, String handle, String folder, String msgType) {
+        sendMnsEvent(masId, MESSAGE_DELETED, handle, folder, null, msgType);
+    }
+
+    public static abstract class MnsClient implements MnsRegister {
+        public static final String TAG = "MnsClient";
+        public static final boolean V = BluetoothMasService.VERBOSE;
+        protected static final String PRE_PATH = TELECOM + "/" + MSG + "/";
+
+        protected Context mContext;
+        protected MessageNotificationListener mListener = null;
+        protected int mMasId;
+
+        protected final long OFFSET_START;
+        protected final long OFFSET_END;
+
+        public MnsClient(Context context, int masId) {
+            mContext = context;
+            mMasId = masId;
+            OFFSET_START = HANDLE_OFFSET[masId];
+            OFFSET_END = HANDLE_OFFSET[masId + 1] - 1;
+        }
+
+        public synchronized void register(MessageNotificationListener listener) {
+            if (V) Log.v(TAG, "MNS_BT: register entered");
+            if (listener != null) {
+                mListener = listener;
+                registerContentObserver();
+            } else {
+                if (V) Log.v(TAG, "MNS_BT: register(null)");
+                unregisterContentObserver();
+                mListener = null;
+            }
+        }
+
+        public boolean isRegistered() {
+            return mListener != null;
+        }
+
+        public int getMasId() {
+            return mMasId;
+        }
+
+        protected abstract void registerContentObserver();
+        protected abstract void unregisterContentObserver();
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMnsEmail.java b/src/org/codeaurora/bluetooth/map/BluetoothMnsEmail.java
new file mode 100644
index 0000000..c348685
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMnsEmail.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.os.Handler;
+import android.util.Log;
+
+import org.codeaurora.bluetooth.map.BluetoothMns.MnsClient;
+import org.codeaurora.bluetooth.map.MapUtils.EmailUtils;
+
+import java.util.Collection;
+import java.util.HashMap;
+
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.EMAIL_BOX_COLUMN_ACCOUNT_KEY;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.EMAIL_BOX_COLUMN_DISPLAY_NAME;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.EMAIL_BOX_COLUMN_RECORD_ID;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.EMAIL_BOX_COLUMN_TYPE;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.EMAIL_BOX_PROJECTION;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.EMAIL_BOX_URI;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.EMAIL_MESSAGE_PROJECTION;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.EMAIL_MESSAGE_URI;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.EMAIL_URI;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.MSG_COL_ACCOUNT_KEY;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.MSG_COL_MAILBOX_KEY;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.MSG_COL_RECORD_ID;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.TYPE_DELETED;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.TYPE_DRAFT;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.TYPE_INBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.TYPE_OUTBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.EmailUtils.TYPE_SENT;
+
+/**
+ * This class run an MNS session.
+ */
+public class BluetoothMnsEmail extends MnsClient {
+    private static final String TAG = "BluetoothMnsEmail";
+    private static final boolean V = BluetoothMasService.VERBOSE;
+    private static final String EMAIL_TO_MAP[] = {
+        "inbox",    // TYPE_INBOX = 0;
+        "",         // TYPE_MAIL = 1;
+        "",         // TYPE_PARENT = 2;
+        "draft",    // TYPE_DRAFTS = 3;
+        "outbox",   // TYPE_OUTBOX = 4;
+        "sent",     // TYPE_SENT = 5;
+        "deleted",  // TYPE_TRASH = 6;
+        ""          // TYPE_JUNK = 7;
+    };
+    private static final String EMAIL = "EMAIL";
+    private EmailContentObserver mEmailObserver = new EmailContentObserver();
+    private long mAccountKey;
+
+    public BluetoothMnsEmail(Context context, Integer masId) {
+        super(context, masId);
+    }
+
+    @Override
+    protected void registerContentObserver() {
+        if (V) Log.v(TAG, "REGISTERING EMAIL MNS");
+        mAccountKey = EmailUtils.getAccountId(mMasId);
+        mEmailObserver.updateEmailBox();
+        mEmailObserver.update(true);
+        mContext.getContentResolver().registerContentObserver(EMAIL_URI, true, mEmailObserver);
+        if (V) Log.v(TAG, "REGISTERING EMAIL MNS DONE");
+    }
+
+    @Override
+    protected void unregisterContentObserver() {
+        if (V) Log.v(TAG, "UNREGISTERING MNS EMAIL");
+        mContext.getContentResolver().unregisterContentObserver(mEmailObserver);
+        if (V) Log.v(TAG, "UNREGISTERED MNS EMAIL");
+    }
+
+    static class EmailBox {
+        long mId;
+        String mDisplayName;
+        long mAccountKey;
+        int mType;
+
+        public EmailBox(long id, String displayName, long accountKey, int type) {
+            mId = id;
+            mDisplayName = displayName;
+            mAccountKey = accountKey;
+            mType = type;
+        }
+
+        @Override
+        public String toString() {
+            return "[id:" + mId + ", display name:" + mDisplayName + ", account key:" +
+                    mAccountKey + ", type:" + mType + "]";
+        }
+    }
+
+    static class EmailMessage {
+        long mId;
+        long mAccountKey;
+        String mFolderName;
+        int mType;
+
+        public EmailMessage(long id, long accountKey, String folderName, int type) {
+            mId = id;
+            mAccountKey = accountKey;
+            mFolderName = folderName;
+            mType = type;
+        }
+
+        @Override
+        public String toString() {
+            return "[id:" + mId + ", folder name:" + mFolderName + ", account key:" + mAccountKey +
+                    ", type:" + mType + "]";
+        }
+    }
+
+    private class EmailContentObserver extends ContentObserver {
+        private static final String TAG = "EmailContentObserver";
+        private HashMap<Long, EmailBox> mEmailBoxList = new HashMap<Long, EmailBox>();
+        private HashMap<Long, EmailMessage> mEmailList = new HashMap<Long, EmailMessage>();
+        /** List of deleted message, do not notify */
+        private HashMap<Long, EmailMessage> mDeletedList = new HashMap<Long, EmailMessage>();
+        private HashMap<Long, EmailMessage> mEmailAddedList = new HashMap<Long, EmailMessage>();
+        /** List of newly deleted message, notify */
+        private HashMap<Long, EmailMessage> mEmailDeletedList = new HashMap<Long, EmailMessage>();
+
+        private static final int UPDATE = 0;
+        private static final int THRESHOLD = 3000;  // 3 sec
+
+        public EmailContentObserver() {
+            super(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            if (V) Log.v(TAG, "onChange(" + selfChange + ")");
+            if (mHandler.hasMessages(UPDATE)) {
+                mHandler.removeMessages(UPDATE);
+            }
+            mHandler.sendEmptyMessageDelayed(UPDATE, THRESHOLD);
+        }
+
+        private Handler mHandler = new Handler() {
+            private static final String TAG = "EmailContentObserver.Hanlder";
+            @Override
+            public void handleMessage(android.os.Message msg) {
+                if (V) Log.v(TAG, "handleMessage(" + msg.what + ") mas Id: " + mMasId);
+                switch (msg.what) {
+                    case UPDATE:
+                        new Thread(new Runnable() {
+                            public void run() {
+                                updateEmailBox();
+                                update(false);
+                                sendEvents();
+                            }
+                        }, "Email Content Observer Thread").start();
+                        break;
+                }
+            }
+        };
+
+        void updateEmailBox() {
+            mEmailBoxList.clear();
+            final ContentResolver resolver = mContext.getContentResolver();
+            Cursor crBox = resolver.query(EMAIL_BOX_URI, EMAIL_BOX_PROJECTION, null, null, null);
+            if (crBox != null) {
+                if (crBox.moveToFirst()) {
+                    do {
+                        final long id = crBox.getLong(EMAIL_BOX_COLUMN_RECORD_ID);
+                        final String displayName = crBox.getString(EMAIL_BOX_COLUMN_DISPLAY_NAME);
+                        final long accountKey = crBox.getLong(EMAIL_BOX_COLUMN_ACCOUNT_KEY);
+                        final int type = crBox.getInt(EMAIL_BOX_COLUMN_TYPE);
+                        final EmailBox box = new EmailBox(id, displayName, accountKey, type);
+                        mEmailBoxList.put(id, box);
+                        if (V) Log.v(TAG, box.toString());
+                    } while (crBox.moveToNext());
+                }
+                crBox.close();
+            }
+        }
+
+        void update(boolean init) {
+            if (init) {
+                clear();
+            }
+            final ContentResolver resolver = mContext.getContentResolver();
+            Cursor crEmail = resolver.query(EMAIL_MESSAGE_URI, EMAIL_MESSAGE_PROJECTION,
+                    null, null, null);
+            if (crEmail != null) {
+                if (crEmail.moveToFirst()) {
+                    final HashMap<Long, EmailBox> boxList = mEmailBoxList;
+                    HashMap<Long, EmailMessage> oldEmailList = mEmailList;
+                    HashMap<Long, EmailMessage> emailList = new HashMap<Long, EmailMessage>();
+                    do {
+                        final long accountKey = crEmail.getLong(MSG_COL_ACCOUNT_KEY);
+                        if (accountKey != mAccountKey) {
+                            continue;
+                        }
+                        final long id = crEmail.getLong(MSG_COL_RECORD_ID);
+                        final long mailboxKey = crEmail.getLong(MSG_COL_MAILBOX_KEY);
+                        if (boxList.containsKey(mailboxKey)) {
+                            final EmailBox box = boxList.get(mailboxKey);
+                            if (box == null) {
+                                continue;
+                            }
+                            final String folderName = isMapFolder(box.mType)
+                                    ? EMAIL_TO_MAP[box.mType] : box.mDisplayName;
+                            final EmailMessage msg = new EmailMessage(id, accountKey,
+                                    folderName, box.mType);
+                            if (box.mType == EmailUtils.TYPE_DELETED) {
+                                if (init) {
+                                    mDeletedList.put(id, msg);
+                                } else if (!mDeletedList.containsKey(id) &&
+                                        !mEmailDeletedList.containsKey(id)) {
+                                    mEmailDeletedList.put(id, msg);
+                                }
+                            } else {
+                                emailList.put(id, msg);
+                                if (!oldEmailList.containsKey(id) && !init &&
+                                        !mEmailAddedList.containsKey(id)) {
+                                    mEmailAddedList.put(id, msg);
+                                }
+                            }
+                        } else {
+                            Log.e(TAG, "Mailbox is not updated");
+                        }
+                    } while (crEmail.moveToNext());
+                    mEmailList = emailList;
+                }
+                crEmail.close();
+            }
+        }
+
+        private void sendEvents() {
+            if (mEmailAddedList.size() > 0) {
+                newEmail();
+                mEmailAddedList.clear();
+            }
+            if (mEmailDeletedList.size() > 0) {
+                mDeletedList.putAll(mEmailDeletedList);
+                deletedEmail();
+                mEmailDeletedList.clear();
+            }
+        }
+
+        private void clear() {
+            mEmailList.clear();
+            mDeletedList.clear();
+            mEmailAddedList.clear();
+            mEmailDeletedList.clear();
+        }
+
+        private boolean isMapFolder(int type) {
+            if (type == TYPE_INBOX || type == TYPE_OUTBOX || type == TYPE_SENT ||
+                    type == TYPE_DRAFT || type == TYPE_DELETED) {
+                return true;
+            }
+            return false;
+        }
+
+        private void newEmail() {
+            if (V) Log.v(TAG, "newEmail()");
+            if (mListener != null) {
+                Collection<EmailMessage> values = mEmailAddedList.values();
+                for (EmailMessage email : values) {
+                    if (V) Log.v(TAG, email.toString());
+                    mListener.onNewMessage(mMasId, String.valueOf(email.mId + OFFSET_START),
+                            PRE_PATH + email.mFolderName, EMAIL);
+                    if (email.mType == TYPE_SENT) {
+                        mListener.onSendingSuccess(mMasId, String.valueOf(email.mId + OFFSET_START),
+                                PRE_PATH + email.mFolderName, EMAIL);
+                    }
+                }
+            }
+        }
+
+        private void deletedEmail() {
+            if (V) Log.v(TAG, "deletedEmail()");
+            if (mListener != null) {
+                Collection<EmailMessage> values = mEmailDeletedList.values();
+                for (EmailMessage email : values) {
+                    if (V) Log.v(TAG, email.toString());
+                    mListener.onMessageDeleted(mMasId, String.valueOf(email.mId + OFFSET_START),
+                            PRE_PATH + email.mFolderName, EMAIL);
+                }
+            }
+        }
+    };
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMnsObexSession.java b/src/org/codeaurora/bluetooth/map/BluetoothMnsObexSession.java
new file mode 100644
index 0000000..6430ecc
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMnsObexSession.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.content.Context;
+import android.os.Handler;
+import android.util.Log;
+import android.os.PowerManager;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.obex.ApplicationParameter;
+import javax.obex.ClientOperation;
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ObexTransport;
+import javax.obex.ResponseCodes;
+
+/**
+ * This class runs as an OBEX client
+ */
+
+// TBD - Do applications need to do anything for power management?
+
+public class BluetoothMnsObexSession {
+
+    private static final String TAG = "BtMns ObexClient";
+    private static final boolean D = BluetoothMasService.DEBUG;
+    private static final boolean V = BluetoothMasService.VERBOSE;
+
+    public final static int MSG_SESSION_ERROR = 1;
+    public final static int MSG_CONNECT_TIMEOUT = 2;
+
+    private ObexTransport mTransport;
+
+    private Context mContext;
+
+    private volatile boolean mWaitingForRemote;
+
+    private PowerManager.WakeLock mWakeLock = null;
+
+    private static final String TYPE_EVENT = "x-bt/MAP-event-report";
+
+    public BluetoothMnsObexSession(Context context, ObexTransport transport) {
+        if (transport == null) {
+            throw new NullPointerException("transport is null");
+        }
+        mContext = context;
+        mTransport = transport;
+    }
+
+    private ClientSession mCs;
+
+    private boolean mConnected = false;
+
+    public boolean isConnected() {
+        return mConnected;
+    }
+
+    public void disconnect() {
+        if(D) Log.d(TAG, "BluetoothMnsObexSession: disconnect");
+        acquireMnsLock();
+        try {
+            if (mCs != null) {
+                mCs.disconnect(null);
+            }
+            mCs = null;
+            if (D) Log.d(TAG, "OBEX session disconnected");
+        } catch (IOException e) {
+            Log.w(TAG, "OBEX session disconnect error " + e.getMessage());
+        }
+        try {
+            if (mCs != null) {
+                if (D) Log.d(TAG, "OBEX session close mCs");
+                mCs.close();
+                if (D) Log.d(TAG, "OBEX session closed");
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "OBEX session close error" + e.getMessage());
+        }
+        try {
+            if (mTransport != null) {
+                mTransport.close();
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "mTransport.close error " + e.getMessage());
+        }
+        if(D) Log.d(TAG, "BluetoothMnsObexSession: exiting from disconnect");
+        releaseMnsLock();
+    }
+
+    private HeaderSet hsConnect = null;
+
+    public void connect() {
+        if(D) Log.d(TAG, "BluetoothMnsObexSession: Create ClientSession with transport " + mTransport.toString());
+        acquireMnsLock();
+        try {
+            mCs = new ClientSession(mTransport);
+            mConnected = true;
+        } catch (IOException e1) {
+            Log.e(TAG, "OBEX session create error " + e1.getMessage());
+        }
+        if (mConnected && mCs != null) {
+            mConnected = false;
+            HeaderSet hs = new HeaderSet();
+            // bb582b41-420c-11db-b0de-0800200c9a66
+            byte[] mnsTarget = { (byte) 0xbb, (byte) 0x58, (byte) 0x2b, (byte) 0x41,
+                                 (byte) 0x42, (byte) 0x0c, (byte) 0x11, (byte) 0xdb,
+                                 (byte) 0xb0, (byte) 0xde, (byte) 0x08, (byte) 0x00,
+                                 (byte) 0x20, (byte) 0x0c, (byte) 0x9a, (byte) 0x66 };
+            hs.setHeader(HeaderSet.TARGET, mnsTarget);
+
+            synchronized (this) {
+                mWaitingForRemote = true;
+            }
+            try {
+                hsConnect = mCs.connect(hs);
+                if (D) Log.d(TAG, "OBEX session created");
+                mConnected = true;
+            } catch (IOException e) {
+                Log.e(TAG, "OBEX session connect error " + e.getMessage());
+            }
+        }
+            synchronized (this) {
+                mWaitingForRemote = false;
+        }
+        if(D) Log.d(TAG, "BluetoothMnsObexSession: exiting from connect");
+        releaseMnsLock();
+    }
+
+    public int sendEvent(File file, byte masInstanceId) {
+        Log.d(TAG, "BluetoothMnsObexSession: sendEvent");
+        acquireMnsLock();
+        boolean error = false;
+        int responseCode = -1;
+        HeaderSet request;
+        byte[] val = new byte[1];
+        val[0] =  masInstanceId;
+        request = new HeaderSet();
+        ApplicationParameter ap = new ApplicationParameter();
+        ap.addAPPHeader((byte)BluetoothMasSpecParams.MAS_TAG_MAS_INSTANCE_ID,
+                        (byte)BluetoothMasSpecParams.MAS_TAG_MAS_INSTANCE_ID_LEN,
+                         val);
+        request.setHeader(HeaderSet.TYPE, TYPE_EVENT);
+        request.setHeader(HeaderSet.APPLICATION_PARAMETER, ap.getAPPparam());
+
+        request.mConnectionID = new byte[4];
+        System.arraycopy(hsConnect.mConnectionID, 0, request.mConnectionID, 0, 4);
+
+        ClientOperation putOperation = null;
+        OutputStream outputStream = null;
+        FileInputStream fileInputStream = null;
+        try {
+            synchronized (this) {
+                mWaitingForRemote = true;
+            }
+            // Send the header first and then the body
+            try {
+                if (V) Log.v(TAG, "Send headerset Event ");
+                putOperation = (ClientOperation)mCs.put(request);
+                // TODO - Should this be kept or Removed
+
+            } catch (IOException e) {
+                Log.e(TAG, "Error when put HeaderSet " + e.getMessage());
+                error = true;
+            }
+            synchronized (this) {
+                mWaitingForRemote = false;
+            }
+            if (!error) {
+                try {
+                    if (V) Log.v(TAG, "Send headerset Event ");
+                    outputStream = putOperation.openOutputStream();
+                } catch (IOException e) {
+                    Log.e(TAG, "Error when opening OutputStream " + e.getMessage());
+                    error = true;
+                }
+            }
+
+            if (!error) {
+                int position = 0;
+                int readLength = 0;
+                long timestamp = 0;
+                int outputBufferSize = putOperation.getMaxPacketSize();
+                byte[] buffer = new byte[outputBufferSize];
+
+                fileInputStream = new FileInputStream(file);
+                BufferedInputStream a = new BufferedInputStream(fileInputStream, 0x4000);
+
+                while ((position != file.length())) {
+                    if (V) timestamp = System.currentTimeMillis();
+
+                    readLength = a.read(buffer, 0, outputBufferSize);
+                    outputStream.write(buffer, 0, readLength);
+
+                    position += readLength;
+                    if (V) {
+                        Log.v(TAG, "Sending file position = " + position
+                                + " readLength " + readLength + " bytes took "
+                                + (System.currentTimeMillis() - timestamp) + " ms");
+                    }
+                }
+                if (position == file.length()) {
+                    Log.i(TAG, "SendFile finished send out file " + file.length()
+                            + " length " + file.length());
+                    outputStream.close();
+                } else {
+                    error = true;
+                    // TBD - Is Output stream close needed here
+                    putOperation.abort();
+                    Log.i(TAG, "SendFile interrupted when send out file "
+                            + " at " + position + " of " + file.length());
+                }
+            }
+        } catch (IOException e) {
+            handleSendException(e.toString());
+            error = true;
+        } catch (IndexOutOfBoundsException e) {
+            handleSendException(e.toString());
+            error = true;
+        } finally {
+            if (fileInputStream != null) {
+                try {
+                    fileInputStream.close();
+                } catch (IOException ei) {
+                    Log.e(TAG, "Error while closing stream"+ ei.toString());
+                }
+            }
+            try {
+                if (!error) {
+                    responseCode = putOperation.getResponseCode();
+                    if (responseCode != -1) {
+                        if (V) Log.v(TAG, "Get response code " + responseCode);
+                        if (responseCode != ResponseCodes.OBEX_HTTP_OK) {
+                            Log.i(TAG, "Response error code is " + responseCode);
+                        }
+                    }
+                }
+                if (putOperation != null) {
+                   putOperation.close();
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error when closing stream after send " + e.getMessage());
+            }
+        }
+        if(D) Log.d(TAG, "BluetoothMnsObexSession: exiting from sendEvent");
+        releaseMnsLock();
+        return responseCode;
+    }
+
+    private void handleSendException(String exception) {
+        Log.e(TAG, "Error when sending event: " + exception);
+    }
+
+    private void acquireMnsLock() {
+        if (V) Log.v(TAG, "About to acquire Mns:mWakeLock");
+        if (mWakeLock == null) {
+            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MnsPartialWakeLock");
+            mWakeLock.setReferenceCounted(false);
+            mWakeLock.acquire();
+            if (V) Log.v(TAG, "Mns:mWakeLock acquired");
+        }
+        else {
+            Log.e(TAG, "Mns:mWakeLock already acquired");
+        }
+    }
+
+    public void releaseMnsLock() {
+        if (V) Log.v(TAG, "About to release Mns:mWakeLock");
+        if (mWakeLock != null) {
+            if (mWakeLock.isHeld()) {
+                mWakeLock.release();
+                if (V) Log.v(TAG, "Mns:mWakeLock released");
+            } else {
+                if (V) Log.v(TAG, "Mns:mWakeLock already released");
+            }
+            mWakeLock = null;
+        }
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMnsPreference.java b/src/org/codeaurora/bluetooth/map/BluetoothMnsPreference.java
new file mode 100644
index 0000000..4d4d673
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMnsPreference.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * This class cache Bluetooth device name and channel locally. Its a temp
+ * solution which should be replaced by bluetooth_devices in SettingsProvider
+ */
+public class BluetoothMnsPreference {
+
+    private static final String TAG = "BluetoothMnsPreference";
+    private static final boolean D = BluetoothMasService.DEBUG;
+    private static final boolean V = BluetoothMasService.VERBOSE;
+
+    private static BluetoothMnsPreference INSTANCE;
+
+    /* Used when obtaining a reference to the singleton instance. */
+    private static Object INSTANCE_LOCK = new Object();
+
+    private boolean mInitialized;
+
+    private Context mContext;
+
+    private SharedPreferences mNamePreference;
+
+    private SharedPreferences mChannelPreference;
+
+    private HashMap<String, Integer> mChannels = new HashMap<String, Integer>();
+
+    private HashMap<String, String> mNames = new HashMap<String, String>();
+
+    public static final String BLUETOOTHMNS_NAME_PREFERENCE = "btmns_names";
+
+    public static final String BLUETOOTHMNS_CHANNEL_PREFERENCE = "btmns_channels";
+
+
+    public static BluetoothMnsPreference getInstance(Context context) {
+        synchronized (INSTANCE_LOCK) {
+            if (INSTANCE == null) {
+                INSTANCE = new BluetoothMnsPreference();
+            }
+            if (!INSTANCE.init(context)) {
+                return null;
+            }
+            return INSTANCE;
+        }
+    }
+
+    private boolean init(Context context) {
+        if (mInitialized)
+            return true;
+        mInitialized = true;
+
+        mContext = context;
+
+        mNamePreference = mContext.getSharedPreferences(
+                BLUETOOTHMNS_NAME_PREFERENCE, Context.MODE_PRIVATE);
+        mChannelPreference = mContext.getSharedPreferences(
+                BLUETOOTHMNS_CHANNEL_PREFERENCE, Context.MODE_PRIVATE);
+
+        mNames = (HashMap<String, String>) mNamePreference.getAll();
+        mChannels = (HashMap<String, Integer>) mChannelPreference.getAll();
+
+        return true;
+    }
+
+    private String getChannelKey(BluetoothDevice remoteDevice, int uuid) {
+        return remoteDevice.getAddress() + "_" + Integer.toHexString(uuid);
+    }
+
+    public String getName(BluetoothDevice remoteDevice) {
+        if (remoteDevice.getAddress().equals("FF:FF:FF:00:00:00")) {
+            return "localhost";
+        }
+        if (!mNames.isEmpty()) {
+            String name = mNames.get(remoteDevice.getAddress());
+            if (name != null) {
+                return name;
+            }
+        }
+        return null;
+    }
+
+    public int getChannel(BluetoothDevice remoteDevice, int uuid) {
+        String key = getChannelKey(remoteDevice, uuid);
+        if (V) Log.v(TAG, "getChannel " + key);
+        Integer channel = null;
+        if (mChannels != null) {
+            channel = mChannels.get(key);
+            if (V) Log.v(TAG, "getChannel for " + remoteDevice + "_"
+                + Integer.toHexString(uuid) + " as " + channel);
+        }
+        return (channel != null) ? channel : -1;
+    }
+
+    public void setName(BluetoothDevice remoteDevice, String name) {
+        if (V) Log.v(TAG, "Setname for " + remoteDevice + " to " + name);
+        if (!name.equals(getName(remoteDevice))) {
+            Editor ed = mNamePreference.edit();
+            ed.putString(remoteDevice.getAddress(), name);
+            ed.commit();
+            mNames.put(remoteDevice.getAddress(), name);
+        }
+    }
+
+    public void setChannel(BluetoothDevice remoteDevice, int uuid, int channel) {
+        if (V) Log.v(TAG, "Setchannel for " + remoteDevice + "_"
+            + Integer.toHexString(uuid) + " to " + channel);
+        if (channel != getChannel(remoteDevice, uuid)) {
+            String key = getChannelKey(remoteDevice, uuid);
+            Editor ed = mChannelPreference.edit();
+            ed.putInt(key, channel);
+            ed.commit();
+            mChannels.put(key, channel);
+        }
+    }
+
+    public void removeChannel(BluetoothDevice remoteDevice, int uuid) {
+        String key = getChannelKey(remoteDevice, uuid);
+        Editor ed = mChannelPreference.edit();
+        ed.remove(key);
+        ed.commit();
+        mChannels.remove(key);
+    }
+
+    public void dump() {
+        Log.d(TAG, "Dumping Names:  ");
+        Log.d(TAG, mNames.toString());
+        Log.d(TAG, "Dumping Channels:  ");
+        Log.d(TAG, mChannels.toString());
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMnsRfcommTransport.java b/src/org/codeaurora/bluetooth/map/BluetoothMnsRfcommTransport.java
new file mode 100644
index 0000000..3a3cfd9
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMnsRfcommTransport.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.bluetooth.BluetoothSocket;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.obex.ObexTransport;
+
+public class BluetoothMnsRfcommTransport implements ObexTransport {
+
+    private final BluetoothSocket mSocket;
+
+    public BluetoothMnsRfcommTransport(BluetoothSocket socket) {
+        super();
+        this.mSocket = socket;
+    }
+
+    public void close() throws IOException {
+        mSocket.close();
+    }
+
+    public DataInputStream openDataInputStream() throws IOException {
+        return new DataInputStream(openInputStream());
+    }
+
+    public DataOutputStream openDataOutputStream() throws IOException {
+        return new DataOutputStream(openOutputStream());
+    }
+
+    public InputStream openInputStream() throws IOException {
+        return mSocket.getInputStream();
+    }
+
+    public OutputStream openOutputStream() throws IOException {
+        return mSocket.getOutputStream();
+    }
+
+    public void connect() throws IOException {
+    }
+
+    public void create() throws IOException {
+    }
+
+    public void disconnect() throws IOException {
+    }
+
+    public void listen() throws IOException {
+    }
+
+    public boolean isConnected() throws IOException {
+        // TODO: add implementation
+        return true;
+    }
+
+    public String getRemoteAddress() {
+        if (mSocket == null)
+            return null;
+        return mSocket.getRemoteDevice().getAddress();
+    }
+
+}
diff --git a/src/org/codeaurora/bluetooth/map/BluetoothMnsSmsMms.java b/src/org/codeaurora/bluetooth/map/BluetoothMnsSmsMms.java
new file mode 100644
index 0000000..b7a062a
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/BluetoothMnsSmsMms.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.os.Handler;
+import android.provider.Telephony.Mms;
+import android.provider.Telephony.MmsSms;
+import android.provider.Telephony.Sms;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import org.codeaurora.bluetooth.map.BluetoothMns.MnsClient;
+import com.google.android.mms.pdu.PduHeaders;
+
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.DELETED;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.OUTBOX;
+import static org.codeaurora.bluetooth.map.MapUtils.SmsMmsUtils.SENT;
+
+/**
+ * This class run an MNS session.
+ */
+public class BluetoothMnsSmsMms extends MnsClient {
+    private static final String TAG = "BluetoothMnsSmsMms";
+    private static final boolean V = BluetoothMasService.VERBOSE;
+    private static final String MSG_TO_MAP[] = {
+        "",         // ALL
+        "inbox",    // INBOX
+        "sent",     // SENT
+        "draft",    // DRAFT
+        "outbox",   // OUTBOX
+        "outbox",   // FAILED
+        "outbox",   // QUEUED
+        "inbox",    // INBOX_SUB1
+        "inbox",    // INBOX_SUB2
+    };
+    private static final String SMS_GSM = "SMS_GSM";
+    private static final String SMS_CDMA = "SMS_CDMA";
+    private static final String MMS = "MMS";
+    private final long SMS_OFFSET_START;
+    private final long MMS_OFFSET_START;
+
+    private MmsSmsContentObserver mMmsSmsObserver = new MmsSmsContentObserver();
+
+    public BluetoothMnsSmsMms(Context context, Integer masId) {
+        super(context, masId);
+        SMS_OFFSET_START = OFFSET_START;
+        MMS_OFFSET_START = OFFSET_START + ((OFFSET_END - OFFSET_START) / 2);
+    }
+
+    @Override
+    protected void registerContentObserver() {
+        if (V) Log.v(TAG, "REGISTERING SMS/MMS MNS");
+        mMmsSmsObserver.update(true);
+        mContext.getContentResolver().registerContentObserver(MmsSms.CONTENT_URI, true,
+                mMmsSmsObserver);
+        if (V) Log.v(TAG, "REGISTERING SMS/MMS MNS DONE");
+    }
+
+    @Override
+    protected void unregisterContentObserver() {
+        if (V) Log.v(TAG, "UNREGISTERING MNS SMS/MMS");
+        mContext.getContentResolver().unregisterContentObserver(mMmsSmsObserver);
+        if (V) Log.v(TAG, "UNREGISTERING MNS SMS/MMS DONE");
+    }
+
+    private static final String[] MMS_PROJECTION = new String[] {Mms._ID, Mms.MESSAGE_BOX,
+        Mms.THREAD_ID, Mms.MESSAGE_TYPE, Mms.DATE};
+    private static final int MMS_ID_COL = 0;
+    private static final int MMS_BOX_TYPE_COL = 1;
+    private static final int MMS_THREAD_ID_COL = 2;
+    private static final int MMS_MSG_TYPE_COL = 3;
+    private static final int MMS_DATE_COL = 4;
+
+    private static final String[] SMS_PROJECTION = new String[] {Sms._ID, Sms.TYPE, Sms.THREAD_ID,
+        Sms.DATE};
+    private static final int SMS_ID_COL = 0;
+    private static final int SMS_TYPE_COL = 1;
+    private static final int SMS_THREAD_ID_COL = 2;
+    private static final int SMS_DATE_COL = 3;
+
+    static class Message {
+        long mId;
+        String mFolderName;
+        int mType;
+        long mThreadId;
+        long mDate;
+
+        public Message(long id, String folderName, int type, long threadId, long date) {
+            mId = id;
+            mFolderName = folderName;
+            mType = type;
+            mThreadId = threadId;
+            mDate = date;
+        }
+    }
+
+    private class MmsSmsContentObserver extends ContentObserver {
+        private static final String TAG = "MmsSmsContentObserver";
+        private ConcurrentHashMap<Long, Message> mSmsList = new ConcurrentHashMap<Long, Message>();
+        private ConcurrentHashMap<Long, Message> mSmsAddedList = new ConcurrentHashMap<Long, Message>();
+        private ConcurrentHashMap<Long, Message> mSmsDeletedList = new ConcurrentHashMap<Long, Message>();
+
+        private ConcurrentHashMap<Long, Message> mMmsList = new ConcurrentHashMap<Long, Message>();
+        private ConcurrentHashMap<Long, Message> mMmsAddedList = new ConcurrentHashMap<Long, Message>();
+        private ConcurrentHashMap<Long, Message> mMmsDeletedList = new ConcurrentHashMap<Long, Message>();
+
+        private static final int UPDATE = 0;
+        private static final int THRESHOLD = 1500;  // 1.5 sec
+
+        public MmsSmsContentObserver() {
+            super(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            if (V) Log.v(TAG, "onChange(" + selfChange + ") SMS mas Id: " + mMasId);
+            if (mHandler.hasMessages(UPDATE)) {
+                mHandler.removeMessages(UPDATE);
+            }
+            mHandler.sendEmptyMessageDelayed(UPDATE, THRESHOLD);
+        }
+
+        private Handler mHandler = new Handler() {
+            private static final String TAG = "MmsSmsContentObserver.Hanlder";
+            @Override
+            public void handleMessage(android.os.Message msg) {
+                if (V) Log.v(TAG, "handleMessage(" + msg.what + ") mas Id: " + mMasId);
+                switch (msg.what) {
+                    case UPDATE:
+                        new Thread(new Runnable() {
+                            public void run() {
+                                update(false);
+                                sendEvents();
+                            }
+                        }, "MmsSms Content Observer Thread").start();
+                        break;
+                }
+            }
+        };
+
+        void update(boolean init) {
+            updateSms(init);
+            updateMms(init);
+        }
+
+        void updateSms(boolean init) {
+            if (init) {
+                clearSms();
+            }
+
+           if(V) Log.v(TAG, "MNS_SMS: updateSMS");
+            final ContentResolver resolver = mContext.getContentResolver();
+            Cursor crSms = resolver.query(Sms.CONTENT_URI, SMS_PROJECTION, null, null, null);
+            if (crSms != null) {
+                if (crSms.moveToFirst()) {
+                    ConcurrentHashMap<Long, Message> oldSmsList = mSmsList;
+                    ConcurrentHashMap<Long, Message> newSmsList = new ConcurrentHashMap<Long, Message>();
+                    do {
+                        final long id = crSms.getLong(SMS_ID_COL);
+                        final int type = crSms.getInt(SMS_TYPE_COL);
+                        final long threadId = crSms.getLong(SMS_THREAD_ID_COL);
+                        final long date = crSms.getLong(SMS_DATE_COL);
+                        if (type > 0 && type < MSG_TO_MAP.length) {
+                            final Message msg = new Message(id, MSG_TO_MAP[type], type, threadId,
+                                    date);
+                            if(V) Log.v(TAG, "MNS_SMS: Found: id: " + id+ "  type: " + type + " threadId: " + threadId + " date: " + date +"\n");
+                            newSmsList.put(id, msg);
+                            if (oldSmsList.containsKey(id)) {
+                                Message old_msg = oldSmsList.remove(id);
+                                if (msg.mType != old_msg.mType) {
+                                    if(V) Log.v(TAG, "MNS_SMS: Add to mSmsAddedList from old");
+                                    mSmsAddedList.put(id, msg);
+                                }
+                            }
+                            else {
+                                final Message oldMsg = oldSmsList.remove(id);
+                                if (!init && (oldMsg == null || oldMsg.mDate != date)) {
+                                    if(V) Log.v(TAG, "MNS_SMS: Add to mSmsAddedList");
+                                    mSmsAddedList.put(id, msg);
+                                }
+                            }
+                        }
+                    } while (crSms.moveToNext());
+                    mSmsList = newSmsList;
+                    mSmsDeletedList = oldSmsList;
+                }
+                else
+                {
+                    // Last sms to be deleted
+                    if(mSmsList.size() > 0)
+                    {
+                        if(V) Log.v(TAG, "MNS_SMS: mSmsList Length: " + mSmsList.size());
+                        mSmsDeletedList = mSmsList;
+                    }
+                }
+                crSms.close();
+            }
+        }
+
+        void updateMms(boolean init) {
+            if (init) {
+                clearMms();
+            }
+            final ContentResolver resolver = mContext.getContentResolver();
+            Cursor crMms = resolver.query(Mms.CONTENT_URI, MMS_PROJECTION, null, null, null);
+            if (crMms != null) {
+                if (crMms.moveToFirst()) {
+                    ConcurrentHashMap<Long, Message> oldMmsList = mMmsList;
+                    ConcurrentHashMap<Long, Message> newMmsList = new ConcurrentHashMap<Long, Message>();
+                    do {
+                        final long id = crMms.getInt(MMS_ID_COL);
+                        final int boxType = crMms.getInt(MMS_BOX_TYPE_COL);
+                        final long threadId = crMms.getLong(MMS_THREAD_ID_COL);
+                        final int msgType = crMms.getInt(MMS_MSG_TYPE_COL);
+                        final long date = crMms.getLong(MMS_DATE_COL);
+                        // TODO need to filter out Pdu by message type?
+                        if (msgType != PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND &&
+                                msgType != PduHeaders.MESSAGE_TYPE_DELIVERY_IND) {
+                            final Message msg = new Message(id, MSG_TO_MAP[boxType],
+                                    boxType, threadId, date);
+                            newMmsList.put(id, msg);
+                            final Message oldMsg = oldMmsList.remove(id);
+                            if (!init && (oldMsg == null || oldMsg.mDate != date)) {
+                                mMmsAddedList.put(id, msg);
+                            }
+                        }
+                    } while (crMms.moveToNext());
+                    mMmsList = newMmsList;
+                    mMmsDeletedList = oldMmsList;
+                }
+                crMms.close();
+            }
+        }
+
+        private void sendEvents() {
+            if (mSmsAddedList.size() > 0) {
+                newSms();
+                mSmsAddedList.clear();
+            }
+            if (mSmsDeletedList.size() > 0) {
+                deletedSms();
+                mSmsDeletedList.clear();
+            }
+            if (mMmsAddedList.size() > 0) {
+                newMms();
+                mMmsAddedList.clear();
+            }
+            if (mMmsDeletedList.size() > 0) {
+                deletedMms();
+                mMmsDeletedList.clear();
+            }
+        }
+
+        private void clearSms() {
+            mSmsList.clear();
+            mSmsAddedList.clear();
+            mSmsDeletedList.clear();
+        }
+
+        private void clearMms() {
+            mMmsList.clear();
+            mMmsAddedList.clear();
+            mMmsDeletedList.clear();
+        }
+
+        private void newSms() {
+            if (V) Log.v(TAG, "newSms() SMS mas Id: " + mMasId);
+            if (mListener != null) {
+                final int phoneType = TelephonyManager.getDefault().getPhoneType();
+                final String type = (phoneType == TelephonyManager.PHONE_TYPE_CDMA)
+                        ? SMS_CDMA : SMS_GSM;
+                Collection<Message> values = mSmsAddedList.values();
+                for (Message msg : values) {
+                    if (msg.mType == Sms.MESSAGE_TYPE_SENT) {
+                        mListener.onSendingSuccess(mMasId, String.valueOf(SMS_OFFSET_START +
+                                msg.mId), PRE_PATH + SENT, type);
+                    } else if (msg.mType == Sms.MESSAGE_TYPE_FAILED) {
+                        mListener.onSendingFailure(mMasId, String.valueOf(SMS_OFFSET_START +
+                                msg.mId), PRE_PATH + OUTBOX, type);
+                    } else if ((msg.mType == Sms.MESSAGE_TYPE_INBOX) ||
+                               (msg.mType == Sms.MESSAGE_TYPE_OUTBOX)) {
+                        String folderName = (msg.mThreadId == -1) ? DELETED : msg.mFolderName;
+                        mListener.onNewMessage(mMasId, String.valueOf(SMS_OFFSET_START + msg.mId),
+                                PRE_PATH + folderName, type);
+                    }
+                }
+            }
+        }
+
+        private void deletedSms() {
+            if (V) Log.v(TAG, "deletedSms() SMS mas Id: " + mMasId);
+            if (mListener != null) {
+                final int phoneType = TelephonyManager.getDefault().getPhoneType();
+                final String type = (phoneType == TelephonyManager.PHONE_TYPE_CDMA)
+                        ? SMS_CDMA : SMS_GSM;
+                Collection<Message> values = mSmsDeletedList.values();
+                for (Message msg : values) {
+                    String folderName = (msg.mThreadId == -1) ? DELETED : msg.mFolderName;
+                    mListener.onMessageDeleted(mMasId, String.valueOf(SMS_OFFSET_START + msg.mId),
+                            PRE_PATH + folderName, type);
+                }
+            }
+        }
+
+        private void newMms() {
+            if (V) Log.v(TAG, "newMms() MMS mas Id: " + mMasId);
+            if (mListener != null) {
+                Collection<Message> values = mMmsAddedList.values();
+                for (Message msg : values) {
+                    String folderName = (msg.mThreadId == -1) ? DELETED : msg.mFolderName;
+                    mListener.onNewMessage(mMasId, String.valueOf(MMS_OFFSET_START + msg.mId),
+                            PRE_PATH + folderName, MMS);
+                    if (msg.mType == Mms.MESSAGE_BOX_SENT) {
+                        mListener.onSendingSuccess(mMasId, String.valueOf(SMS_OFFSET_START +
+                                msg.mId), PRE_PATH + SENT, MMS);
+                    }
+                }
+            }
+        }
+
+        private void deletedMms() {
+            if (V) Log.v(TAG, "deletedMms() MMS mas Id: " + mMasId);
+            if (mListener != null) {
+                Collection<Message> values = mMmsDeletedList.values();
+                for (Message msg : values) {
+                    String folderName = (msg.mThreadId == -1) ? DELETED : msg.mFolderName;
+                    mListener.onMessageDeleted(mMasId, String.valueOf(MMS_OFFSET_START + msg.mId),
+                            PRE_PATH + folderName, MMS);
+                }
+            }
+        }
+    };
+}
diff --git a/src/org/codeaurora/bluetooth/map/IBluetoothMasApp.java b/src/org/codeaurora/bluetooth/map/IBluetoothMasApp.java
new file mode 100644
index 0000000..c5bf471
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/IBluetoothMasApp.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map;
+
+import android.bluetooth.BluetoothDevice;
+
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageListingRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageRsp;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasPushMsgRsp;
+import org.codeaurora.bluetooth.map.MapUtils.MapUtils.BadRequestException;
+
+import java.io.File;
+
+public interface IBluetoothMasApp {
+    public static final int BIT_SUBJECT = 0x1;
+    public static final int BIT_DATETIME = 0x2;
+    public static final int BIT_SENDER_NAME = 0x4;
+    public static final int BIT_SENDER_ADDRESSING = 0x8;
+
+    public static final int BIT_RECIPIENT_NAME = 0x10;
+    public static final int BIT_RECIPIENT_ADDRESSING = 0x20;
+    public static final int BIT_TYPE = 0x40;
+    public static final int BIT_SIZE = 0x80;
+
+    public static final int BIT_RECEPTION_STATUS = 0x100;
+    public static final int BIT_TEXT = 0x200;
+    public static final int BIT_ATTACHMENT_SIZE = 0x400;
+    public static final int BIT_PRIORITY = 0x800;
+
+    public static final int BIT_READ = 0x1000;
+    public static final int BIT_SENT = 0x2000;
+    public static final int BIT_PROTECTED = 0x4000;
+    public static final int BIT_REPLYTO_ADDRESSING = 0x8000;
+
+    /**
+     * Message Access Profile SPEC V10
+     * 3.1.1 Handle
+     * The handle shall be a 64 bit unsigned integer whose value is defined by the MSE.
+     * 7.1 SDP Interoperability Requirements
+     * Up to 12 MAS Instances may be supported by a MSE device.
+     * The value range of the MASInstanceID. shall be 0..255.
+     * Although id range is 0..255, 0~11 are selected for conventional indexing
+     */
+    public static final long HANDLE_OFFSET[] = {
+        0,          // MAS id 0
+        1 << 59,    // MAS id 1
+        2 << 59,    // MAS id 2
+        3 << 59,    // MAS id 3
+        4 << 59,    // MAS id 4
+        5 << 59,    // MAS id 5
+        6 << 59,    // MAS id 6
+        7 << 59,    // MAS id 7
+        8 << 59,    // MAS id 8
+        9 << 59,    // MAS id 9
+        10 << 59,   // MAS id 10
+        11 << 59,   // MAS id 11
+        Long.MAX_VALUE
+    };
+
+    public static final int EMAIL_MAX_PUSHMSG_SIZE = 409600;
+
+    public static final int DELETED_THREAD_ID = -1;
+
+    public static final String TELECOM = "telecom";
+    public static final String MSG = "msg";
+
+    public static final int MESSAGE_TYPE_EMAIL = 1 << 0;
+    public static final int MESSAGE_TYPE_SMS_GSM = 1 << 1;
+    public static final int MESSAGE_TYPE_SMS_CDMA = 1 << 2;
+    public static final int MESSAGE_TYPE_MMS = 1 << 3;
+    public static final int MESSAGE_TYPE_SMS = MESSAGE_TYPE_SMS_GSM | MESSAGE_TYPE_SMS_CDMA;
+    public static final int MESSAGE_TYPE_SMS_MMS = MESSAGE_TYPE_SMS | MESSAGE_TYPE_MMS;
+
+    public boolean setPath(boolean up, String name);
+    public boolean checkPath(boolean up, String name, boolean setPathFlag);
+    public int folderListingSize();
+    public String folderListing(BluetoothMasAppParams appParam);
+    //private String getFullPath(String child);
+    public BluetoothMasMessageListingRsp msgListing(String name,
+        BluetoothMasAppParams appParams);
+    public BluetoothMasMessageRsp msg(String msgHandle,
+        BluetoothMasAppParams bluetoothMasAppParams);
+    public BluetoothMasPushMsgRsp pushMsg(String name, File file,
+        BluetoothMasAppParams bluetoothMasAppParams) throws BadRequestException;
+    public int msgStatus(String msgHandle, BluetoothMasAppParams bluetoothMasAppParams);
+    public int msgUpdate();
+    public void onConnect();
+    public void onDisconnect();
+    public int notification(BluetoothDevice remoteDevice,
+        BluetoothMasAppParams bluetoothMasAppParams);
+    public void startMnsSession(BluetoothDevice remoteDevice);
+    public void stopMnsSession(BluetoothDevice remoteDevice);
+    public int getMasId();
+    public boolean checkPrecondition();
+
+    public interface MessageNotificationListener {
+        public static final String NEW_MESSAGE = "NewMessage";
+        public static final String DELIVERY_SUCCESS = "DeliverySuccess";
+        public static final String SENDING_SUCCESS = "SendingSuccess";
+        public static final String DELIVERY_FAILURE = "DeliveryFailure";
+        public static final String SENDING_FAILURE = "SendingFailure";
+        public static final String MESSAGE_DELETED = "MessageDeleted";
+        public static final String MESSAGE_SHIFT = "MessageShift";
+        public void onNewMessage(int masId, String handle, String folder, String msgType);
+        public void onDeliverySuccess(int masId, String handle, String folder, String msgType);
+        public void onSendingSuccess(int masId, String handle, String folder, String msgType);
+        public void onDeliveryFailure(int masId, String handle, String folder, String msgType);
+        public void onSendingFailure(int masId, String handle, String folder, String msgType);
+        public void onMessageDeleted(int masId, String handle, String folder, String msgType);
+        public void onMessageShift(int masId, String handle, String toFolder, String fromFolder,
+                String msgType);
+    }
+
+    public interface MnsRegister {
+        public void register(MessageNotificationListener listener);
+        public boolean isRegistered();
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/BmessageConsts.java b/src/org/codeaurora/bluetooth/map/MapUtils/BmessageConsts.java
new file mode 100644
index 0000000..e424653
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/BmessageConsts.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map.MapUtils;
+
+public class BmessageConsts {
+
+    public String bmsg_version = null;
+    public String status = null;
+    public String type = null;
+    public String folder = null;
+    public String vcard_version = null;
+    public String recipient_vcard_name = null;
+    public String recipient_vcard_phone_number = null;
+    public String recipient_vcard_email = null;
+    public String originator_vcard_name = null;
+    public String originator_vcard_phone_number = null;
+    public String originator_vcard_email = null;
+    public String body_encoding = null;
+    public int body_length = 0;
+    public String body_msg = null;
+    public String body_part_ID = null;
+    public String body_language = null;
+    public String body_charset = null;
+    public String subject = null;
+
+    // Setters and Getters
+
+    public String getBody_language() {
+        return body_language;
+    }
+
+    public void setBody_language(String body_language) {
+        this.body_language = body_language;
+    }
+
+    public String getBody_part_ID() {
+        return body_part_ID;
+    }
+
+    public void setBody_part_ID(String body_part_ID) {
+        this.body_part_ID = body_part_ID;
+    }
+
+    public String getBmsg_version() {
+        return bmsg_version;
+    }
+
+    public void setBmsg_version(String bmsg_version) {
+        this.bmsg_version = bmsg_version;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getFolder() {
+        return folder;
+    }
+
+    public void setFolder(String folder) {
+        this.folder = folder;
+    }
+
+    public String getVcard_version() {
+        return vcard_version;
+    }
+
+    public void setVcard_version(String vcard_version) {
+        this.vcard_version = vcard_version;
+    }
+
+    // Name
+    public String getRecipientVcard_name() {
+        return recipient_vcard_name;
+    }
+
+    public String getOriginatorVcard_name() {
+        return originator_vcard_name;
+    }
+
+    // recipient_vcard_name
+
+    public void setRecipientVcard_name(String vcard_name) {
+        this.recipient_vcard_name = vcard_name;
+    }
+
+    public void setOriginatorVcard_name(String vcard_name) {
+        this.originator_vcard_name = vcard_name;
+    }
+
+    // Name
+
+    // Phone
+    public String getRecipientVcard_email() {
+        return recipient_vcard_email;
+    }
+
+    public String getOriginatorVcard_email() {
+        return originator_vcard_email;
+    }
+
+    public void setRecipientVcard_email(String email) {
+        this.recipient_vcard_email = email;
+    }
+
+    public void setOriginatorVcard_email(String email) {
+        this.originator_vcard_email = email;
+    }
+
+    // Phone
+    //Email
+    public String getRecipientVcard_phone_number() {
+        return recipient_vcard_phone_number;
+    }
+
+    public String getOriginatorVcard_phone_number() {
+        return originator_vcard_phone_number;
+    }
+
+    public void setRecipientVcard_phone_number(String vcard_phone_number) {
+        this.recipient_vcard_phone_number = vcard_phone_number;
+    }
+
+    public void setOriginatorVcard_phone_number(String vcard_phone_number) {
+        this.originator_vcard_phone_number = vcard_phone_number;
+    }
+
+
+
+
+    //end Email
+
+    public String getBody_charset() {
+        return body_charset;
+    }
+
+    public void setBody_charset(String body_charset) {
+        this.body_charset = body_charset;
+    }
+
+    public String getBody_encoding() {
+        return body_encoding;
+    }
+
+    public void setBody_encoding(String body_encoding) {
+        this.body_encoding = body_encoding;
+    }
+
+    public int getBody_length() {
+        return body_length;
+    }
+
+    public void setBody_length(int body_length) {
+        this.body_length = body_length;
+    }
+
+    public String getBody_msg() {
+        return body_msg;
+    }
+
+    public void setBody_msg(String body_msg) {
+        this.body_msg = body_msg;
+    }
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+}
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/CommonUtils.java b/src/org/codeaurora/bluetooth/map/MapUtils/CommonUtils.java
new file mode 100644
index 0000000..73546d0
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/CommonUtils.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map.MapUtils;
+
+import android.content.Context;
+import android.text.format.Time;
+import android.util.Log;
+import android.util.TimeFormatException;
+
+import org.codeaurora.bluetooth.map.BluetoothMasAppParams;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.obex.ResponseCodes;
+
+public class CommonUtils {
+    public static final String TAG = "CommonUtils";
+
+    public static final ArrayList<String> FIXED_FOLDERS;
+
+    static {
+        FIXED_FOLDERS = new ArrayList<String>();
+        FIXED_FOLDERS.add("inbox");
+        FIXED_FOLDERS.add("sent");
+        FIXED_FOLDERS.add("deleted");
+        FIXED_FOLDERS.add("outbox");
+        FIXED_FOLDERS.add("draft");
+    }
+
+    public static class BluetoothMasPushMsgRsp {
+        public int response;
+        public String msgHandle;
+    }
+
+    public static class BluetoothMasMessageListingRsp {
+        public File file = null;
+        public int msgListingSize = 0;
+        public byte newMessage = 0;
+        public int rsp = ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    public static class BluetoothMasMessageRsp {
+        public byte fractionDeliver = 0;
+        public File file = null;
+        public int rsp = ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    public static class BluetoothMsgListRsp {
+        public int messageListingSize = 0;
+        public BluetoothMasMessageListingRsp rsp;
+        public List<MsgListingConsts> msgList = new ArrayList<MsgListingConsts>();
+    }
+
+    public static String getFullPath(String child, Context context, List<String> folderList, String CurrentPath) {
+        String tempPath = null;
+        if (child != null) {
+            if (CurrentPath == null) {
+                if (child.equals("telecom")) {
+                    // Telecom is fine
+                    tempPath = "telecom";
+                }
+            }
+            else if (CurrentPath.equals("telecom")) {
+                if (child.equals("msg")) {
+                    tempPath = CurrentPath + "/" + child;
+                }
+            }
+            else { //Get Path for any folder or subfolder
+                for (String folder : folderList) { //TODO NEED TO LOOK INTO THIS
+                    if(child.toUpperCase().contains("GMAIL")){
+                        if (folder.equalsIgnoreCase(child)
+                                || folder.toUpperCase().contains(child.toUpperCase())) {
+                            //added second condition above for gmail sent folder
+                            tempPath = CurrentPath + "/" + folder;
+                            break;
+                        }
+                    }
+                    else{
+                        if (folder.equalsIgnoreCase(child)) {
+                            tempPath = CurrentPath + "/" + folder;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return tempPath;
+    }
+
+    public static int validateFilterPeriods(BluetoothMasAppParams appParams) {
+        int filterPeriodValid = -1;
+        String periodStr = "";
+        /* Filter Period Begin */
+        if ((appParams.FilterPeriodBegin != null)
+                && (appParams.FilterPeriodBegin.length() > 0)) {
+            Time time = new Time();
+            try {
+                time.parse(appParams.FilterPeriodBegin.trim());
+                if (periodStr.length() != 0) {
+                        periodStr += " AND ";
+                }
+                periodStr += "date >= " + time.toMillis(false);
+            } catch (TimeFormatException e) {
+                Log.d(TAG, "Bad formatted FilterPeriodBegin "
+                        + appParams.FilterPeriodBegin);
+                filterPeriodValid = 0;
+            }
+        }
+
+        /* Filter Period End */
+        if ((appParams.FilterPeriodEnd != null)
+                && (appParams.FilterPeriodEnd.length() > 0 )) {
+            Time time = new Time();
+            try {
+                time.parse(appParams.FilterPeriodEnd.trim());
+                if (periodStr.length() != 0) {
+                        periodStr += " AND ";
+                }
+                periodStr += "date < " + time.toMillis(false);
+            } catch (TimeFormatException e) {
+                Log.d(TAG, "Bad formatted FilterPeriodEnd "
+                        + appParams.FilterPeriodEnd);
+                filterPeriodValid = 0;
+            }
+        }
+        return filterPeriodValid;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/EmailUtils.java b/src/org/codeaurora/bluetooth/map/MapUtils/EmailUtils.java
new file mode 100644
index 0000000..5f92b3c
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/EmailUtils.java
@@ -0,0 +1,1054 @@
+/*
+ * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map.MapUtils;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.text.Html;
+import android.text.format.Time;
+import android.util.Log;
+import android.util.TimeFormatException;
+
+import org.codeaurora.bluetooth.map.BluetoothMasAppParams;
+import org.codeaurora.bluetooth.map.BluetoothMasService;
+import org.codeaurora.bluetooth.map.MapUtils.CommonUtils.BluetoothMasMessageRsp;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Random;
+import java.util.Locale;
+
+public class EmailUtils {
+    public static final String TAG = "EmailUtils";
+    public static final boolean V = BluetoothMasService.VERBOSE;
+
+    public static final int BIT_SUBJECT = 0x1;
+    public static final int BIT_DATETIME = 0x2;
+    public static final int BIT_SENDER_NAME = 0x4;
+    public static final int BIT_SENDER_ADDRESSING = 0x8;
+
+    public static final int BIT_RECIPIENT_NAME = 0x10;
+    public static final int BIT_RECIPIENT_ADDRESSING = 0x20;
+    public static final int BIT_TYPE = 0x40;
+    public static final int BIT_SIZE = 0x80;
+
+    public static final int BIT_RECEPTION_STATUS = 0x100;
+    public static final int BIT_TEXT = 0x200;
+    public static final int BIT_ATTACHMENT_SIZE = 0x400;
+    public static final int BIT_PRIORITY = 0x800;
+
+    public static final int BIT_READ = 0x1000;
+    public static final int BIT_SENT = 0x2000;
+    public static final int BIT_PROTECTED = 0x4000;
+    public static final int BIT_REPLYTO_ADDRESSING = 0x8000;
+
+    public static final String BMW = "BMW";
+
+    public static List<String> folderListEmail(List<String> folderList, Context context) {
+        String[] projection = new String[] {"displayName"};
+        Uri uri = Uri.parse("content://com.android.email.provider/mailbox");
+        Cursor cr = context.getContentResolver().query(uri, projection, null, null, null);
+
+        if (cr != null && cr.moveToFirst()) {
+            do {
+                if (V){
+                    Log.v(TAG, " Column Name: "+ cr.getColumnName(0) + " Value: " + cr.getString(0));
+                }
+                int folderFlag = 0;
+                for(int i=0; i< folderList.size(); i++){
+                    if(folderList.get(i).equalsIgnoreCase(cr.getString(0))){
+                        folderFlag = 1;
+                        break;
+                    }
+                }
+                if(cr.getString(0).equalsIgnoreCase("Drafts")){ //TODO need to remove this hardcoded value
+                    folderFlag = 1;
+                }
+                if(folderFlag == 0){
+                    folderList.add(cr.getString(0));
+                }
+
+            } while ( cr.moveToNext());
+        }
+        if (V){
+            Log.v(TAG, " Folder Listing of SMS,MMS and EMAIL: "+folderList);
+        }
+        if (cr != null) {
+            cr.close();
+        }
+        return folderList;
+    }
+
+    public static String getWhereIsQueryForTypeEmail(String folder, Context context, int masId) {
+        String query = "mailboxKey = -1";
+        String folderId;
+        Uri uri = Uri.parse("content://com.android.email.provider/mailbox");
+        if (folder == null) {
+            return query;
+        }
+        if (folder.contains("'")){
+            folder = folder.replace("'", "''");
+        }
+        Cursor cr = context.getContentResolver().query(
+                uri, null, "(" + ACCOUNT_KEY + "=" + getAccountId(masId) +
+                ") AND (UPPER(displayName) = '"+ folder.toUpperCase()+"')" , null, null);
+        if (cr != null) {
+            if ( cr.moveToFirst()) {
+                do {
+                    folderId = cr.getString(cr.getColumnIndex("_id"));
+                    query = "mailboxKey = "+ folderId;
+                    break;
+                } while ( cr.moveToNext());
+            }
+            cr.close();
+        }
+        return query;
+    }
+
+    public static int getMessageSizeEmail(long messageId, Context context) {
+        if (V){
+            Log.v(TAG, ":: Message Id in getMessageSizeEmail ::"+ messageId);
+        }
+        int msgSize = 0;
+        String textContent, htmlContent;
+        Uri uri = Uri.parse("content://com.android.email.provider/body");
+
+        Cursor cr = context.getContentResolver().query(
+                uri, null, "messageKey = "+ messageId , null, null);
+
+        if (cr != null && cr.moveToFirst()) {
+            do {
+                textContent = cr.getString(cr.getColumnIndex("textContent"));
+                htmlContent = cr.getString(cr.getColumnIndex("htmlContent"));
+                if(textContent != null && textContent.length() != 0){
+                    msgSize = textContent.length();
+                }
+                else if(textContent == null){
+                    if(htmlContent != null && htmlContent.length() != 0){
+                        msgSize = htmlContent.length();
+                    }
+                }
+                break;
+            } while (cr.moveToNext());
+        }
+        if (cr != null) {
+            cr.close();
+        }
+        return msgSize;
+    }
+
+    public static int getAttachmentSizeEmail(long messageId, Context context) {
+        if (V){
+            Log.v(TAG, ":: Message Id in getAttachmentSizeEmail ::"+ messageId);
+        }
+        int attchSize = 0;
+        Uri uri = Uri.parse("content://com.android.email.provider/attachment");
+
+        Cursor cr = context.getContentResolver().query(
+                uri, new String[]{"size"}, "messageKey = "+ messageId , null, null);
+        if (cr != null && cr.moveToFirst()) {
+            do {
+                attchSize += cr.getInt(0);
+            } while (cr.moveToNext());
+        }
+        if (cr != null) {
+            cr.close();
+        }
+        return attchSize;
+    }
+
+    public static String getFolderName(String[] splitStringsEmail) {
+        String folderName=" ";
+        int len = splitStringsEmail.length;
+        if (V){
+            Log.v(TAG, ":: Split Strings Array in getFolderName ::"+ splitStringsEmail);
+        }
+        folderName = splitStringsEmail[len -1];
+        if (V){
+            Log.v(TAG, "folderName :: " + folderName);
+        }
+        return folderName;
+    }
+
+    public static String getConditionString(String folderName, Context context,
+            BluetoothMasAppParams appParams, int masId) {
+        String whereClauseEmail = getWhereIsQueryForTypeEmail(folderName, context, masId);
+
+        /* Filter readstatus: 0 no filtering, 0x01 get unread, 0x10 get read */
+        if (appParams.FilterReadStatus != 0) {
+            if ((appParams.FilterReadStatus & 0x1) != 0) {
+                if (whereClauseEmail.length() != 0) {
+                    whereClauseEmail += " AND ";
+                }
+                whereClauseEmail += " flagRead = 0 ";
+            }
+            if (V){
+                Log.v(TAG, "Filter Read Status Value:"+appParams.FilterReadStatus);
+                Log.v(TAG, "Filter Read Status Condition Value:"+(appParams.FilterReadStatus & 0x02));
+            }
+            if ((appParams.FilterReadStatus & 0x02) != 0) {
+                if (whereClauseEmail.length() != 0) {
+                    whereClauseEmail += " AND ";
+                }
+                whereClauseEmail += " flagRead = 1 ";
+            }
+        }
+        if (V){
+            Log.v(TAG, "Filter Recipient Value:"+appParams.FilterRecipient);
+            Log.v(TAG, "Filter Recipient Condition 1 :"+(appParams.FilterRecipient != null));
+            if (appParams.FilterRecipient != null) {
+                Log.v(TAG, "Filter Recipient Condition 2 :"+(appParams.FilterRecipient.length() != 0));
+            }
+        }
+        //Filter Recipient
+        if ((appParams.FilterRecipient != null) && (appParams.FilterRecipient.length() > 0)
+                && !(appParams.FilterRecipient.equalsIgnoreCase("*"))) {
+                if(appParams.FilterRecipient.contains("*")){
+                    appParams.FilterRecipient = appParams.FilterRecipient.replace('*', '%');
+                }
+                if (whereClauseEmail.length() != 0) {
+                    whereClauseEmail += " AND ";
+                }
+            whereClauseEmail += " toList LIKE '%"+appParams.FilterRecipient.trim()+"%'";
+        }
+
+        // TODO Filter Originator
+
+        if ((appParams.FilterOriginator != null)
+                && (appParams.FilterOriginator.length() > 0)
+                && !(appParams.FilterOriginator.equalsIgnoreCase("*"))) {
+                if(appParams.FilterOriginator.contains("*")){
+                    appParams.FilterOriginator = appParams.FilterOriginator.replace('*', '%');
+                }
+            // For incoming message
+            if (whereClauseEmail.length() != 0) {
+                whereClauseEmail += " AND ";
+            }
+            String str1 = appParams.FilterOriginator;
+            whereClauseEmail += "fromList LIKE '%"+appParams.FilterOriginator.trim()+"%'";
+        }
+        if (V){
+            Log.v(TAG, "whereClauseEmail :" + whereClauseEmail);
+        }// TODO Filter priority?
+
+        /* Filter Period Begin */
+        if ((appParams.FilterPeriodBegin != null)
+                && (appParams.FilterPeriodBegin.length() != 0)) {
+            Time time = new Time();
+
+            try {
+                time.parse(appParams.FilterPeriodBegin.trim());
+                if (whereClauseEmail.length() != 0) {
+                    whereClauseEmail += " AND ";
+                }
+                whereClauseEmail += "timeStamp >= " + time.toMillis(false);
+
+            } catch (TimeFormatException e) {
+                Log.d(TAG, "Bad formatted FilterPeriodBegin, Ignore"
+                        + appParams.FilterPeriodBegin);
+            }
+        }
+
+        /* Filter Period End */
+        if ((appParams.FilterPeriodEnd != null)
+                && (appParams.FilterPeriodEnd.length() != 0)) {
+            Time time = new Time();
+            try {
+                time.parse(appParams.FilterPeriodEnd.trim());
+                if (whereClauseEmail.length() != 0) {
+                    whereClauseEmail += " AND ";
+                }
+                whereClauseEmail += "timeStamp < " + time.toMillis(false);
+            } catch (TimeFormatException e) {
+                Log.d(TAG, "Bad formatted FilterPeriodEnd, Ignore"
+                        + appParams.FilterPeriodEnd);
+            }
+        }
+
+        return whereClauseEmail;
+    }
+
+    public static MsgListingConsts bldEmailMsgLstItem(Context context, String folderName,
+                BluetoothMasAppParams appParams, String subject, String timestamp,
+                String senderName, String senderAddressing, String recipientName,
+                String recipientAddressing, String msgId, String readStatus, String replyToStr,
+                long offset) {
+
+        MsgListingConsts emailMsg = new MsgListingConsts();
+        emailMsg.setMsg_handle(Long.valueOf(msgId)+ offset);
+
+        Time time = new Time();
+        time.set(Long.valueOf(timestamp));
+
+        String datetimeStr = time.toString().substring(0, 15);
+
+        emailMsg.msgInfo.setDateTime(datetimeStr);
+
+        if (V){
+            Log.v(TAG, "bldEmailMsgLstItem");
+            Log.v(TAG, "Subject: " + subject);
+            Log.v(TAG, "timestamp: " + timestamp);
+            Log.v(TAG, "senderName: " + senderName);
+            Log.v(TAG, "senderAddressing: " + senderAddressing);
+            Log.v(TAG, "recipientName: " + recipientName);
+            Log.v(TAG, "recipientAddressing: " + recipientAddressing);
+            Log.v(TAG, "msgId: " + msgId);
+            Log.v(TAG, "readStatus: " + readStatus);
+            Log.v(TAG, "replyToStr: " + replyToStr);
+            Log.v(TAG, "offset: " + offset);
+        }
+
+        if ((appParams.ParameterMask & BIT_SUBJECT) != 0) {
+
+            if (V){
+                Log.v(TAG, "bldEmailMsgLstItem :: Subject " + subject);
+            }
+            if ((subject != null && appParams.SubjectLength > 0)
+                    && (subject.length() > appParams.SubjectLength)) {
+                subject = subject.substring(0,
+                        appParams.SubjectLength);
+            }
+            if(subject != null){
+                emailMsg.setSubject(subject.trim());
+            }
+            emailMsg.sendSubject = true;
+       }
+
+        if ((appParams.ParameterMask & BIT_DATETIME) != 0) {
+            /*emailMsg.setDatetime(time.toString().substring(0, 15)
+                    + "-0700");*/
+            emailMsg.setDatetime(datetimeStr);
+        }
+
+        if ((appParams.ParameterMask & BIT_SENDER_NAME) != 0) {
+            if(senderName != null) {
+                if(senderName.contains("")){
+                    String[] senderStr = senderName.split("");
+                    if(senderStr !=null && senderStr.length > 0){
+                        if (V){
+                            Log.v(TAG, " ::Sender name split String 0:: " + senderStr[0]
+                                    + "::Sender name split String 1:: " + senderStr[1]);
+                        }
+                        emailMsg.setSender_name(senderStr[1].trim());
+                    }
+                }
+                else{
+                    emailMsg.setSender_name(senderName.trim());
+                }
+            }
+       }
+
+        if ((appParams.ParameterMask & BIT_SENDER_ADDRESSING) != 0) {
+            if(senderAddressing != null) {
+                if(senderAddressing.contains("")){
+                    String[] senderAddrStr = senderAddressing.split("");
+                    if(senderAddrStr !=null && senderAddrStr.length > 0){
+                        if (V){
+                            Log.v(TAG, " ::Sender Addressing split String 0:: " + senderAddrStr[0]
+                                    + "::Sender Addressing split String 1:: " + senderAddrStr[1]);
+                        }
+                        emailMsg.setSender_addressing(senderAddrStr[0].trim());
+                    }
+                }
+                else{
+                    emailMsg.setSender_addressing(senderAddressing.trim());
+                }
+            }
+        }
+
+        if ((appParams.ParameterMask & BIT_RECIPIENT_NAME) != 0) {
+            String multiRecepients = "";
+            if(recipientName != null){
+                if(recipientName.contains("")){
+                    List<String> recipientNameArr = new ArrayList<String>();
+                    List<String> recipientEmailArr = new ArrayList<String>();
+                    String[] multiRecipientStr = recipientName.split("");
+                    for(int i=0; i < multiRecipientStr.length ; i++){
+                        if(multiRecipientStr[i].contains("")){
+                            String[] recepientStr = multiRecipientStr[i].split("");
+                            recipientNameArr.add(recepientStr[1]);
+                            recipientEmailArr.add(recepientStr[0]);
+                        }
+                    }
+                    if(recipientNameArr != null && recipientNameArr.size() > 0){
+                        for(int i=0; i < recipientNameArr.size() ; i++){
+                            if(i < (recipientNameArr.size()-1)){
+                                multiRecepients += recipientNameArr.get(i)+";";
+                            }
+                            else{
+                                multiRecepients += recipientNameArr.get(i);
+                            }
+                        }
+                    }
+                    emailMsg.setRecepient_name(multiRecepients.trim());
+                }
+                else if(recipientName.contains("")){
+                    String[] recepientStr = recipientName.split("");
+                    if(recepientStr !=null && recepientStr.length > 0){
+                        if (V){
+                            Log.v(TAG, " ::Recepient name split String 0:: " + recepientStr[0]
+                                    + "::Recepient name split String 1:: " + recepientStr[1]);
+                        }
+                        emailMsg.setRecepient_name(recepientStr[1].trim());
+                    }
+                }
+                else{
+                    emailMsg.setRecepient_name(recipientName.trim());
+                }
+            }
+        }
+
+        if ((appParams.ParameterMask & BIT_RECIPIENT_ADDRESSING) != 0) {
+            String multiRecepientAddrs = "";
+
+            if (recipientAddressing != null) {
+                if (recipientAddressing.contains("")) {
+                    List<String> recipientNameArr = new ArrayList<String>();
+                    List<String> recipientEmailArr = new ArrayList<String>();
+                    if  (recipientName != null) {
+                        String[] multiRecipientStr = recipientName.split("");
+                        for (int i=0; i < multiRecipientStr.length ; i++) {
+                            if (multiRecipientStr[i].contains("")) {
+                                String[] recepientStr = multiRecipientStr[i].split("");
+                                recipientNameArr.add(recepientStr[1]);
+                                recipientEmailArr.add(recepientStr[0]);
+                            }
+                        }
+                    }
+                    final int recipientEmailArrSize = recipientEmailArr.size();
+                    if (recipientEmailArrSize > 0) {
+                        for (int i=0; i < recipientEmailArrSize ; i++) {
+                            if (i < (recipientEmailArrSize-1)) {
+                                multiRecepientAddrs += recipientEmailArr.get(i)+";";
+                            } else {
+                                multiRecepientAddrs += recipientEmailArr.get(i);
+                            }
+                        }
+                    }
+                    emailMsg.setRecepient_addressing(multiRecepientAddrs.trim());
+                    emailMsg.setSendRecipient_addressing(true);
+                } else if (recipientAddressing.contains("")) {
+                    String[] recepientAddrStr = recipientAddressing.split("");
+                    if (recepientAddrStr !=null && recepientAddrStr.length > 0) {
+                        if (V){
+                            Log.v(TAG, " ::Recepient addressing split String 0:: " + recepientAddrStr[0]
+                                    + "::Recepient addressing split String 1:: " + recepientAddrStr[1]);
+                        }
+                        emailMsg.setRecepient_addressing(recepientAddrStr[0].trim());
+                        emailMsg.setSendRecipient_addressing(true);
+                    }
+                } else {
+                    emailMsg.setRecepient_addressing(recipientAddressing.trim());
+                    emailMsg.setSendRecipient_addressing(true);
+                }
+            }
+        }
+
+        if ((appParams.ParameterMask & BIT_TYPE) != 0) {
+            emailMsg.setType("EMAIL");
+        }
+
+        if ((appParams.ParameterMask & BIT_SIZE) != 0) {
+            int  msgSize = 0;
+            msgSize = getMessageSizeEmail(Long.valueOf(msgId), context);
+            emailMsg.setSize(msgSize);
+        }
+
+        if ((appParams.ParameterMask & BIT_RECEPTION_STATUS) != 0) {
+            emailMsg.setReception_status("complete");
+        }
+
+        if ((appParams.ParameterMask & BIT_TEXT) != 0) {
+            // TODO Set text to "yes"
+            emailMsg.setContains_text("yes");
+        }
+
+        if ((appParams.ParameterMask & BIT_ATTACHMENT_SIZE) != 0) {
+            emailMsg.setAttachment_size(getAttachmentSizeEmail(Long.valueOf(msgId), context));
+        }
+
+        if ((appParams.ParameterMask & BIT_PRIORITY) != 0) {
+            // TODO Get correct priority
+            emailMsg.setPriority("no");
+        }
+
+        if ((appParams.ParameterMask & BIT_READ) != 0) {
+            if (V){
+                Log.v(TAG, " ::Read Status:: " + readStatus);
+            }
+            if (readStatus.equalsIgnoreCase("1")) {
+                emailMsg.setRead("yes");
+            } else {
+                emailMsg.setRead("no");
+            }
+        }
+
+        if ((appParams.ParameterMask & BIT_SENT) != 0) {
+            // TODO Get sent status?
+            if (folderName.equalsIgnoreCase("sent") || folderName.toUpperCase().contains("SENT")) {
+                emailMsg.setSent("yes");
+            } else {
+                emailMsg.setSent("no");
+            }
+        }
+
+        if ((appParams.ParameterMask & BIT_PROTECTED) != 0) {
+            emailMsg.setMsg_protected("no");
+        }
+
+        if ((appParams.ParameterMask & BIT_REPLYTO_ADDRESSING) != 0) {
+            //TODO need to test
+            if (V){
+                Log.v(TAG, " ::Reply To addressing:: " + replyToStr);
+            }
+            if (replyToStr !=null && replyToStr.length() != 0){
+                if (replyToStr.contains("")){
+                    String replyToStrArr[] = replyToStr.split("");
+                    replyToStr = replyToStrArr[0];
+                }
+                emailMsg.setReplyTo_addressing(replyToStr);
+            } else{
+                emailMsg.setReplyTo_addressing(emailMsg.getSender_addressing());
+            }
+        }
+        return emailMsg;
+    }
+
+    public static String bldEmailBmsg(long msgHandle, BluetoothMasMessageRsp rsp, Context context,
+            String remoteDeviceName) {
+        String str = null;
+        //Query the message table for obtaining the message related details
+        Cursor cr1 = null;
+        int folderId;
+        String timeStamp = null;
+        String subjectText = null;
+        Uri uri1 = Uri.parse("content://com.android.email.provider/message");
+        String whereClause = " _id = " + msgHandle;
+
+        // Create a bMessage
+        BmessageConsts bmsg = new BmessageConsts();
+
+        cr1 = context.getContentResolver().query(uri1, null, whereClause, null,
+                null);
+        if (cr1 != null && cr1.getCount() > 0) {
+            cr1.moveToFirst();
+            folderId = cr1.getInt(cr1.getColumnIndex("mailboxKey"));
+            String containingFolder = getContainingFolderEmail(folderId, context);
+            timeStamp = cr1.getString(cr1.getColumnIndex("timeStamp"));
+            subjectText = cr1.getString(cr1.getColumnIndex("subject"));
+
+            // TODO Get Current type
+            bmsg.setType("EMAIL");
+
+            bmsg.setBmsg_version("1.0");
+            if (cr1.getString(cr1.getColumnIndex("flagRead")).equalsIgnoreCase("1")) {
+                bmsg.setStatus("READ");
+            } else {
+                bmsg.setStatus("UNREAD");
+            }
+
+            bmsg.setFolder(MapUtilsConsts.Telecom + "/" + MapUtilsConsts.Msg +
+                        "/" + containingFolder);
+
+            bmsg.setVcard_version("2.1");
+
+            String senderName = null;
+            if((senderName = cr1.getString(cr1.getColumnIndex("fromList"))) != null ){
+                if(senderName.contains("")){
+                    String[] senderStr = senderName.split("");
+                    if(senderStr !=null && senderStr.length > 0){
+                        bmsg.setOriginatorVcard_name(senderStr[1].trim());
+                        bmsg.setOriginatorVcard_email(senderStr[0].trim());
+                    }
+                }
+                else{
+                    bmsg.setOriginatorVcard_name(senderName.trim());
+                    bmsg.setOriginatorVcard_email(senderName.trim());
+                }
+            }
+            String recipientName = null;
+            String multiRecepients = null;
+            if((recipientName = cr1.getString(cr1.getColumnIndex("toList"))) != null){
+                if(recipientName.contains("")){
+                    String[] recepientStr = recipientName.split("");
+                    if(recepientStr !=null && recepientStr.length > 0){
+                        bmsg.setRecipientVcard_name(recepientStr[1].trim());
+                        bmsg.setRecipientVcard_email(recepientStr[0].trim());
+                    }
+                }
+                else if(recipientName.contains("")){
+                    multiRecepients = recipientName.replace('', ';');
+                    if(multiRecepients != null){
+                        if (V){
+                            Log.v(TAG, " ::Recepient name :: " + multiRecepients);
+                        }
+                        bmsg.setRecipientVcard_name(multiRecepients.trim());
+                        bmsg.setRecipientVcard_email(multiRecepients.trim());
+                    }
+                }
+                else{
+                    bmsg.setRecipientVcard_name(recipientName.trim());
+                    bmsg.setRecipientVcard_email(recipientName.trim());
+                }
+            }
+        }
+        if (cr1 != null) {
+            cr1.close();
+        }
+
+        //Query the body table for obtaining the message body
+        Cursor cr2 = null;
+        Uri uri2 = Uri.parse("content://com.android.email.provider/body");
+        String whereStr = " messageKey = " + msgHandle;
+        cr2 = context.getContentResolver().query(uri2, null, whereStr, null,
+                null);
+        if (cr2 != null) {
+            StringBuilder sb = new StringBuilder();
+            String emailBody = null;
+
+            //Set content type according to content from body table
+            String contenType = "text/plain";
+            if (cr2.getCount() > 0) {
+                cr2.moveToFirst();
+                emailBody = cr2.getString(cr2.getColumnIndex("textContent"));
+                if (emailBody == null || emailBody.length() == 0){
+                    String msgBody = cr2.getString(cr2.getColumnIndex("htmlContent"));
+                    if (msgBody != null){
+                        CharSequence msgText = Html.fromHtml(msgBody);
+                        emailBody = msgText.toString();
+                    }
+                }
+            }
+
+            Date date = new Date(Long.parseLong(timeStamp));
+            sb.append("From:").append(bmsg.getOriginatorVcard_email()).append("\r\n");
+            sb.append("To:").append(bmsg.getRecipientVcard_email()).append("\r\n");
+            if (remoteDeviceName != null && remoteDeviceName.startsWith(BMW)) {
+                sb.append("Mime-Version: 1.0").append("\r\n");
+                sb.append("Content-Type: text/plain; charset=\"UTF-8\"").append("\r\n");
+                sb.append("Content-Transfer-Encoding: 8bit").append("\r\n");
+                // BMW 14692 carkit accepts Date format in "EEE, dd MMM yyyy HH:mm:ss Z"
+                sb.append("Date:");
+                sb.append(new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US).format(date));
+                sb.append("\r\n");
+                sb.append("Subject:").append(subjectText).append("\r\n").append("\r\n");
+                sb.append(emailBody).append("\r\n");
+            } else {
+                Random randomGenerator = new Random();
+                int randomInt = randomGenerator.nextInt(1000);
+                String boundary = "MessageBoundary."+randomInt;
+                if (emailBody != null){
+                    while (emailBody.contains(boundary)){
+                        randomInt = randomGenerator.nextInt(1000);
+                        boundary = "MessageBoundary."+randomInt;
+                    }
+                }
+                sb.append("Date: ").append(date.toString()).append("\r\n");
+                sb.append("Subject:").append(subjectText).append("\r\n");
+                sb.append("Mime-Version: 1.0").append("\r\n");
+                sb.append(
+                        "Content-Type: multipart/mixed; boundary=\""+boundary+"\"")
+                        .append("\r\n");
+                sb.append("Content-Transfer-Encoding: 8bit").append("\r\n")
+                        .append("\r\n");
+                sb.append("MIME Message").append("\r\n");
+                sb.append("--"+boundary).append("\r\n");
+                sb.append("Content-Type: text/plain; charset=\"UTF-8\"").append("\r\n");
+                sb.append("Content-Transfer-Encoding: 8bit").append("\r\n");
+                sb.append("Content-Disposition:inline").append("\r\n")
+                        .append("\r\n");
+                sb.append(emailBody).append("\r\n");
+                sb.append("--"+boundary+"--").append("\r\n");
+            }
+
+            bmsg.setBody_msg(sb.toString());
+            bmsg.setBody_length(sb.length() + 22);
+            // Send a bMessage
+            if (V){
+                Log.v(TAG, "bMessageEmail test\n");
+                Log.v(TAG, "=======================\n\n");
+            }
+            str = MapUtils.toBmessageEmail(bmsg);
+            cr2.close();
+        }
+        if (V){
+            Log.v(TAG, "======FINAL BMSG=================\n\n");
+            Log.v(TAG, str);
+            Log.v(TAG, "\n\n");
+        }
+        return str;
+    }
+
+    /**
+     * Get the folder name (MAP representation) for Email based on the
+     * mailboxKey value in message table
+     */
+    public static String getContainingFolderEmail(int folderId, Context context) {
+        Cursor cr;
+        String folderName = null;
+        String whereClause = "_id = " + folderId;
+        cr = context.getContentResolver().query(
+                Uri.parse("content://com.android.email.provider/mailbox"),
+                null, whereClause, null, null);
+        if (cr != null) {
+            if (cr.getCount() > 0) {
+                cr.moveToFirst();
+                folderName = cr.getString(cr.getColumnIndex("displayName"));
+            }
+            cr.close();
+        }
+        return folderName;
+    }
+
+    public static final String AUTHORITY = "com.android.email.provider";
+    public static final Uri EMAIL_URI = Uri.parse("content://" + AUTHORITY);
+    public static final Uri EMAIL_ACCOUNT_URI = Uri.withAppendedPath(EMAIL_URI, "account");
+    public static final Uri EMAIL_BOX_URI = Uri.withAppendedPath(EMAIL_URI, "mailbox");
+    public static final Uri EMAIL_MESSAGE_URI = Uri.withAppendedPath(EMAIL_URI, "message");
+    public static final String RECORD_ID = "_id";
+    public static final String DISPLAY_NAME = "displayName";
+    public static final String SERVER_ID = "serverId";
+    public static final String ACCOUNT_KEY = "accountKey";
+    public static final String MAILBOX_KEY = "mailboxKey";
+    public static final String EMAIL_ADDRESS = "emailAddress";
+    public static final String IS_DEFAULT = "isDefault";
+    public static final String TYPE = "type";
+    public static final String[] EMAIL_BOX_PROJECTION = new String[] {
+        RECORD_ID, DISPLAY_NAME, ACCOUNT_KEY, TYPE
+    };
+    public static final int EMAIL_BOX_COLUMN_RECORD_ID = 0;
+    public static final int EMAIL_BOX_COLUMN_DISPLAY_NAME = 1;
+    public static final int EMAIL_BOX_COLUMN_ACCOUNT_KEY = 2;
+    public static final int EMAIL_BOX_COLUMN_TYPE = 3;
+    public static final String[] EMAIL_MESSAGE_PROJECTION = new String[] {
+        RECORD_ID, MAILBOX_KEY, ACCOUNT_KEY
+    };
+    public static final int MSG_COL_RECORD_ID = 0;
+    public static final int MSG_COL_MAILBOX_KEY = 1;
+    public static final int MSG_COL_ACCOUNT_KEY = 2;
+    private static final String[] ACCOUNT_ID_PROJECTION = new String[] {
+        RECORD_ID, EMAIL_ADDRESS, IS_DEFAULT
+    };
+    private static final String[] ACCOUNT_ID_NAME_PROJECTION = new String[] {
+       RECORD_ID, EMAIL_ADDRESS, DISPLAY_NAME
+    };
+    // Types of mailboxes. From EmailContent.java
+    // inbox
+    public static final int TYPE_INBOX = 0;
+    // draft
+    public static final int TYPE_DRAFT = 3;
+    // outbox
+    public static final int TYPE_OUTBOX = 4;
+    // sent
+    public static final int TYPE_SENT = 5;
+    // deleted
+    public static final int TYPE_DELETED = 6;
+
+    public static HashMap<Long, Integer> sAccToMas = new HashMap<Long, Integer>();
+    public static HashMap<Integer, Long> sMasToAcc = new HashMap<Integer, Long>();
+
+    public static void clearMapTable() {
+        sAccToMas.clear();
+        sMasToAcc.clear();
+    }
+
+    public static void updateMapTable(long accountId, int masId) {
+        if (sAccToMas.containsKey(accountId)) {
+            sAccToMas.remove(accountId);
+        }
+        if (sMasToAcc.containsKey(masId)) {
+            sMasToAcc.remove(masId);
+        }
+        sAccToMas.put(accountId, masId);
+        sMasToAcc.put(masId, accountId);
+    }
+
+    public static long getAccountId(int masId) {
+        Long accountId = sMasToAcc.get(masId);
+        return (accountId != null) ? accountId : -1;
+    }
+
+    public static int getMasId(long accountId) {
+        Integer masId = sAccToMas.get(accountId);
+        return (masId != null) ? masId : -1;
+    }
+
+    public static void removeMasIdIfNotPresent(List<Long> accountIdList) {
+        Collection<Long> oldList = sMasToAcc.values();
+        ArrayList<Long> toRemove = new ArrayList<Long>();
+        for (long oldId : oldList) {
+            if (!accountIdList.contains(oldId)) {
+                // remove it
+                toRemove.add(oldId);
+            }
+        }
+        for (long accountId : toRemove) {
+            Integer masId = sAccToMas.remove(accountId);
+            if (masId != null) {
+                sMasToAcc.remove(masId);
+            }
+        }
+    }
+
+    public static int countEmailAccount(Context context) {
+        return SqlHelper.count(context, EMAIL_ACCOUNT_URI, null, null);
+    }
+
+    /**
+     * Returns whether Email account exists
+     * @param context the calling Context
+     * @return true if any Email account exists; false otherwise
+     */
+    public static boolean hasEmailAccount(Context context) {
+        int numAccounts = SqlHelper.count(context, EMAIL_ACCOUNT_URI, null, null);
+        if (numAccounts > 0) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public static boolean hasEmailAccount(Context context, long accountId) {
+        String where = RECORD_ID + "=" + accountId;
+        int numAccounts = SqlHelper.count(context, EMAIL_ACCOUNT_URI, where, null);
+        if (numAccounts > 0) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the first Email account id that satisfies where condition
+     * @param context the calling Context
+     * @param where the condition respect to {@link #RECORD_ID}, {@link #EMAIL_ADDRESS}, {@link #IS_DEFAULT}
+     * @return Email account id
+     */
+    public static long getEmailAccountId(Context context, String where) {
+        if (V) Log.v(TAG, "getEmailAccountId(" + where + ")");
+        long id = -1;
+        Cursor cursor = context.getContentResolver().query(EMAIL_ACCOUNT_URI,
+                ACCOUNT_ID_PROJECTION, where, null, null);
+        if (cursor != null) {
+            if (cursor.moveToFirst()) {
+                id = cursor.getLong(0);
+            }
+            cursor.close();
+        }
+        if (V) Log.v(TAG, "id = " + id);
+        return id;
+    }
+
+    /**
+     * Returns the first Email account id name that satisfies where condition
+     * @param context the calling Context
+     * @param where the condition respect to {@link #RECORD_ID}, {@link #EMAIL_ADDRESS}, {@link #IS_DEFAULT}
+     * @return Email account id Email
+     */
+    public static String getEmailAccountIdEmail(Context context, String where) {
+        if (V) Log.v(TAG, "getEmailAccountIdName(" + where + ")");
+        String idEmail = null;
+        Cursor cursor = context.getContentResolver().query(EMAIL_ACCOUNT_URI,
+                ACCOUNT_ID_NAME_PROJECTION, where, null, null);
+        if (cursor != null) {
+            if (cursor.moveToFirst()) {
+                idEmail = cursor.getString(1);
+            }
+            cursor.close();
+        }
+        if (V) Log.v(TAG, "idEmail = " + idEmail);
+        return idEmail;
+    }
+
+    /**
+     * Returns the first Email account id name that satisfies where condition
+     * @param context the calling Context
+     * @param where the condition respect to {@link #RECORD_ID}, {@link #EMAIL_ADDRESS}, {@link #IS_DEFAULT}
+     * @return Email account id Display Name
+     */
+    public static String getEmailAccountDisplayName(Context context, String where) {
+        if (V) Log.v(TAG, "getEmailAccountIdName(" + where + ")");
+        String displayName = null;
+        Cursor cursor = context.getContentResolver().query(EMAIL_ACCOUNT_URI,
+                ACCOUNT_ID_NAME_PROJECTION, where, null, null);
+        if (cursor != null) {
+            if (cursor.moveToFirst()) {
+                displayName = cursor.getString(2);
+            }
+            cursor.close();
+        }
+        if (V) Log.v(TAG, "displayName = " + displayName);
+        return displayName;
+    }
+
+
+    /**
+     * Returns the default Email account id; the first account id if no default account
+     * @param context the calling Context
+     * @return the default Email account id
+     */
+    public static long getDefaultEmailAccountId(Context context) {
+        if (V) Log.v(TAG, "getDefaultEmailAccountId()");
+        long id = getEmailAccountId(context, IS_DEFAULT + "=1");
+        if (id == -1) {
+            id = getEmailAccountId(context, null);
+        }
+        if (V) Log.v(TAG, "id = " + id);
+        return id;
+    }
+
+    public static List<Long> getEmailAccountIdList(Context context) {
+        if (V) Log.v(TAG, "getEmailAccountIdList()");
+        long id = -1;
+        ArrayList<Long> list = new ArrayList<Long>();
+        Cursor cursor = context.getContentResolver().query(EMAIL_ACCOUNT_URI,
+                ACCOUNT_ID_PROJECTION, null, null, null);
+        if (cursor != null) {
+            if (cursor.moveToFirst()) {
+                do {
+                    id = cursor.getLong(0);
+                    list.add(id);
+                    if (V) Log.v(TAG, "id = " + id);
+                } while (cursor.moveToNext());
+            }
+            cursor.close();
+        }
+        return list;
+    }
+
+    /**
+     * Return Email sub folder list for the id and serverId path
+     * @param context the calling Context
+     * @param id the email account id
+     * @return the list of  server id's of Email sub folder
+     */
+    public static List<String> getEmailFolderListAtPath(Context context, long id, String path) {
+        if (V) Log.v(TAG, "getEmailFolderListAtPath: id = " + id + "path: " + path);
+        StringBuilder sb = new StringBuilder();
+        if (id > 0) {
+            sb.append(ACCOUNT_KEY);
+            sb.append("=");
+            sb.append(id);
+            sb.append(" AND ");
+        }
+        //Return Default List for no path
+        if(path.equals("")) {
+            sb.append(SERVER_ID);
+            sb.append("=");
+            sb.append(DISPLAY_NAME);
+        }
+        else {
+            sb.append(SERVER_ID);
+            sb.append(" LIKE '");
+            sb.append(path);
+            sb.append("/%'");
+        }
+        return SqlHelper.getListForColumn(context, EMAIL_BOX_URI, SERVER_ID, sb.toString(), null);
+    }
+    /**
+     * Return Email folder list for the id
+     * @param context the calling Context
+     * @param id the email account id
+     * @return the list of Email folder
+     */
+    public static List<String> getEmailFolderList(Context context, long id) {
+        if (V) Log.v(TAG, "getEmailFolderList: id = " + id);
+        StringBuilder sb = new StringBuilder();
+        if (id > 0) {
+            sb.append(ACCOUNT_KEY);
+            sb.append("=");
+            sb.append(id);
+        }
+        return SqlHelper.getListForColumn(context, EMAIL_BOX_URI, DISPLAY_NAME, sb.toString(), null);
+    }
+
+    /**
+     * Return folder name for the type of mailbox
+     * @param context the calling Context
+     * @param id the email account id
+     * @param type
+     * @return
+     */
+    public static String getFolderForType(Context context, long id, int type) {
+        if (V) Log.v(TAG, "getFolderForType: id = " + id + ", type = " + type);
+        StringBuilder sb = new StringBuilder();
+        if (id > 0) {
+            sb.append(ACCOUNT_KEY);
+            sb.append("=");
+            sb.append(id);
+            sb.append(" AND ");
+        }
+        sb.append(TYPE);
+        sb.append("=");
+        sb.append(type);
+        return SqlHelper.getFirstValueForColumn(context, EMAIL_BOX_URI, DISPLAY_NAME, sb.toString(), null);
+    }
+
+    /**
+     * Return list of folder names for the type of mailbox
+     * @param context the calling Context
+     * @param id the email account id
+     * @param type
+     * @return
+     */
+    public static List<String> getFoldersForType(Context context, long id, int type) {
+        if (V) Log.v(TAG, "getFolderForType: id = " + id + ", type = " + type);
+        StringBuilder sb = new StringBuilder();
+        if (id > 0) {
+            sb.append(ACCOUNT_KEY);
+            sb.append("=");
+            sb.append(id);
+            sb.append(" AND ");
+        }
+        sb.append(TYPE);
+        sb.append("=");
+        sb.append(type);
+        return SqlHelper.getListForColumn(context, EMAIL_BOX_URI, DISPLAY_NAME, sb.toString(), null);
+    }
+
+    public static int getTypeForFolder(Context context, long id, String folderName) {
+        if (V) Log.v(TAG, "getTypeForFolder: id = " + id + ", folderName = " + folderName);
+        StringBuilder sb = new StringBuilder();
+        if (id > 0) {
+            sb.append(ACCOUNT_KEY);
+            sb.append("=");
+            sb.append(id);
+            sb.append(" AND ");
+        }
+        sb.append(DISPLAY_NAME);
+        sb.append("=");
+        sb.append("'"+folderName+"'");
+        return SqlHelper.getFirstIntForColumn(context, EMAIL_BOX_URI, TYPE, sb.toString(), null);
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/MapUtils.java b/src/org/codeaurora/bluetooth/map/MapUtils/MapUtils.java
new file mode 100644
index 0000000..6def60e
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/MapUtils.java
@@ -0,0 +1,1986 @@
+/*
+ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map.MapUtils;
+
+import android.content.Context;
+import com.android.vcard.VCardProperty;
+import com.android.vcard.VCardInterpreter;
+import com.android.vcard.VCardParser;
+import com.android.vcard.VCardParser_V21;
+import com.android.vcard.VCardParser_V30;
+import com.android.vcard.exception.VCardException;
+import com.android.vcard.exception.VCardVersionException;
+import android.util.Log;
+import android.util.Xml;
+import java.io.UnsupportedEncodingException;
+
+import org.codeaurora.bluetooth.map.BluetoothMasService;
+
+import org.xmlpull.v1.XmlSerializer;
+import com.android.internal.util.FastXmlSerializer;
+
+import java.io.IOException;
+import java.io.StringBufferInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.StringWriter;
+import java.util.List;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
+
+import static com.android.vcard.VCardConstants.PROPERTY_EMAIL;
+import static com.android.vcard.VCardConstants.PROPERTY_FN;
+import static com.android.vcard.VCardConstants.PROPERTY_N;
+import static com.android.vcard.VCardConstants.PROPERTY_TEL;
+import static com.android.vcard.VCardConstants.VERSION_V21;
+import static com.android.vcard.VCardConstants.VERSION_V30;
+
+/**
+ * MapUtils is a class of utility methods that provide routines for converting
+ * data to either XML or bMessage formats. The class shall also support parsing
+ * XML and bMessage formatted data.
+ * <p>
+ * The following methods are currently supported:
+ * <p>
+ * folderListingXML()
+ *
+ * @version 0.1
+ *
+ */
+public class MapUtils {
+    public static final String TAG = "MapUtils";
+    public static final boolean V = BluetoothMasService.VERBOSE;
+    private static final String CRLF = "\r\n";
+
+    /**
+     * folderListingXML
+     *
+     * This method takes a list of folder names and returns a String with the
+     * XML version of the List
+     *
+     * @param list
+     *            An array of strings where each element represents a folder
+     *            name
+     * @return This method returns either null or a String
+     */
+    public static String folderListingXML(List<String> list) {
+        String str = "<?xml version=\"1.0\"?><!DOCTYPE folder-listing SYSTEM \"obex-folder-listing.dtd\"><folder-listing version=\"1.0\">";
+
+        for (String s : list) {
+            str += "<folder name=\"";
+            str += s;
+            str += "\"/>";
+        }
+
+        str += "</folder-listing>";
+
+        return str;
+    }
+
+    /**
+     * messageListingXML
+     *
+     * This method takes a list of message objects and returns a String with the
+     * XML version of the List
+     *
+     * @param list
+     *            An array of message objects where each element represents a
+     *            message
+     * @return This method returns either null or a String
+     */
+    public static String messageListingXML(List<MsgListingConsts> list) {
+        XmlSerializer serializer = new FastXmlSerializer();
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        OutputStreamWriter myOutputStreamWriter = null;
+        try {
+            myOutputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            Log.e(TAG, "Failed to encode: charset=" + "UTF-8");
+            return null;
+        }
+        try {
+            String str1;
+            String str2 = "<?xml version=\"1.0\"?>";
+            serializer.setOutput(myOutputStreamWriter);
+            serializer.startDocument("UTF-8", true);
+            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+            serializer.text("\n");
+            serializer.startTag(null, "MAP-msg-listing");
+            serializer.attribute(null, "version", "1.0");
+            for (MsgListingConsts msg : list) {
+                serializer.startTag(null, "msg");
+
+                serializer.attribute(null, "handle", ("" + msg.msg_handle));
+                if (msg.sendSubject == true) {
+                    if (msg.subject == null){
+                        serializer.attribute(null, "subject", "");
+                    } else {
+                        serializer.attribute(null, "subject", msg.subject);
+                    }
+
+                }
+                if (msg.datetime != null) {
+                    serializer.attribute(null, "datetime", msg.datetime);
+                }
+                if (msg.sender_name != null) {
+                    serializer.attribute(null, "sender_name", msg.sender_name);
+                }
+
+                if (msg.sender_addressing != null) {
+                    serializer.attribute(null, "sender_addressing",
+                            msg.sender_addressing);
+                }
+
+                if (msg.replyto_addressing != null) {
+                    serializer.attribute(null, "replyto_addressing",
+                            msg.replyto_addressing);
+                }
+
+                if (msg.recepient_name != null) {
+                    serializer.attribute(null, "recipient_name",
+                            msg.recepient_name);
+                }
+                if (msg.sendRecipient_addressing == true) {
+                    if (msg.recepient_addressing != null) {
+                        serializer.attribute(null, "recipient_addressing",
+                                msg.recepient_addressing);
+                    } else {
+                        serializer.attribute(null, "recipient_addressing", "");
+                    }
+                }
+                if (msg.type != null) {
+                    serializer.attribute(null, "type", msg.type);
+                }
+                if (msg.size != -1) {
+                    serializer.attribute(null, "size", ("" + msg.size));
+                }
+
+                if (msg.contains_text != null) {
+                    serializer.attribute(null, "text", msg.contains_text);
+                }
+
+                if (msg.reception_status != null) {
+                    serializer.attribute(null, "reception_status",
+                            msg.reception_status);
+                }
+
+                if (msg.attachment_size != -1) {
+                    serializer.attribute(null, "attachment_size",
+                            ("" + Integer.toString(msg.attachment_size)));
+                }
+
+                if (msg.priority != null) {
+                    serializer.attribute(null, "priority", msg.priority);
+                }
+
+                if (msg.read != null) {
+                    serializer.attribute(null, "read", msg.read);
+                }
+
+                if (msg.sent != null) {
+                    serializer.attribute(null, "sent", msg.sent);
+                }
+
+                if (msg.msg_protected != null) {
+                    serializer.attribute(null, "protected", msg.msg_protected);
+                }
+
+                serializer.endTag(null, "msg");
+
+            }
+            serializer.endTag(null, "MAP-msg-listing");
+            serializer.endDocument();
+            try {
+                str1 = outputStream.toString("UTF-8");
+                if (V) Log.v(TAG, "Printing XML-Converted String: " + str1);
+            int line1 = 0;
+            line1 = str1.indexOf("\n");
+            str2 += str1.substring(line1 + 1);
+            if (list.size() > 0) {
+                int indxHandle = str2.indexOf("msg handle");
+                String str3 = "<" + str2.substring(indxHandle);
+                str2 = str2.substring(0, (indxHandle - 1)) + str3;
+            }
+            return str2;
+            } catch (UnsupportedEncodingException e) {
+                Log.e(TAG, "Failed to encode: charset=" + "UTF-8");
+                return null;
+            }
+        } catch (IllegalArgumentException e) {
+
+            e.printStackTrace();
+        } catch (IllegalStateException e) {
+
+            e.printStackTrace();
+        } catch (IOException e) {
+
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * msgListingGetHdrXML
+     *
+     * This method returns a String with the XML header
+     *
+     * @return This method returns a String
+     */
+    public static String msgListingGetHdrXML() {
+        String str1 = "<MAP-msg-listing version = \"1.0\">\n";
+        return str1;
+    }
+
+    /**
+     * msgListingGetFooterXML
+     *
+     * This method returns a String with the XML footer
+     *
+     * @return This method returns a String
+     */
+    public static String msgListingGetFooterXML() {
+        String str1 = "</MAP-msg-listing>\n";
+        return str1;
+    }
+
+    /**
+     * msgListingGetMsgsXML
+     *
+     * This method takes a list of message objects and returns a String with the
+     * XML messages
+     *
+     * @param list
+     *            An array of message objects where each element represents a
+     *            message
+     * @return This method returns either null or a String
+     */
+    public static String msgListingGetMsgsXML(List<MsgListingConsts> list) {
+        XmlSerializer serializer = Xml.newSerializer();
+        StringWriter writer = new StringWriter();
+        try {
+            String str1;
+            serializer.setOutput(writer);
+            serializer.startDocument("", false);
+            serializer.text("\n");
+            for (MsgListingConsts msg : list) {
+                serializer.startTag("", "msg");
+                serializer.attribute("", "handle", ("" + msg.msg_handle));
+                if (msg.subject != null) {
+                    serializer.attribute("", "subject", msg.subject);
+                } else {
+
+                }
+                if (msg.datetime != null) {
+                    serializer.attribute("", "datetime", msg.datetime);
+                } else {
+
+                }
+                if (msg.sender_name != null) {
+                    serializer.attribute("", "sender_name", msg.sender_name);
+                } else {
+
+                }
+
+                if (msg.sender_addressing != null) {
+                    serializer.attribute("", "sender_addressing",
+                            msg.sender_addressing);
+                } else {
+
+                }
+                if (msg.recepient_name != null) {
+                    serializer.attribute("", "recipient_name",
+                            msg.recepient_name);
+                } else {
+
+                }
+                if (msg.recepient_addressing != null) {
+                    serializer.attribute("", "recipient_addressing",
+                            msg.recepient_addressing);
+                } else {
+
+                }
+                if (msg.type != null) {
+                    serializer.attribute("", "type", msg.type);
+                } else {
+
+                }
+                if (msg.size != 0) {
+                    serializer.attribute("", "size", ("" + msg.size));
+                } else {
+
+                }
+                if (msg.attachment_size != -1) {
+                    serializer.attribute("", "attachment_size",
+                            ("" + Integer.toString(msg.attachment_size)));
+                } else {
+
+                }
+                if (msg.contains_text != null) {
+                    serializer.attribute("", "text", msg.contains_text);
+                } else {
+
+                }
+                if (msg.priority != null) {
+                    serializer.attribute("", "priority", msg.priority);
+                } else {
+
+                }
+                if (msg.read != null) {
+                    serializer.attribute("", "read", msg.read);
+                } else {
+
+                }
+                if (msg.sent != null) {
+                    serializer.attribute("", "sent", msg.sent);
+                } else {
+
+                }
+
+                if (msg.replyto_addressing != null) {
+                    serializer.attribute("", "replyto_addressing",
+                            msg.replyto_addressing);
+                } else {
+
+                }
+
+                serializer.endTag("", "msg");
+
+            }
+            serializer.endDocument();
+            str1 = writer.toString();
+
+            int line1 = 0;
+            line1 = str1.indexOf("\n");
+            if (line1 > 0) {
+                return (str1.substring((line1)));
+            } else {
+                return str1;
+            }
+
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+        } catch (IllegalStateException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * mapEventReportXML
+     *
+     * This method takes a list of map event report object and returns a String
+     * with the XML message
+     *
+     * @param type
+     *            Report type (e.g. NewMessage)
+     * @param handle
+     *            handle created by caller
+     * @param folder
+     *            Path to folder to use
+     * @param Oldfolder
+     *            Path to old folder to use
+     * @param msgType
+     *            Type of message (SMS_GSM, SMS_CDMA)
+     *
+     * @return This method returns either null or a String
+     */
+    public static String mapEventReportXML(String type, String handle, String folder,
+            String oldFolder, String msgType) {
+        XmlSerializer serializer = Xml.newSerializer();
+        StringWriter writer = new StringWriter();
+
+        try {
+            String str1;
+            serializer.setOutput(writer);
+            serializer.startDocument("", false);
+            serializer.text("\n");
+            serializer.startTag("", "MAP-event-report");
+            serializer.attribute("", "version", "1.0");
+            serializer.text("\n");
+
+            serializer.startTag("", "event");
+            if (type != null) {
+                serializer.attribute("", "type", ("" + type));
+            } else {
+
+            }
+            if (handle != null) {
+                serializer.attribute("", "handle", ("" + handle));
+            } else {
+
+            }
+            if (folder != null) {
+                serializer.attribute("", "folder", ("" + folder));
+            } else {
+
+            }
+            if (oldFolder != null) {
+                serializer.attribute("", "old_folder", ("" + oldFolder));
+            } else {
+
+            }
+
+            if (msgType != null) {
+                serializer.attribute("", "msg_type", ("" + msgType));
+            } else {
+
+            }
+            serializer.endTag("", "event");
+            serializer.text("\n");
+            serializer.endTag("", "MAP-event-report");
+            serializer.endDocument();
+            str1 = writer.toString();
+            int line1 = 0;
+            line1 = str1.indexOf("\n");
+            if (line1 > 0) {
+                int index = str1.indexOf("event type");
+                String str2 = "<" + str1.substring(index);
+                str1 = "<MAP-event-report version=\"1.0\">" + "\n" + str2;
+                return str1;
+            } else {
+                return str1;
+            }
+
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+        } catch (IllegalStateException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    /**
+     * toBmessageSMS
+     *
+     * This method takes as input a list of BmessageConsts objects and creates a
+     * String in the bMessage format.
+     *
+     * @param list
+     *            An array of message objects where each element represents a
+     *            message
+     * @return This method returns either null or a String
+     */
+    public static String toBmessageSMS(BmessageConsts bmsg) {
+        StringBuilder sb = new StringBuilder();
+
+        try {
+            sb.append("BEGIN:BMSG");
+            sb.append("\r\n");
+            if (bmsg.bmsg_version != null) {
+                sb.append("VERSION:").append(bmsg.bmsg_version).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.status != null) {
+                sb.append("STATUS:").append(bmsg.status).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.type != null) {
+                sb.append("TYPE:").append(bmsg.type).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.folder != null) {
+                sb.append("FOLDER:").append(bmsg.folder).append("\r\n");
+            } else {
+
+            }
+
+            // Originator
+            sb.append("BEGIN:VCARD").append("\r\n");
+
+            if (bmsg.vcard_version != null) {
+                sb.append("VERSION:").append(bmsg.vcard_version).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.originator_vcard_name != null) {
+                sb.append("N:").append(bmsg.originator_vcard_name)
+                        .append("\r\n");
+            } else {
+
+            }
+            if (bmsg.originator_vcard_phone_number != null) {
+                sb.append("TEL:").append(bmsg.originator_vcard_phone_number)
+                        .append("\r\n");
+            } else {
+
+            }
+
+            sb.append("END:VCARD").append("\r\n");
+            // End Originator
+
+            sb.append("BEGIN:BENV").append("\r\n");
+
+            // Recipient
+            sb.append("BEGIN:VCARD").append("\r\n");
+
+            if (bmsg.vcard_version != null) {
+                sb.append("VERSION:").append(bmsg.vcard_version).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.recipient_vcard_name != null) {
+                sb.append("N:").append(bmsg.recipient_vcard_name)
+                        .append("\r\n");
+            } else {
+
+            }
+            if (bmsg.recipient_vcard_phone_number != null) {
+                sb.append("TEL:").append(bmsg.recipient_vcard_phone_number)
+                        .append("\r\n");
+            } else {
+
+            }
+            sb.append("END:VCARD").append("\r\n");
+            // End Recipient
+
+            sb.append("BEGIN:BBODY").append("\r\n");
+
+            if (bmsg.body_charset != null) {
+                sb.append("CHARSET:").append(bmsg.body_charset)
+                        .append("\r\n");
+            } else {
+
+            }
+
+            if (bmsg.body_encoding != null) {
+                sb.append("ENCODING:").append(bmsg.body_encoding)
+                        .append("\r\n");
+            } else {
+
+            }
+            if (bmsg.body_length != 0) {
+                sb.append("LENGTH:").append(bmsg.body_length).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.body_msg != null) {
+                sb.append("BEGIN:MSG\r\n");
+                sb.append(bmsg.body_msg).append("\r\n");
+                sb.append("END:MSG\r\n");
+
+            } else {
+
+            }
+
+            sb.append("END:BBODY").append("\r\n");
+            sb.append("END:BENV").append("\r\n");
+
+            sb.append("END:BMSG");
+            sb.append("\r\n");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return sb.toString();
+
+    }
+
+    /**
+     * toBmessageMMS
+     *
+     * This method takes as input a list of BmessageConsts objects and creates a
+     * String in the bMessage format.
+     *
+     * @param list
+     *            An array of message objects where each element represents a
+     *            message
+     * @return This method returns either null or a String
+     */
+    public static String toBmessageMMS(BmessageConsts bmsg) {
+        StringBuilder sb = new StringBuilder();
+
+        try {
+            sb.append("BEGIN:BMSG");
+            sb.append("\r\n");
+            if (bmsg.bmsg_version != null) {
+                sb.append("VERSION:").append(bmsg.bmsg_version).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.status != null) {
+                sb.append("STATUS:").append(bmsg.status).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.type != null) {
+                sb.append("TYPE:").append(bmsg.type).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.folder != null) {
+                sb.append("FOLDER:").append(bmsg.folder).append("\r\n");
+            } else {
+
+            }
+
+            // Originator
+            sb.append("BEGIN:VCARD").append("\r\n");
+
+            if (bmsg.vcard_version != null) {
+                sb.append("VERSION:").append(bmsg.vcard_version).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.originator_vcard_name != null) {
+                sb.append("N:").append(bmsg.originator_vcard_name)
+                        .append("\r\n");
+            } else {
+
+            }
+            if (bmsg.originator_vcard_phone_number != null) {
+                sb.append("TEL:").append(bmsg.originator_vcard_phone_number)
+                        .append("\r\n");
+            } else {
+
+            }
+
+            sb.append("END:VCARD").append("\r\n");
+            // End Originator
+
+            sb.append("BEGIN:BENV").append("\r\n");
+
+            if ((bmsg.recipient_vcard_phone_number != null) &&
+                            (bmsg.recipient_vcard_phone_number.contains(";"))) {
+                if (V) Log.v (TAG, "recipient_vcard_name:" + bmsg.recipient_vcard_name);
+                if (V) Log.v (TAG, "recipient_vcard_phone_number:" + bmsg.recipient_vcard_phone_number);
+                String numberTokens[] = bmsg.recipient_vcard_phone_number.split(";");
+                String nameTokens[] = bmsg.recipient_vcard_name.split(";");
+                if (V) Log.v (TAG, "Length:name:" + nameTokens.length + "number:" + numberTokens.length);
+                for (int i=0; i < numberTokens.length; i++) {
+                    // Recipient
+                    sb.append("BEGIN:VCARD").append("\r\n");
+
+                    if (bmsg.vcard_version != null) {
+                        sb.append("VERSION:").append(bmsg.vcard_version).append("\r\n");
+                    } else {
+
+                    }
+
+                    if (nameTokens[i] != null) {
+                        sb.append("N:").append(nameTokens[i])
+                            .append("\r\n");
+                    } else {
+
+                    }
+
+                    if (numberTokens[i] != null) {
+                        sb.append("TEL:").append(numberTokens[i])
+                            .append("\r\n");
+                    } else {
+
+                    }
+
+                    sb.append("END:VCARD").append("\r\n");
+                    // End Recipient
+                }
+            } else {
+                // Recipient
+                sb.append("BEGIN:VCARD").append("\r\n");
+
+                if (bmsg.vcard_version != null) {
+                    sb.append("VERSION:").append(bmsg.vcard_version).append("\r\n");
+                } else {
+
+                }
+                if (bmsg.recipient_vcard_name != null) {
+                    sb.append("N:").append(bmsg.recipient_vcard_name)
+                        .append("\r\n");
+                } else {
+
+                }
+                if (bmsg.recipient_vcard_phone_number != null) {
+                    sb.append("TEL:").append(bmsg.recipient_vcard_phone_number)
+                        .append("\r\n");
+                } else {
+
+                }
+                sb.append("END:VCARD").append("\r\n");
+                // End Recipient
+            }
+
+            sb.append("BEGIN:BBODY").append("\r\n");
+
+            sb.append("PARTID:26988").append("\r\n");
+
+            if (bmsg.body_encoding != null) {
+                sb.append("ENCODING:").append(bmsg.body_encoding)
+                        .append("\r\n");
+            } else {
+
+            }
+            sb.append("CHARSET:UTF-8").append("\r\n");
+            sb.append("LANGUAGE:").append("\r\n");
+
+            if (bmsg.body_length != 0) {
+                sb.append("LENGTH:").append(bmsg.body_length).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.body_msg != null) {
+                sb.append("BEGIN:MSG\r\n");
+                sb.append(bmsg.body_msg).append("\r\n");
+                sb.append("END:MSG\r\n");
+
+            } else {
+
+            }
+
+            sb.append("END:BBODY").append("\r\n");
+            sb.append("END:BENV").append("\r\n");
+
+            sb.append("END:BMSG");
+            sb.append("\r\n");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * toBmessageEmail
+     *
+     * This method takes as input a list of BmessageConsts objects and creates a
+     * String in the bMessage format.
+     *
+     * @param list
+     *            An array of message objects where each element represents a
+     *            message
+     * @return This method returns either null or a String
+     */
+    public static String toBmessageEmail(BmessageConsts bmsg) {
+        StringBuilder sb = new StringBuilder();
+
+        try {
+            sb.append("BEGIN:BMSG");
+            sb.append("\r\n");
+            if (bmsg.bmsg_version != null) {
+                sb.append("VERSION:").append(bmsg.bmsg_version).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.status != null) {
+                sb.append("STATUS:").append(bmsg.status).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.type != null) {
+                sb.append("TYPE:").append(bmsg.type).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.folder != null) {
+                sb.append("FOLDER:").append(bmsg.folder).append("\r\n");
+            } else {
+
+            }
+
+            // Originator
+            sb.append("BEGIN:VCARD").append("\r\n");
+
+            if (bmsg.vcard_version != null) {
+                sb.append("VERSION:").append(bmsg.vcard_version).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.originator_vcard_name != null) {
+                sb.append("N:").append(bmsg.originator_vcard_name)
+                        .append("\r\n");
+            } else {
+
+            }
+            sb.append("TEL:").append("\r\n");
+            if (bmsg.originator_vcard_email != null) {
+                sb.append("EMAIL:").append(bmsg.originator_vcard_email)
+                        .append("\r\n");
+            } else {
+
+            }
+
+            sb.append("END:VCARD").append("\r\n");
+            // End Originator
+
+            sb.append("BEGIN:BENV").append("\r\n");
+
+            // Recipient
+            sb.append("BEGIN:VCARD").append("\r\n");
+
+            if (bmsg.vcard_version != null) {
+                sb.append("VERSION:").append(bmsg.vcard_version).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.recipient_vcard_name != null) {
+                sb.append("N:").append(bmsg.recipient_vcard_name)
+                        .append("\r\n");
+            } else {
+
+            }
+            if (bmsg.recipient_vcard_name != null) {
+                sb.append("FN:").append(bmsg.recipient_vcard_name)
+                        .append("\r\n");
+            } else {
+
+            }
+            sb.append("TEL:").append("\r\n");
+            if (bmsg.recipient_vcard_email != null) {
+                sb.append("EMAIL:").append(bmsg.recipient_vcard_email)
+                        .append("\r\n");
+            } else {
+
+            }
+            sb.append("END:VCARD").append("\r\n");
+            // End Recipient
+
+            sb.append("BEGIN:BBODY").append("\r\n");
+
+            if (bmsg.body_encoding != null) {
+                sb.append("ENCODING:").append(bmsg.body_encoding)
+                        .append("\r\n");
+            } else {
+                sb.append("ENCODING:8BIT").append("\r\n");
+            }
+
+            sb.append("CHARSET:UTF-8").append("\r\n");
+
+            if (bmsg.body_length != 0) {
+                sb.append("LENGTH:").append(bmsg.body_length).append("\r\n");
+            } else {
+
+            }
+            if (bmsg.body_msg != null) {
+                sb.append("BEGIN:MSG\r\n");
+                sb.append(bmsg.body_msg).append("\r\n");
+                sb.append("END:MSG\r\n");
+
+            } else {
+
+            }
+
+            sb.append("END:BBODY").append("\r\n");
+            sb.append("END:BENV").append("\r\n");
+
+            sb.append("END:BMSG");
+            sb.append("\r\n");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return sb.toString();
+
+    }
+
+
+    /**
+     * fromBmessageSMS
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String and loads a BmessageConsts object that is returned
+     *
+     * @param String
+     *            - which is a bMessage formatted SMS message
+     * @return This method returns a BmessageConsts object
+     * @throws BadRequestException
+     */
+    public static BmessageConsts fromBmessageSMS(String bmsg) throws BadRequestException {
+        BmessageConsts bMsgObj = new BmessageConsts();
+        String vCard = fetchRecipientVcard(bmsg);
+
+        RecipientVCard recipient = parseVCard(vCard);
+        if (recipient.mTel.length() == 0) {
+            throw new BadRequestException("No TEL in vCard");
+        }
+        bMsgObj.setRecipientVcard_phone_number(recipient.mTel);
+        if (V) Log.v(TAG, "Tel: " + recipient.mTel);
+
+        // Extract vCard Version
+        bMsgObj.setVcard_version(recipient.mVersion);
+
+        // Extract bMessage Version
+        bMsgObj.setBmsg_version(fetchVersion(bmsg));
+
+        // Extract Message Status
+        bMsgObj.setStatus(fetchReadStatus(bmsg));
+
+        // Extract Message Type
+        bMsgObj.setType(fetchType(bmsg));
+
+        // Extract Message Folder
+        bMsgObj.setFolder(fetchFolder(bmsg));
+
+        // Fetch Message Length
+        bMsgObj.setBody_length(fetchBodyLength(bmsg));
+
+        // Extract Message
+        bMsgObj.setBody_msg(fetchBodyMsg(bmsg));
+
+        // Extract Message encoding
+        bMsgObj.setBody_encoding(fetchBodyEncoding(bmsg));
+
+        return bMsgObj;
+    }
+
+    /**
+     * fromBmessageMMS
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String and loads a BmessageConsts object that is returned
+     *
+     * @param String
+     *            - which is a bMessage formatted SMS message
+     * @return This method returns a BmessageConsts object
+     * @throws BadRequestException
+     */
+    public static BmessageConsts fromBmessageMMS(String bmsg) throws BadRequestException {
+        BmessageConsts bMsgObj = new BmessageConsts();
+
+        String phoneNumber = null;
+        String vCard = fetchRecipientVcard(bmsg);
+        if (V) Log.v(TAG, "vCard Info: " + vCard);
+
+        RecipientVCard recipient = parseVCard(vCard);
+        if (recipient.mEmail.length() > 0) {
+            phoneNumber = recipient.mEmail;
+        } else if (recipient.mTel.length() > 0) {
+            phoneNumber = recipient.mTel;
+        } else {
+            throw new BadRequestException("No Email/Tel in vCard");
+        }
+
+        if (V) Log.v(TAG, "Email: " + recipient.mEmail);
+        if (V) Log.v(TAG, "Tel: " + recipient.mTel);
+        if (V) Log.v(TAG, "Recipeint address: " + phoneNumber);
+        bMsgObj.setRecipientVcard_phone_number(phoneNumber);
+
+        // Extract vCard Version
+        bMsgObj.setVcard_version(recipient.mVersion);
+
+        // Extract bMessage Version
+        bMsgObj.setBmsg_version(fetchVersion(bmsg));
+
+        // Extract Message Status
+        bMsgObj.setStatus(fetchReadStatus(bmsg));
+
+        // Extract Message Type
+        bMsgObj.setType(fetchType(bmsg));
+
+        // Extract Message Folder
+        bMsgObj.setFolder(fetchFolder(bmsg));
+
+        // Fetch Message Length
+        bMsgObj.setBody_length(fetchBodyLength(bmsg));
+
+        // Extract Message
+        bMsgObj.setBody_msg(fetchBodyMsgMMS(bmsg));
+
+        // Extract Message encoding
+        bMsgObj.setBody_encoding(fetchBodyEncoding(bmsg));
+
+        return bMsgObj;
+    }
+
+    /**
+     * fromBmessageEmail
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String and loads a BmessageConsts object that is returned
+     *
+     * @param String
+     *            - which is a bMessage formatted Email message
+     * @return This method returns a BmessageConsts object
+     */
+
+    public static BmessageConsts fromBmessageEmail(Context context,
+                        String bmsg, int mMasId) throws BadRequestException {
+        BmessageConsts bMsgObj = new BmessageConsts();
+        String vCard = fetchRecipientVcard(bmsg);
+        if (V) Log.v(TAG, "vCard Info: " + vCard);
+
+        RecipientVCard recipient = parseVCard(vCard);
+        if (recipient.mEmail.length() == 0) {
+            throw new BadRequestException("No Email in recipient vCard");
+        }
+        bMsgObj.setRecipientVcard_email(recipient.mEmail);
+        if (V) Log.v(TAG, "Email: " + recipient.mEmail);
+
+        String vcardOrig = fetchOriginatorVcardEmail(bmsg);
+        RecipientVCard originator = parseVCard(vcardOrig);
+        if (originator.mEmail.length() == 0) {
+            long accountId = -1;
+            accountId = EmailUtils.getAccountId(mMasId);
+            if ((accountId != -1) && (context != null)) {
+                originator.mEmail = EmailUtils.getEmailAccountIdEmail
+                (context,EmailUtils.RECORD_ID + "=" + accountId);
+                Log.v(TAG, "Orig Email inserted by MSE as: " + originator.mEmail);
+                originator.mFormattedName = EmailUtils.getEmailAccountDisplayName
+                (context,EmailUtils.RECORD_ID + "=" + accountId);
+                Log.v(TAG, "Orig F-Name inserted by MSE as: " + originator.mFormattedName);
+            }
+            if (originator.mEmail.length() == 0) {
+                throw new BadRequestException("No Email in originator vCard");
+            }
+        }
+        bMsgObj.setOriginatorVcard_email(originator.mEmail);
+        if (V) Log.v(TAG, "Orig Email: " + originator.mEmail);
+        if (originator.mFormattedName.length() > 0) {
+            if (V) Log.v(TAG, "Orig Formatted Name: " + originator.mFormattedName);
+            bMsgObj.setOriginatorVcard_name(originator.mFormattedName);
+        } else {
+            if (V) Log.v(TAG, "Orig Name: " + originator.mName);
+            bMsgObj.setOriginatorVcard_name(originator.mName);
+        }
+
+        if (V){
+            Log.v(TAG, "Bmsg version:: "+fetchVersion(bmsg));
+        }
+        // Extract bMessage Version
+        bMsgObj.setBmsg_version(fetchVersion(bmsg));
+
+        if (V){
+            Log.v(TAG, "Read status:: "+fetchReadStatus(bmsg));
+        }
+        // Extract Message Status
+        bMsgObj.setStatus(fetchReadStatus(bmsg));
+
+        if (V){
+            Log.v(TAG, "Message Type:: "+fetchType(bmsg));
+        }
+        // Extract Message Type
+        bMsgObj.setType(fetchType(bmsg));
+
+        if (V){
+            Log.v(TAG, "Folder:: "+fetchFolder(bmsg));
+        }
+        // Extract Message Folder
+        bMsgObj.setFolder(fetchFolder(bmsg));
+
+        if (V){
+            Log.v(TAG, "body length:: "+fetchBodyLength(bmsg));
+        }
+        // Fetch Message Length
+        bMsgObj.setBody_length(fetchBodyLength(bmsg));
+        // Extract Message
+        bMsgObj.setBody_msg(fetchBodyEmail(bmsg));
+
+        if (V){
+            Log.v(TAG, "Message encoding:: "+fetchBodyEncoding(bmsg));
+        }
+        // Extract Message encoding
+        bMsgObj.setBody_encoding(fetchBodyEncoding(bmsg));
+
+        // Extract Subject of the email
+        bMsgObj.setSubject(fetchSubjectEmail(bmsg));
+
+        return bMsgObj;
+    }
+
+    /**
+     * fetchVcardEmail
+     *
+     * This method takes as input a vCard formatted String. It parses the String
+     * and returns the vCard Email as a String
+     *
+     * @param
+     * @return String This method returns a vCard Email String
+     */
+    private static String fetchVcardEmail(String vCard) {
+        int pos = vCard.indexOf(("EMAIL:"));
+        int beginVersionPos = pos + (("EMAIL:").length());
+        if (V){
+            Log.v(TAG,"Begin Version Position Email:: "+beginVersionPos);
+        }
+        int endVersionPos = vCard.indexOf("\n", beginVersionPos);
+        if (V){
+            Log.v(TAG,"End version Pos Email:: "+endVersionPos);
+        }
+        return vCard.substring(beginVersionPos, endVersionPos);
+    }
+
+    private static String fetchOriginatorEmail(String vCard) {
+        int pos = vCard.indexOf(("From:"));
+        int beginVersionPos = pos + (("From:").length());
+        int endVersionPos = vCard.indexOf(CRLF, beginVersionPos);
+        return vCard.substring(beginVersionPos, endVersionPos);
+    }
+
+    private static String fetchRecipientEmail(String vCard) {
+        int pos = vCard.indexOf(("To:"));
+        int beginVersionPos = pos + (("To:").length());
+        int endVersionPos = vCard.indexOf(CRLF, beginVersionPos);
+        return vCard.substring(beginVersionPos, endVersionPos);
+    }
+
+    private static String fetchRecepientVcardEmail(String bmsg) {
+        // Find the position of the first vCard in the string
+        int pos = bmsg.indexOf("BEGIN:BENV");
+        if (V){
+            Log.v(TAG, "vCard start position:: "+pos);
+        }
+        if (pos > 0) {
+            if (V){
+                Log.v(TAG, "vCard start position greater than 0::");
+            }
+            int beginVcardPos = pos + ("\r\n".length());
+            int endVcardPos = bmsg.indexOf("END:BENV");
+
+            return bmsg.substring(beginVcardPos, endVcardPos);
+
+        } else {
+            return "";
+        }
+    }
+
+    private static String fetchOriginatorVcardEmail(String bmsg) throws BadRequestException {
+        // Find the position of the first vCard in the string
+        int vCardBeginPos = bmsg.indexOf("BEGIN:VCARD");
+        if (vCardBeginPos == -1) {
+            // no vCard bad request
+            throw new BadRequestException("No Vcard");
+        }
+        if (V) Log.v(TAG, "vCard start position: " + vCardBeginPos);
+        int bEnvPos = bmsg.indexOf("BEGIN:BENV");
+        if (vCardBeginPos > bEnvPos) {
+            // the first vCard is not originator
+            return "";
+        }
+        int vCardEndPos = bmsg.indexOf("END:VCARD", vCardBeginPos);
+        if (vCardEndPos == -1) {
+            // no END:VCARD bad request
+            throw new BadRequestException("No END:VCARD");
+        }
+        vCardEndPos += "END:VCARD".length();
+
+        return bmsg.substring(vCardBeginPos, vCardEndPos);
+    }
+
+    private static String fetchSubjectEmail(String body) {
+        int pos = body.indexOf("Subject:");
+
+        if (pos > 0) {
+            int beginVersionPos = pos + (("Subject:").length());
+            int endVersionPos = body.indexOf("\n", beginVersionPos);
+            return body.substring(beginVersionPos, endVersionPos);
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * fetchVersion
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String and returns the bMessage version string
+     *
+     * @param
+     * @return String This method returns a Version String
+     */
+    private static String fetchVersion(String bmsg) {
+        int pos = bmsg.indexOf("VERSION:");
+        if (pos > 0) {
+
+            int beginVersionPos = pos + (("VERSION:").length());
+            int endVersionPos = bmsg.indexOf(CRLF, beginVersionPos);
+            return bmsg.substring(beginVersionPos, endVersionPos);
+
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * fetchOriginatorVcard
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String and returns the orginator vCard string
+     *
+     * @param
+     * @return String This method returns a vCard String
+     */
+    private static String fetchOriginatorVcard(String bmsg) {
+        // Find the position of the first vCard in the string
+        int pos = bmsg.indexOf("\r\nBEGIN:VCARD");
+        if (pos > 0) {
+            int beginVcardPos = pos + ("\r\n".length());
+            int endVcardPos = bmsg.indexOf("END:VCARD");
+
+            return bmsg.substring(beginVcardPos, endVcardPos);
+
+        } else {
+
+            return null;
+
+        }
+    }
+
+    /**
+     * fetchRecipientVcard
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String looking for the first envelope. Once it finds the envelop, it then
+     * looks for the first vCard and returns it as a String
+     *
+     * @param
+     * @return String This method returns a Vcard String
+     */
+    private static String fetchRecipientVcard(String bmsg) throws BadRequestException {
+        // Locate BENV
+        int locBENV = 0;
+        int pos = 0;
+        locBENV = bmsg.indexOf(CRLF + "BEGIN:BENV");
+        pos = bmsg.indexOf(CRLF + "BEGIN:VCARD", locBENV);
+        if (pos < 0) {
+            // no vCard in BENV
+            throw new BadRequestException("No vCard in BENV");
+        }
+        if (pos > 0) {
+            int beginVcardPos = pos + CRLF.length();
+            int endVcardPos = bmsg.indexOf("END:VCARD", pos);
+            if (endVcardPos < 0) {
+                // no END:VCARD in BENV
+                throw new BadRequestException("No END:VCARD in BENV");
+            }
+            endVcardPos += "END:VCARD".length();
+            return bmsg.substring(beginVcardPos, endVcardPos);
+
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * fetchReadStatus
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String and returns the bMessage read status String
+     *
+     * @param
+     * @return String This method returns a Read Status String
+     */
+    private static String fetchReadStatus(String bmsg) {
+        int pos = bmsg.indexOf("STATUS:");
+        if (pos > 0) {
+
+            int beginStatusPos = pos + (("STATUS:").length());
+            int endStatusPos = bmsg.indexOf(CRLF, beginStatusPos);
+            return bmsg.substring(beginStatusPos, endStatusPos);
+
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * fetchType
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String and returns the bMessage type String
+     *
+     * @param
+     * @return String This method returns a message type String
+     */
+    public static String fetchType(String bmsg) {
+        int pos = bmsg.indexOf("TYPE:");
+        if (pos > 0) {
+            int beginTypePos = pos + (("TYPE:").length());
+            int endTypePos = bmsg.indexOf(CRLF, beginTypePos);
+
+            return bmsg.substring(beginTypePos, endTypePos);
+
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * fetchFolder
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String and returns the bMessage Folder path String
+     *
+     * @param
+     * @return String This method returns a Folder path String
+     */
+    private static String fetchFolder(String bmsg) {
+        int pos = bmsg.indexOf("FOLDER:");
+        if (pos > 0) {
+            int beginVersionPos = pos + (("FOLDER:").length());
+            int endVersionPos = bmsg.indexOf(CRLF, beginVersionPos);
+
+            return bmsg.substring(beginVersionPos, endVersionPos);
+
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * fetchBody
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String and returns the bMessage Body as a String
+     *
+     * @param
+     * @return String This method returns a Body String
+     */
+    @SuppressWarnings("unused")
+    private static String fetchBody(String bmsg) {
+        int pos = bmsg.indexOf("BEGIN:BBODY");
+        if (pos > 0) {
+            int beginVersionPos = pos + (("BEGIN:BBODY").length());
+            int endVersionPos = bmsg.indexOf("END:BBODY", beginVersionPos);
+
+            return bmsg.substring(beginVersionPos, endVersionPos);
+
+        } else {
+            return null;
+        }
+
+    }
+
+    /**
+     * fetchBodyPartID
+     *
+     * This method takes as input a String consisting of the body portion of the
+     * bMessage. It parses the String and returns the bMessage Body Part ID as a
+     * String
+     *
+     * @param
+     * @return String This method returns a Body Part ID String
+     */
+    @SuppressWarnings("unused")
+    private static String fetchBodyPartID(String body) {
+        int pos = body.indexOf("PARTID:");
+        if (pos > 0) {
+            int beginVersionPos = pos + (("PARTID:").length());
+            int endVersionPos = body.indexOf(CRLF, beginVersionPos);
+            return body.substring(beginVersionPos, endVersionPos);
+
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * fetchCharset
+     *
+     * This method takes as input a String consisting of the body portion of the
+     * bMessage. It parses the String and returns the bMessage Charset as a
+     * String
+     *
+     * @param
+     * @return String This method returns a Charset String
+     */
+    @SuppressWarnings("unused")
+    private static String fetchCharset(String body) {
+        int pos = body.indexOf("CHARSET:");
+        if (pos > 0) {
+
+            int beginVersionPos = pos + (("CHARSET:").length());
+            int endVersionPos = body.indexOf(CRLF, beginVersionPos);
+
+            return body.substring(beginVersionPos, endVersionPos);
+
+        } else {
+
+            return null;
+        }
+    }
+
+    /**
+     * fetchBodyEncoding
+     *
+     * This method takes as input a String consisting of the body portion of the
+     * bMessage. It parses the String and returns the bMessage Body Encoding as
+     * a String
+     *
+     * @param
+     * @return String This method returns a Body Encoding String
+     */
+    private static String fetchBodyEncoding(String body) {
+        int pos = body.indexOf("ENCODING:");
+        if (pos > 0) {
+            int beginVersionPos = pos + (("ENCODING:").length());
+            int endVersionPos = body.indexOf(CRLF, beginVersionPos);
+            return body.substring(beginVersionPos, endVersionPos);
+
+        } else {
+
+            return null;
+        }
+    }
+
+    /**
+     * fetchBodyLanguage
+     *
+     * This method takes as input a String consisting of the body portion of the
+     * bMessage. It parses the String and returns the bMessage Body Language as
+     * a String
+     *
+     * @param
+     * @return String This method returns a Body Language String
+     */
+    @SuppressWarnings("unused")
+    private static String fetchBodyLanguage(String body) {
+        int pos = body.indexOf("LANGUAGE:");
+        if (pos > 0) {
+            int beginVersionPos = pos + (("LANGUAGE:").length());
+            int endVersionPos = body.indexOf(CRLF, beginVersionPos);
+            return body.substring(beginVersionPos, endVersionPos);
+
+        } else {
+
+            return null;
+        }
+    }
+
+    /**
+     * fetchBodyLength
+     *
+     * This method takes as input a String consisting of the body portion of the
+     * bMessage. It parses the String and returns the bMessage Body Length as an
+     * Integer
+     *
+     * @param
+     * @return String This method returns a Body Length Integer
+     */
+    private static Integer fetchBodyLength(String body) {
+        int pos = body.indexOf("LENGTH:");
+        if (pos > 0) {
+            int beginVersionPos = pos + (("LENGTH:").length());
+            int endVersionPos = body.indexOf(CRLF, beginVersionPos);
+            String bd = body.substring(beginVersionPos,
+                       endVersionPos);
+            Integer bl = Integer.valueOf(bd);
+            return bl;
+
+        } else {
+
+            return null;
+        }
+    }
+
+    /**
+     * fetchBodyMsg
+     *
+     * This method takes as input a String consisting of the body portion of the
+     * bMessage. It parses the String and returns the bMessage Body Message as a
+     * String
+     *
+     * @param
+     * @return String This method returns a Body Message String
+     */
+    private static String fetchBodyMsg(String body) {
+        int pos = body.indexOf("BEGIN:MSG");
+        if (pos > 0) {
+            int beginVersionPos = pos
+                    + (("BEGIN:MSG").length() + CRLF.length());
+            int endVersionPos = (body.indexOf("END:MSG", beginVersionPos) - CRLF
+                    .length());
+            return body.substring(beginVersionPos, endVersionPos);
+        } else {
+            return "";
+        }
+    }
+
+    private static String fetchBodyMsgMMS(String body) {
+        int pos = body.indexOf("BEGIN:MSG");
+        if (pos > 0) {
+            /* MMS body should contain both Begin and End message tags */
+            int beginVersionPos = pos;
+            int endVersionPos = body.indexOf("END:MSG", beginVersionPos) + ("END:MSG").length();
+            return body.substring(beginVersionPos, endVersionPos);
+        } else {
+            return "";
+        }
+    }
+
+    private static String fetchBodyMsgEmail(String body) {
+        if (V){
+            Log.v(TAG, "bMessageEmail inside fetch body ::"+body);
+        }
+        int pos = body.indexOf("Content-Disposition:inline");
+        if (pos > 0) {
+            int beginVersionPos = pos
+                    + (("Content-Disposition:inline").length() + CRLF.length());
+            int endVersionPos = (body.indexOf("--RPI-Messaging", beginVersionPos) - CRLF
+                    .length());
+
+            return body.substring(beginVersionPos, endVersionPos);
+
+        } else {
+
+            return null;
+        }
+    }
+
+    private static String fetchBoundary(String body) {
+        int pos = body.indexOf("boundary=\"");
+        if (pos > 0) {
+            int beginVersionPos = pos + (("boundary=\"").length());
+            int endVersionPos = body.indexOf("\"", beginVersionPos);
+            return body.substring(beginVersionPos, endVersionPos);
+
+        } else {
+
+            return null;
+        }
+    }
+
+    public static String fetchBodyEmail(String body) throws BadRequestException {
+        if (V) Log.v(TAG, "inside fetch body Email :"+body);
+
+        int beginVersionPos = -1;
+        int rfc822Flag = 0;
+        int mimeFlag = 0;
+        int beginVersionPos1 = -1;
+        String contentType;
+        int pos1 = 0;
+        String boundary = fetchBoundary(body);
+        if(boundary != null && !boundary.equalsIgnoreCase("")){
+            pos1 = body.indexOf("--"+boundary);
+            mimeFlag = 1;
+        }
+        else{
+            pos1 = body.indexOf("Date:");
+            mimeFlag = 0;
+        }
+        int contentIndex = body.indexOf("Content-Type",pos1);
+        if(contentIndex > 0){
+            contentType = fetchContentType(body, boundary);
+            if(contentType != null && contentType.trim().equalsIgnoreCase("message/rfc822")){
+                rfc822Flag = 1;
+            }
+        }
+        int pos = body.indexOf(CRLF, pos1) + CRLF.length();
+        while (pos > 0) {
+            if(body.startsWith(CRLF, pos)) {
+                beginVersionPos = pos + CRLF.length();
+                break;
+            } else {
+                final int next = body.indexOf(CRLF, pos);
+                if (next == -1) {
+                    // throw new BadRequestException("Ill-formatted bMessage, no empty line");
+                    // PTS: Instead of throwing Exception, return MSG
+                    int beginMsg = body.indexOf("BEGIN:MSG");
+                    if (beginMsg == -1) {
+                        throw new BadRequestException("Ill-formatted bMessage, no BEGIN:MSG");
+                    }
+                    int endMsg = body.indexOf("END:MSG", beginMsg);
+                    if (endMsg == -1) {
+                        throw new BadRequestException("Ill-formatted bMessage, no END:MSG");
+                    }
+                    return body.substring(beginMsg + "BEGIN:MSG".length(), endMsg - CRLF.length());
+                } else {
+                    pos = next + CRLF.length();
+                }
+            }
+        }
+        if(beginVersionPos > 0){
+            int endVersionPos;
+            if(rfc822Flag == 0){
+                if(mimeFlag == 0) {
+                    endVersionPos = body.indexOf("END:MSG", beginVersionPos) ;
+                    if (endVersionPos != -1) {
+                        return body.substring(beginVersionPos, (endVersionPos - CRLF.length()));
+                    }
+                    else {
+                        return body.substring(beginVersionPos);
+                    }
+                } else {
+                    endVersionPos = (body.indexOf("--"+boundary+"--", beginVersionPos) - CRLF.length());
+                }
+                try {
+                    return body.substring(beginVersionPos, endVersionPos);
+                } catch (IndexOutOfBoundsException e) {
+                    throw new BadRequestException("Ill-formatted bMessage, no end boundary");
+                }
+            }
+            else if(rfc822Flag == 1){
+                endVersionPos = (body.indexOf("--"+boundary+"--", beginVersionPos));
+                try {
+                    body = body.substring(beginVersionPos, endVersionPos);
+                } catch (IndexOutOfBoundsException e) {
+                    throw new BadRequestException("Ill-formatted bMessage, no end boundary");
+                }
+                int pos2 = body.indexOf(CRLF) + CRLF.length();
+                while (pos2 > 0) {
+                    if(body.startsWith(CRLF, pos2)) {
+                        beginVersionPos1 = pos2 + CRLF.length();
+                        break;
+                    } else {
+                        final int next = body.indexOf(CRLF, pos2);
+                        if (next == -1) {
+                            throw new BadRequestException("Ill-formatted bMessage, no empty line");
+                        } else {
+                            pos2 = next + CRLF.length();
+                        }
+                    }
+                }
+                if(beginVersionPos1 > 0){
+                    return body.substring(beginVersionPos1);
+                }
+            }
+        }
+        return null;
+    }
+
+    private static String fetchContentType(String bmsg, String boundary) {
+        int pos1 = bmsg.indexOf("--"+boundary);
+        int pos = bmsg.indexOf("Content-Type:", pos1);
+        if (pos > 0) {
+
+            int beginVersionPos = pos + (("Content-Type:").length());
+            int endVersionPos = bmsg.indexOf(CRLF, beginVersionPos);
+            return bmsg.substring(beginVersionPos, endVersionPos);
+
+        } else {
+
+            return null;
+
+        }
+    }
+
+    /**
+     * fetchNumEnv
+     *
+     * This method takes as input a String in the bMessage format. It parses the
+     * String and returns the number of envelope headers that it finds as an
+     * Integer
+     *
+     * @param
+     * @return String This method returns the number of Envelope headers as an
+     *         Integer
+     */
+    @SuppressWarnings("unused")
+    private static Integer fetchNumEnv(String bmsg) {
+        int envCnt = 0;
+        int pos = 0;
+        int loopCnt = 0;
+        pos = bmsg.indexOf((CRLF + "BEGIN:BENV"), pos);
+        if (pos < 0) {
+            loopCnt = 4;
+        } else {
+            envCnt = envCnt + 1;
+        }
+        while (loopCnt < 4) {
+            pos = bmsg.indexOf((CRLF + "BEGIN:BENV"), pos + CRLF.length());
+            if (pos < 0) {
+                loopCnt = 4;
+            } else {
+                envCnt = envCnt + 1;
+            }
+        }
+
+        return envCnt;
+    }
+
+    /**
+     * fetchVcardVersion
+     *
+     * This method takes as input a vCard formatted String. It parses the String
+     * and returns the vCard version as a String
+     *
+     * @param
+     * @return String This method returns a vCard version String
+     */
+    private static String fetchVcardVersion(String vCard) {
+        int pos = vCard.indexOf(CRLF + "VERSION:");
+        int beginVersionPos = pos + (("VERSION:").length() + CRLF.length());
+        int endVersionPos = vCard.indexOf(CRLF, beginVersionPos);
+
+        return vCard.substring(beginVersionPos, endVersionPos);
+    }
+
+    /**
+     * fetchVcardName
+     *
+     * This method takes as input a vCard formatted String. It parses the String
+     * and returns the vCard name as a String
+     *
+     * @param
+     * @return String This method returns a vCard name String
+     */
+    @SuppressWarnings("unused")
+    private static String fetchVcardName(String vCard) {
+
+        int pos = vCard.indexOf((CRLF + "N:"));
+        int beginNPos = pos + "N:".length() + CRLF.length();
+        int endNPos = vCard.indexOf(CRLF, beginNPos);
+        return vCard.substring(beginNPos, endNPos);
+    }
+
+    /**
+     * fetchVcardTel
+     *
+     * This method takes as input a vCard formatted String. It parses the String
+     * and returns the vCard phone number as a String
+     *
+     * @param
+     * @return String This method returns a vCard phone number String
+     */
+    private static String fetchVcardTel(String vCard) {
+
+        int pos = vCard.indexOf((CRLF + "TEL:"));
+        int beginVersionPos = pos + (("TEL:").length() + CRLF.length());
+        int endVersionPos = vCard.indexOf(CRLF, beginVersionPos);
+        return vCard.substring(beginVersionPos, endVersionPos);
+    }
+
+    /**
+     * fetchVcardEmail
+     *
+     * This method takes as input a vCard formatted String. It parses the String
+     * and returns the vCard phone number as a String
+     *
+     * @param
+     * @return String This method returns a vCard phone number String
+     */
+    private static String fetchVcardEmailforMms(String vCard) {
+        int pos = vCard.indexOf((CRLF + "EMAIL:"));
+        int beginVersionPos = pos + (("EMAIL:").length() + CRLF.length());
+        int endVersionPos = vCard.indexOf(CRLF, beginVersionPos);
+        return vCard.substring(beginVersionPos, endVersionPos);
+    }
+
+    public static class BadRequestException extends Exception {
+        public BadRequestException(String reason) {
+            super("BadRequestException: " + reason);
+        }
+    }
+
+    public static class RecipientVCard implements VCardInterpreter {
+        String mName = "";
+        String mFormattedName = "";
+        String mTel = "";
+        String mEmail = "";
+        String mVersion = "";
+        String mCurrentProperty = "";
+
+        /* This is a workaround to replace predifined XML escaping entities
+         * with original characters from VCardInterpreter to handle the XML
+         * parsing limitation of MCE (Denso Carkit).
+         * TODO: Above limitaion MUST be handled @MCE itself.
+        */
+        private static String replaceSpecialVcardString(String input) {
+                String str = input;
+                if(str != null){
+                    str = str.toLowerCase().replace("&lt;", "<");
+                    str = str.toLowerCase().replace("&gt;", ">");
+                }
+                return str;
+        }
+
+        public void end() {
+            if (V) Log.v(TAG, "end()");
+        }
+
+        public void endEntry() {
+            if (V) Log.v(TAG, "endEntry()");
+        }
+
+        public void endProperty() {
+            if (V) Log.v(TAG, "endProperty()");
+            mCurrentProperty = "";
+        }
+
+        public void propertyGroup(String group) {
+            if (V) Log.v(TAG, "propertyGroup(" + group + ")");
+        }
+
+        public void propertyName(String name) {
+            if (V) Log.v(TAG, "propertyName(" + name + ")");
+            mCurrentProperty = name;
+        }
+
+        public void propertyParamType(String type) {
+            if (V) Log.v(TAG, "propertyParamType(" + type + ")");
+        }
+
+        public void onPropertyCreated(VCardProperty property) {
+            List <String> values;
+
+            if (V) Log.v(TAG, "onPropertyCreated(" + property + ")");
+
+            values = property.getValueList();
+            if (values == null){
+                Log.e(TAG, "NULL Value List received");
+                return;
+            }
+            /* TODO: replaceSpecialVcardString() is a temporary fix bought to
+             * overcome the limitation of XML parsing with MCE (Denso Carkit)
+             * and later this must to be handled  from MCE itself.
+             */
+            // The first appeared property in a vCard will be used
+            if (PROPERTY_N.equals(property.getName()) && mName.length() == 0) {
+                StringBuilder sb = new StringBuilder();
+
+                sb.append(values.get(0));
+                final int size = values.size();
+                for (int i = 0; i < size; i ++) {
+                    sb.append(", ");
+                    sb.append(values.get(i));
+                }
+                mName = RecipientVCard.replaceSpecialVcardString(sb.toString());
+                if (V) Log.v(TAG, PROPERTY_N + ": " + mName);
+            } else if (PROPERTY_TEL.equals(property.getName()) && mTel.length() == 0) {
+                mTel = RecipientVCard.replaceSpecialVcardString(values.get(0));
+                if (V) Log.v(TAG, PROPERTY_TEL + ": " + mTel);
+            } else if (PROPERTY_EMAIL.equals(property.getName()) && mEmail.length() == 0) {
+                mEmail = RecipientVCard.replaceSpecialVcardString(values.get(0));
+                if (V) Log.v(TAG, PROPERTY_EMAIL + ": " + mEmail);
+            } else if (PROPERTY_FN.equals(property.getName()) && mFormattedName.length() == 0) {
+                mFormattedName = RecipientVCard.replaceSpecialVcardString(values.get(0));
+                if (V) Log.v(TAG, PROPERTY_FN + ": " + mFormattedName);
+            }
+        }
+
+        public void onVCardStarted() {
+            if (V) Log.v(TAG, "onVCardStarted");
+        }
+
+        public void onVCardEnded() {
+            if (V) Log.v(TAG, "onVCardEnded");
+        }
+
+        public void onEntryStarted() {
+            if (V) Log.v(TAG, "onEntryStarted");
+            mName = "";
+            mFormattedName = "";
+            mTel = "";
+            mEmail = "";
+        }
+
+        public void onEntryEnded() {
+            if (V) Log.v(TAG, "onEntryEnded");
+        }
+
+
+        public void propertyParamValue(String value) {
+            if (V) Log.v(TAG, "propertyParamValue(" + value + ")");
+        }
+
+        public void propertyValues(List<String> values) {
+            if (V) Log.v(TAG, "propertyValues(" + values.toString() + "), Property=" + mCurrentProperty);
+            /* TODO: replaceSpecialVcardString() is a temporary fix bought to
+             * overcome the limitation of XML parsing with MCE (Denso Carkit)
+             * and later this must to be handled  from MCE itself.
+             */
+            // The first appeared property in a vCard will be used
+            if (PROPERTY_N.equals(mCurrentProperty) && mName.length() == 0) {
+                StringBuilder sb = new StringBuilder();
+                sb.append(values.get(0));
+                final int size = values.size();
+                for (int i = 0; i < size; i ++) {
+                    sb.append(", ");
+                    sb.append(values.get(i));
+                }
+                mName = RecipientVCard.replaceSpecialVcardString(sb.toString());
+                if (V) Log.v(TAG, PROPERTY_N + ": " + mName);
+            } else if (PROPERTY_TEL.equals(mCurrentProperty) && mTel.length() == 0) {
+                mTel = RecipientVCard.replaceSpecialVcardString(values.get(0));
+                if (V) Log.v(TAG, PROPERTY_TEL + ": " + mTel);
+            } else if (PROPERTY_EMAIL.equals(mCurrentProperty) && mEmail.length() == 0) {
+                 mEmail = RecipientVCard.replaceSpecialVcardString(values.get(0));
+                if (V) Log.v(TAG, PROPERTY_EMAIL + ": " + mEmail);
+            } else if (PROPERTY_FN.equals(mCurrentProperty) && mFormattedName.length() == 0) {
+                mFormattedName = RecipientVCard.replaceSpecialVcardString(values.get(0));
+                if (V) Log.v(TAG, PROPERTY_FN + ": " + mFormattedName);
+            }
+        }
+
+        public void start() {
+            if (V) Log.v(TAG, "start()");
+        }
+
+        public void startEntry() {
+            if (V) Log.v(TAG, "startEntry()");
+            mName = "";
+            mFormattedName = "";
+            mTel = "";
+            mEmail = "";
+        }
+
+        public void startProperty() {
+            if (V) Log.v(TAG, "startProperty()");
+            mCurrentProperty = "";
+        }
+    }
+
+    static RecipientVCard parseVCard(String vCard) throws BadRequestException {
+        if (V) Log.v(TAG, "parseVCard(" + vCard + ")");
+        RecipientVCard recipient = new RecipientVCard();
+
+        if (vCard.length() == 0) {
+            return recipient;
+        }
+
+        try {
+            ByteArrayInputStream is = null;
+            try {
+                byte vCardBytes[] = vCard.getBytes("UTF-8");
+                is = new ByteArrayInputStream(vCardBytes);
+            } catch (UnsupportedEncodingException ex) {
+                Log.w(TAG, "Unable to parse vCard", ex);
+                throw new BadRequestException("Unable to parse vCard");
+            }
+            VCardParser parser = new VCardParser_V21();
+            try {
+                if (V) Log.v(TAG, "try " + VERSION_V21);
+                recipient.mVersion = VERSION_V21;
+                parser.parse(is, recipient);
+            } catch (VCardVersionException e) {
+                is.close();
+                is = new ByteArrayInputStream(vCard.getBytes("UTF-8"));
+                try {
+                    if (V) Log.v(TAG, "try " + VERSION_V30);
+                    recipient.mVersion = VERSION_V30;
+                    parser = new VCardParser_V30();
+                    parser.parse(is, recipient);
+                } catch (VCardVersionException e1) {
+                    throw new VCardException("vCard with unsupported version.");
+                }
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "Unable to parse vCard", e);
+            throw new BadRequestException("Unable to parse vCard");
+        } catch (VCardException e) {
+            Log.w(TAG, "Unable to parse vCard", e);
+            throw new BadRequestException("Unable to parse vCard");
+        }
+
+        return recipient;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/MapUtilsConsts.java b/src/org/codeaurora/bluetooth/map/MapUtils/MapUtilsConsts.java
new file mode 100644
index 0000000..a77b3dd
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/MapUtilsConsts.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map.MapUtils;
+
+/**
+ * List of strings used to construct Bmessages
+ *
+ */
+public final class MapUtilsConsts {
+    public static final String BEGIN_BMSG = "BEGIN:BMSG";
+    public static final String END_BMSG = "END:BMSG";
+    public static final String BEGIN_BENV = "BEGIN:BENV";
+    public static final String END_BBENV = "END:BENV";
+
+    public static final String Telecom = "telecom";
+    public static final String Msg = "msg";
+
+    public static final String Inbox = "inbox";
+    public static final String Outbox = "outbox";
+    public static final String Sent = "sent";
+    public static final String Deleted = "deleted";
+    public static final String Draft = "draft";
+    public static final String Drafts = "drafts";
+    public static final String Undelivered = "undelivered";
+    public static final String Failed = "failed";
+    public static final String Queued = "queued";
+}
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/MsgListingConsts.java b/src/org/codeaurora/bluetooth/map/MapUtils/MsgListingConsts.java
new file mode 100644
index 0000000..3d81642
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/MsgListingConsts.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map.MapUtils;
+
+public class MsgListingConsts {
+
+    public class MsgInfo {
+        public String dateTime = null;
+
+        public String getDateTime() {
+            return dateTime;
+        }
+
+        public void setDateTime(String dateTime) {
+            this.dateTime = dateTime;
+        }
+
+    }
+    public MsgInfo msgInfo = new MsgInfo();
+
+    public long msg_handle = 0;
+    public String subject = null;
+    public boolean  sendSubject = false;
+    public String datetime = null;
+    public String sender_name = null;
+    public String sender_addressing = null;
+    public String recepient_name = null;
+    public boolean sendRecipient_addressing = false;
+    public String recepient_addressing = null;
+    public String type = null;
+    public int size = -1;
+    public String reception_status = null;
+    public int attachment_size = -1;
+    public String contains_text = null;
+    public String priority = null;
+    public String read = null;
+    public String sent = null;
+    public String msg_protected = null;
+    public String replyto_addressing = null;
+
+    public long getMsg_handle() {
+        return msg_handle;
+    }
+
+    public void setMsg_handle(long msg_handle) {
+        this.msg_handle = msg_handle;
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public void setSendSubject(boolean flag) {
+        this.sendSubject = flag;
+    }
+
+    public String getDatetime() {
+        return datetime;
+    }
+
+    public void setDatetime(String datetime) {
+        this.datetime = datetime;
+    }
+
+    public String getSender_name() {
+        return sender_name;
+    }
+
+    public void setSender_name(String sender_name) {
+        this.sender_name = sender_name;
+    }
+
+    public String getSender_addressing() {
+        return sender_addressing;
+    }
+
+    public void setSender_addressing(String sender_addressing) {
+        this.sender_addressing = sender_addressing;
+    }
+
+    public String getRecepient_name() {
+        return recepient_name;
+    }
+
+    public void setRecepient_name(String recepient_name) {
+        this.recepient_name = recepient_name;
+    }
+
+    public String getRecepient_addressing() {
+        return recepient_addressing;
+    }
+
+    public void setSendRecipient_addressing(boolean flag) {
+        this.sendRecipient_addressing = flag;
+    }
+
+
+    public void setRecepient_addressing(String recepient_addressing) {
+        this.recepient_addressing = recepient_addressing;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public void setSize(int size) {
+        this.size = size;
+    }
+
+    public String getReception_status() {
+        return reception_status;
+    }
+
+    public void setReception_status(String reception_status) {
+        this.reception_status = reception_status;
+    }
+
+    public int getAttachment_size() {
+        return attachment_size;
+    }
+
+    public void setAttachment_size(int attachment_size) {
+        this.attachment_size = attachment_size;
+    }
+
+    public String getContains_text() {
+        return contains_text;
+    }
+
+    public void setContains_text(String contains_text) {
+        this.contains_text = contains_text;
+    }
+
+    public String getPriority() {
+        return priority;
+    }
+
+    public void setPriority(String priority) {
+        this.priority = priority;
+    }
+
+    public String getRead() {
+        return read;
+    }
+
+    public void setRead(String read) {
+        this.read = read;
+    }
+
+    public void setSent(String sent) {
+        this.sent = sent;
+    }
+
+    public String getSent() {
+        return sent;
+    }
+
+    public String getMsg_protected() {
+        return msg_protected;
+    }
+
+    public void setMsg_protected(String msg_protected) {
+        this.msg_protected = msg_protected;
+    }
+
+    public String getReplyTo_addressing() {
+        return sender_addressing;
+    }
+
+    public void setReplyTo_addressing(String replyto_addressing) {
+        this.replyto_addressing = replyto_addressing;
+    }
+
+}
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/SmsMmsUtils.java b/src/org/codeaurora/bluetooth/map/MapUtils/SmsMmsUtils.java
new file mode 100644
index 0000000..73964c7
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/SmsMmsUtils.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map.MapUtils;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.text.format.Time;
+import android.util.Log;
+import android.util.TimeFormatException;
+
+import org.codeaurora.bluetooth.map.BluetoothMasAppParams;
+
+import java.util.ArrayList;
+
+public class SmsMmsUtils {
+    public static final String TAG = "SmsMmsUtils";
+    public static final int BIT_SUBJECT = 0x1;
+    public static final int BIT_DATETIME = 0x2;
+    public static final int BIT_SENDER_NAME = 0x4;
+    public static final int BIT_SENDER_ADDRESSING = 0x8;
+
+    public static final int BIT_RECIPIENT_NAME = 0x10;
+    public static final int BIT_RECIPIENT_ADDRESSING = 0x20;
+    public static final int BIT_TYPE = 0x40;
+    public static final int BIT_SIZE = 0x80;
+
+    public static final int BIT_RECEPTION_STATUS = 0x100;
+    public static final int BIT_TEXT = 0x200;
+    public static final int BIT_ATTACHMENT_SIZE = 0x400;
+    public static final int BIT_PRIORITY = 0x800;
+
+    public static final int BIT_READ = 0x1000;
+    public static final int BIT_SENT = 0x2000;
+    public static final int BIT_PROTECTED = 0x4000;
+    public static final int BIT_REPLYTO_ADDRESSING = 0x8000;
+
+    public static final String INBOX = "inbox";
+    public static final String OUTBOX = "outbox";
+    public static final String SENT = "sent";
+    public static final String DELETED = "deleted";
+    public static final String DRAFT = "draft";
+    public static final String DRAFTS = "drafts";
+    public static final String UNDELIVERED = "undelivered";
+    public static final String FAILED = "failed";
+    public static final String QUEUED = "queued";
+
+    public static final int DELETED_THREAD_ID = -1;
+
+    static final int PHONELOOKUP_ID_COLUMN_INDEX = 0;
+    static final int PHONELOOKUP_LOOKUP_KEY_COLUMN_INDEX = 1;
+    static final int PHONELOOKUP_DISPLAY_NAME_COLUMN_INDEX = 2;
+
+    static final int EMAIL_DATA_COLUMN_INDEX = 0;
+
+    public static class VcardContent {
+        public String name = "";
+        public String tel = "";
+        public String email = "";
+    }
+
+    public static final ArrayList<String> FORLDER_LIST_SMS_MMS;
+    public static final ArrayList<String> FORLDER_LIST_SMS_MMS_MNS;
+
+    static {
+        FORLDER_LIST_SMS_MMS = new ArrayList<String>();
+        FORLDER_LIST_SMS_MMS.add(INBOX);
+        FORLDER_LIST_SMS_MMS.add(OUTBOX);
+        FORLDER_LIST_SMS_MMS.add(SENT);
+        FORLDER_LIST_SMS_MMS.add(DELETED);
+        FORLDER_LIST_SMS_MMS.add(DRAFT);
+
+        FORLDER_LIST_SMS_MMS_MNS = new ArrayList<String>();
+        FORLDER_LIST_SMS_MMS_MNS.add(INBOX);
+        FORLDER_LIST_SMS_MMS_MNS.add(OUTBOX);
+        FORLDER_LIST_SMS_MMS_MNS.add(SENT);
+        FORLDER_LIST_SMS_MMS_MNS.add(DRAFT);
+        FORLDER_LIST_SMS_MMS_MNS.add(FAILED);
+        FORLDER_LIST_SMS_MMS_MNS.add(QUEUED);
+    }
+
+    public static int getFolderTypeMms(String folder) {
+        int folderType = -5 ;
+
+        if (INBOX.equalsIgnoreCase(folder)) {
+            folderType = 1;
+        }
+        else if (OUTBOX.equalsIgnoreCase(folder)) {
+            folderType = 4;
+        }
+        else if (SENT.equalsIgnoreCase(folder)) {
+            folderType = 2;
+        }
+        else if (DRAFT.equalsIgnoreCase(folder) || DRAFTS.equalsIgnoreCase(folder)) {
+            folderType = 3;
+        }
+        else if (DELETED.equalsIgnoreCase(folder)) {
+            folderType = -1;
+        }
+        return folderType;
+    }
+
+    public static String getWhereIsQueryForType(String folder) {
+        String query = null;
+
+        if (INBOX.equalsIgnoreCase(folder)) {
+            query = "type = 1 AND thread_id <> " + DELETED_THREAD_ID;
+        }
+        else if (OUTBOX.equalsIgnoreCase(folder)) {
+            query = "(type = 4 OR type = 5 OR type = 6) AND thread_id <> " + DELETED_THREAD_ID;
+        }
+        else if (SENT.equalsIgnoreCase(folder)) {
+            query = "type = 2 AND thread_id <> " + DELETED_THREAD_ID;
+        }
+        else if (DRAFT.equalsIgnoreCase(folder)) {
+            query = "type = 3 AND thread_id <> " + DELETED_THREAD_ID;
+        }
+        else if (DELETED.equalsIgnoreCase(folder)) {
+            query = "thread_id = " + DELETED_THREAD_ID;
+        }
+        else{
+            query = "type = -1";
+        }
+        return query;
+    }
+
+    public static String getConditionStringSms(String folderName, BluetoothMasAppParams appParams) {
+        String whereClause = getWhereIsQueryForType(folderName);
+
+         /* Filter readstatus: 0 no filtering, 0x01 get unread, 0x10 get read */
+        if (appParams.FilterReadStatus != 0) {
+             if ((appParams.FilterReadStatus & 0x1) != 0) {
+                 if (whereClause.length() != 0) {
+                     whereClause += " AND ";
+                 }
+                 whereClause += " read=0 ";
+             }
+             if ((appParams.FilterReadStatus & 0x02) != 0) {
+                 if (whereClause.length() != 0) {
+                     whereClause += " AND ";
+                 }
+                 whereClause += " read=1 ";
+             }
+         }
+         // TODO Filter priority?
+
+         /* Filter Period Begin */
+         if ((appParams.FilterPeriodBegin != null)
+                 && (appParams.FilterPeriodBegin.length() > 0)) {
+             Time time = new Time();
+             try {
+                 time.parse(appParams.FilterPeriodBegin.trim());
+                 if (whereClause.length() != 0) {
+                     whereClause += " AND ";
+                 }
+                 whereClause += "date >= " + time.toMillis(false);
+             } catch (TimeFormatException e) {
+                 Log.d(TAG, "Bad formatted FilterPeriodBegin "
+                         + appParams.FilterPeriodBegin);
+             }
+         }
+
+         /* Filter Period End */
+         if ((appParams.FilterPeriodEnd != null)
+                 && (appParams.FilterPeriodEnd.length() > 0 )) {
+             Time time = new Time();
+             try {
+                 time.parse(appParams.FilterPeriodEnd.trim());
+                 if (whereClause.length() != 0) {
+                     whereClause += " AND ";
+                 }
+                 whereClause += "date < " + time.toMillis(false);
+             } catch (TimeFormatException e) {
+                 Log.d(TAG, "Bad formatted FilterPeriodEnd "
+                         + appParams.FilterPeriodEnd);
+             }
+         }
+         return whereClause;
+    }
+
+    public static final Uri SMS_URI = Uri.parse("content://sms");
+    public static final Uri MMS_URI = Uri.parse("content://mms");
+    public static final String[] THREAD_ID_COLUMN = new String[]{"thread_id"};
+
+    /**
+     * Obtain the number of MMS messages
+     */
+    public static int getNumMmsMsgs(Context context, String name) {
+        int msgCount = 0;
+
+        if (DELETED.equalsIgnoreCase(name)) {
+            Uri uri = Uri.parse("content://mms/");
+            ContentResolver cr = context.getContentResolver();
+            Cursor cursor = cr.query(uri, null, "thread_id = " + DELETED_THREAD_ID, null, null);
+            if(cursor != null){
+                msgCount = cursor.getCount();
+                cursor.close();
+            }
+        } else {
+            Uri uri = Uri.parse("content://mms/" + name);
+            ContentResolver cr = context.getContentResolver();
+            Cursor cursor = cr.query(uri, null, "thread_id <> " + DELETED_THREAD_ID, null, null);
+            if(cursor != null){
+                msgCount = cursor.getCount();
+                cursor.close();
+            }
+        }
+        return msgCount;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/SortMsgListByDate.java b/src/org/codeaurora/bluetooth/map/MapUtils/SortMsgListByDate.java
new file mode 100644
index 0000000..a230895
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/SortMsgListByDate.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map.MapUtils;
+
+import java.util.Comparator;
+import org.codeaurora.bluetooth.map.MapUtils.MsgListingConsts;
+
+public class SortMsgListByDate implements Comparator<MsgListingConsts> {
+
+    public int compare(MsgListingConsts object1, MsgListingConsts object2) {
+
+        return object2.msgInfo.getDateTime().compareTo(object1.msgInfo.getDateTime());
+    }
+
+}
diff --git a/src/org/codeaurora/bluetooth/map/MapUtils/SqlHelper.java b/src/org/codeaurora/bluetooth/map/MapUtils/SqlHelper.java
new file mode 100644
index 0000000..e4e87c6
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/map/MapUtils/SqlHelper.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *          notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *          notice, this list of conditions and the following disclaimer in the
+ *          documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *          the names of its contributors may be used to endorse or promote
+ *          products derived from this software without specific prior written
+ *          permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.map.MapUtils;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.util.Log;
+
+import org.codeaurora.bluetooth.map.BluetoothMasService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SqlHelper {
+    public static final String TAG = "SqlHelper";
+    public static final boolean V = BluetoothMasService.VERBOSE;
+    private static final String[] COUNT_COLUMNS = new String[]{"count(*)"};
+
+    /**
+     * Generic count method that can be used for any ContentProvider
+     * @param resolver the calling Context
+     * @param uri the Uri for the provider query
+     * @param selection as with a query call
+     * @param selectionArgs as with a query call
+     * @return the number of items matching the query (or zero)
+     */
+    public static int count(Context context, Uri uri, String selection, String[] selectionArgs) {
+        if (V) Log.v(TAG, "count(" + uri + ", " + selection + ", " + selectionArgs + ")");
+        int cnt = 0;
+        Cursor cursor = context.getContentResolver().query(uri,
+                COUNT_COLUMNS, selection, selectionArgs, null);
+        if (cursor != null) {
+            if (cursor.moveToFirst()) {
+                cnt = cursor.getInt(0);
+                if (V) Log.v(TAG, "count = " + cnt);
+            }
+            cursor.close();
+        }
+        return cnt;
+    }
+
+    /**
+     * Generic method to retrieve the first value for the column
+     * @param resolver the calling Context
+     * @param uri the Uri for the provider query
+     * @param columnName the column name to be retrieved
+     * @param selection as with a query call
+     * @param selectionArgs as with a query call
+     * @return the value first of that column
+     */
+    public static String getFirstValueForColumn(Context context, Uri uri,
+            String columnName, String selection, String[] selectionArgs) {
+        if (V) Log.v(TAG, "getFirstValueForColumn(" + uri + ", " + columnName +
+                ", " + selection + ", " + selectionArgs + ")");
+        String value = "";
+        Cursor cr = context.getContentResolver().query(uri, null, selection, selectionArgs, null);
+        if (cr != null) {
+            if (cr.moveToFirst()) {
+                value = cr.getString(cr.getColumnIndex(columnName));
+                if (V) Log.v(TAG, "value = " + value);
+            }
+            cr.close();
+        }
+        return value;
+    }
+
+    /**
+     * Generic method to retrieve the first value for the column
+     * @param resolver the calling Context
+     * @param uri the Uri for the provider query
+     * @param columnName the column name to be retrieved
+     * @param selection as with a query call
+     * @param selectionArgs as with a query call
+     * @return the value first of that column
+     */
+    public static int getFirstIntForColumn(Context context, Uri uri,
+            String columnName, String selection, String[] selectionArgs) {
+        if (V) Log.v(TAG, "getFirstIntForColumn(" + uri + ", " + columnName +
+                ", " + selection + ", " + selectionArgs + ")");
+        int value = -1;
+        Cursor cr = context.getContentResolver().query(uri, null, selection, selectionArgs, null);
+        if (cr != null) {
+            if (cr.moveToFirst()) {
+                value = cr.getInt(cr.getColumnIndex(columnName));
+                if (V) Log.v(TAG, "value = " + value);
+            }
+            cr.close();
+        }
+        return value;
+    }
+
+    /**
+     * Generic method to retrieve the list for the column
+     * @param resolver the calling Context's ContentResolver
+     * @param uri the Uri for the provider query
+     * @param columnName the column name to be retrieved
+     * @param selection as with a query call
+     * @param selectionArgs as with a query call
+     * @return the value first of that column
+     */
+    public static List<String> getListForColumn(Context context, Uri uri,
+            String columnName, String selection, String[] selectionArgs) {
+        ArrayList<String> list = new ArrayList<String>();
+        if (V) Log.v(TAG, "getListForColumn(" + uri + ", " + columnName + ", " +
+                selection + ", " + selectionArgs + ")");
+        Cursor cr = context.getContentResolver().query(uri, null, selection, selectionArgs, null);
+        if (cr != null) {
+            if (cr.moveToFirst()) {
+                final int columnIndex = cr.getColumnIndex(columnName);
+                do {
+                    final String value = cr.getString(columnIndex);
+                    list.add(value);
+                    if (V) Log.v(TAG, "adding: " + value);
+                } while (cr.moveToNext());
+            }
+            cr.close();
+        }
+        return list;
+    }
+}
