diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 866d84a..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-src_dirs:= src/android/bluetooth/client/map
-
-LOCAL_SRC_FILES := \
-        $(call all-java-files-under, $(src_dirs))
-
-LOCAL_MODULE:= android.bluetooth.client.map
-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/OWNERS b/OWNERS
deleted file mode 100644
index 1fa3bc5..0000000
--- a/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-pirozzoj@google.com
diff --git a/src/android/bluetooth/client/map/BluetoothMapBmessage.java b/src/android/bluetooth/client/map/BluetoothMapBmessage.java
deleted file mode 100644
index e06b033..0000000
--- a/src/android/bluetooth/client/map/BluetoothMapBmessage.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-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("charset", mBbodyCharset);
-            json.put("message", mMessage);
-        } catch (JSONException e) {
-            // do nothing
-        }
-
-        return json.toString();
-    }
-}
diff --git a/src/android/bluetooth/client/map/BluetoothMapBmessageBuilder.java b/src/android/bluetooth/client/map/BluetoothMapBmessageBuilder.java
deleted file mode 100644
index 8629423..0000000
--- a/src/android/bluetooth/client/map/BluetoothMapBmessageBuilder.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-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/android/bluetooth/client/map/BluetoothMapBmessageParser.java b/src/android/bluetooth/client/map/BluetoothMapBmessageParser.java
deleted file mode 100644
index ea9bc7f..0000000
--- a/src/android/bluetooth/client/map/BluetoothMapBmessageParser.java
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-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 android.bluetooth.client.map.BluetoothMapBmessage.Status;
-import android.bluetooth.client.map.BluetoothMapBmessage.Type;
-import android.bluetooth.client.map.utils.BmsgTokenizer;
-import android.bluetooth.client.map.utils.BmsgTokenizer.Property;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.text.ParseException;
-
-class BluetoothMapBmessageParser {
-
-    private final static String TAG = "BluetoothMapBmessageParser";
-    private final static boolean DBG = false;
-
-    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();
-
-        if (DBG) {
-            Log.d(TAG, "actual wired contents: " + str);
-        }
-
-        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.parseInt(prop.value);
-                } catch (NumberFormatException e) {
-                    throw new ParseException("Invalid LENGTH value", mParser.pos());
-                }
-
-            }
-
-        } while (!prop.equals(BEGIN_MSG));
-
-        /*
-         * check that the charset is always set to UTF-8. We expect only text transfer (in lieu with
-         * the MAPv12 specifying only RFC2822 (text only) for MMS/EMAIL and SMS do not support
-         * non-text content. If the charset is not set to UTF-8, it is safe to set the message as
-         * empty. We force the getMessage (see BluetoothMasClient) to only call getMessage with
-         * UTF-8 as the MCE is not obliged to support native charset.
-         */
-        if (!mBmsg.mBbodyCharset.equals("UTF-8")) {
-            Log.e(TAG, "The charset was not set to charset UTF-8: " + mBmsg.mBbodyCharset);
-        }
-
-        /*
-         * <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) {
-            if (prop.equals(END_MSG)) {
-                if (mBmsg.mBbodyCharset.equals("UTF-8")) {
-                    mBmsg.mMessage = new String(data, 0, messageLen, StandardCharsets.UTF_8);
-                } else {
-                    mBmsg.mMessage = null;
-                }
-            } else {
-                /* Handle possible exception for incorrect LENGTH value
-                 * from MSE while parsing  GET Message response */
-                Log.e(TAG, "Prop Invalid: "+ prop.toString());
-                Log.e(TAG, "Possible Invalid LENGTH value");
-                throw expected(END_MSG);
-            }
-        } else {
-
-            data = null;
-
-            /*
-             * now we check if bMessage can be parsed if LENGTH is handled as
-             * number of characters instead of number of bytes
-             */
-            if (offset < 0 || offset > remng.length()) {
-                /* Handle possible exception for incorrect LENGTH value
-                 * from MSE while parsing  GET Message response */
-                throw new ParseException("Invalid LENGTH value", mParser.pos());
-            }
-
-            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);
-            }
-
-            if (mBmsg.mBbodyCharset.equals("UTF-8")) {
-                mBmsg.mMessage = remng.substring(0, messageLen);
-            } else {
-                mBmsg.mMessage = null;
-            }
-        }
-
-        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/android/bluetooth/client/map/BluetoothMapEventReport.java b/src/android/bluetooth/client/map/BluetoothMapEventReport.java
deleted file mode 100644
index 5963db4..0000000
--- a/src/android/bluetooth/client/map/BluetoothMapEventReport.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-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/android/bluetooth/client/map/BluetoothMapFolderListing.java b/src/android/bluetooth/client/map/BluetoothMapFolderListing.java
deleted file mode 100644
index f0494b3..0000000
--- a/src/android/bluetooth/client/map/BluetoothMapFolderListing.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-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/android/bluetooth/client/map/BluetoothMapMessage.java b/src/android/bluetooth/client/map/BluetoothMapMessage.java
deleted file mode 100644
index 5ce6c4b..0000000
--- a/src/android/bluetooth/client/map/BluetoothMapMessage.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-import android.bluetooth.client.map.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");
-        String dateTime = attrs.get("datetime");
-        //Handle possible NPE when not able to retreive datetime attribute
-        if(dateTime != null){
-            mDateTime = (new ObexTime(dateTime)).getTime();
-        } else {
-            mDateTime = null;
-        }
-
-
-        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/android/bluetooth/client/map/BluetoothMapMessagesListing.java b/src/android/bluetooth/client/map/BluetoothMapMessagesListing.java
deleted file mode 100644
index 2fb3dea..0000000
--- a/src/android/bluetooth/client/map/BluetoothMapMessagesListing.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-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/android/bluetooth/client/map/BluetoothMapRfcommTransport.java b/src/android/bluetooth/client/map/BluetoothMapRfcommTransport.java
deleted file mode 100644
index 5bec982..0000000
--- a/src/android/bluetooth/client/map/BluetoothMapRfcommTransport.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import android.bluetooth.BluetoothSocket;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import javax.obex.ObexTransport;
-
-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());
-    }
-
-    @Override
-    public int getMaxTransmitPacketSize() {
-        return -1;
-    }
-
-    @Override
-    public int getMaxReceivePacketSize() {
-        return -1;
-    }
-
-    @Override
-    public boolean isSrmSupported() {
-        return false;
-    }
-}
diff --git a/src/android/bluetooth/client/map/BluetoothMasClient.java b/src/android/bluetooth/client/map/BluetoothMasClient.java
deleted file mode 100644
index 87f5a38..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasClient.java
+++ /dev/null
@@ -1,1106 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothMasInstance;
-import android.bluetooth.BluetoothSocket;
-import android.bluetooth.SdpMasRecord;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import android.bluetooth.client.map.BluetoothMasRequestSetMessageStatus.StatusIndicator;
-import android.bluetooth.client.map.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 SdpMasRecord 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) {
-        // Send  event, status and notification state for both sucess and failure case.
-        mCallback.obtainMessage(event, success ? STATUS_OK : STATUS_FAILED, mMas.getMasInstanceId(),
-            param).sendToTarget();
-    }
-
-    private class SocketConnectThread extends Thread {
-        private BluetoothSocket socket = null;
-
-        public SocketConnectThread() {
-            super("SocketConnectThread");
-        }
-
-        @Override
-        public void run() {
-            try {
-                socket = mDevice.createRfcommSocket(mMas.getRfcommCannelNumber());
-                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) {
-        //Handle possible NPE for obexTime constructor utility
-            if(filterBegin != null )
-                periodBegin = (new ObexTime(filterBegin)).toString();
-            if(filterEnd != null)
-                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, SdpMasRecord 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 SdpMasRecord 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.getMasInstanceId(), mSessionHandler);
-
-        BluetoothMasRequest request = new BluetoothMasRequestSetNotificationRegistration(true);
-        return mObexSession.makeRequest(request);
-    }
-
-    private boolean disableNotifications() {
-        Log.v(TAG, "enableNotifications()");
-
-        if (mMnsService != null) {
-            mMnsService.unregisterCallback(mMas.getMasInstanceId());
-        }
-
-        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, boolean attachment) {
-        if (mObexSession == null) {
-            return false;
-        }
-
-        try {
-            /* just to validate */
-            new BigInteger(handle, 16);
-        } catch (NumberFormatException e) {
-            return false;
-        }
-
-        // Since we support only text messaging via Bluetooth, it is OK to restrict the requests to
-        // force conversion to UTF-8.
-        BluetoothMasRequest request =
-            new BluetoothMasRequestGetMessage(handle, CharsetType.UTF_8, 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/android/bluetooth/client/map/BluetoothMasObexClientSession.java b/src/android/bluetooth/client/map/BluetoothMasObexClientSession.java
deleted file mode 100644
index 9bf75d4..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasObexClientSession.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.util.Log;
-
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-
-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
-    };
-
-    private boolean DBG = true;
-
-    static final int MSG_OBEX_CONNECTED = 100;
-    static final int MSG_OBEX_DISCONNECTED = 101;
-    static final int MSG_REQUEST_COMPLETED = 102;
-
-    private static final int CONNECT = 0;
-    private static final int DISCONNECT = 1;
-    private static final int REQUEST = 2;
-
-    private final ObexTransport mTransport;
-
-    private final Handler mSessionHandler;
-
-    private ClientSession mSession;
-
-    private HandlerThread mThread;
-    private Handler mHandler;
-
-    private boolean mConnected;
-
-    private static class ObexClientHandler extends Handler {
-       WeakReference<BluetoothMasObexClientSession> mInst;
-
-       ObexClientHandler(Looper looper, BluetoothMasObexClientSession inst) {
-          super(looper);
-          mInst = new WeakReference<BluetoothMasObexClientSession>(inst);
-       }
-
-       @Override
-       public void handleMessage(Message msg) {
-          BluetoothMasObexClientSession inst = mInst.get();
-          if (!inst.connected() && msg.what != CONNECT) {
-              Log.w(TAG, "Cannot execute " + msg + " when not CONNECTED.");
-              return;
-          }
-
-          switch (msg.what) {
-              case CONNECT:
-                  inst.connect();
-                  break;
-
-              case DISCONNECT:
-                  inst.disconnect();
-                  break;
-
-              case REQUEST:
-                  inst.executeRequest((BluetoothMasRequest) msg.obj);
-                  break;
-          }
-       }
-    }
-
-    public BluetoothMasObexClientSession(ObexTransport transport, Handler handler) {
-        mTransport = transport;
-        mSessionHandler = handler;
-    }
-
-    public void start() {
-        if (DBG) Log.d(TAG, "start called.");
-        if (mConnected) {
-            if (DBG) Log.d(TAG, "Already connected, nothing to do.");
-            return;
-        }
-
-        // Start a thread to handle messages here.
-        mThread = new HandlerThread("BluetoothMasObexClientSessionThread");
-        mThread.start();
-        mHandler = new ObexClientHandler(mThread.getLooper(), this);
-
-        // Connect it to the target device via OBEX.
-        mHandler.obtainMessage(CONNECT).sendToTarget();
-    }
-
-    public boolean makeRequest(BluetoothMasRequest request) {
-        if (DBG) Log.d(TAG, "makeRequest called with: " + request);
-
-        boolean status = mHandler.sendMessage(mHandler.obtainMessage(REQUEST, request));
-        if (!status) {
-            Log.e(TAG, "Adding messages failed, state: " + mConnected);
-            return false;
-        }
-        return true;
-    }
-
-    public void stop() {
-        if (DBG) Log.d(TAG, "stop called...");
-
-        mThread.quit();
-        disconnect();
-    }
-
-    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;
-                mSessionHandler.obtainMessage(MSG_OBEX_CONNECTED).sendToTarget();
-            } else {
-                disconnect();
-            }
-        } catch (IOException e) {
-            disconnect();
-        }
-    }
-
-    private void disconnect() {
-        if (mSession != null) {
-            try {
-                mSession.disconnect(null);
-            } catch (IOException e) {
-            }
-
-            try {
-                mSession.close();
-            } catch (IOException e) {
-            }
-        }
-
-        mConnected = false;
-        mSessionHandler.obtainMessage(MSG_OBEX_DISCONNECTED).sendToTarget();
-    }
-
-    private void executeRequest(BluetoothMasRequest request) {
-        try {
-            request.execute(mSession);
-            mSessionHandler.obtainMessage(MSG_REQUEST_COMPLETED, request).sendToTarget();
-        } catch (IOException e) {
-            if (DBG) Log.d(TAG, "Request failed: " + request);
-
-            // Disconnect to cleanup.
-            disconnect();
-        }
-    }
-
-
-    private boolean connected() {
-        return mConnected;
-    }
-}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequest.java b/src/android/bluetooth/client/map/BluetoothMasRequest.java
deleted file mode 100644
index 0c9c29c..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-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_PARAMETER_MASK = 0x10;
-    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/android/bluetooth/client/map/BluetoothMasRequestGetFolderListing.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetFolderListing.java
deleted file mode 100644
index db22ada..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequestGetFolderListing.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-import android.bluetooth.client.map.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();
-        // Allow GetFolderListing for maxListCount value 0 also.
-        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/android/bluetooth/client/map/BluetoothMasRequestGetFolderListingSize.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetFolderListingSize.java
deleted file mode 100644
index 910c036..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequestGetFolderListingSize.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import android.bluetooth.client.map.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/android/bluetooth/client/map/BluetoothMasRequestGetMessage.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessage.java
deleted file mode 100644
index 923bff0..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequestGetMessage.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import android.util.Log;
-
-
-import android.bluetooth.client.map.BluetoothMasClient.CharsetType;
-import android.bluetooth.client.map.utils.ObexAppParameters;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
-
-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);
-        }
-
-        // Convert the input stream using UTF-8 since the attributes in the payload are all encoded
-        // according to it. The actual message body may need to be transcoded depending on
-        // charset/encoding defined for body-content.
-        String bmsg;
-        try {
-            bmsg = baos.toString(StandardCharsets.UTF_8.name());
-        } catch (UnsupportedEncodingException ex) {
-            Log.e(TAG,
-                "Coudn't decode the bmessage with UTF-8. Something must be really messed up.");
-            return;
-        }
-
-        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/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListing.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListing.java
deleted file mode 100644
index 2ad167d..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListing.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import android.bluetooth.client.map.BluetoothMasClient.MessagesFilter;
-import android.bluetooth.client.map.utils.ObexAppParameters;
-import android.bluetooth.client.map.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);
-        }
-        /* Include parameterMask only when specific values are selected,
-         * to avoid IOT specific issue with no paramterMask header support.
-         */
-        if (parameters >  0 ) {
-            oap.add(OAP_TAGID_PARAMETER_MASK, parameters);
-        }
-        // Allow GetMessageListing for maxlistcount value 0 also.
-        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);
-            if(mseTime != null )
-               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/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListingSize.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListingSize.java
deleted file mode 100644
index cdadb2e..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListingSize.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import  android.bluetooth.client.map.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/android/bluetooth/client/map/BluetoothMasRequestPushMessage.java b/src/android/bluetooth/client/map/BluetoothMasRequestPushMessage.java
deleted file mode 100644
index 8fc9bd4..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequestPushMessage.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import java.io.IOException;
-import java.math.BigInteger;
-
-import javax.obex.ClientSession;
-import javax.obex.HeaderSet;
-import javax.obex.ResponseCodes;
-
-import android.bluetooth.client.map.BluetoothMasClient.CharsetType;
-import android.bluetooth.client.map.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/android/bluetooth/client/map/BluetoothMasRequestSetMessageStatus.java b/src/android/bluetooth/client/map/BluetoothMasRequestSetMessageStatus.java
deleted file mode 100644
index 140312e..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequestSetMessageStatus.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import android.bluetooth.client.map.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/android/bluetooth/client/map/BluetoothMasRequestSetNotificationRegistration.java b/src/android/bluetooth/client/map/BluetoothMasRequestSetNotificationRegistration.java
deleted file mode 100644
index debb508..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequestSetNotificationRegistration.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import android.bluetooth.client.map.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/android/bluetooth/client/map/BluetoothMasRequestSetPath.java b/src/android/bluetooth/client/map/BluetoothMasRequestSetPath.java
deleted file mode 100644
index 71e2dbe..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequestSetPath.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-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/android/bluetooth/client/map/BluetoothMasRequestUpdateInbox.java b/src/android/bluetooth/client/map/BluetoothMasRequestUpdateInbox.java
deleted file mode 100644
index aeec632..0000000
--- a/src/android/bluetooth/client/map/BluetoothMasRequestUpdateInbox.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-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/android/bluetooth/client/map/BluetoothMnsObexServer.java b/src/android/bluetooth/client/map/BluetoothMnsObexServer.java
deleted file mode 100644
index 672e9cf..0000000
--- a/src/android/bluetooth/client/map/BluetoothMnsObexServer.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-import android.os.Handler;
-import android.util.Log;
-
-import android.bluetooth.client.map.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;
-        }
-
-        reply.setHeader(HeaderSet.WHO, MNS_TARGET);
-        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/android/bluetooth/client/map/BluetoothMnsService.java b/src/android/bluetooth/client/map/BluetoothMnsService.java
deleted file mode 100644
index 42175e0..0000000
--- a/src/android/bluetooth/client/map/BluetoothMnsService.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map;
-
-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/android/bluetooth/client/map/utils/BmsgTokenizer.java b/src/android/bluetooth/client/map/utils/BmsgTokenizer.java
deleted file mode 100644
index 9f23961..0000000
--- a/src/android/bluetooth/client/map/utils/BmsgTokenizer.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map.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/android/bluetooth/client/map/utils/ObexAppParameters.java b/src/android/bluetooth/client/map/utils/ObexAppParameters.java
deleted file mode 100644
index cae379b..0000000
--- a/src/android/bluetooth/client/map/utils/ObexAppParameters.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map.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/android/bluetooth/client/map/utils/ObexTime.java b/src/android/bluetooth/client/map/utils/ObexTime.java
deleted file mode 100644
index b35ce81..0000000
--- a/src/android/bluetooth/client/map/utils/ObexTime.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth.client.map.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));
-    }
-}
