diff --git a/Android.mk b/Android.mk
index 7ae59ea..33c1115 100644
--- a/Android.mk
+++ b/Android.mk
@@ -2,9 +2,13 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := optional
+src_dirs:= src/org/codeaurora/bluetooth/btcservice \
+           src/org/codeaurora/bluetooth/map \
+           src/org/codeaurora/bluetooth/ftp \
+           src/org/codeaurora/bluetooth/sap
 
 LOCAL_SRC_FILES := \
-        $(call all-java-files-under, src)
+        $(call all-java-files-under, $(src_dirs))
 
 LOCAL_PACKAGE_NAME := BluetoothExt
 LOCAL_CERTIFICATE := platform
@@ -19,4 +23,18 @@
 
 include $(BUILD_PACKAGE)
 
+include $(CLEAR_VARS)
+
+src_dirs:=  src/org/codeaurora/bluetooth/mapclient
+
+LOCAL_SRC_FILES := \
+        $(call all-java-files-under, $(src_dirs))
+
+LOCAL_MODULE:= org.codeaurora.bluetooth.mapclient
+LOCAL_JAVA_LIBRARIES := javax.obex
+LOCAL_STATIC_JAVA_LIBRARIES := com.android.vcard
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMapBmessage.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapBmessage.java
new file mode 100644
index 0000000..eae2636
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapBmessage.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import com.android.vcard.VCardEntry;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+
+/**
+ * Object representation of message in bMessage format
+ * <p>
+ * This object will be received in {@link BluetoothMasClient#EVENT_GET_MESSAGE}
+ * callback message.
+ */
+public class BluetoothMapBmessage {
+
+    String mBmsgVersion;
+    Status mBmsgStatus;
+    Type mBmsgType;
+    String mBmsgFolder;
+
+    String mBbodyEncoding;
+    String mBbodyCharset;
+    String mBbodyLanguage;
+    int mBbodyLength;
+
+    String mMessage;
+
+    ArrayList<VCardEntry> mOriginators;
+    ArrayList<VCardEntry> mRecipients;
+
+    public enum Status {
+        READ, UNREAD
+    }
+
+    public enum Type {
+        EMAIL, SMS_GSM, SMS_CDMA, MMS
+    }
+
+    /**
+     * Constructs empty message object
+     */
+    public BluetoothMapBmessage() {
+        mOriginators = new ArrayList<VCardEntry>();
+        mRecipients = new ArrayList<VCardEntry>();
+    }
+
+    public VCardEntry getOriginator() {
+        if (mOriginators.size() > 0) {
+            return mOriginators.get(0);
+        } else {
+            return null;
+        }
+    }
+
+    public ArrayList<VCardEntry> getOriginators() {
+        return mOriginators;
+    }
+
+    public BluetoothMapBmessage addOriginator(VCardEntry vcard) {
+        mOriginators.add(vcard);
+        return this;
+    }
+
+    public ArrayList<VCardEntry> getRecipients() {
+        return mRecipients;
+    }
+
+    public BluetoothMapBmessage addRecipient(VCardEntry vcard) {
+        mRecipients.add(vcard);
+        return this;
+    }
+
+    public Status getStatus() {
+        return mBmsgStatus;
+    }
+
+    public BluetoothMapBmessage setStatus(Status status) {
+        mBmsgStatus = status;
+        return this;
+    }
+
+    public Type getType() {
+        return mBmsgType;
+    }
+
+    public BluetoothMapBmessage setType(Type type) {
+        mBmsgType = type;
+        return this;
+    }
+
+    public String getFolder() {
+        return mBmsgFolder;
+    }
+
+    public BluetoothMapBmessage setFolder(String folder) {
+        mBmsgFolder = folder;
+        return this;
+    }
+
+    public String getEncoding() {
+        return mBbodyEncoding;
+    }
+
+    public BluetoothMapBmessage setEncoding(String encoding) {
+        mBbodyEncoding = encoding;
+        return this;
+    }
+
+    public String getCharset() {
+        return mBbodyCharset;
+    }
+
+    public BluetoothMapBmessage setCharset(String charset) {
+        mBbodyCharset = charset;
+        return this;
+    }
+
+    public String getLanguage() {
+        return mBbodyLanguage;
+    }
+
+    public BluetoothMapBmessage setLanguage(String language) {
+        mBbodyLanguage = language;
+        return this;
+    }
+
+    public String getBodyContent() {
+        return mMessage;
+    }
+
+    public BluetoothMapBmessage setBodyContent(String body) {
+        mMessage = body;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        JSONObject json = new JSONObject();
+
+        try {
+            json.put("status", mBmsgStatus);
+            json.put("type", mBmsgType);
+            json.put("folder", mBmsgFolder);
+            json.put("message", mMessage);
+        } catch (JSONException e) {
+            // do nothing
+        }
+
+        return json.toString();
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMapBmessageBuilder.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapBmessageBuilder.java
new file mode 100644
index 0000000..b8683d0
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapBmessageBuilder.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 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.mapclient;
+import com.android.vcard.VCardEntry;
+import com.android.vcard.VCardEntry.EmailData;
+import com.android.vcard.VCardEntry.NameData;
+import com.android.vcard.VCardEntry.PhoneData;
+
+import java.util.List;
+
+class BluetoothMapBmessageBuilder {
+
+    private final static String CRLF = "\r\n";
+
+    private final static String BMSG_BEGIN = "BEGIN:BMSG";
+    private final static String BMSG_VERSION = "VERSION:1.0";
+    private final static String BMSG_STATUS = "STATUS:";
+    private final static String BMSG_TYPE = "TYPE:";
+    private final static String BMSG_FOLDER = "FOLDER:";
+    private final static String BMSG_END = "END:BMSG";
+
+    private final static String BENV_BEGIN = "BEGIN:BENV";
+    private final static String BENV_END = "END:BENV";
+
+    private final static String BBODY_BEGIN = "BEGIN:BBODY";
+    private final static String BBODY_ENCODING = "ENCODING:";
+    private final static String BBODY_CHARSET = "CHARSET:";
+    private final static String BBODY_LANGUAGE = "LANGUAGE:";
+    private final static String BBODY_LENGTH = "LENGTH:";
+    private final static String BBODY_END = "END:BBODY";
+
+    private final static String MSG_BEGIN = "BEGIN:MSG";
+    private final static String MSG_END = "END:MSG";
+
+    private final static String VCARD_BEGIN = "BEGIN:VCARD";
+    private final static String VCARD_VERSION = "VERSION:2.1";
+    private final static String VCARD_N = "N:";
+    private final static String VCARD_EMAIL = "EMAIL:";
+    private final static String VCARD_TEL = "TEL:";
+    private final static String VCARD_END = "END:VCARD";
+
+    private final StringBuilder mBmsg;
+
+    private BluetoothMapBmessageBuilder() {
+        mBmsg = new StringBuilder();
+    }
+
+    static public String createBmessage(BluetoothMapBmessage bmsg) {
+        BluetoothMapBmessageBuilder b = new BluetoothMapBmessageBuilder();
+
+        b.build(bmsg);
+
+        return b.mBmsg.toString();
+    }
+
+    private void build(BluetoothMapBmessage bmsg) {
+        int bodyLen = MSG_BEGIN.length() + MSG_END.length() + 3 * CRLF.length()
+                + bmsg.mMessage.getBytes().length;
+
+        mBmsg.append(BMSG_BEGIN).append(CRLF);
+
+        mBmsg.append(BMSG_VERSION).append(CRLF);
+        mBmsg.append(BMSG_STATUS).append(bmsg.mBmsgStatus).append(CRLF);
+        mBmsg.append(BMSG_TYPE).append(bmsg.mBmsgType).append(CRLF);
+        mBmsg.append(BMSG_FOLDER).append(bmsg.mBmsgFolder).append(CRLF);
+
+        for (VCardEntry vcard : bmsg.mOriginators) {
+            buildVcard(vcard);
+        }
+
+        {
+            mBmsg.append(BENV_BEGIN).append(CRLF);
+
+            for (VCardEntry vcard : bmsg.mRecipients) {
+                buildVcard(vcard);
+            }
+
+            {
+                mBmsg.append(BBODY_BEGIN).append(CRLF);
+
+                if (bmsg.mBbodyEncoding != null) {
+                    mBmsg.append(BBODY_ENCODING).append(bmsg.mBbodyEncoding).append(CRLF);
+                }
+
+                if (bmsg.mBbodyCharset != null) {
+                    mBmsg.append(BBODY_CHARSET).append(bmsg.mBbodyCharset).append(CRLF);
+                }
+
+                if (bmsg.mBbodyLanguage != null) {
+                    mBmsg.append(BBODY_LANGUAGE).append(bmsg.mBbodyLanguage).append(CRLF);
+                }
+
+                mBmsg.append(BBODY_LENGTH).append(bodyLen).append(CRLF);
+
+                {
+                    mBmsg.append(MSG_BEGIN).append(CRLF);
+
+                    mBmsg.append(bmsg.mMessage).append(CRLF);
+
+                    mBmsg.append(MSG_END).append(CRLF);
+                }
+
+                mBmsg.append(BBODY_END).append(CRLF);
+            }
+
+            mBmsg.append(BENV_END).append(CRLF);
+        }
+
+        mBmsg.append(BMSG_END).append(CRLF);
+    }
+
+    private void buildVcard(VCardEntry vcard) {
+        String n = buildVcardN(vcard);
+        List<PhoneData> tel = vcard.getPhoneList();
+        List<EmailData> email = vcard.getEmailList();
+
+        mBmsg.append(VCARD_BEGIN).append(CRLF);
+
+        mBmsg.append(VCARD_VERSION).append(CRLF);
+
+        mBmsg.append(VCARD_N).append(n).append(CRLF);
+
+        if (tel != null && tel.size() > 0) {
+            mBmsg.append(VCARD_TEL).append(tel.get(0).getNumber()).append(CRLF);
+        }
+
+        if (email != null && email.size() > 0) {
+            mBmsg.append(VCARD_EMAIL).append(email.get(0).getAddress()).append(CRLF);
+        }
+
+        mBmsg.append(VCARD_END).append(CRLF);
+    }
+
+    private String buildVcardN(VCardEntry vcard) {
+        NameData nd = vcard.getNameData();
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(nd.getFamily()).append(";");
+        sb.append(nd.getGiven() == null ? "" : nd.getGiven()).append(";");
+        sb.append(nd.getMiddle() == null ? "" : nd.getMiddle()).append(";");
+        sb.append(nd.getPrefix() == null ? "" : nd.getPrefix()).append(";");
+        sb.append(nd.getSuffix() == null ? "" : nd.getSuffix());
+
+        return sb.toString();
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMapBmessageParser.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapBmessageParser.java
new file mode 100644
index 0000000..2081ba8
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapBmessageParser.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import android.util.Log;
+
+import com.android.vcard.VCardEntry;
+import com.android.vcard.VCardEntryConstructor;
+import com.android.vcard.VCardEntryHandler;
+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 org.codeaurora.bluetooth.mapclient.BluetoothMapBmessage.Status;
+import org.codeaurora.bluetooth.mapclient.BluetoothMapBmessage.Type;
+import org.codeaurora.bluetooth.utils.BmsgTokenizer;
+import org.codeaurora.bluetooth.utils.BmsgTokenizer.Property;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.text.ParseException;
+
+class BluetoothMapBmessageParser {
+
+    private final static String TAG = "BluetoothMapBmessageParser";
+
+    private final static String CRLF = "\r\n";
+
+    private final static Property BEGIN_BMSG = new Property("BEGIN", "BMSG");
+    private final static Property END_BMSG = new Property("END", "BMSG");
+
+    private final static Property BEGIN_VCARD = new Property("BEGIN", "VCARD");
+    private final static Property END_VCARD = new Property("END", "VCARD");
+
+    private final static Property BEGIN_BENV = new Property("BEGIN", "BENV");
+    private final static Property END_BENV = new Property("END", "BENV");
+
+    private final static Property BEGIN_BBODY = new Property("BEGIN", "BBODY");
+    private final static Property END_BBODY = new Property("END", "BBODY");
+
+    private final static Property BEGIN_MSG = new Property("BEGIN", "MSG");
+    private final static Property END_MSG = new Property("END", "MSG");
+
+    private final static int CRLF_LEN = 2;
+
+    /*
+     * length of "container" for 'message' in bmessage-body-content:
+     * BEGIN:MSG<CRLF> + <CRLF> + END:MSG<CRFL>
+     */
+    private final static int MSG_CONTAINER_LEN = 22;
+
+    private BmsgTokenizer mParser;
+
+    private final BluetoothMapBmessage mBmsg;
+
+    private BluetoothMapBmessageParser() {
+        mBmsg = new BluetoothMapBmessage();
+    }
+
+    static public BluetoothMapBmessage createBmessage(String str) {
+        BluetoothMapBmessageParser p = new BluetoothMapBmessageParser();
+
+        try {
+            p.parse(str);
+        } catch (IOException e) {
+            Log.e(TAG, "I/O exception when parsing bMessage", e);
+            return null;
+        } catch (ParseException e) {
+            Log.e(TAG, "Cannot parse bMessage", e);
+            return null;
+        }
+
+        return p.mBmsg;
+    }
+
+    private ParseException expected(Property... props) {
+        boolean first = true;
+        StringBuilder sb = new StringBuilder();
+
+        for (Property prop : props) {
+            if (!first) {
+                sb.append(" or ");
+            }
+            sb.append(prop);
+            first = false;
+        }
+
+        return new ParseException("Expected: " + sb.toString(), mParser.pos());
+    }
+
+    private void parse(String str) throws IOException, ParseException {
+
+        Property prop;
+
+        /*
+         * <bmessage-object>::= { "BEGIN:BMSG" <CRLF> <bmessage-property>
+         * [<bmessage-originator>]* <bmessage-envelope> "END:BMSG" <CRLF> }
+         */
+
+        mParser = new BmsgTokenizer(str + CRLF);
+
+        prop = mParser.next();
+        if (!prop.equals(BEGIN_BMSG)) {
+            throw expected(BEGIN_BMSG);
+        }
+
+        prop = parseProperties();
+
+        while (prop.equals(BEGIN_VCARD)) {
+
+            /* <bmessage-originator>::= <vcard> <CRLF> */
+
+            StringBuilder vcard = new StringBuilder();
+            prop = extractVcard(vcard);
+
+            VCardEntry entry = parseVcard(vcard.toString());
+            mBmsg.mOriginators.add(entry);
+        }
+
+        if (!prop.equals(BEGIN_BENV)) {
+            throw expected(BEGIN_BENV);
+        }
+
+        prop = parseEnvelope(1);
+
+        if (!prop.equals(END_BMSG)) {
+            throw expected(END_BENV);
+        }
+
+        /*
+         * there should be no meaningful data left in stream here so we just
+         * ignore whatever is left
+         */
+
+        mParser = null;
+    }
+
+    private Property parseProperties() throws ParseException {
+
+        Property prop;
+
+        /*
+         * <bmessage-property>::=<bmessage-version-property>
+         * <bmessage-readstatus-property> <bmessage-type-property>
+         * <bmessage-folder-property> <bmessage-version-property>::="VERSION:"
+         * <common-digit>*"."<common-digit>* <CRLF>
+         * <bmessage-readstatus-property>::="STATUS:" 'readstatus' <CRLF>
+         * <bmessage-type-property>::="TYPE:" 'type' <CRLF>
+         * <bmessage-folder-property>::="FOLDER:" 'foldername' <CRLF>
+         */
+
+        do {
+            prop = mParser.next();
+
+            if (prop.name.equals("VERSION")) {
+                mBmsg.mBmsgVersion = prop.value;
+
+            } else if (prop.name.equals("STATUS")) {
+                for (Status s : Status.values()) {
+                    if (prop.value.equals(s.toString())) {
+                        mBmsg.mBmsgStatus = s;
+                        break;
+                    }
+                }
+
+            } else if (prop.name.equals("TYPE")) {
+                for (Type t : Type.values()) {
+                    if (prop.value.equals(t.toString())) {
+                        mBmsg.mBmsgType = t;
+                        break;
+                    }
+                }
+
+            } else if (prop.name.equals("FOLDER")) {
+                mBmsg.mBmsgFolder = prop.value;
+
+            }
+
+        } while (!prop.equals(BEGIN_VCARD) && !prop.equals(BEGIN_BENV));
+
+        return prop;
+    }
+
+    private Property parseEnvelope(int level) throws IOException, ParseException {
+
+        Property prop;
+
+        /*
+         * we can support as many nesting level as we want, but MAP spec clearly
+         * defines that there should be no more than 3 levels. so we verify it
+         * here.
+         */
+
+        if (level > 3) {
+            throw new ParseException("bEnvelope is nested more than 3 times", mParser.pos());
+        }
+
+        /*
+         * <bmessage-envelope> ::= { "BEGIN:BENV" <CRLF> [<bmessage-recipient>]*
+         * <bmessage-envelope> | <bmessage-content> "END:BENV" <CRLF> }
+         */
+
+        prop = mParser.next();
+
+        while (prop.equals(BEGIN_VCARD)) {
+
+            /* <bmessage-originator>::= <vcard> <CRLF> */
+
+            StringBuilder vcard = new StringBuilder();
+            prop = extractVcard(vcard);
+
+            if (level == 1) {
+                VCardEntry entry = parseVcard(vcard.toString());
+                mBmsg.mRecipients.add(entry);
+            }
+        }
+
+        if (prop.equals(BEGIN_BENV)) {
+            prop = parseEnvelope(level + 1);
+
+        } else if (prop.equals(BEGIN_BBODY)) {
+            prop = parseBody();
+
+        } else {
+            throw expected(BEGIN_BENV, BEGIN_BBODY);
+        }
+
+        if (!prop.equals(END_BENV)) {
+            throw expected(END_BENV);
+        }
+
+        return mParser.next();
+    }
+
+    private Property parseBody() throws IOException, ParseException {
+
+        Property prop;
+
+        /*
+         * <bmessage-content>::= { "BEGIN:BBODY"<CRLF> [<bmessage-body-part-ID>
+         * <CRLF>] <bmessage-body-property> <bmessage-body-content>* <CRLF>
+         * "END:BBODY"<CRLF> } <bmessage-body-part-ID>::="PARTID:" 'Part-ID'
+         * <bmessage-body-property>::=[<bmessage-body-encoding-property>]
+         * [<bmessage-body-charset-property>]
+         * [<bmessage-body-language-property>]
+         * <bmessage-body-content-length-property>
+         * <bmessage-body-encoding-property>::="ENCODING:"'encoding' <CRLF>
+         * <bmessage-body-charset-property>::="CHARSET:"'charset' <CRLF>
+         * <bmessage-body-language-property>::="LANGUAGE:"'language' <CRLF>
+         * <bmessage-body-content-length-property>::= "LENGTH:" <common-digit>*
+         * <CRLF>
+         */
+
+        do {
+            prop = mParser.next();
+
+            if (prop.name.equals("PARTID")) {
+            } else if (prop.name.equals("ENCODING")) {
+                mBmsg.mBbodyEncoding = prop.value;
+
+            } else if (prop.name.equals("CHARSET")) {
+                mBmsg.mBbodyCharset = prop.value;
+
+            } else if (prop.name.equals("LANGUAGE")) {
+                mBmsg.mBbodyLanguage = prop.value;
+
+            } else if (prop.name.equals("LENGTH")) {
+                try {
+                    mBmsg.mBbodyLength = Integer.valueOf(prop.value);
+                } catch (NumberFormatException e) {
+                    throw new ParseException("Invalid LENGTH value", mParser.pos());
+                }
+
+            }
+
+        } while (!prop.equals(BEGIN_MSG));
+
+        /*
+         * <bmessage-body-content>::={ "BEGIN:MSG"<CRLF> 'message'<CRLF>
+         * "END:MSG"<CRLF> }
+         */
+
+        int messageLen = mBmsg.mBbodyLength - MSG_CONTAINER_LEN;
+        int offset = messageLen + CRLF_LEN;
+        int restartPos = mParser.pos() + offset;
+
+        /*
+         * length is specified in bytes so we need to convert from unicode
+         * string back to bytes array
+         */
+
+        String remng = mParser.remaining();
+        byte[] data = remng.getBytes();
+
+        /* restart parsing from after 'message'<CRLF> */
+        mParser = new BmsgTokenizer(new String(data, offset, data.length - offset), restartPos);
+
+        prop = mParser.next(true);
+
+        if (prop != null && prop.equals(END_MSG)) {
+            mBmsg.mMessage = new String(data, 0, messageLen);
+        } else {
+
+            data = null;
+
+            /*
+             * now we check if bMessage can be parsed if LENGTH is handled as
+             * number of characters instead of number of bytes
+             */
+
+            Log.w(TAG, "byte LENGTH seems to be invalid, trying with char length");
+
+            mParser = new BmsgTokenizer(remng.substring(offset));
+
+            prop = mParser.next();
+
+            if (!prop.equals(END_MSG)) {
+                throw expected(END_MSG);
+            }
+
+            mBmsg.mMessage = remng.substring(0, messageLen);
+        }
+
+        prop = mParser.next();
+
+        if (!prop.equals(END_BBODY)) {
+            throw expected(END_BBODY);
+        }
+
+        return mParser.next();
+    }
+
+    private Property extractVcard(StringBuilder out) throws IOException, ParseException {
+        Property prop;
+
+        out.append(BEGIN_VCARD).append(CRLF);
+
+        do {
+            prop = mParser.next();
+            out.append(prop).append(CRLF);
+        } while (!prop.equals(END_VCARD));
+
+        return mParser.next();
+    }
+
+    private class VcardHandler implements VCardEntryHandler {
+
+        VCardEntry vcard;
+
+        @Override
+        public void onStart() {
+        }
+
+        @Override
+        public void onEntryCreated(VCardEntry entry) {
+            vcard = entry;
+        }
+
+        @Override
+        public void onEnd() {
+        }
+    };
+
+    private VCardEntry parseVcard(String str) throws IOException, ParseException {
+        VCardEntry vcard = null;
+
+        try {
+            VCardParser p = new VCardParser_V21();
+            VCardEntryConstructor c = new VCardEntryConstructor();
+            VcardHandler handler = new VcardHandler();
+            c.addEntryHandler(handler);
+            p.addInterpreter(c);
+            p.parse(new ByteArrayInputStream(str.getBytes()));
+
+            vcard = handler.vcard;
+
+        } catch (VCardVersionException e1) {
+
+            try {
+                VCardParser p = new VCardParser_V30();
+                VCardEntryConstructor c = new VCardEntryConstructor();
+                VcardHandler handler = new VcardHandler();
+                c.addEntryHandler(handler);
+                p.addInterpreter(c);
+                p.parse(new ByteArrayInputStream(str.getBytes()));
+
+                vcard = handler.vcard;
+
+            } catch (VCardVersionException e2) {
+                // will throw below
+            } catch (VCardException e2) {
+                // will throw below
+            }
+
+        } catch (VCardException e1) {
+            // will throw below
+        }
+
+        if (vcard == null) {
+            throw new ParseException("Cannot parse vCard object (neither 2.1 nor 3.0?)",
+                    mParser.pos());
+        }
+
+        return vcard;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMapEventReport.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapEventReport.java
new file mode 100644
index 0000000..bcc94b0
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapEventReport.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 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.mapclient;
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.HashMap;
+
+/**
+ * Object representation of event report received by MNS
+ * <p>
+ * This object will be received in {@link BluetoothMasClient#EVENT_EVENT_REPORT}
+ * callback message.
+ */
+public class BluetoothMapEventReport {
+
+    private final static String TAG = "BluetoothMapEventReport";
+
+    public enum Type {
+        NEW_MESSAGE("NewMessage"), DELIVERY_SUCCESS("DeliverySuccess"),
+        SENDING_SUCCESS("SendingSuccess"), DELIVERY_FAILURE("DeliveryFailure"),
+        SENDING_FAILURE("SendingFailure"), MEMORY_FULL("MemoryFull"),
+        MEMORY_AVAILABLE("MemoryAvailable"), MESSAGE_DELETED("MessageDeleted"),
+        MESSAGE_SHIFT("MessageShift");
+
+        private final String mSpecName;
+
+        private Type(String specName) {
+            mSpecName = specName;
+        }
+
+        @Override
+        public String toString() {
+            return mSpecName;
+        }
+    }
+
+    private final Type mType;
+
+    private final String mHandle;
+
+    private final String mFolder;
+
+    private final String mOldFolder;
+
+    private final BluetoothMapBmessage.Type mMsgType;
+
+    private BluetoothMapEventReport(HashMap<String, String> attrs) throws IllegalArgumentException {
+        mType = parseType(attrs.get("type"));
+
+        if (mType != Type.MEMORY_FULL && mType != Type.MEMORY_AVAILABLE) {
+            String handle = attrs.get("handle");
+            try {
+                /* just to validate */
+                new BigInteger(attrs.get("handle"), 16);
+
+                mHandle = attrs.get("handle");
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("Invalid value for handle:" + handle);
+            }
+        } else {
+            mHandle = null;
+        }
+
+        mFolder = attrs.get("folder");
+
+        mOldFolder = attrs.get("old_folder");
+
+        if (mType != Type.MEMORY_FULL && mType != Type.MEMORY_AVAILABLE) {
+            String s = attrs.get("msg_type");
+
+            if ("".equals(s)) {
+                // Some phones (e.g. SGS3 for MessageDeleted) send empty
+                // msg_type, in such case leave it as null rather than throw
+                // parse exception
+                mMsgType = null;
+            } else {
+                mMsgType = parseMsgType(s);
+            }
+        } else {
+            mMsgType = null;
+        }
+    }
+
+    private Type parseType(String type) throws IllegalArgumentException {
+        for (Type t : Type.values()) {
+            if (t.toString().equals(type)) {
+                return t;
+            }
+        }
+
+        throw new IllegalArgumentException("Invalid value for type: " + type);
+    }
+
+    private BluetoothMapBmessage.Type parseMsgType(String msgType) throws IllegalArgumentException {
+        for (BluetoothMapBmessage.Type t : BluetoothMapBmessage.Type.values()) {
+            if (t.name().equals(msgType)) {
+                return t;
+            }
+        }
+
+        throw new IllegalArgumentException("Invalid value for msg_type: " + msgType);
+    }
+
+    /**
+     * @return {@link BluetoothMapEventReport.Type} object corresponding to
+     *         <code>type</code> application parameter in MAP specification
+     */
+    public Type getType() {
+        return mType;
+    }
+
+    /**
+     * @return value corresponding to <code>handle</code> parameter in MAP
+     *         specification
+     */
+    public String getHandle() {
+        return mHandle;
+    }
+
+    /**
+     * @return value corresponding to <code>folder</code> parameter in MAP
+     *         specification
+     */
+    public String getFolder() {
+        return mFolder;
+    }
+
+    /**
+     * @return value corresponding to <code>old_folder</code> parameter in MAP
+     *         specification
+     */
+    public String getOldFolder() {
+        return mOldFolder;
+    }
+
+    /**
+     * @return {@link BluetoothMapBmessage.Type} object corresponding to
+     *         <code>msg_type</code> application parameter in MAP specification
+     */
+    public BluetoothMapBmessage.Type getMsgType() {
+        return mMsgType;
+    }
+
+    @Override
+    public String toString() {
+        JSONObject json = new JSONObject();
+
+        try {
+            json.put("type", mType);
+            json.put("handle", mHandle);
+            json.put("folder", mFolder);
+            json.put("old_folder", mOldFolder);
+            json.put("msg_type", mMsgType);
+        } catch (JSONException e) {
+            // do nothing
+        }
+
+        return json.toString();
+    }
+
+    static BluetoothMapEventReport fromStream(DataInputStream in) {
+        BluetoothMapEventReport ev = null;
+
+        try {
+            XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
+            xpp.setInput(in, "utf-8");
+
+            int event = xpp.getEventType();
+            while (event != XmlPullParser.END_DOCUMENT) {
+                switch (event) {
+                    case XmlPullParser.START_TAG:
+                        if (xpp.getName().equals("event")) {
+                            HashMap<String, String> attrs = new HashMap<String, String>();
+
+                            for (int i = 0; i < xpp.getAttributeCount(); i++) {
+                                attrs.put(xpp.getAttributeName(i), xpp.getAttributeValue(i));
+                            }
+
+                            ev = new BluetoothMapEventReport(attrs);
+
+                            // return immediately, only one event should be here
+                            return ev;
+                        }
+                        break;
+                }
+
+                event = xpp.next();
+            }
+
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "XML parser error when parsing XML", e);
+        } catch (IOException e) {
+            Log.e(TAG, "I/O error when parsing XML", e);
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Invalid event received", e);
+        }
+
+        return ev;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMapFolderListing.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapFolderListing.java
new file mode 100644
index 0000000..c2d531a
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapFolderListing.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 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.mapclient;
+import android.util.Log;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+class BluetoothMapFolderListing {
+
+    private static final String TAG = "BluetoothMasFolderListing";
+
+    private final ArrayList<String> mFolders;
+
+    public BluetoothMapFolderListing(InputStream in) {
+        mFolders = new ArrayList<String>();
+
+        parse(in);
+    }
+
+    public void parse(InputStream in) {
+
+        try {
+            XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
+            xpp.setInput(in, "utf-8");
+
+            int event = xpp.getEventType();
+            while (event != XmlPullParser.END_DOCUMENT) {
+                switch (event) {
+                    case XmlPullParser.START_TAG:
+                        if (xpp.getName().equals("folder")) {
+                            mFolders.add(xpp.getAttributeValue(null, "name"));
+                        }
+                        break;
+                }
+
+                event = xpp.next();
+            }
+
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "XML parser error when parsing XML", e);
+        } catch (IOException e) {
+            Log.e(TAG, "I/O error when parsing XML", e);
+        }
+    }
+
+    public ArrayList<String> getList() {
+        return mFolders;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMapMessage.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapMessage.java
new file mode 100644
index 0000000..05b2dd7
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapMessage.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 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.mapclient;
+import org.codeaurora.bluetooth.utils.ObexTime;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.HashMap;
+
+/**
+ * Object representation of message received in messages listing
+ * <p>
+ * This object will be received in
+ * {@link BluetoothMasClient#EVENT_GET_MESSAGES_LISTING} callback message.
+ */
+public class BluetoothMapMessage {
+
+    private final String mHandle;
+
+    private final String mSubject;
+
+    private final Date mDateTime;
+
+    private final String mSenderName;
+
+    private final String mSenderAddressing;
+
+    private final String mReplytoAddressing;
+
+    private final String mRecipientName;
+
+    private final String mRecipientAddressing;
+
+    private final Type mType;
+
+    private final int mSize;
+
+    private final boolean mText;
+
+    private final ReceptionStatus mReceptionStatus;
+
+    private final int mAttachmentSize;
+
+    private final boolean mPriority;
+
+    private final boolean mRead;
+
+    private final boolean mSent;
+
+    private final boolean mProtected;
+
+    public enum Type {
+        UNKNOWN, EMAIL, SMS_GSM, SMS_CDMA, MMS
+    };
+
+    public enum ReceptionStatus {
+        UNKNOWN, COMPLETE, FRACTIONED, NOTIFICATION
+    }
+
+    BluetoothMapMessage(HashMap<String, String> attrs) throws IllegalArgumentException {
+        int size;
+
+        try {
+            /* just to validate */
+            new BigInteger(attrs.get("handle"), 16);
+
+            mHandle = attrs.get("handle");
+        } catch (NumberFormatException e) {
+            /*
+             * handle MUST have proper value, if it does not then throw
+             * something here
+             */
+            throw new IllegalArgumentException(e);
+        }
+
+        mSubject = attrs.get("subject");
+
+        mDateTime = (new ObexTime(attrs.get("datetime"))).getTime();
+
+        mSenderName = attrs.get("sender_name");
+
+        mSenderAddressing = attrs.get("sender_addressing");
+
+        mReplytoAddressing = attrs.get("replyto_addressing");
+
+        mRecipientName = attrs.get("recipient_name");
+
+        mRecipientAddressing = attrs.get("recipient_addressing");
+
+        mType = strToType(attrs.get("type"));
+
+        try {
+            size = Integer.parseInt(attrs.get("size"));
+        } catch (NumberFormatException e) {
+            size = 0;
+        }
+
+        mSize = size;
+
+        mText = yesnoToBoolean(attrs.get("text"));
+
+        mReceptionStatus = strToReceptionStatus(attrs.get("reception_status"));
+
+        try {
+            size = Integer.parseInt(attrs.get("attachment_size"));
+        } catch (NumberFormatException e) {
+            size = 0;
+        }
+
+        mAttachmentSize = size;
+
+        mPriority = yesnoToBoolean(attrs.get("priority"));
+
+        mRead = yesnoToBoolean(attrs.get("read"));
+
+        mSent = yesnoToBoolean(attrs.get("sent"));
+
+        mProtected = yesnoToBoolean(attrs.get("protected"));
+    }
+
+    private boolean yesnoToBoolean(String yesno) {
+        return "yes".equals(yesno);
+    }
+
+    private Type strToType(String s) {
+        if ("EMAIL".equals(s)) {
+            return Type.EMAIL;
+        } else if ("SMS_GSM".equals(s)) {
+            return Type.SMS_GSM;
+        } else if ("SMS_CDMA".equals(s)) {
+            return Type.SMS_CDMA;
+        } else if ("MMS".equals(s)) {
+            return Type.MMS;
+        }
+
+        return Type.UNKNOWN;
+    }
+
+    private ReceptionStatus strToReceptionStatus(String s) {
+        if ("complete".equals(s)) {
+            return ReceptionStatus.COMPLETE;
+        } else if ("fractioned".equals(s)) {
+            return ReceptionStatus.FRACTIONED;
+        } else if ("notification".equals(s)) {
+            return ReceptionStatus.NOTIFICATION;
+        }
+
+        return ReceptionStatus.UNKNOWN;
+    }
+
+    @Override
+    public String toString() {
+        JSONObject json = new JSONObject();
+
+        try {
+            json.put("handle", mHandle);
+            json.put("subject", mSubject);
+            json.put("datetime", mDateTime);
+            json.put("sender_name", mSenderName);
+            json.put("sender_addressing", mSenderAddressing);
+            json.put("replyto_addressing", mReplytoAddressing);
+            json.put("recipient_name", mRecipientName);
+            json.put("recipient_addressing", mRecipientAddressing);
+            json.put("type", mType);
+            json.put("size", mSize);
+            json.put("text", mText);
+            json.put("reception_status", mReceptionStatus);
+            json.put("attachment_size", mAttachmentSize);
+            json.put("priority", mPriority);
+            json.put("read", mRead);
+            json.put("sent", mSent);
+            json.put("protected", mProtected);
+        } catch (JSONException e) {
+            // do nothing
+        }
+
+        return json.toString();
+    }
+
+    /**
+     * @return value corresponding to <code>handle</code> parameter in MAP
+     *         specification
+     */
+    public String getHandle() {
+        return mHandle;
+    }
+
+    /**
+     * @return value corresponding to <code>subject</code> parameter in MAP
+     *         specification
+     */
+    public String getSubject() {
+        return mSubject;
+    }
+
+    /**
+     * @return <code>Date</code> object corresponding to <code>datetime</code>
+     *         parameter in MAP specification
+     */
+    public Date getDateTime() {
+        return mDateTime;
+    }
+
+    /**
+     * @return value corresponding to <code>sender_name</code> parameter in MAP
+     *         specification
+     */
+    public String getSenderName() {
+        return mSenderName;
+    }
+
+    /**
+     * @return value corresponding to <code>sender_addressing</code> parameter
+     *         in MAP specification
+     */
+    public String getSenderAddressing() {
+        return mSenderAddressing;
+    }
+
+    /**
+     * @return value corresponding to <code>replyto_addressing</code> parameter
+     *         in MAP specification
+     */
+    public String getReplytoAddressing() {
+        return mReplytoAddressing;
+    }
+
+    /**
+     * @return value corresponding to <code>recipient_name</code> parameter in
+     *         MAP specification
+     */
+    public String getRecipientName() {
+        return mRecipientName;
+    }
+
+    /**
+     * @return value corresponding to <code>recipient_addressing</code>
+     *         parameter in MAP specification
+     */
+    public String getRecipientAddressing() {
+        return mRecipientAddressing;
+    }
+
+    /**
+     * @return {@link Type} object corresponding to <code>type</code> parameter
+     *         in MAP specification
+     */
+    public Type getType() {
+        return mType;
+    }
+
+    /**
+     * @return value corresponding to <code>size</code> parameter in MAP
+     *         specification
+     */
+    public int getSize() {
+        return mSize;
+    }
+
+    /**
+     * @return {@link .ReceptionStatus} object corresponding to
+     *         <code>reception_status</code> parameter in MAP specification
+     */
+    public ReceptionStatus getReceptionStatus() {
+        return mReceptionStatus;
+    }
+
+    /**
+     * @return value corresponding to <code>attachment_size</code> parameter in
+     *         MAP specification
+     */
+    public int getAttachmentSize() {
+        return mAttachmentSize;
+    }
+
+    /**
+     * @return value corresponding to <code>text</code> parameter in MAP
+     *         specification
+     */
+    public boolean isText() {
+        return mText;
+    }
+
+    /**
+     * @return value corresponding to <code>priority</code> parameter in MAP
+     *         specification
+     */
+    public boolean isPriority() {
+        return mPriority;
+    }
+
+    /**
+     * @return value corresponding to <code>read</code> parameter in MAP
+     *         specification
+     */
+    public boolean isRead() {
+        return mRead;
+    }
+
+    /**
+     * @return value corresponding to <code>sent</code> parameter in MAP
+     *         specification
+     */
+    public boolean isSent() {
+        return mSent;
+    }
+
+    /**
+     * @return value corresponding to <code>protected</code> parameter in MAP
+     *         specification
+     */
+    public boolean isProtected() {
+        return mProtected;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMapMessagesListing.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapMessagesListing.java
new file mode 100644
index 0000000..e895dcc
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapMessagesListing.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import android.util.Log;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+class BluetoothMapMessagesListing {
+
+    private static final String TAG = "BluetoothMapMessagesListing";
+
+    private final ArrayList<BluetoothMapMessage> mMessages;
+
+    public BluetoothMapMessagesListing(InputStream in) {
+        mMessages = new ArrayList<BluetoothMapMessage>();
+
+        parse(in);
+    }
+
+    public void parse(InputStream in) {
+
+        try {
+            XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
+            xpp.setInput(in, "utf-8");
+
+            int event = xpp.getEventType();
+            while (event != XmlPullParser.END_DOCUMENT) {
+                switch (event) {
+                    case XmlPullParser.START_TAG:
+                        if (xpp.getName().equals("msg")) {
+
+                            HashMap<String, String> attrs = new HashMap<String, String>();
+
+                            for (int i = 0; i < xpp.getAttributeCount(); i++) {
+                                attrs.put(xpp.getAttributeName(i), xpp.getAttributeValue(i));
+                            }
+
+                            try {
+                                BluetoothMapMessage msg = new BluetoothMapMessage(attrs);
+                                mMessages.add(msg);
+                            } catch (IllegalArgumentException e) {
+                                /* TODO: provide something more useful here */
+                                Log.w(TAG, "Invalid <msg/>");
+                            }
+                        }
+                        break;
+                }
+
+                event = xpp.next();
+            }
+
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "XML parser error when parsing XML", e);
+        } catch (IOException e) {
+            Log.e(TAG, "I/O error when parsing XML", e);
+        }
+    }
+
+    public ArrayList<BluetoothMapMessage> getList() {
+        return mMessages;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMapRfcommTransport.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapRfcommTransport.java
new file mode 100644
index 0000000..8cc62a0
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMapRfcommTransport.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+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;
+
+class BluetoothMapRfcommTransport implements ObexTransport {
+    private final BluetoothSocket mSocket;
+
+    public BluetoothMapRfcommTransport(BluetoothSocket socket) {
+        super();
+        mSocket = socket;
+    }
+
+    @Override
+    public void create() throws IOException {
+    }
+
+    @Override
+    public void listen() throws IOException {
+    }
+
+    @Override
+    public void close() throws IOException {
+        mSocket.close();
+    }
+
+    @Override
+    public void connect() throws IOException {
+    }
+
+    @Override
+    public void disconnect() throws IOException {
+    }
+
+    @Override
+    public InputStream openInputStream() throws IOException {
+        return mSocket.getInputStream();
+    }
+
+    @Override
+    public OutputStream openOutputStream() throws IOException {
+        return mSocket.getOutputStream();
+    }
+
+    @Override
+    public DataInputStream openDataInputStream() throws IOException {
+        return new DataInputStream(openInputStream());
+    }
+
+    @Override
+    public DataOutputStream openDataOutputStream() throws IOException {
+        return new DataOutputStream(openOutputStream());
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasClient.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasClient.java
new file mode 100644
index 0000000..5d4ec2f
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasClient.java
@@ -0,0 +1,1114 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothMasInstance;
+import android.bluetooth.BluetoothSocket;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import org.codeaurora.bluetooth.mapclient.BluetoothMasRequestSetMessageStatus.StatusIndicator;
+import org.codeaurora.bluetooth.utils.ObexTime;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.math.BigInteger;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+
+import javax.obex.ObexTransport;
+
+public class BluetoothMasClient {
+
+    private final static String TAG = "BluetoothMasClient";
+
+    private static final int SOCKET_CONNECTED = 10;
+
+    private static final int SOCKET_ERROR = 11;
+
+    /**
+     * Callback message sent when connection state changes
+     * <p>
+     * <code>arg1</code> is set to {@link #STATUS_OK} when connection is
+     * established successfully and {@link #STATUS_FAILED} when connection
+     * either failed or was disconnected (depends on request from application)
+     *
+     * @see #connect()
+     * @see #disconnect()
+     */
+    public static final int EVENT_CONNECT = 1;
+
+    /**
+     * Callback message sent when MSE accepted update inbox request
+     *
+     * @see #updateInbox()
+     */
+    public static final int EVENT_UPDATE_INBOX = 2;
+
+    /**
+     * Callback message sent when path is changed
+     * <p>
+     * <code>obj</code> is set to path currently set on MSE
+     *
+     * @see #setFolderRoot()
+     * @see #setFolderUp()
+     * @see #setFolderDown(String)
+     */
+    public static final int EVENT_SET_PATH = 3;
+
+    /**
+     * Callback message sent when folder listing is received
+     * <p>
+     * <code>obj</code> contains ArrayList of sub-folder names
+     *
+     * @see #getFolderListing()
+     * @see #getFolderListing(int, int)
+     */
+    public static final int EVENT_GET_FOLDER_LISTING = 4;
+
+    /**
+     * Callback message sent when folder listing size is received
+     * <p>
+     * <code>obj</code> contains number of items in folder listing
+     *
+     * @see #getFolderListingSize()
+     */
+    public static final int EVENT_GET_FOLDER_LISTING_SIZE = 5;
+
+    /**
+     * Callback message sent when messages listing is received
+     * <p>
+     * <code>obj</code> contains ArrayList of {@link BluetoothMapBmessage}
+     *
+     * @see #getMessagesListing(String, int)
+     * @see #getMessagesListing(String, int, MessagesFilter, int)
+     * @see #getMessagesListing(String, int, MessagesFilter, int, int, int)
+     */
+    public static final int EVENT_GET_MESSAGES_LISTING = 6;
+
+    /**
+     * Callback message sent when message is received
+     * <p>
+     * <code>obj</code> contains {@link BluetoothMapBmessage}
+     *
+     * @see #getMessage(String, CharsetType, boolean)
+     */
+    public static final int EVENT_GET_MESSAGE = 7;
+
+    /**
+     * Callback message sent when message status is changed
+     *
+     * @see #setMessageDeletedStatus(String, boolean)
+     * @see #setMessageReadStatus(String, boolean)
+     */
+    public static final int EVENT_SET_MESSAGE_STATUS = 8;
+
+    /**
+     * Callback message sent when message is pushed to MSE
+     * <p>
+     * <code>obj</code> contains handle of message as allocated by MSE
+     *
+     * @see #pushMessage(String, BluetoothMapBmessage, CharsetType)
+     * @see #pushMessage(String, BluetoothMapBmessage, CharsetType, boolean,
+     *      boolean)
+     */
+    public static final int EVENT_PUSH_MESSAGE = 9;
+
+    /**
+     * Callback message sent when notification status is changed
+     * <p>
+     * <code>obj</code> contains <code>1</code> if notifications are enabled and
+     * <code>0</code> otherwise
+     *
+     * @see #setNotificationRegistration(boolean)
+     */
+    public static final int EVENT_SET_NOTIFICATION_REGISTRATION = 10;
+
+    /**
+     * Callback message sent when event report is received from MSE to MNS
+     * <p>
+     * <code>obj</code> contains {@link BluetoothMapEventReport}
+     *
+     * @see #setNotificationRegistration(boolean)
+     */
+    public static final int EVENT_EVENT_REPORT = 11;
+
+    /**
+     * Callback message sent when messages listing size is received
+     * <p>
+     * <code>obj</code> contains number of items in messages listing
+     *
+     * @see #getMessagesListingSize()
+     */
+    public static final int EVENT_GET_MESSAGES_LISTING_SIZE = 12;
+
+    /**
+     * Status for callback message when request is successful
+     */
+    public static final int STATUS_OK = 0;
+
+    /**
+     * Status for callback message when request is not successful
+     */
+    public static final int STATUS_FAILED = 1;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_DEFAULT = 0x00000000;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_SUBJECT = 0x00000001;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_DATETIME = 0x00000002;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_SENDER_NAME = 0x00000004;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_SENDER_ADDRESSING = 0x00000008;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_RECIPIENT_NAME = 0x00000010;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_RECIPIENT_ADDRESSING = 0x00000020;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_TYPE = 0x00000040;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_SIZE = 0x00000080;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_RECEPTION_STATUS = 0x00000100;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_TEXT = 0x00000200;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_ATTACHMENT_SIZE = 0x00000400;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_PRIORITY = 0x00000800;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_READ = 0x00001000;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_SENT = 0x00002000;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_PROTECTED = 0x00004000;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_REPLYTO_ADDRESSING = 0x00008000;
+
+    public enum ConnectionState {
+        DISCONNECTED, CONNECTING, CONNECTED, DISCONNECTING;
+    }
+
+    public enum CharsetType {
+        NATIVE, UTF_8;
+    }
+
+    /** device associated with client */
+    private final BluetoothDevice mDevice;
+
+    /** MAS instance associated with client */
+    private final BluetoothMasInstance mMas;
+
+    /** callback handler to application */
+    private final Handler mCallback;
+
+    private ConnectionState mConnectionState = ConnectionState.DISCONNECTED;
+
+    private boolean mNotificationEnabled = false;
+
+    private SocketConnectThread mConnectThread = null;
+
+    private ObexTransport mObexTransport = null;
+
+    private BluetoothMasObexClientSession mObexSession = null;
+
+    private SessionHandler mSessionHandler = null;
+
+    private BluetoothMnsService mMnsService = null;
+
+    private ArrayDeque<String> mPath = null;
+
+    private static class SessionHandler extends Handler {
+
+        private final WeakReference<BluetoothMasClient> mClient;
+
+        public SessionHandler(BluetoothMasClient client) {
+            super();
+
+            mClient = new WeakReference<BluetoothMasClient>(client);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+
+            BluetoothMasClient client = mClient.get();
+            if (client == null) {
+                return;
+            }
+            Log.v(TAG, "handleMessage  "+msg.what);
+
+            switch (msg.what) {
+                case SOCKET_ERROR:
+                    client.mConnectThread = null;
+                    client.sendToClient(EVENT_CONNECT, false);
+                    break;
+
+                case SOCKET_CONNECTED:
+                    client.mConnectThread = null;
+
+                    client.mObexTransport = (ObexTransport) msg.obj;
+
+                    client.mObexSession = new BluetoothMasObexClientSession(client.mObexTransport,
+                            client.mSessionHandler);
+                    client.mObexSession.start();
+                    break;
+
+                case BluetoothMasObexClientSession.MSG_OBEX_CONNECTED:
+                    client.mPath.clear(); // we're in root after connected
+                    client.mConnectionState = ConnectionState.CONNECTED;
+                    client.sendToClient(EVENT_CONNECT, true);
+                    break;
+
+                case BluetoothMasObexClientSession.MSG_OBEX_DISCONNECTED:
+                    client.mConnectionState = ConnectionState.DISCONNECTED;
+                    client.mNotificationEnabled = false;
+                    client.mObexSession = null;
+                    client.sendToClient(EVENT_CONNECT, false);
+                    break;
+
+                case BluetoothMasObexClientSession.MSG_REQUEST_COMPLETED:
+                    BluetoothMasRequest request = (BluetoothMasRequest) msg.obj;
+                    int status = request.isSuccess() ? STATUS_OK : STATUS_FAILED;
+
+                    Log.v(TAG, "MSG_REQUEST_COMPLETED (" + status + ") for "
+                            + request.getClass().getName());
+
+                    if (request instanceof BluetoothMasRequestUpdateInbox) {
+                        client.sendToClient(EVENT_UPDATE_INBOX, request.isSuccess());
+
+                    } else if (request instanceof BluetoothMasRequestSetPath) {
+                        if (request.isSuccess()) {
+                            BluetoothMasRequestSetPath req = (BluetoothMasRequestSetPath) request;
+                            switch (req.mDir) {
+                                case UP:
+                                    if (client.mPath.size() > 0) {
+                                        client.mPath.removeLast();
+                                    }
+                                    break;
+
+                                case ROOT:
+                                    client.mPath.clear();
+                                    break;
+
+                                case DOWN:
+                                    client.mPath.addLast(req.mName);
+                                    break;
+                            }
+                        }
+
+                        client.sendToClient(EVENT_SET_PATH, request.isSuccess(),
+                                client.getCurrentPath());
+
+                    } else if (request instanceof BluetoothMasRequestGetFolderListing) {
+                        BluetoothMasRequestGetFolderListing req = (BluetoothMasRequestGetFolderListing) request;
+                        ArrayList<String> folders = req.getList();
+
+                        client.sendToClient(EVENT_GET_FOLDER_LISTING, request.isSuccess(), folders);
+
+                    } else if (request instanceof BluetoothMasRequestGetFolderListingSize) {
+                        int size = ((BluetoothMasRequestGetFolderListingSize) request).getSize();
+
+                        client.sendToClient(EVENT_GET_FOLDER_LISTING_SIZE, request.isSuccess(),
+                                size);
+
+                    } else if (request instanceof BluetoothMasRequestGetMessagesListing) {
+                        BluetoothMasRequestGetMessagesListing req = (BluetoothMasRequestGetMessagesListing) request;
+                        ArrayList<BluetoothMapMessage> msgs = req.getList();
+
+                        client.sendToClient(EVENT_GET_MESSAGES_LISTING, request.isSuccess(), msgs);
+
+                    } else if (request instanceof BluetoothMasRequestGetMessage) {
+                        BluetoothMasRequestGetMessage req = (BluetoothMasRequestGetMessage) request;
+                        BluetoothMapBmessage bmsg = req.getMessage();
+
+                        client.sendToClient(EVENT_GET_MESSAGE, request.isSuccess(), bmsg);
+
+                    } else if (request instanceof BluetoothMasRequestSetMessageStatus) {
+                        client.sendToClient(EVENT_SET_MESSAGE_STATUS, request.isSuccess());
+
+                    } else if (request instanceof BluetoothMasRequestPushMessage) {
+                        BluetoothMasRequestPushMessage req = (BluetoothMasRequestPushMessage) request;
+                        String handle = req.getMsgHandle();
+
+                        client.sendToClient(EVENT_PUSH_MESSAGE, request.isSuccess(), handle);
+
+                    } else if (request instanceof BluetoothMasRequestSetNotificationRegistration) {
+                        BluetoothMasRequestSetNotificationRegistration req = (BluetoothMasRequestSetNotificationRegistration) request;
+
+                        client.mNotificationEnabled = req.isSuccess() ? req.getStatus()
+                                : client.mNotificationEnabled;
+
+                        client.sendToClient(EVENT_SET_NOTIFICATION_REGISTRATION,
+                                request.isSuccess(),
+                                client.mNotificationEnabled ? 1 : 0);
+                    } else if (request instanceof BluetoothMasRequestGetMessagesListingSize) {
+                        int size = ((BluetoothMasRequestGetMessagesListingSize) request).getSize();
+                        client.sendToClient(EVENT_GET_MESSAGES_LISTING_SIZE, request.isSuccess(),
+                                size);
+                    }
+                    break;
+
+                case BluetoothMnsService.EVENT_REPORT:
+                    /* pass event report directly to app */
+                    client.sendToClient(EVENT_EVENT_REPORT, true, msg.obj);
+                    break;
+            }
+        }
+    }
+
+    private void sendToClient(int event, boolean success) {
+        sendToClient(event, success, null);
+    }
+
+    private void sendToClient(int event, boolean success, int param) {
+        sendToClient(event, success, Integer.valueOf(param));
+    }
+
+    private void sendToClient(int event, boolean success, Object param) {
+        if (success) {
+            mCallback.obtainMessage(event, STATUS_OK, mMas.getId(), param).sendToTarget();
+        } else {
+            mCallback.obtainMessage(event, STATUS_FAILED, mMas.getId(), null).sendToTarget();
+        }
+    }
+
+    private class SocketConnectThread extends Thread {
+        private BluetoothSocket socket = null;
+
+        public SocketConnectThread() {
+            super("SocketConnectThread");
+        }
+
+        @Override
+        public void run() {
+            try {
+                socket = mDevice.createRfcommSocket(mMas.getChannel());
+                socket.connect();
+
+                BluetoothMapRfcommTransport transport;
+                transport = new BluetoothMapRfcommTransport(socket);
+
+                mSessionHandler.obtainMessage(SOCKET_CONNECTED, transport).sendToTarget();
+            } catch (IOException e) {
+                Log.e(TAG, "Error when creating/connecting socket", e);
+
+                closeSocket();
+                mSessionHandler.obtainMessage(SOCKET_ERROR).sendToTarget();
+            }
+        }
+
+        @Override
+        public void interrupt() {
+            closeSocket();
+        }
+
+        private void closeSocket() {
+            try {
+                if (socket != null) {
+                    socket.close();
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error when closing socket", e);
+            }
+        }
+    }
+
+    /**
+     * Object representation of filters to be applied on message listing
+     *
+     * @see #getMessagesListing(String, int, MessagesFilter, int)
+     * @see #getMessagesListing(String, int, MessagesFilter, int, int, int)
+     */
+    public static final class MessagesFilter {
+
+        public final static byte MESSAGE_TYPE_ALL = 0x00;
+        public final static byte MESSAGE_TYPE_SMS_GSM = 0x01;
+        public final static byte MESSAGE_TYPE_SMS_CDMA = 0x02;
+        public final static byte MESSAGE_TYPE_EMAIL = 0x04;
+        public final static byte MESSAGE_TYPE_MMS = 0x08;
+
+        public final static byte READ_STATUS_ANY = 0x00;
+        public final static byte READ_STATUS_UNREAD = 0x01;
+        public final static byte READ_STATUS_READ = 0x02;
+
+        public final static byte PRIORITY_ANY = 0x00;
+        public final static byte PRIORITY_HIGH = 0x01;
+        public final static byte PRIORITY_NON_HIGH = 0x02;
+
+        byte messageType = MESSAGE_TYPE_ALL;
+
+        String periodBegin = null;
+
+        String periodEnd = null;
+
+        byte readStatus = READ_STATUS_ANY;
+
+        String recipient = null;
+
+        String originator = null;
+
+        byte priority = PRIORITY_ANY;
+
+        public MessagesFilter() {
+        }
+
+        public void setMessageType(byte filter) {
+            messageType = filter;
+        }
+
+        public void setPeriod(Date filterBegin, Date filterEnd) {
+            periodBegin = (new ObexTime(filterBegin)).toString();
+            periodEnd = (new ObexTime(filterEnd)).toString();
+        }
+
+        public void setReadStatus(byte readfilter) {
+            readStatus = readfilter;
+        }
+
+        public void setRecipient(String filter) {
+            if ("".equals(filter)) {
+                recipient = null;
+            } else {
+                recipient = filter;
+            }
+        }
+
+        public void setOriginator(String filter) {
+            if ("".equals(filter)) {
+                originator = null;
+            } else {
+                originator = filter;
+            }
+        }
+
+        public void setPriority(byte filter) {
+            priority = filter;
+        }
+    }
+
+    /**
+     * Constructs client object to communicate with single MAS instance on MSE
+     *
+     * @param device {@link BluetoothDevice} corresponding to remote device
+     *            acting as MSE
+     * @param mas {@link BluetoothMasInstance} object describing MAS instance on
+     *            remote device
+     * @param callback {@link Handler} object to which callback messages will be
+     *            sent Each message will have <code>arg1</code> set to either
+     *            {@link #STATUS_OK} or {@link #STATUS_FAILED} and
+     *            <code>arg2</code> to MAS instance ID. <code>obj</code> in
+     *            message is event specific.
+     */
+    public BluetoothMasClient(BluetoothDevice device, BluetoothMasInstance mas,
+            Handler callback) {
+        mDevice = device;
+        mMas = mas;
+        mCallback = callback;
+
+        mPath = new ArrayDeque<String>();
+    }
+
+    /**
+     * Retrieves MAS instance data associated with client
+     *
+     * @return instance data object
+     */
+    public BluetoothMasInstance getInstanceData() {
+        return mMas;
+    }
+
+    /**
+     * Connects to MAS instance
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_CONNECT}
+     */
+    public void connect() {
+        if (mSessionHandler == null) {
+            mSessionHandler = new SessionHandler(this);
+        }
+
+        if (mConnectThread == null && mObexSession == null) {
+            mConnectionState = ConnectionState.CONNECTING;
+
+            mConnectThread = new SocketConnectThread();
+            mConnectThread.start();
+        }
+    }
+
+    /**
+     * Disconnects from MAS instance
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_CONNECT}
+     */
+    public void disconnect() {
+        if (mConnectThread == null && mObexSession == null) {
+            return;
+        }
+
+        mConnectionState = ConnectionState.DISCONNECTING;
+
+        if (mConnectThread != null) {
+            mConnectThread.interrupt();
+        }
+
+        if (mObexSession != null) {
+            mObexSession.stop();
+        }
+    }
+
+    @Override
+    public void finalize() {
+        disconnect();
+    }
+
+    /**
+     * Gets current connection state
+     *
+     * @return current connection state
+     * @see ConnectionState
+     */
+    public ConnectionState getState() {
+        return mConnectionState;
+    }
+
+    private boolean enableNotifications() {
+        Log.v(TAG, "enableNotifications()");
+
+        if (mMnsService == null) {
+            mMnsService = new BluetoothMnsService();
+        }
+
+        mMnsService.registerCallback(mMas.getId(), mSessionHandler);
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetNotificationRegistration(true);
+        return mObexSession.makeRequest(request);
+    }
+
+    private boolean disableNotifications() {
+        Log.v(TAG, "enableNotifications()");
+
+        if (mMnsService != null) {
+            mMnsService.unregisterCallback(mMas.getId());
+        }
+
+        mMnsService = null;
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetNotificationRegistration(false);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Sets state of notifications for MAS instance
+     * <p>
+     * Once notifications are enabled, callback handler will receive
+     * {@link #EVENT_EVENT_REPORT} when new notification is received
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_SET_NOTIFICATION_REGISTRATION}
+     *
+     * @param status <code>true</code> if notifications shall be enabled,
+     *            <code>false</code> otherwise
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setNotificationRegistration(boolean status) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        if (status) {
+            return enableNotifications();
+        } else {
+            return disableNotifications();
+        }
+    }
+
+    /**
+     * Gets current state of notifications for MAS instance
+     *
+     * @return <code>true</code> if notifications are enabled,
+     *         <code>false</code> otherwise
+     */
+    public boolean getNotificationRegistration() {
+        return mNotificationEnabled;
+    }
+
+    /**
+     * Goes back to root of folder hierarchy
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_SET_PATH}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setFolderRoot() {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetPath(true);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Goes back to parent folder in folder hierarchy
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_SET_PATH}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setFolderUp() {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetPath(false);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Goes down to specified sub-folder in folder hierarchy
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_SET_PATH}
+     *
+     * @param name name of sub-folder
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setFolderDown(String name) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        if (name == null || name.isEmpty() || name.contains("/")) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetPath(name);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Gets current path in folder hierarchy
+     *
+     * @return current path
+     */
+    public String getCurrentPath() {
+        if (mPath.size() == 0) {
+            return "";
+        }
+
+        Iterator<String> iter = mPath.iterator();
+
+        StringBuilder sb = new StringBuilder(iter.next());
+
+        while (iter.hasNext()) {
+            sb.append("/").append(iter.next());
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Gets list of sub-folders in current folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_FOLDER_LISTING}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean getFolderListing() {
+        return getFolderListing((short) 0, (short) 0);
+    }
+
+    /**
+     * Gets list of sub-folders in current folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_FOLDER_LISTING}
+     *
+     * @param maxListCount maximum number of items returned or <code>0</code>
+     *            for default value
+     * @param listStartOffset index of first item returned or <code>0</code> for
+     *            default value
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     * @throws IllegalArgumentException if either maxListCount or
+     *             listStartOffset are outside allowed range [0..65535]
+     */
+    public boolean getFolderListing(int maxListCount, int listStartOffset) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestGetFolderListing(maxListCount,
+                listStartOffset);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Gets number of sub-folders in current folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_FOLDER_LISTING_SIZE}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean getFolderListingSize() {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestGetFolderListingSize();
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Gets list of messages in specified sub-folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_MESSAGES_LISTING}
+     *
+     * @param folder name of sub-folder or <code>null</code> for current folder
+     * @param parameters bit-mask specifying requested parameters in listing or
+     *            <code>0</code> for default value
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean getMessagesListing(String folder, int parameters) {
+        return getMessagesListing(folder, parameters, null, (byte) 0, 0, 0);
+    }
+
+    /**
+     * Gets list of messages in specified sub-folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_MESSAGES_LISTING}
+     *
+     * @param folder name of sub-folder or <code>null</code> for current folder
+     * @param parameters corresponds to <code>ParameterMask</code> application
+     *            parameter in MAP specification
+     * @param filter {@link MessagesFilter} object describing filters to be
+     *            applied on listing by MSE
+     * @param subjectLength maximum length of message subject in returned
+     *            listing or <code>0</code> for default value
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     * @throws IllegalArgumentException if subjectLength is outside allowed
+     *             range [0..255]
+     */
+    public boolean getMessagesListing(String folder, int parameters, MessagesFilter filter,
+            int subjectLength) {
+
+        return getMessagesListing(folder, parameters, filter, subjectLength, 0, 0);
+    }
+
+    /**
+     * Gets list of messages in specified sub-folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_MESSAGES_LISTING}
+     *
+     * @param folder name of sub-folder or <code>null</code> for current folder
+     * @param parameters corresponds to <code>ParameterMask</code> application
+     *            parameter in MAP specification
+     * @param filter {@link MessagesFilter} object describing filters to be
+     *            applied on listing by MSE
+     * @param subjectLength maximum length of message subject in returned
+     *            listing or <code>0</code> for default value
+     * @param maxListCount maximum number of items returned or <code>0</code>
+     *            for default value
+     * @param listStartOffset index of first item returned or <code>0</code> for
+     *            default value
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     * @throws IllegalArgumentException if subjectLength is outside allowed
+     *             range [0..255] or either maxListCount or listStartOffset are
+     *             outside allowed range [0..65535]
+     */
+    public boolean getMessagesListing(String folder, int parameters, MessagesFilter filter,
+            int subjectLength, int maxListCount, int listStartOffset) {
+
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestGetMessagesListing(folder,
+                parameters, filter, subjectLength, maxListCount, listStartOffset);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Gets number of messages in current folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_MESSAGES_LISTING_SIZE}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean getMessagesListingSize() {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestGetMessagesListingSize();
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Retrieves message from MSE
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_GET_MESSAGE}
+     *
+     * @param handle handle of message to retrieve
+     * @param charset {@link CharsetType} object corresponding to
+     *            <code>Charset</code> application parameter in MAP
+     *            specification
+     * @param attachment corresponds to <code>Attachment</code> application
+     *            parameter in MAP specification
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean getMessage(String handle, CharsetType charset, boolean attachment) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        try {
+            /* just to validate */
+            new BigInteger(handle, 16);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestGetMessage(handle, charset,
+                attachment);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Sets read status of message on MSE
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_SET_MESSAGE_STATUS}
+     *
+     * @param handle handle of message
+     * @param read <code>true</code> for "read", <code>false</code> for "unread"
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setMessageReadStatus(String handle, boolean read) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        try {
+            /* just to validate */
+            new BigInteger(handle, 16);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetMessageStatus(handle,
+                StatusIndicator.READ, read);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Sets deleted status of message on MSE
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_SET_MESSAGE_STATUS}
+     *
+     * @param handle handle of message
+     * @param deleted <code>true</code> for "deleted", <code>false</code> for
+     *            "undeleted"
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setMessageDeletedStatus(String handle, boolean deleted) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        try {
+            /* just to validate */
+            new BigInteger(handle, 16);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetMessageStatus(handle,
+                StatusIndicator.DELETED, deleted);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Pushes new message to MSE
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_PUSH_MESSAGE}
+     *
+     * @param folder name of sub-folder to push to or <code>null</code> for
+     *            current folder
+     * @param charset {@link CharsetType} object corresponding to
+     *            <code>Charset</code> application parameter in MAP
+     *            specification
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean pushMessage(String folder, BluetoothMapBmessage bmsg, CharsetType charset) {
+        return pushMessage(folder, bmsg, charset, false, false);
+    }
+
+    /**
+     * Pushes new message to MSE
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_PUSH_MESSAGE}
+     *
+     * @param folder name of sub-folder to push to or <code>null</code> for
+     *            current folder
+     * @param bmsg {@link BluetoothMapBmessage} object representing message to
+     *            be pushed
+     * @param charset {@link CharsetType} object corresponding to
+     *            <code>Charset</code> application parameter in MAP
+     *            specification
+     * @param transparent corresponds to <code>Transparent</code> application
+     *            parameter in MAP specification
+     * @param retry corresponds to <code>Transparent</code> application
+     *            parameter in MAP specification
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean pushMessage(String folder, BluetoothMapBmessage bmsg, CharsetType charset,
+            boolean transparent, boolean retry) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        String bmsgString = BluetoothMapBmessageBuilder.createBmessage(bmsg);
+
+        BluetoothMasRequest request =
+                new BluetoothMasRequestPushMessage(folder, bmsgString, charset, transparent, retry);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Requests MSE to initiate ubdate of inbox
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_UPDATE_INBOX}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean updateInbox() {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestUpdateInbox();
+        return mObexSession.makeRequest(request);
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasObexClientSession.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasObexClientSession.java
new file mode 100644
index 0000000..da95276
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasObexClientSession.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import android.os.Handler;
+import android.os.Process;
+import android.util.Log;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ObexTransport;
+import javax.obex.ResponseCodes;
+
+class BluetoothMasObexClientSession {
+    private static final String TAG = "BluetoothMasObexClientSession";
+
+    private static final byte[] MAS_TARGET = new byte[] {
+            (byte) 0xbb, 0x58, 0x2b, 0x40, 0x42, 0x0c, 0x11, (byte) 0xdb, (byte) 0xb0, (byte) 0xde,
+            0x08, 0x00, 0x20, 0x0c, (byte) 0x9a, 0x66
+    };
+
+    static final int MSG_OBEX_CONNECTED = 100;
+    static final int MSG_OBEX_DISCONNECTED = 101;
+    static final int MSG_REQUEST_COMPLETED = 102;
+
+    private final ObexTransport mTransport;
+
+    private final Handler mSessionHandler;
+
+    private ClientThread mClientThread;
+
+    private volatile boolean mInterrupted;
+
+    private class ClientThread extends Thread {
+        private final ObexTransport mTransport;
+
+        private ClientSession mSession;
+
+        private BluetoothMasRequest mRequest;
+
+        private boolean mConnected;
+
+        public ClientThread(ObexTransport transport) {
+            super("MAS ClientThread");
+
+            mTransport = transport;
+            mConnected = false;
+        }
+
+        @Override
+        public void run() {
+            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+
+            connect();
+
+            if (mConnected) {
+                mSessionHandler.obtainMessage(MSG_OBEX_CONNECTED).sendToTarget();
+            } else {
+                mSessionHandler.obtainMessage(MSG_OBEX_DISCONNECTED).sendToTarget();
+                return;
+            }
+
+            while (!mInterrupted) {
+                synchronized (this) {
+                    if (mRequest == null) {
+                        try {
+                            this.wait();
+                        } catch (InterruptedException e) {
+                            mInterrupted = true;
+                        }
+                    }
+                }
+
+                if (!mInterrupted && mRequest != null) {
+                    try {
+                        mRequest.execute(mSession);
+                    } catch (IOException e) {
+                        // this will "disconnect" to cleanup
+                        mInterrupted = true;
+                    }
+
+                    BluetoothMasRequest oldReq = mRequest;
+                    mRequest = null;
+
+                    mSessionHandler.obtainMessage(MSG_REQUEST_COMPLETED, oldReq).sendToTarget();
+                }
+            }
+
+            disconnect();
+
+            mSessionHandler.obtainMessage(MSG_OBEX_DISCONNECTED).sendToTarget();
+        }
+
+        private void connect() {
+            try {
+                mSession = new ClientSession(mTransport);
+
+                HeaderSet headerset = new HeaderSet();
+                headerset.setHeader(HeaderSet.TARGET, MAS_TARGET);
+
+                headerset = mSession.connect(headerset);
+
+                if (headerset.getResponseCode() == ResponseCodes.OBEX_HTTP_OK) {
+                    mConnected = true;
+                } else {
+                    disconnect();
+                }
+            } catch (IOException e) {
+            }
+        }
+
+        private void disconnect() {
+            try {
+                mSession.disconnect(null);
+            } catch (IOException e) {
+            }
+
+            try {
+                mSession.close();
+            } catch (IOException e) {
+            }
+
+            mConnected = false;
+        }
+
+        public synchronized boolean schedule(BluetoothMasRequest request) {
+            if (mRequest != null) {
+                return false;
+            }
+
+            mRequest = request;
+            notify();
+
+            return true;
+        }
+    }
+
+    public BluetoothMasObexClientSession(ObexTransport transport, Handler handler) {
+        mTransport = transport;
+        mSessionHandler = handler;
+    }
+
+    public void start() {
+        if (mClientThread == null) {
+            mClientThread = new ClientThread(mTransport);
+            mClientThread.start();
+        }
+
+    }
+
+    public void stop() {
+        if (mClientThread != null) {
+            mClientThread.interrupt();
+
+            (new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        mClientThread.join();
+                        mClientThread = null;
+                    } catch (InterruptedException e) {
+                        Log.w(TAG, "Interrupted while waiting for thread to join");
+                    }
+                }
+            }).run();
+        }
+    }
+
+    public boolean makeRequest(BluetoothMasRequest request) {
+        if (mClientThread == null) {
+            return false;
+        }
+
+        return mClientThread.schedule(request);
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequest.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequest.java
new file mode 100644
index 0000000..ed4e579
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.obex.ClientOperation;
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.Operation;
+import javax.obex.ResponseCodes;
+
+abstract class BluetoothMasRequest {
+
+    protected static final byte OAP_TAGID_MAX_LIST_COUNT = 0x01;
+    protected static final byte OAP_TAGID_START_OFFSET = 0x02;
+    protected static final byte OAP_TAGID_FILTER_MESSAGE_TYPE = 0x03;
+    protected static final byte OAP_TAGID_FILTER_PERIOD_BEGIN = 0x04;
+    protected static final byte OAP_TAGID_FILTER_PERIOD_END = 0x05;
+    protected static final byte OAP_TAGID_FILTER_READ_STATUS = 0x06;
+    protected static final byte OAP_TAGID_FILTER_RECIPIENT = 0x07;
+    protected static final byte OAP_TAGID_FILTER_ORIGINATOR = 0x08;
+    protected static final byte OAP_TAGID_FILTER_PRIORITY = 0x09;
+    protected static final byte OAP_TAGID_ATTACHMENT = 0x0a;
+    protected static final byte OAP_TAGID_TRANSPARENT = 0xb;
+    protected static final byte OAP_TAGID_RETRY = 0xc;
+    protected static final byte OAP_TAGID_NEW_MESSAGE = 0x0d;
+    protected static final byte OAP_TAGID_NOTIFICATION_STATUS = 0x0e;
+    protected static final byte OAP_TAGID_MAS_INSTANCE_ID = 0x0f;
+    protected static final byte OAP_TAGID_FOLDER_LISTING_SIZE = 0x11;
+    protected static final byte OAP_TAGID_MESSAGES_LISTING_SIZE = 0x12;
+    protected static final byte OAP_TAGID_SUBJECT_LENGTH = 0x13;
+    protected static final byte OAP_TAGID_CHARSET = 0x14;
+    protected static final byte OAP_TAGID_STATUS_INDICATOR = 0x17;
+    protected static final byte OAP_TAGID_STATUS_VALUE = 0x18;
+    protected static final byte OAP_TAGID_MSE_TIME = 0x19;
+
+    protected static byte NOTIFICATION_ON = 0x01;
+    protected static byte NOTIFICATION_OFF = 0x00;
+
+    protected static byte ATTACHMENT_ON = 0x01;
+    protected static byte ATTACHMENT_OFF = 0x00;
+
+    protected static byte CHARSET_NATIVE = 0x00;
+    protected static byte CHARSET_UTF8 = 0x01;
+
+    protected static byte STATUS_INDICATOR_READ = 0x00;
+    protected static byte STATUS_INDICATOR_DELETED = 0x01;
+
+    protected static byte STATUS_NO = 0x00;
+    protected static byte STATUS_YES = 0x01;
+
+    protected static byte TRANSPARENT_OFF = 0x00;
+    protected static byte TRANSPARENT_ON = 0x01;
+
+    protected static byte RETRY_OFF = 0x00;
+    protected static byte RETRY_ON = 0x01;
+
+    /* used for PUT requests which require filler byte */
+    protected static final byte[] FILLER_BYTE = {
+        0x30
+    };
+
+    protected HeaderSet mHeaderSet;
+
+    protected int mResponseCode;
+
+    public BluetoothMasRequest() {
+        mHeaderSet = new HeaderSet();
+    }
+
+    abstract public void execute(ClientSession session) throws IOException;
+
+    protected void executeGet(ClientSession session) throws IOException {
+        ClientOperation op = null;
+
+        try {
+            op = (ClientOperation) session.get(mHeaderSet);
+
+            /*
+             * MAP spec does not explicitly require that GET request should be
+             * sent in single packet but for some reason PTS complains when
+             * final GET packet with no headers follows non-final GET with all
+             * headers. So this is workaround, at least temporary. TODO: check
+             * with PTS
+             */
+            op.setGetFinalFlag(true);
+
+            /*
+             * this will trigger ClientOperation to use non-buffered stream so
+             * we can abort operation
+             */
+            op.continueOperation(true, false);
+
+            readResponseHeaders(op.getReceivedHeader());
+
+            InputStream is = op.openInputStream();
+            readResponse(is);
+            is.close();
+
+            op.close();
+
+            mResponseCode = op.getResponseCode();
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+
+            throw e;
+        }
+    }
+
+    protected void executePut(ClientSession session, byte[] body) throws IOException {
+        Operation op = null;
+
+        mHeaderSet.setHeader(HeaderSet.LENGTH, Long.valueOf(body.length));
+
+        try {
+            op = session.put(mHeaderSet);
+
+            DataOutputStream out = op.openDataOutputStream();
+            out.write(body);
+            out.close();
+
+            readResponseHeaders(op.getReceivedHeader());
+
+            op.close();
+            mResponseCode = op.getResponseCode();
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+
+            throw e;
+        }
+    }
+
+    final public boolean isSuccess() {
+        return (mResponseCode == ResponseCodes.OBEX_HTTP_OK);
+    }
+
+    protected void readResponse(InputStream stream) throws IOException {
+        /* nothing here by default */
+    }
+
+    protected void readResponseHeaders(HeaderSet headerset) {
+        /* nothing here by default */
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetFolderListing.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetFolderListing.java
new file mode 100644
index 0000000..225d26d
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetFolderListing.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 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.mapclient;
+import org.codeaurora.bluetooth.utils.ObexAppParameters;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestGetFolderListing extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-obex/folder-listing";
+
+    private BluetoothMapFolderListing mResponse = null;
+
+    public BluetoothMasRequestGetFolderListing(int maxListCount, int listStartOffset) {
+
+        if (maxListCount < 0 || maxListCount > 65535) {
+            throw new IllegalArgumentException("maxListCount should be [0..65535]");
+        }
+
+        if (listStartOffset < 0 || listStartOffset > 65535) {
+            throw new IllegalArgumentException("listStartOffset should be [0..65535]");
+        }
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        if (maxListCount > 0) {
+            oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) maxListCount);
+        }
+
+        if (listStartOffset > 0) {
+            oap.add(OAP_TAGID_START_OFFSET, (short) listStartOffset);
+        }
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) {
+        mResponse = new BluetoothMapFolderListing(stream);
+    }
+
+    public ArrayList<String> getList() {
+        if (mResponse == null) {
+            return null;
+        }
+
+        return mResponse.getList();
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetFolderListingSize.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetFolderListingSize.java
new file mode 100644
index 0000000..8915e48
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetFolderListingSize.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import org.codeaurora.bluetooth.utils.ObexAppParameters;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestGetFolderListingSize extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-obex/folder-listing";
+
+    private int mSize;
+
+    public BluetoothMasRequestGetFolderListingSize() {
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+        oap.add(OAP_TAGID_MAX_LIST_COUNT, 0);
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+        mSize = oap.getShort(OAP_TAGID_FOLDER_LISTING_SIZE);
+    }
+
+    public int getSize() {
+        return mSize;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetMessage.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetMessage.java
new file mode 100644
index 0000000..21bc040
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetMessage.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import android.util.Log;
+
+
+import org.codeaurora.bluetooth.mapclient.BluetoothMasClient.CharsetType;
+import org.codeaurora.bluetooth.utils.ObexAppParameters;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+final class BluetoothMasRequestGetMessage extends BluetoothMasRequest {
+
+    private static final String TAG = "BluetoothMasRequestGetMessage";
+
+    private static final String TYPE = "x-bt/message";
+
+    private BluetoothMapBmessage mBmessage;
+
+    public BluetoothMasRequestGetMessage(String handle, CharsetType charset, boolean attachment) {
+
+        mHeaderSet.setHeader(HeaderSet.NAME, handle);
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        oap.add(OAP_TAGID_CHARSET, CharsetType.UTF_8.equals(charset) ? CHARSET_UTF8
+                : CHARSET_NATIVE);
+
+        oap.add(OAP_TAGID_ATTACHMENT, attachment ? ATTACHMENT_ON : ATTACHMENT_OFF);
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) {
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+
+        try {
+            int len;
+            while ((len = stream.read(buf)) != -1) {
+                baos.write(buf, 0, len);
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "I/O exception while reading response", e);
+        }
+
+        String bmsg = baos.toString();
+
+        mBmessage = BluetoothMapBmessageParser.createBmessage(bmsg);
+
+        if (mBmessage == null) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+    }
+
+    public BluetoothMapBmessage getMessage() {
+        return mBmessage;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetMessagesListing.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetMessagesListing.java
new file mode 100644
index 0000000..c44810a
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetMessagesListing.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import org.codeaurora.bluetooth.mapclient.BluetoothMasClient.MessagesFilter;
+import org.codeaurora.bluetooth.utils.ObexAppParameters;
+import org.codeaurora.bluetooth.utils.ObexTime;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Date;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestGetMessagesListing extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-bt/MAP-msg-listing";
+
+    private BluetoothMapMessagesListing mResponse = null;
+
+    private boolean mNewMessage = false;
+
+    private Date mServerTime = null;
+
+    public BluetoothMasRequestGetMessagesListing(String folderName, int parameters,
+            BluetoothMasClient.MessagesFilter filter, int subjectLength, int maxListCount,
+            int listStartOffset) {
+
+        if (subjectLength < 0 || subjectLength > 255) {
+            throw new IllegalArgumentException("subjectLength should be [0..255]");
+        }
+
+        if (maxListCount < 0 || maxListCount > 65535) {
+            throw new IllegalArgumentException("maxListCount should be [0..65535]");
+        }
+
+        if (listStartOffset < 0 || listStartOffset > 65535) {
+            throw new IllegalArgumentException("listStartOffset should be [0..65535]");
+        }
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        if (folderName == null) {
+            mHeaderSet.setHeader(HeaderSet.NAME, "");
+        } else {
+            mHeaderSet.setHeader(HeaderSet.NAME, folderName);
+        }
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        if (filter != null) {
+            if (filter.messageType != MessagesFilter.MESSAGE_TYPE_ALL) {
+                oap.add(OAP_TAGID_FILTER_MESSAGE_TYPE, filter.messageType);
+            }
+
+            if (filter.periodBegin != null) {
+                oap.add(OAP_TAGID_FILTER_PERIOD_BEGIN, filter.periodBegin);
+            }
+
+            if (filter.periodEnd != null) {
+                oap.add(OAP_TAGID_FILTER_PERIOD_END, filter.periodEnd);
+            }
+
+            if (filter.readStatus != MessagesFilter.READ_STATUS_ANY) {
+                oap.add(OAP_TAGID_FILTER_READ_STATUS, filter.readStatus);
+            }
+
+            if (filter.recipient != null) {
+                oap.add(OAP_TAGID_FILTER_RECIPIENT, filter.recipient);
+            }
+
+            if (filter.originator != null) {
+                oap.add(OAP_TAGID_FILTER_ORIGINATOR, filter.originator);
+            }
+
+            if (filter.priority != MessagesFilter.PRIORITY_ANY) {
+                oap.add(OAP_TAGID_FILTER_PRIORITY, filter.priority);
+            }
+        }
+
+        if (subjectLength != 0) {
+            oap.add(OAP_TAGID_SUBJECT_LENGTH, (byte) subjectLength);
+        }
+
+        if (maxListCount != 0) {
+            oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) maxListCount);
+        }
+
+        if (listStartOffset != 0) {
+            oap.add(OAP_TAGID_START_OFFSET, (short) listStartOffset);
+        }
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) {
+        mResponse = new BluetoothMapMessagesListing(stream);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+        mNewMessage = ((oap.getByte(OAP_TAGID_NEW_MESSAGE) & 0x01) == 1);
+
+        if (oap.exists(OAP_TAGID_MSE_TIME)) {
+            String mseTime = oap.getString(OAP_TAGID_MSE_TIME);
+
+            mServerTime = (new ObexTime(mseTime)).getTime();
+        }
+    }
+
+    public ArrayList<BluetoothMapMessage> getList() {
+        if (mResponse == null) {
+            return null;
+        }
+
+        return mResponse.getList();
+    }
+
+    public boolean getNewMessageStatus() {
+        return mNewMessage;
+    }
+
+    public Date getMseTime() {
+        return mServerTime;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetMessagesListingSize.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetMessagesListingSize.java
new file mode 100644
index 0000000..464a093
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestGetMessagesListingSize.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import  org.codeaurora.bluetooth.utils.ObexAppParameters;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestGetMessagesListingSize extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-bt/MAP-msg-listing";
+
+    private int mSize;
+
+    public BluetoothMasRequestGetMessagesListingSize() {
+        mHeaderSet.setHeader(HeaderSet.NAME, "");
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+        oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) 0);
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+        mSize = oap.getShort(OAP_TAGID_MESSAGES_LISTING_SIZE);
+    }
+
+    public int getSize() {
+        return mSize;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestPushMessage.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestPushMessage.java
new file mode 100644
index 0000000..4eda451
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestPushMessage.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+import org.codeaurora.bluetooth.mapclient.BluetoothMasClient.CharsetType;
+import org.codeaurora.bluetooth.utils.ObexAppParameters;
+
+final class BluetoothMasRequestPushMessage extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-bt/message";
+    private String mMsg;
+    private String mMsgHandle;
+
+    private BluetoothMasRequestPushMessage(String folder) {
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+        if (folder == null) {
+            folder = "";
+        }
+        mHeaderSet.setHeader(HeaderSet.NAME, folder);
+    }
+
+    public BluetoothMasRequestPushMessage(String folder, String msg, CharsetType charset,
+            boolean transparent, boolean retry) {
+        this(folder);
+        mMsg = msg;
+        ObexAppParameters oap = new ObexAppParameters();
+        oap.add(OAP_TAGID_TRANSPARENT, transparent ? TRANSPARENT_ON : TRANSPARENT_OFF);
+        oap.add(OAP_TAGID_RETRY, retry ? RETRY_ON : RETRY_OFF);
+        oap.add(OAP_TAGID_CHARSET, charset == CharsetType.NATIVE ? CHARSET_NATIVE : CHARSET_UTF8);
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        try {
+            String handle = (String) headerset.getHeader(HeaderSet.NAME);
+            if (handle != null) {
+                /* just to validate */
+                new BigInteger(handle, 16);
+
+                mMsgHandle = handle;
+            }
+        } catch (NumberFormatException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+    }
+
+    public String getMsgHandle() {
+        return mMsgHandle;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executePut(session, mMsg.getBytes());
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestSetMessageStatus.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestSetMessageStatus.java
new file mode 100644
index 0000000..367f88e
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestSetMessageStatus.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import org.codeaurora.bluetooth.utils.ObexAppParameters;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestSetMessageStatus extends BluetoothMasRequest {
+
+    public enum StatusIndicator {
+        READ, DELETED;
+    }
+
+    private static final String TYPE = "x-bt/messageStatus";
+
+    public BluetoothMasRequestSetMessageStatus(String handle, StatusIndicator statusInd,
+            boolean statusValue) {
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+        mHeaderSet.setHeader(HeaderSet.NAME, handle);
+
+        ObexAppParameters oap = new ObexAppParameters();
+        oap.add(OAP_TAGID_STATUS_INDICATOR,
+                statusInd == StatusIndicator.READ ? STATUS_INDICATOR_READ
+                        : STATUS_INDICATOR_DELETED);
+        oap.add(OAP_TAGID_STATUS_VALUE, statusValue ? STATUS_YES : STATUS_NO);
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executePut(session, FILLER_BYTE);
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestSetNotificationRegistration.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestSetNotificationRegistration.java
new file mode 100644
index 0000000..b62d7af
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestSetNotificationRegistration.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import org.codeaurora.bluetooth.utils.ObexAppParameters;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestSetNotificationRegistration extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-bt/MAP-NotificationRegistration";
+
+    private final boolean mStatus;
+
+    public BluetoothMasRequestSetNotificationRegistration(boolean status) {
+        mStatus = status;
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        oap.add(OAP_TAGID_NOTIFICATION_STATUS, status ? NOTIFICATION_ON : NOTIFICATION_OFF);
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executePut(session, FILLER_BYTE);
+    }
+
+    public boolean getStatus() {
+        return mStatus;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestSetPath.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestSetPath.java
new file mode 100644
index 0000000..507224f
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestSetPath.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+class BluetoothMasRequestSetPath extends BluetoothMasRequest {
+
+    enum SetPathDir {
+        ROOT, UP, DOWN
+    };
+
+    SetPathDir mDir;
+
+    String mName;
+
+    public BluetoothMasRequestSetPath(String name) {
+        mDir = SetPathDir.DOWN;
+        mName = name;
+
+        mHeaderSet.setHeader(HeaderSet.NAME, name);
+    }
+
+    public BluetoothMasRequestSetPath(boolean goRoot) {
+        mHeaderSet.setEmptyNameHeader();
+        if (goRoot) {
+            mDir = SetPathDir.ROOT;
+        } else {
+            mDir = SetPathDir.UP;
+        }
+    }
+
+    @Override
+    public void execute(ClientSession session) {
+        HeaderSet hs = null;
+
+        try {
+            switch (mDir) {
+                case ROOT:
+                case DOWN:
+                    hs = session.setPath(mHeaderSet, false, false);
+                    break;
+                case UP:
+                    hs = session.setPath(mHeaderSet, true, false);
+                    break;
+            }
+
+            mResponseCode = hs.getResponseCode();
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestUpdateInbox.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestUpdateInbox.java
new file mode 100644
index 0000000..2b05dc0
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMasRequestUpdateInbox.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestUpdateInbox extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-bt/MAP-messageUpdate";
+
+    public BluetoothMasRequestUpdateInbox() {
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executePut(session, FILLER_BYTE);
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMnsObexServer.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMnsObexServer.java
new file mode 100644
index 0000000..9bf8fb5
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMnsObexServer.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import android.os.Handler;
+import android.util.Log;
+
+import org.codeaurora.bluetooth.utils.ObexAppParameters;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import javax.obex.HeaderSet;
+import javax.obex.Operation;
+import javax.obex.ResponseCodes;
+import javax.obex.ServerRequestHandler;
+
+class BluetoothMnsObexServer extends ServerRequestHandler {
+
+    private final static String TAG = "BluetoothMnsObexServer";
+
+    private static final byte[] MNS_TARGET = new byte[] {
+            (byte) 0xbb, 0x58, 0x2b, 0x41, 0x42, 0x0c, 0x11, (byte) 0xdb, (byte) 0xb0, (byte) 0xde,
+            0x08, 0x00, 0x20, 0x0c, (byte) 0x9a, 0x66
+    };
+
+    private final static String TYPE = "x-bt/MAP-event-report";
+
+    private final Handler mCallback;
+
+    public BluetoothMnsObexServer(Handler callback) {
+        super();
+
+        mCallback = callback;
+    }
+
+    @Override
+    public int onConnect(final HeaderSet request, HeaderSet reply) {
+        Log.v(TAG, "onConnect");
+
+        try {
+            byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
+
+            if (!Arrays.equals(uuid, MNS_TARGET)) {
+                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+            }
+
+        } catch (IOException e) {
+            // this should never happen since getHeader won't throw exception it
+            // declares to throw
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    @Override
+    public void onDisconnect(final HeaderSet request, HeaderSet reply) {
+        Log.v(TAG, "onDisconnect");
+    }
+
+    @Override
+    public int onGet(final Operation op) {
+        Log.v(TAG, "onGet");
+
+        return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+    }
+
+    @Override
+    public int onPut(final Operation op) {
+        Log.v(TAG, "onPut");
+
+        try {
+            HeaderSet headerset;
+            headerset = op.getReceivedHeader();
+
+            String type = (String) headerset.getHeader(HeaderSet.TYPE);
+            ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+            if (!TYPE.equals(type) || !oap.exists(BluetoothMasRequest.OAP_TAGID_MAS_INSTANCE_ID)) {
+                return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            }
+
+            Byte inst = oap.getByte(BluetoothMasRequest.OAP_TAGID_MAS_INSTANCE_ID);
+
+            BluetoothMapEventReport ev = BluetoothMapEventReport.fromStream(op
+                    .openDataInputStream());
+
+            op.close();
+
+            mCallback.obtainMessage(BluetoothMnsService.MSG_EVENT, inst, 0, ev).sendToTarget();
+        } catch (IOException e) {
+            Log.e(TAG, "I/O exception when handling PUT request", e);
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    @Override
+    public int onAbort(final HeaderSet request, HeaderSet reply) {
+        Log.v(TAG, "onAbort");
+
+        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
+    }
+
+    @Override
+    public int onSetPath(final HeaderSet request, HeaderSet reply,
+            final boolean backup, final boolean create) {
+        Log.v(TAG, "onSetPath");
+
+        return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+    }
+
+    @Override
+    public void onClose() {
+        Log.v(TAG, "onClose");
+
+        // TODO: call session handler so it can disconnect
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/BluetoothMnsService.java b/src/org/codeaurora/bluetooth/mapclient/BluetoothMnsService.java
new file mode 100644
index 0000000..125d37a
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/BluetoothMnsService.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 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.mapclient;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothSocket;
+import android.os.Handler;
+import android.os.Message;
+import android.os.ParcelUuid;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.lang.ref.WeakReference;
+
+import javax.obex.ServerSession;
+
+class BluetoothMnsService {
+
+    private static final String TAG = "BluetoothMnsService";
+
+    private static final ParcelUuid MAP_MNS =
+            ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
+
+    static final int MSG_EVENT = 1;
+
+    /* for BluetoothMasClient */
+    static final int EVENT_REPORT = 1001;
+
+    /* these are shared across instances */
+    static private SparseArray<Handler> mCallbacks = null;
+    static private SocketAcceptThread mAcceptThread = null;
+    static private Handler mSessionHandler = null;
+    static private BluetoothServerSocket mServerSocket = null;
+
+    private static class SessionHandler extends Handler {
+
+        private final WeakReference<BluetoothMnsService> mService;
+
+        SessionHandler(BluetoothMnsService service) {
+            mService = new WeakReference<BluetoothMnsService>(service);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            Log.d(TAG, "Handler: msg: " + msg.what);
+
+            switch (msg.what) {
+                case MSG_EVENT:
+                    int instanceId = msg.arg1;
+
+                    synchronized (mCallbacks) {
+                        Handler cb = mCallbacks.get(instanceId);
+
+                        if (cb != null) {
+                            BluetoothMapEventReport ev = (BluetoothMapEventReport) msg.obj;
+                            cb.obtainMessage(EVENT_REPORT, ev).sendToTarget();
+                        } else {
+                            Log.w(TAG, "Got event for instance which is not registered: "
+                                    + instanceId);
+                        }
+                    }
+                    break;
+            }
+        }
+    }
+
+    private static class SocketAcceptThread extends Thread {
+
+        private boolean mInterrupted = false;
+
+        @Override
+        public void run() {
+
+            if (mServerSocket != null) {
+                Log.w(TAG, "Socket already created, exiting");
+                return;
+            }
+
+            try {
+                BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+                mServerSocket = adapter.listenUsingEncryptedRfcommWithServiceRecord(
+                        "MAP Message Notification Service", MAP_MNS.getUuid());
+            } catch (IOException e) {
+                mInterrupted = true;
+                Log.e(TAG, "I/O exception when trying to create server socket", e);
+            }
+
+            while (!mInterrupted) {
+                try {
+                    Log.v(TAG, "waiting to accept connection...");
+
+                    BluetoothSocket sock = mServerSocket.accept();
+
+                    Log.v(TAG, "new incoming connection from "
+                            + sock.getRemoteDevice().getName());
+
+                    // session will live until closed by remote
+                    BluetoothMnsObexServer srv = new BluetoothMnsObexServer(mSessionHandler);
+                    BluetoothMapRfcommTransport transport = new BluetoothMapRfcommTransport(
+                            sock);
+                    new ServerSession(transport, srv, null);
+                } catch (IOException ex) {
+                    Log.v(TAG, "I/O exception when waiting to accept (aborted?)");
+                    mInterrupted = true;
+                }
+            }
+
+            if (mServerSocket != null) {
+                try {
+                    mServerSocket.close();
+                } catch (IOException e) {
+                    // do nothing
+                }
+
+                mServerSocket = null;
+            }
+        }
+    }
+
+    BluetoothMnsService() {
+        Log.v(TAG, "BluetoothMnsService()");
+
+        if (mCallbacks == null) {
+            Log.v(TAG, "BluetoothMnsService(): allocating callbacks");
+            mCallbacks = new SparseArray<Handler>();
+        }
+
+        if (mSessionHandler == null) {
+            Log.v(TAG, "BluetoothMnsService(): allocating session handler");
+            mSessionHandler = new SessionHandler(this);
+        }
+    }
+
+    public void registerCallback(int instanceId, Handler callback) {
+        Log.v(TAG, "registerCallback()");
+
+        synchronized (mCallbacks) {
+            mCallbacks.put(instanceId, callback);
+
+            if (mAcceptThread == null) {
+                Log.v(TAG, "registerCallback(): starting MNS server");
+                mAcceptThread = new SocketAcceptThread();
+                mAcceptThread.setName("BluetoothMnsAcceptThread");
+                mAcceptThread.start();
+            }
+        }
+    }
+
+    public void unregisterCallback(int instanceId) {
+        Log.v(TAG, "unregisterCallback()");
+
+        synchronized (mCallbacks) {
+            mCallbacks.remove(instanceId);
+
+            if (mCallbacks.size() == 0) {
+                Log.v(TAG, "unregisterCallback(): shutting down MNS server");
+
+                if (mServerSocket != null) {
+                    try {
+                        mServerSocket.close();
+                    } catch (IOException e) {
+                    }
+
+                    mServerSocket = null;
+                }
+
+                mAcceptThread.interrupt();
+
+                try {
+                    mAcceptThread.join(5000);
+                } catch (InterruptedException e) {
+                }
+
+                mAcceptThread = null;
+            }
+        }
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/utils/BmsgTokenizer.java b/src/org/codeaurora/bluetooth/mapclient/utils/BmsgTokenizer.java
new file mode 100644
index 0000000..6a6558c
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/utils/BmsgTokenizer.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 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.utils;
+
+import android.util.Log;
+
+import java.text.ParseException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class BmsgTokenizer {
+
+    private final String mStr;
+
+    private final Matcher mMatcher;
+
+    private int mPos = 0;
+
+    private final int mOffset;
+
+    static public class Property {
+        public final String name;
+        public final String value;
+
+        public Property(String name, String value) {
+            if (name == null || value == null) {
+                throw new IllegalArgumentException();
+            }
+
+            this.name = name;
+            this.value = value;
+
+            Log.v("BMSG >> ", toString());
+        }
+
+        @Override
+        public String toString() {
+            return name + ":" + value;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            return ((o instanceof Property) && ((Property) o).name.equals(name) && ((Property) o).value
+                    .equals(value));
+        }
+    };
+
+    public BmsgTokenizer(String str) {
+        this(str, 0);
+    }
+
+    public BmsgTokenizer(String str, int offset) {
+        mStr = str;
+        mOffset = offset;
+        mMatcher = Pattern.compile("(([^:]*):(.*))?\r\n").matcher(str);
+        mPos = mMatcher.regionStart();
+    }
+
+    public Property next(boolean alwaysReturn) throws ParseException {
+        boolean found = false;
+
+        do {
+            mMatcher.region(mPos, mMatcher.regionEnd());
+
+            if (!mMatcher.lookingAt()) {
+                if (alwaysReturn) {
+                    return null;
+                }
+
+                throw new ParseException("Property or empty line expected", pos());
+            }
+
+            mPos = mMatcher.end();
+
+            if (mMatcher.group(1) != null) {
+                found = true;
+            }
+        } while (!found);
+
+        return new Property(mMatcher.group(2), mMatcher.group(3));
+    }
+
+    public Property next() throws ParseException {
+        return next(false);
+    }
+
+    public String remaining() {
+        return mStr.substring(mPos);
+    }
+
+    public int pos() {
+        return mPos + mOffset;
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/utils/ObexAppParameters.java b/src/org/codeaurora/bluetooth/mapclient/utils/ObexAppParameters.java
new file mode 100644
index 0000000..4db0398
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/utils/ObexAppParameters.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 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.utils;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.obex.HeaderSet;
+
+public final class ObexAppParameters {
+
+    private final HashMap<Byte, byte[]> mParams;
+
+    public ObexAppParameters() {
+        mParams = new HashMap<Byte, byte[]>();
+    }
+
+    public ObexAppParameters(byte[] raw) {
+        mParams = new HashMap<Byte, byte[]>();
+
+        if (raw != null) {
+            for (int i = 0; i < raw.length;) {
+                if (raw.length - i < 2) {
+                    break;
+                }
+
+                byte tag = raw[i++];
+                byte len = raw[i++];
+
+                if (raw.length - i - len < 0) {
+                    break;
+                }
+
+                byte[] val = new byte[len];
+
+                System.arraycopy(raw, i, val, 0, len);
+                this.add(tag, val);
+
+                i += len;
+            }
+        }
+    }
+
+    public static ObexAppParameters fromHeaderSet(HeaderSet headerset) {
+        try {
+            byte[] raw = (byte[]) headerset.getHeader(HeaderSet.APPLICATION_PARAMETER);
+            return new ObexAppParameters(raw);
+        } catch (IOException e) {
+            // won't happen
+        }
+
+        return null;
+    }
+
+    public byte[] getHeader() {
+        int length = 0;
+
+        for (Map.Entry<Byte, byte[]> entry : mParams.entrySet()) {
+            length += (entry.getValue().length + 2);
+        }
+
+        byte[] ret = new byte[length];
+
+        int idx = 0;
+        for (Map.Entry<Byte, byte[]> entry : mParams.entrySet()) {
+            length = entry.getValue().length;
+
+            ret[idx++] = entry.getKey();
+            ret[idx++] = (byte) length;
+            System.arraycopy(entry.getValue(), 0, ret, idx, length);
+            idx += length;
+        }
+
+        return ret;
+    }
+
+    public void addToHeaderSet(HeaderSet headerset) {
+        if (mParams.size() > 0) {
+            headerset.setHeader(HeaderSet.APPLICATION_PARAMETER, getHeader());
+        }
+    }
+
+    public boolean exists(byte tag) {
+        return mParams.containsKey(tag);
+    }
+
+    public void add(byte tag, byte val) {
+        byte[] bval = ByteBuffer.allocate(1).put(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, short val) {
+        byte[] bval = ByteBuffer.allocate(2).putShort(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, int val) {
+        byte[] bval = ByteBuffer.allocate(4).putInt(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, long val) {
+        byte[] bval = ByteBuffer.allocate(8).putLong(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, String val) {
+        byte[] bval = val.getBytes();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, byte[] bval) {
+        mParams.put(tag, bval);
+    }
+
+    public byte getByte(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null || bval.length < 1) {
+            return 0;
+        }
+
+        return ByteBuffer.wrap(bval).get();
+    }
+
+    public short getShort(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null || bval.length < 2) {
+            return 0;
+        }
+
+        return ByteBuffer.wrap(bval).getShort();
+    }
+
+    public int getInt(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null || bval.length < 4) {
+            return 0;
+        }
+
+        return ByteBuffer.wrap(bval).getInt();
+    }
+
+    public String getString(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null) {
+            return null;
+        }
+
+        return new String(bval);
+    }
+
+    public byte[] getByteArray(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        return bval;
+    }
+
+    @Override
+    public String toString() {
+        return mParams.toString();
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/mapclient/utils/ObexTime.java b/src/org/codeaurora/bluetooth/mapclient/utils/ObexTime.java
new file mode 100644
index 0000000..18c0c8e
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/mapclient/utils/ObexTime.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 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.utils;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class ObexTime {
+
+    private Date mDate;
+
+    public ObexTime(String time) {
+        /*
+         * match OBEX time string: YYYYMMDDTHHMMSS with optional UTF offset
+         * +/-hhmm
+         */
+        Pattern p = Pattern
+                .compile("(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})(([+-])(\\d{2})(\\d{2}))?");
+        Matcher m = p.matcher(time);
+
+        if (m.matches()) {
+
+            /*
+             * matched groups are numberes as follows: YYYY MM DD T HH MM SS +
+             * hh mm ^^^^ ^^ ^^ ^^ ^^ ^^ ^ ^^ ^^ 1 2 3 4 5 6 8 9 10 all groups
+             * are guaranteed to be numeric so conversion will always succeed
+             * (except group 8 which is either + or -)
+             */
+
+            Calendar cal = Calendar.getInstance();
+            cal.set(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)) - 1,
+                    Integer.parseInt(m.group(3)), Integer.parseInt(m.group(4)),
+                    Integer.parseInt(m.group(5)), Integer.parseInt(m.group(6)));
+
+            /*
+             * if 7th group is matched then we have UTC offset information
+             * included
+             */
+            if (m.group(7) != null) {
+                int ohh = Integer.parseInt(m.group(9));
+                int omm = Integer.parseInt(m.group(10));
+
+                /* time zone offset is specified in miliseconds */
+                int offset = (ohh * 60 + omm) * 60 * 1000;
+
+                if (m.group(8).equals("-")) {
+                    offset = -offset;
+                }
+
+                TimeZone tz = TimeZone.getTimeZone("UTC");
+                tz.setRawOffset(offset);
+
+                cal.setTimeZone(tz);
+            }
+
+            mDate = cal.getTime();
+        }
+    }
+
+    public ObexTime(Date date) {
+        mDate = date;
+    }
+
+    public Date getTime() {
+        return mDate;
+    }
+
+    @Override
+    public String toString() {
+        if (mDate == null) {
+            return null;
+        }
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(mDate);
+
+        /* note that months are numbered stating from 0 */
+        return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02d",
+                cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1,
+                cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY),
+                cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
+    }
+}
