diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c
index 4426874..60cc521 100644
--- a/cmds/keystore/keystore.c
+++ b/cmds/keystore/keystore.c
@@ -46,7 +46,7 @@
  * user-defined password. To keep things simple, buffers are always larger than
  * the maximum space we needed, so boundary checks on buffers are omitted. */
 
-#define KEY_SIZE        120
+#define KEY_SIZE        ((NAME_MAX - 15) / 2)
 #define VALUE_SIZE      32768
 #define PASSWORD_SIZE   VALUE_SIZE
 
@@ -442,10 +442,11 @@
     uid_t euid;
     uint32_t perms;
 } users[] = {
-    {AID_SYSTEM,   0,          ~GET},
+    {AID_SYSTEM,   ~0,         ~GET},
     {AID_VPN,      AID_SYSTEM, GET},
     {AID_WIFI,     AID_SYSTEM, GET},
-    {0,            0,          TEST | GET | INSERT | DELETE | EXIST | SAW},
+    {AID_ROOT,     AID_SYSTEM, GET},
+    {~0,           ~0,         TEST | GET | INSERT | DELETE | EXIST | SAW},
 };
 
 static int8_t process(int8_t code) {
@@ -453,7 +454,7 @@
     struct action *action = actions;
     int i;
 
-    while (user->uid && user->uid != uid) {
+    while (~user->uid && user->uid != uid) {
         ++user;
     }
     while (action->code && action->code != code) {
@@ -468,7 +469,7 @@
     if (action->state && action->state != state) {
         return state;
     }
-    if (user->euid) {
+    if (~user->euid) {
         uid = user->euid;
     }
     for (i = 0; i < MAX_PARAM && action->lengths[i]; ++i) {
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index c080513..7ca7875 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -156,7 +156,11 @@
     if (mFlags & DisplayHardware::DIRECT_TEXTURE) {
         if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) {
             if (mTextures[index].dirty) {
-                initializeEglImage(buffer, &mTextures[index]);
+                if (initializeEglImage(buffer, &mTextures[index]) != NO_ERROR) {
+                    // not sure what we can do here...
+                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
+                    goto slowpath;
+                }
             }
         } else {
             if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width ||
@@ -166,8 +170,13 @@
                         buffer->width, buffer->height, buffer->format,
                         GraphicBuffer::USAGE_SW_WRITE_OFTEN |
                         GraphicBuffer::USAGE_HW_TEXTURE);
-                initializeEglImage(
-                        mHybridBuffer, &mTextures[0]);
+                if (initializeEglImage(
+                        mHybridBuffer, &mTextures[0]) != NO_ERROR) {
+                    // not sure what we can do here...
+                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
+                    mHybridBuffer.clear();
+                    goto slowpath;
+                }
             }
 
             GGLSurface t;
@@ -236,6 +245,7 @@
     } else
 #endif
     {
+slowpath:
         for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
             mTextures[i].image = EGL_NO_IMAGE_KHR;
         }
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index b0109ca..63b5720 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -666,22 +666,15 @@
             dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
             (EGLClientBuffer)clientBuf, attrs);
 
-    LOGE_IF(texture->image == EGL_NO_IMAGE_KHR,
-            "eglCreateImageKHR() failed. err=0x%4x",
-            eglGetError());
-
     if (texture->image != EGL_NO_IMAGE_KHR) {
         glBindTexture(GL_TEXTURE_2D, texture->name);
         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
                 (GLeglImageOES)texture->image);
         GLint error = glGetError();
         if (UNLIKELY(error != GL_NO_ERROR)) {
-            // this failed, for instance, because we don't support NPOT.
-            // FIXME: do something!
             LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
                  "failed err=0x%04x",
                  this, texture->image, error);
-            mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
             err = INVALID_OPERATION;
         } else {
             // Everything went okay!
@@ -691,6 +684,8 @@
             texture->height = clientBuf->height;
         }
     } else {
+        LOGE("layer=%p, eglCreateImageKHR() failed. err=0x%4x",
+                this, eglGetError());
         err = INVALID_OPERATION;
     }
     return err;
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 6d1685b..5c21593 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -261,7 +261,8 @@
 // LayerBuffer::Buffer
 // ============================================================================
 
-LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset)
+LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers,
+        ssize_t offset, size_t bufferSize)
     : mBufferHeap(buffers), mSupportsCopybit(false)
 {
     NativeBuffer& src(mNativeBuffer);
@@ -280,7 +281,7 @@
     if (module && module->perform) {
         int err = module->perform(module,
                 GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER,
-                buffers.heap->heapID(), buffers.heap->getSize(),
+                buffers.heap->heapID(), bufferSize,
                 offset, buffers.heap->base(),
                 &src.img.handle);
 
@@ -415,7 +416,7 @@
 
     sp<Buffer> buffer;
     if (buffers.heap != 0) {
-        buffer = new LayerBuffer::Buffer(buffers, offset);
+        buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize);
         if (buffer->getStatus() != NO_ERROR)
             buffer.clear();
         setBuffer(buffer);
@@ -469,6 +470,11 @@
     if (mLayer.mFlags & DisplayHardware::DIRECT_TEXTURE) {
         err = INVALID_OPERATION;
         if (ourBuffer->supportsCopybit()) {
+
+            // there are constraints on buffers used by the GPU and these may not
+            // be honored here. We need to change the API so the buffers
+            // are allocated with gralloc. For now disable this code-path
+#if 0
             // First, try to use the buffer as an EGLImage directly
             if (mUseEGLImageDirectly) {
                 // NOTE: Assume the buffer is allocated with the proper USAGE flags
@@ -483,6 +489,8 @@
                     mUseEGLImageDirectly = false;
                 }
             }
+#endif
+
             copybit_device_t* copybit = mLayer.mBlitEngine;
             if (copybit && err != NO_ERROR) {
                 // create our EGLImageKHR the first time
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index eb5b8eb..b176623 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -99,7 +99,8 @@
 
     class Buffer : public LightRefBase<Buffer> {
     public:
-        Buffer(const ISurface::BufferHeap& buffers, ssize_t offset);
+        Buffer(const ISurface::BufferHeap& buffers,
+                ssize_t offset, size_t bufferSize);
         inline bool supportsCopybit() const {
             return mSupportsCopybit;
         }
diff --git a/mms-common/Android.mk b/mms-common/Android.mk
deleted file mode 100644
index 57f1ccc..0000000
--- a/mms-common/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# Note: the source code is in java/, not src/, because this code is also part of
-# the framework library, and build/core/pathmap.mk expects a java/ subdirectory.
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := mms-common
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-LOCAL_STATIC_JAVA_LIBRARIES += android-common
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-# Include this library in the build server's output directory
-$(call dist-for-goals, droid, $(LOCAL_BUILT_MODULE):mms-common.jar)
-
-# Build the test package
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/mms-common/java/com/android/mmscommon/CharacterSets.java b/mms-common/java/com/android/mmscommon/CharacterSets.java
deleted file mode 100644
index f19b078..0000000
--- a/mms-common/java/com/android/mmscommon/CharacterSets.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon;
-
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-
-public class CharacterSets {
-    /**
-     * IANA assigned MIB enum numbers.
-     *
-     * From wap-230-wsp-20010705-a.pdf
-     * Any-charset = <Octet 128>
-     * Equivalent to the special RFC2616 charset value "*"
-     */
-    public static final int ANY_CHARSET = 0x00;
-    public static final int US_ASCII    = 0x03;
-    public static final int ISO_8859_1  = 0x04;
-    public static final int ISO_8859_2  = 0x05;
-    public static final int ISO_8859_3  = 0x06;
-    public static final int ISO_8859_4  = 0x07;
-    public static final int ISO_8859_5  = 0x08;
-    public static final int ISO_8859_6  = 0x09;
-    public static final int ISO_8859_7  = 0x0A;
-    public static final int ISO_8859_8  = 0x0B;
-    public static final int ISO_8859_9  = 0x0C;
-    public static final int SHIFT_JIS   = 0x11;
-    public static final int UTF_8       = 0x6A;
-    public static final int BIG5        = 0x07EA;
-    public static final int UCS2        = 0x03E8;
-    public static final int UTF_16      = 0x03F7;
-
-    /**
-     * If the encoding of given data is unsupported, use UTF_8 to decode it.
-     */
-    public static final int DEFAULT_CHARSET = UTF_8;
-
-    /**
-     * Array of MIB enum numbers.
-     */
-    private static final int[] MIBENUM_NUMBERS = {
-        ANY_CHARSET,
-        US_ASCII,
-        ISO_8859_1,
-        ISO_8859_2,
-        ISO_8859_3,
-        ISO_8859_4,
-        ISO_8859_5,
-        ISO_8859_6,
-        ISO_8859_7,
-        ISO_8859_8,
-        ISO_8859_9,
-        SHIFT_JIS,
-        UTF_8,
-        BIG5,
-        UCS2,
-        UTF_16,
-    };
-
-    /**
-     * The Well-known-charset Mime name.
-     */
-    public static final String MIMENAME_ANY_CHARSET = "*";
-    public static final String MIMENAME_US_ASCII    = "us-ascii";
-    public static final String MIMENAME_ISO_8859_1  = "iso-8859-1";
-    public static final String MIMENAME_ISO_8859_2  = "iso-8859-2";
-    public static final String MIMENAME_ISO_8859_3  = "iso-8859-3";
-    public static final String MIMENAME_ISO_8859_4  = "iso-8859-4";
-    public static final String MIMENAME_ISO_8859_5  = "iso-8859-5";
-    public static final String MIMENAME_ISO_8859_6  = "iso-8859-6";
-    public static final String MIMENAME_ISO_8859_7  = "iso-8859-7";
-    public static final String MIMENAME_ISO_8859_8  = "iso-8859-8";
-    public static final String MIMENAME_ISO_8859_9  = "iso-8859-9";
-    public static final String MIMENAME_SHIFT_JIS   = "shift_JIS";
-    public static final String MIMENAME_UTF_8       = "utf-8";
-    public static final String MIMENAME_BIG5        = "big5";
-    public static final String MIMENAME_UCS2        = "iso-10646-ucs-2";
-    public static final String MIMENAME_UTF_16      = "utf-16";
-
-    public static final String DEFAULT_CHARSET_NAME = MIMENAME_UTF_8;
-
-    /**
-     * Array of the names of character sets.
-     */
-    private static final String[] MIME_NAMES = {
-        MIMENAME_ANY_CHARSET,
-        MIMENAME_US_ASCII,
-        MIMENAME_ISO_8859_1,
-        MIMENAME_ISO_8859_2,
-        MIMENAME_ISO_8859_3,
-        MIMENAME_ISO_8859_4,
-        MIMENAME_ISO_8859_5,
-        MIMENAME_ISO_8859_6,
-        MIMENAME_ISO_8859_7,
-        MIMENAME_ISO_8859_8,
-        MIMENAME_ISO_8859_9,
-        MIMENAME_SHIFT_JIS,
-        MIMENAME_UTF_8,
-        MIMENAME_BIG5,
-        MIMENAME_UCS2,
-        MIMENAME_UTF_16,
-    };
-
-    private static final HashMap<Integer, String> MIBENUM_TO_NAME_MAP;
-    private static final HashMap<String, Integer> NAME_TO_MIBENUM_MAP;
-
-    static {
-        // Create the HashMaps.
-        MIBENUM_TO_NAME_MAP = new HashMap<Integer, String>();
-        NAME_TO_MIBENUM_MAP = new HashMap<String, Integer>();
-        assert(MIBENUM_NUMBERS.length == MIME_NAMES.length);
-        int count = MIBENUM_NUMBERS.length - 1;
-        for(int i = 0; i <= count; i++) {
-            MIBENUM_TO_NAME_MAP.put(MIBENUM_NUMBERS[i], MIME_NAMES[i]);
-            NAME_TO_MIBENUM_MAP.put(MIME_NAMES[i], MIBENUM_NUMBERS[i]);
-        }
-    }
-
-    private CharacterSets() {} // Non-instantiatable
-
-    /**
-     * Map an MIBEnum number to the name of the charset which this number
-     * is assigned to by IANA.
-     *
-     * @param mibEnumValue An IANA assigned MIBEnum number.
-     * @return The name string of the charset.
-     * @throws UnsupportedEncodingException
-     */
-    public static String getMimeName(int mibEnumValue)
-            throws UnsupportedEncodingException {
-        String name = MIBENUM_TO_NAME_MAP.get(mibEnumValue);
-        if (name == null) {
-            throw new UnsupportedEncodingException();
-        }
-        return name;
-    }
-
-    /**
-     * Map a well-known charset name to its assigned MIBEnum number.
-     *
-     * @param mimeName The charset name.
-     * @return The MIBEnum number assigned by IANA for this charset.
-     * @throws UnsupportedEncodingException
-     */
-    public static int getMibEnumValue(String mimeName)
-            throws UnsupportedEncodingException {
-        if(null == mimeName) {
-            return -1;
-        }
-
-        Integer mibEnumValue = NAME_TO_MIBENUM_MAP.get(mimeName);
-        if (mibEnumValue == null) {
-            throw new UnsupportedEncodingException();
-        }
-        return mibEnumValue;
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/ContentType.java b/mms-common/java/com/android/mmscommon/ContentType.java
deleted file mode 100644
index ca449fe..0000000
--- a/mms-common/java/com/android/mmscommon/ContentType.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 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 com.android.mmscommon;
-
-import java.util.ArrayList;
-
-public class ContentType {
-    public static final String MMS_MESSAGE       = "application/vnd.wap.mms-message";
-    // The phony content type for generic PDUs (e.g. ReadOrig.ind,
-    // Notification.ind, Delivery.ind).
-    public static final String MMS_GENERIC       = "application/vnd.wap.mms-generic";
-    public static final String MULTIPART_MIXED   = "application/vnd.wap.multipart.mixed";
-    public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related";
-    public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative";
-
-    public static final String TEXT_PLAIN        = "text/plain";
-    public static final String TEXT_HTML         = "text/html";
-    public static final String TEXT_VCALENDAR    = "text/x-vCalendar";
-    public static final String TEXT_VCARD        = "text/x-vCard";
-
-    public static final String IMAGE_UNSPECIFIED = "image/*";
-    public static final String IMAGE_JPEG        = "image/jpeg";
-    public static final String IMAGE_JPG         = "image/jpg";
-    public static final String IMAGE_GIF         = "image/gif";
-    public static final String IMAGE_WBMP        = "image/vnd.wap.wbmp";
-    public static final String IMAGE_PNG         = "image/png";
-
-    public static final String AUDIO_UNSPECIFIED = "audio/*";
-    public static final String AUDIO_AAC         = "audio/aac";
-    public static final String AUDIO_AMR         = "audio/amr";
-    public static final String AUDIO_IMELODY     = "audio/imelody";
-    public static final String AUDIO_MID         = "audio/mid";
-    public static final String AUDIO_MIDI        = "audio/midi";
-    public static final String AUDIO_MP3         = "audio/mp3";
-    public static final String AUDIO_MPEG3       = "audio/mpeg3";
-    public static final String AUDIO_MPEG        = "audio/mpeg";
-    public static final String AUDIO_MPG         = "audio/mpg";
-    public static final String AUDIO_MP4         = "audio/mp4";
-    public static final String AUDIO_X_MID       = "audio/x-mid";
-    public static final String AUDIO_X_MIDI      = "audio/x-midi";
-    public static final String AUDIO_X_MP3       = "audio/x-mp3";
-    public static final String AUDIO_X_MPEG3     = "audio/x-mpeg3";
-    public static final String AUDIO_X_MPEG      = "audio/x-mpeg";
-    public static final String AUDIO_X_MPG       = "audio/x-mpg";
-    public static final String AUDIO_3GPP        = "audio/3gpp";
-    public static final String AUDIO_OGG         = "application/ogg";
-
-    public static final String VIDEO_UNSPECIFIED = "video/*";
-    public static final String VIDEO_3GPP        = "video/3gpp";
-    public static final String VIDEO_3G2         = "video/3gpp2";
-    public static final String VIDEO_H263        = "video/h263";
-    public static final String VIDEO_MP4         = "video/mp4";
-
-    public static final String APP_SMIL          = "application/smil";
-    public static final String APP_WAP_XHTML     = "application/vnd.wap.xhtml+xml";
-    public static final String APP_XHTML         = "application/xhtml+xml";
-
-    public static final String APP_DRM_CONTENT   = "application/vnd.oma.drm.content";
-    public static final String APP_DRM_MESSAGE   = "application/vnd.oma.drm.message";
-
-    private static final ArrayList<String> sSupportedContentTypes = new ArrayList<String>();
-    private static final ArrayList<String> sSupportedImageTypes = new ArrayList<String>();
-    private static final ArrayList<String> sSupportedAudioTypes = new ArrayList<String>();
-    private static final ArrayList<String> sSupportedVideoTypes = new ArrayList<String>();
-
-    static {
-        sSupportedContentTypes.add(TEXT_PLAIN);
-        sSupportedContentTypes.add(TEXT_HTML);
-        sSupportedContentTypes.add(TEXT_VCALENDAR);
-        sSupportedContentTypes.add(TEXT_VCARD);
-
-        sSupportedContentTypes.add(IMAGE_JPEG);
-        sSupportedContentTypes.add(IMAGE_GIF);
-        sSupportedContentTypes.add(IMAGE_WBMP);
-        sSupportedContentTypes.add(IMAGE_PNG);
-        sSupportedContentTypes.add(IMAGE_JPG);
-        //supportedContentTypes.add(IMAGE_SVG); not yet supported.
-
-        sSupportedContentTypes.add(AUDIO_AAC);
-        sSupportedContentTypes.add(AUDIO_AMR);
-        sSupportedContentTypes.add(AUDIO_IMELODY);
-        sSupportedContentTypes.add(AUDIO_MID);
-        sSupportedContentTypes.add(AUDIO_MIDI);
-        sSupportedContentTypes.add(AUDIO_MP3);
-        sSupportedContentTypes.add(AUDIO_MPEG3);
-        sSupportedContentTypes.add(AUDIO_MPEG);
-        sSupportedContentTypes.add(AUDIO_MPG);
-        sSupportedContentTypes.add(AUDIO_X_MID);
-        sSupportedContentTypes.add(AUDIO_X_MIDI);
-        sSupportedContentTypes.add(AUDIO_X_MP3);
-        sSupportedContentTypes.add(AUDIO_X_MPEG3);
-        sSupportedContentTypes.add(AUDIO_X_MPEG);
-        sSupportedContentTypes.add(AUDIO_X_MPG);
-        sSupportedContentTypes.add(AUDIO_3GPP);
-        sSupportedContentTypes.add(AUDIO_OGG);
-
-        sSupportedContentTypes.add(VIDEO_3GPP);
-        sSupportedContentTypes.add(VIDEO_3G2);
-        sSupportedContentTypes.add(VIDEO_H263);
-        sSupportedContentTypes.add(VIDEO_MP4);
-
-        sSupportedContentTypes.add(APP_SMIL);
-        sSupportedContentTypes.add(APP_WAP_XHTML);
-        sSupportedContentTypes.add(APP_XHTML);
-
-        sSupportedContentTypes.add(APP_DRM_CONTENT);
-        sSupportedContentTypes.add(APP_DRM_MESSAGE);
-
-        // add supported image types
-        sSupportedImageTypes.add(IMAGE_JPEG);
-        sSupportedImageTypes.add(IMAGE_GIF);
-        sSupportedImageTypes.add(IMAGE_WBMP);
-        sSupportedImageTypes.add(IMAGE_PNG);
-        sSupportedImageTypes.add(IMAGE_JPG);
-
-        // add supported audio types
-        sSupportedAudioTypes.add(AUDIO_AAC);
-        sSupportedAudioTypes.add(AUDIO_AMR);
-        sSupportedAudioTypes.add(AUDIO_IMELODY);
-        sSupportedAudioTypes.add(AUDIO_MID);
-        sSupportedAudioTypes.add(AUDIO_MIDI);
-        sSupportedAudioTypes.add(AUDIO_MP3);
-        sSupportedAudioTypes.add(AUDIO_MPEG3);
-        sSupportedAudioTypes.add(AUDIO_MPEG);
-        sSupportedAudioTypes.add(AUDIO_MPG);
-        sSupportedAudioTypes.add(AUDIO_MP4);
-        sSupportedAudioTypes.add(AUDIO_X_MID);
-        sSupportedAudioTypes.add(AUDIO_X_MIDI);
-        sSupportedAudioTypes.add(AUDIO_X_MP3);
-        sSupportedAudioTypes.add(AUDIO_X_MPEG3);
-        sSupportedAudioTypes.add(AUDIO_X_MPEG);
-        sSupportedAudioTypes.add(AUDIO_X_MPG);
-        sSupportedAudioTypes.add(AUDIO_3GPP);
-        sSupportedAudioTypes.add(AUDIO_OGG);
-
-        // add supported video types
-        sSupportedVideoTypes.add(VIDEO_3GPP);
-        sSupportedVideoTypes.add(VIDEO_3G2);
-        sSupportedVideoTypes.add(VIDEO_H263);
-        sSupportedVideoTypes.add(VIDEO_MP4);
-    }
-
-    // This class should never be instantiated.
-    private ContentType() {
-    }
-
-    public static boolean isSupportedType(String contentType) {
-        return (null != contentType) && sSupportedContentTypes.contains(contentType);
-    }
-
-    public static boolean isSupportedImageType(String contentType) {
-        return isImageType(contentType) && isSupportedType(contentType);
-    }
-
-    public static boolean isSupportedAudioType(String contentType) {
-        return isAudioType(contentType) && isSupportedType(contentType);
-    }
-
-    public static boolean isSupportedVideoType(String contentType) {
-        return isVideoType(contentType) && isSupportedType(contentType);
-    }
-
-    public static boolean isTextType(String contentType) {
-        return (null != contentType) && contentType.startsWith("text/");
-    }
-
-    public static boolean isImageType(String contentType) {
-        return (null != contentType) && contentType.startsWith("image/");
-    }
-
-    public static boolean isAudioType(String contentType) {
-        return (null != contentType) && contentType.startsWith("audio/");
-    }
-
-    public static boolean isVideoType(String contentType) {
-        return (null != contentType) && contentType.startsWith("video/");
-    }
-
-    public static boolean isDrmType(String contentType) {
-        return (null != contentType)
-                && (contentType.equals(APP_DRM_CONTENT)
-                        || contentType.equals(APP_DRM_MESSAGE));
-    }
-
-    public static boolean isUnspecified(String contentType) {
-        return (null != contentType) && contentType.endsWith("*");
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getImageTypes() {
-        return (ArrayList<String>) sSupportedImageTypes.clone();
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getAudioTypes() {
-        return (ArrayList<String>) sSupportedAudioTypes.clone();
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getVideoTypes() {
-        return (ArrayList<String>) sSupportedVideoTypes.clone();
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getSupportedTypes() {
-        return (ArrayList<String>) sSupportedContentTypes.clone();
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/EncodedStringValue.java b/mms-common/java/com/android/mmscommon/EncodedStringValue.java
deleted file mode 100644
index 0a4424e..0000000
--- a/mms-common/java/com/android/mmscommon/EncodedStringValue.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 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 com.android.mmscommon;
-
-import android.util.Config;
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-
-/**
- * Encoded-string-value = Text-string | Value-length Char-set Text-string
- */
-public class EncodedStringValue implements Cloneable {
-    private static final String TAG = "EncodedStringValue";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
-
-    /**
-     * The Char-set value.
-     */
-    private int mCharacterSet;
-
-    /**
-     * The Text-string value.
-     */
-    private byte[] mData;
-
-    /**
-     * Constructor.
-     *
-     * @param charset the Char-set value
-     * @param data the Text-string value
-     * @throws NullPointerException if Text-string value is null.
-     */
-    public EncodedStringValue(int charset, byte[] data) {
-        // TODO: CharSet needs to be validated against MIBEnum.
-        if(null == data) {
-            throw new NullPointerException("EncodedStringValue: Text-string is null.");
-        }
-
-        mCharacterSet = charset;
-        mData = new byte[data.length];
-        System.arraycopy(data, 0, mData, 0, data.length);
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param data the Text-string value
-     * @throws NullPointerException if Text-string value is null.
-     */
-    public EncodedStringValue(byte[] data) {
-        this(CharacterSets.DEFAULT_CHARSET, data);
-    }
-
-    public EncodedStringValue(String data) {
-        try {
-            mData = data.getBytes(CharacterSets.DEFAULT_CHARSET_NAME);
-            mCharacterSet = CharacterSets.DEFAULT_CHARSET;
-        } catch (UnsupportedEncodingException e) {
-            Log.e(TAG, "Default encoding must be supported.", e);
-        }
-    }
-
-    /**
-     * Get Char-set value.
-     *
-     * @return the value
-     */
-    public int getCharacterSet() {
-        return mCharacterSet;
-    }
-
-    /**
-     * Set Char-set value.
-     *
-     * @param charset the Char-set value
-     */
-    public void setCharacterSet(int charset) {
-        // TODO: CharSet needs to be validated against MIBEnum.
-        mCharacterSet = charset;
-    }
-
-    /**
-     * Get Text-string value.
-     *
-     * @return the value
-     */
-    public byte[] getTextString() {
-        byte[] byteArray = new byte[mData.length];
-
-        System.arraycopy(mData, 0, byteArray, 0, mData.length);
-        return byteArray;
-    }
-
-    /**
-     * Set Text-string value.
-     *
-     * @param textString the Text-string value
-     * @throws NullPointerException if Text-string value is null.
-     */
-    public void setTextString(byte[] textString) {
-        if(null == textString) {
-            throw new NullPointerException("EncodedStringValue: Text-string is null.");
-        }
-
-        mData = new byte[textString.length];
-        System.arraycopy(textString, 0, mData, 0, textString.length);
-    }
-
-    /**
-     * Convert this object to a {@link java.lang.String}. If the encoding of
-     * the EncodedStringValue is null or unsupported, it will be
-     * treated as iso-8859-1 encoding.
-     *
-     * @return The decoded String.
-     */
-    public String getString()  {
-        if (CharacterSets.ANY_CHARSET == mCharacterSet) {
-            return new String(mData); // system default encoding.
-        } else {
-            try {
-                String name = CharacterSets.getMimeName(mCharacterSet);
-                return new String(mData, name);
-            } catch (UnsupportedEncodingException e) {
-            	if (LOCAL_LOGV) {
-            		Log.v(TAG, e.getMessage(), e);
-            	}
-            	try {
-                    return new String(mData, CharacterSets.MIMENAME_ISO_8859_1);
-                } catch (UnsupportedEncodingException _) {
-                    return new String(mData); // system default encoding.
-                }
-            }
-        }
-    }
-
-    /**
-     * Append to Text-string.
-     *
-     * @param textString the textString to append
-     * @throws NullPointerException if the text String is null
-     *                      or an IOException occured.
-     */
-    public void appendTextString(byte[] textString) {
-        if(null == textString) {
-            throw new NullPointerException("Text-string is null.");
-        }
-
-        if(null == mData) {
-            mData = new byte[textString.length];
-            System.arraycopy(textString, 0, mData, 0, textString.length);
-        } else {
-            ByteArrayOutputStream newTextString = new ByteArrayOutputStream();
-            try {
-                newTextString.write(mData);
-                newTextString.write(textString);
-            } catch (IOException e) {
-                e.printStackTrace();
-                throw new NullPointerException(
-                        "appendTextString: failed when write a new Text-string");
-            }
-
-            mData = newTextString.toByteArray();
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see java.lang.Object#clone()
-     */
-    @Override
-    public Object clone() throws CloneNotSupportedException {
-        super.clone();
-        int len = mData.length;
-        byte[] dstBytes = new byte[len];
-        System.arraycopy(mData, 0, dstBytes, 0, len);
-
-        try {
-            return new EncodedStringValue(mCharacterSet, dstBytes);
-        } catch (Exception e) {
-            Log.e(TAG, "failed to clone an EncodedStringValue: " + this);
-            e.printStackTrace();
-            throw new CloneNotSupportedException(e.getMessage());
-        }
-    }
-
-    /**
-     * Split this encoded string around matches of the given pattern.
-     *
-     * @param pattern the delimiting pattern
-     * @return the array of encoded strings computed by splitting this encoded
-     *         string around matches of the given pattern
-     */
-    public EncodedStringValue[] split(String pattern) {
-        String[] temp = getString().split(pattern);
-        EncodedStringValue[] ret = new EncodedStringValue[temp.length];
-        for (int i = 0; i < ret.length; ++i) {
-            try {
-                ret[i] = new EncodedStringValue(mCharacterSet,
-                        temp[i].getBytes());
-            } catch (NullPointerException _) {
-                // Can't arrive here
-                return null;
-            }
-        }
-        return ret;
-    }
-
-    /**
-     * Extract an EncodedStringValue[] from a given String.
-     */
-    public static EncodedStringValue[] extract(String src) {
-        String[] values = src.split(";");
-
-        ArrayList<EncodedStringValue> list = new ArrayList<EncodedStringValue>();
-        for (int i = 0; i < values.length; i++) {
-            if (values[i].length() > 0) {
-                list.add(new EncodedStringValue(values[i]));
-            }
-        }
-
-        int len = list.size();
-        if (len > 0) {
-            return list.toArray(new EncodedStringValue[len]);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Concatenate an EncodedStringValue[] into a single String.
-     */
-    public static String concat(EncodedStringValue[] addr) {
-        StringBuilder sb = new StringBuilder();
-        int maxIndex = addr.length - 1;
-        for (int i = 0; i <= maxIndex; i++) {
-            sb.append(addr[i].getString());
-            if (i < maxIndex) {
-                sb.append(";");
-            }
-        }
-
-        return sb.toString();
-    }
-
-    public static EncodedStringValue copy(EncodedStringValue value) {
-        if (value == null) {
-            return null;
-        }
-
-        return new EncodedStringValue(value.mCharacterSet, value.mData);
-    }
-
-    public static EncodedStringValue[] encodeStrings(String[] array) {
-        int count = array.length;
-        if (count > 0) {
-            EncodedStringValue[] encodedArray = new EncodedStringValue[count];
-            for (int i = 0; i < count; i++) {
-                encodedArray[i] = new EncodedStringValue(array[i]);
-            }
-            return encodedArray;
-        }
-        return null;
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/InvalidHeaderValueException.java b/mms-common/java/com/android/mmscommon/InvalidHeaderValueException.java
deleted file mode 100644
index 34d5871..0000000
--- a/mms-common/java/com/android/mmscommon/InvalidHeaderValueException.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon;
-
-/**
- * Thrown when an invalid header value was set.
- */
-public class InvalidHeaderValueException extends MmsException {
-    private static final long serialVersionUID = -2053384496042052262L;
-
-    /**
-     * Constructs an InvalidHeaderValueException with no detailed message.
-     */
-    public InvalidHeaderValueException() {
-        super();
-    }
-
-    /**
-     * Constructs an InvalidHeaderValueException with the specified detailed message.
-     *
-     * @param message the detailed message.
-     */
-    public InvalidHeaderValueException(String message) {
-        super(message);
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/MmsException.java b/mms-common/java/com/android/mmscommon/MmsException.java
deleted file mode 100644
index 296a2c3..0000000
--- a/mms-common/java/com/android/mmscommon/MmsException.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon;
-
-/**
- * A generic exception that is thrown by the Mms client.
- */
-public class MmsException extends Exception {
-    private static final long serialVersionUID = -7323249827281485390L;
-
-    /**
-     * Creates a new MmsException.
-     */
-    public MmsException() {
-        super();
-    }
-
-    /**
-     * Creates a new MmsException with the specified detail message.
-     *
-     * @param message the detail message.
-     */
-    public MmsException(String message) {
-        super(message);
-    }
-
-    /**
-     * Creates a new MmsException with the specified cause.
-     *
-     * @param cause the cause.
-     */
-    public MmsException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Creates a new MmsException with the specified detail message and cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public MmsException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/PduHeaders.java b/mms-common/java/com/android/mmscommon/PduHeaders.java
deleted file mode 100644
index d8f1211..0000000
--- a/mms-common/java/com/android/mmscommon/PduHeaders.java
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class PduHeaders {
-    /**
-     * All pdu header fields.
-     */
-    public static final int BCC                             = 0x81;
-    public static final int CC                              = 0x82;
-    public static final int CONTENT_LOCATION                = 0x83;
-    public static final int CONTENT_TYPE                    = 0x84;
-    public static final int DATE                            = 0x85;
-    public static final int DELIVERY_REPORT                 = 0x86;
-    public static final int DELIVERY_TIME                   = 0x87;
-    public static final int EXPIRY                          = 0x88;
-    public static final int FROM                            = 0x89;
-    public static final int MESSAGE_CLASS                   = 0x8A;
-    public static final int MESSAGE_ID                      = 0x8B;
-    public static final int MESSAGE_TYPE                    = 0x8C;
-    public static final int MMS_VERSION                     = 0x8D;
-    public static final int MESSAGE_SIZE                    = 0x8E;
-    public static final int PRIORITY                        = 0x8F;
-
-    public static final int READ_REPLY                      = 0x90;
-    public static final int READ_REPORT                     = 0x90;
-    public static final int REPORT_ALLOWED                  = 0x91;
-    public static final int RESPONSE_STATUS                 = 0x92;
-    public static final int RESPONSE_TEXT                   = 0x93;
-    public static final int SENDER_VISIBILITY               = 0x94;
-    public static final int STATUS                          = 0x95;
-    public static final int SUBJECT                         = 0x96;
-    public static final int TO                              = 0x97;
-    public static final int TRANSACTION_ID                  = 0x98;
-    public static final int RETRIEVE_STATUS                 = 0x99;
-    public static final int RETRIEVE_TEXT                   = 0x9A;
-    public static final int READ_STATUS                     = 0x9B;
-    public static final int REPLY_CHARGING                  = 0x9C;
-    public static final int REPLY_CHARGING_DEADLINE         = 0x9D;
-    public static final int REPLY_CHARGING_ID               = 0x9E;
-    public static final int REPLY_CHARGING_SIZE             = 0x9F;
-
-    public static final int PREVIOUSLY_SENT_BY              = 0xA0;
-    public static final int PREVIOUSLY_SENT_DATE            = 0xA1;
-    public static final int STORE                           = 0xA2;
-    public static final int MM_STATE                        = 0xA3;
-    public static final int MM_FLAGS                        = 0xA4;
-    public static final int STORE_STATUS                    = 0xA5;
-    public static final int STORE_STATUS_TEXT               = 0xA6;
-    public static final int STORED                          = 0xA7;
-    public static final int ATTRIBUTES                      = 0xA8;
-    public static final int TOTALS                          = 0xA9;
-    public static final int MBOX_TOTALS                     = 0xAA;
-    public static final int QUOTAS                          = 0xAB;
-    public static final int MBOX_QUOTAS                     = 0xAC;
-    public static final int MESSAGE_COUNT                   = 0xAD;
-    public static final int CONTENT                         = 0xAE;
-    public static final int START                           = 0xAF;
-
-    public static final int ADDITIONAL_HEADERS              = 0xB0;
-    public static final int DISTRIBUTION_INDICATOR          = 0xB1;
-    public static final int ELEMENT_DESCRIPTOR              = 0xB2;
-    public static final int LIMIT                           = 0xB3;
-    public static final int RECOMMENDED_RETRIEVAL_MODE      = 0xB4;
-    public static final int RECOMMENDED_RETRIEVAL_MODE_TEXT = 0xB5;
-    public static final int STATUS_TEXT                     = 0xB6;
-    public static final int APPLIC_ID                       = 0xB7;
-    public static final int REPLY_APPLIC_ID                 = 0xB8;
-    public static final int AUX_APPLIC_ID                   = 0xB9;
-    public static final int CONTENT_CLASS                   = 0xBA;
-    public static final int DRM_CONTENT                     = 0xBB;
-    public static final int ADAPTATION_ALLOWED              = 0xBC;
-    public static final int REPLACE_ID                      = 0xBD;
-    public static final int CANCEL_ID                       = 0xBE;
-    public static final int CANCEL_STATUS                   = 0xBF;
-
-    /**
-     * X-Mms-Message-Type field types.
-     */
-    public static final int MESSAGE_TYPE_SEND_REQ           = 0x80;
-    public static final int MESSAGE_TYPE_SEND_CONF          = 0x81;
-    public static final int MESSAGE_TYPE_NOTIFICATION_IND   = 0x82;
-    public static final int MESSAGE_TYPE_NOTIFYRESP_IND     = 0x83;
-    public static final int MESSAGE_TYPE_RETRIEVE_CONF      = 0x84;
-    public static final int MESSAGE_TYPE_ACKNOWLEDGE_IND    = 0x85;
-    public static final int MESSAGE_TYPE_DELIVERY_IND       = 0x86;
-    public static final int MESSAGE_TYPE_READ_REC_IND       = 0x87;
-    public static final int MESSAGE_TYPE_READ_ORIG_IND      = 0x88;
-    public static final int MESSAGE_TYPE_FORWARD_REQ        = 0x89;
-    public static final int MESSAGE_TYPE_FORWARD_CONF       = 0x8A;
-    public static final int MESSAGE_TYPE_MBOX_STORE_REQ     = 0x8B;
-    public static final int MESSAGE_TYPE_MBOX_STORE_CONF    = 0x8C;
-    public static final int MESSAGE_TYPE_MBOX_VIEW_REQ      = 0x8D;
-    public static final int MESSAGE_TYPE_MBOX_VIEW_CONF     = 0x8E;
-    public static final int MESSAGE_TYPE_MBOX_UPLOAD_REQ    = 0x8F;
-    public static final int MESSAGE_TYPE_MBOX_UPLOAD_CONF   = 0x90;
-    public static final int MESSAGE_TYPE_MBOX_DELETE_REQ    = 0x91;
-    public static final int MESSAGE_TYPE_MBOX_DELETE_CONF   = 0x92;
-    public static final int MESSAGE_TYPE_MBOX_DESCR         = 0x93;
-    public static final int MESSAGE_TYPE_DELETE_REQ         = 0x94;
-    public static final int MESSAGE_TYPE_DELETE_CONF        = 0x95;
-    public static final int MESSAGE_TYPE_CANCEL_REQ         = 0x96;
-    public static final int MESSAGE_TYPE_CANCEL_CONF        = 0x97;
-
-    /**
-     *  X-Mms-Delivery-Report |
-     *  X-Mms-Read-Report |
-     *  X-Mms-Report-Allowed |
-     *  X-Mms-Sender-Visibility |
-     *  X-Mms-Store |
-     *  X-Mms-Stored |
-     *  X-Mms-Totals |
-     *  X-Mms-Quotas |
-     *  X-Mms-Distribution-Indicator |
-     *  X-Mms-DRM-Content |
-     *  X-Mms-Adaptation-Allowed |
-     *  field types.
-     */
-    public static final int VALUE_YES                       = 0x80;
-    public static final int VALUE_NO                        = 0x81;
-
-    /**
-     *  Delivery-Time |
-     *  Expiry and Reply-Charging-Deadline |
-     *  field type components.
-     */
-    public static final int VALUE_ABSOLUTE_TOKEN            = 0x80;
-    public static final int VALUE_RELATIVE_TOKEN            = 0x81;
-
-    /**
-     * X-Mms-MMS-Version field types.
-     */
-    public static final int MMS_VERSION_1_3                 = ((1 << 4) | 3);
-    public static final int MMS_VERSION_1_2                 = ((1 << 4) | 2);
-    public static final int MMS_VERSION_1_1                 = ((1 << 4) | 1);
-    public static final int MMS_VERSION_1_0                 = ((1 << 4) | 0);
-
-    // Current version is 1.2.
-    public static final int CURRENT_MMS_VERSION             = MMS_VERSION_1_2;
-
-    /**
-     *  From field type components.
-     */
-    public static final int FROM_ADDRESS_PRESENT_TOKEN      = 0x80;
-    public static final int FROM_INSERT_ADDRESS_TOKEN       = 0x81;
-
-    public static final String FROM_ADDRESS_PRESENT_TOKEN_STR = "address-present-token";
-    public static final String FROM_INSERT_ADDRESS_TOKEN_STR = "insert-address-token";
-
-    /**
-     *  X-Mms-Status Field.
-     */
-    public static final int STATUS_EXPIRED                  = 0x80;
-    public static final int STATUS_RETRIEVED                = 0x81;
-    public static final int STATUS_REJECTED                 = 0x82;
-    public static final int STATUS_DEFERRED                 = 0x83;
-    public static final int STATUS_UNRECOGNIZED             = 0x84;
-    public static final int STATUS_INDETERMINATE            = 0x85;
-    public static final int STATUS_FORWARDED                = 0x86;
-    public static final int STATUS_UNREACHABLE              = 0x87;
-
-    /**
-     *  MM-Flags field type components.
-     */
-    public static final int MM_FLAGS_ADD_TOKEN              = 0x80;
-    public static final int MM_FLAGS_REMOVE_TOKEN           = 0x81;
-    public static final int MM_FLAGS_FILTER_TOKEN           = 0x82;
-
-    /**
-     *  X-Mms-Message-Class field types.
-     */
-    public static final int MESSAGE_CLASS_PERSONAL          = 0x80;
-    public static final int MESSAGE_CLASS_ADVERTISEMENT     = 0x81;
-    public static final int MESSAGE_CLASS_INFORMATIONAL     = 0x82;
-    public static final int MESSAGE_CLASS_AUTO              = 0x83;
-
-    public static final String MESSAGE_CLASS_PERSONAL_STR = "personal";
-    public static final String MESSAGE_CLASS_ADVERTISEMENT_STR = "advertisement";
-    public static final String MESSAGE_CLASS_INFORMATIONAL_STR = "informational";
-    public static final String MESSAGE_CLASS_AUTO_STR = "auto";
-
-    /**
-     *  X-Mms-Priority field types.
-     */
-    public static final int PRIORITY_LOW                    = 0x80;
-    public static final int PRIORITY_NORMAL                 = 0x81;
-    public static final int PRIORITY_HIGH                   = 0x82;
-
-    /**
-     *  X-Mms-Response-Status field types.
-     */
-    public static final int RESPONSE_STATUS_OK                   = 0x80;
-    public static final int RESPONSE_STATUS_ERROR_UNSPECIFIED    = 0x81;
-    public static final int RESPONSE_STATUS_ERROR_SERVICE_DENIED = 0x82;
-
-    public static final int RESPONSE_STATUS_ERROR_MESSAGE_FORMAT_CORRUPT     = 0x83;
-    public static final int RESPONSE_STATUS_ERROR_SENDING_ADDRESS_UNRESOLVED = 0x84;
-
-    public static final int RESPONSE_STATUS_ERROR_MESSAGE_NOT_FOUND    = 0x85;
-    public static final int RESPONSE_STATUS_ERROR_NETWORK_PROBLEM      = 0x86;
-    public static final int RESPONSE_STATUS_ERROR_CONTENT_NOT_ACCEPTED = 0x87;
-    public static final int RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE  = 0x88;
-    public static final int RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE    = 0xC0;
-
-    public static final int RESPONSE_STATUS_ERROR_TRANSIENT_SENDNG_ADDRESS_UNRESOLVED = 0xC1;
-    public static final int RESPONSE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND         = 0xC2;
-    public static final int RESPONSE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM           = 0xC3;
-    public static final int RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS           = 0xC4;
-
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_FAILURE                             = 0xE0;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_SERVICE_DENIED                      = 0xE1;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT              = 0xE2;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_SENDING_ADDRESS_UNRESOLVED          = 0xE3;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND                   = 0xE4;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_CONTENT_NOT_ACCEPTED                = 0xE5;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_LIMITATIONS_NOT_MET  = 0xE6;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_REQUEST_NOT_ACCEPTED = 0xE6;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_FORWARDING_DENIED    = 0xE8;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_NOT_SUPPORTED        = 0xE9;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_ADDRESS_HIDING_NOT_SUPPORTED        = 0xEA;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID                     = 0xEB;
-    public static final int RESPONSE_STATUS_ERROR_PERMANENT_END                                 = 0xFF;
-
-    /**
-     *  X-Mms-Retrieve-Status field types.
-     */
-    public static final int RETRIEVE_STATUS_OK                                  = 0x80;
-    public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE             = 0xC0;
-    public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND   = 0xC1;
-    public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM     = 0xC2;
-    public static final int RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE             = 0xE0;
-    public static final int RETRIEVE_STATUS_ERROR_PERMANENT_SERVICE_DENIED      = 0xE1;
-    public static final int RETRIEVE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND   = 0xE2;
-    public static final int RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED = 0xE3;
-    public static final int RETRIEVE_STATUS_ERROR_END                           = 0xFF;
-
-    /**
-     *  X-Mms-Sender-Visibility field types.
-     */
-    public static final int SENDER_VISIBILITY_HIDE          = 0x80;
-    public static final int SENDER_VISIBILITY_SHOW          = 0x81;
-
-    /**
-     *  X-Mms-Read-Status field types.
-     */
-    public static final int READ_STATUS_READ                        = 0x80;
-    public static final int READ_STATUS__DELETED_WITHOUT_BEING_READ = 0x81;
-
-    /**
-     *  X-Mms-Cancel-Status field types.
-     */
-    public static final int CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED = 0x80;
-    public static final int CANCEL_STATUS_REQUEST_CORRUPTED             = 0x81;
-
-    /**
-     *  X-Mms-Reply-Charging field types.
-     */
-    public static final int REPLY_CHARGING_REQUESTED           = 0x80;
-    public static final int REPLY_CHARGING_REQUESTED_TEXT_ONLY = 0x81;
-    public static final int REPLY_CHARGING_ACCEPTED            = 0x82;
-    public static final int REPLY_CHARGING_ACCEPTED_TEXT_ONLY  = 0x83;
-
-    /**
-     *  X-Mms-MM-State field types.
-     */
-    public static final int MM_STATE_DRAFT                  = 0x80;
-    public static final int MM_STATE_SENT                   = 0x81;
-    public static final int MM_STATE_NEW                    = 0x82;
-    public static final int MM_STATE_RETRIEVED              = 0x83;
-    public static final int MM_STATE_FORWARDED              = 0x84;
-
-    /**
-     * X-Mms-Recommended-Retrieval-Mode field types.
-     */
-    public static final int RECOMMENDED_RETRIEVAL_MODE_MANUAL = 0x80;
-
-    /**
-     *  X-Mms-Content-Class field types.
-     */
-    public static final int CONTENT_CLASS_TEXT              = 0x80;
-    public static final int CONTENT_CLASS_IMAGE_BASIC       = 0x81;
-    public static final int CONTENT_CLASS_IMAGE_RICH        = 0x82;
-    public static final int CONTENT_CLASS_VIDEO_BASIC       = 0x83;
-    public static final int CONTENT_CLASS_VIDEO_RICH        = 0x84;
-    public static final int CONTENT_CLASS_MEGAPIXEL         = 0x85;
-    public static final int CONTENT_CLASS_CONTENT_BASIC     = 0x86;
-    public static final int CONTENT_CLASS_CONTENT_RICH      = 0x87;
-
-    /**
-     *  X-Mms-Store-Status field types.
-     */
-    public static final int STORE_STATUS_SUCCESS                                = 0x80;
-    public static final int STORE_STATUS_ERROR_TRANSIENT_FAILURE                = 0xC0;
-    public static final int STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM        = 0xC1;
-    public static final int STORE_STATUS_ERROR_PERMANENT_FAILURE                = 0xE0;
-    public static final int STORE_STATUS_ERROR_PERMANENT_SERVICE_DENIED         = 0xE1;
-    public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2;
-    public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND      = 0xE3;
-    public static final int STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL             = 0xE4;
-    public static final int STORE_STATUS_ERROR_END                              = 0xFF;
-
-    /**
-     * The map contains the value of all headers.
-     */
-    private HashMap<Integer, Object> mHeaderMap = null;
-
-    /**
-     * Constructor of PduHeaders.
-     */
-    public PduHeaders() {
-        mHeaderMap = new HashMap<Integer, Object>();
-    }
-
-    /**
-     * Get octet value by header field.
-     *
-     * @param field the field
-     * @return the octet value of the pdu header
-     *          with specified header field. Return 0 if
-     *          the value is not set.
-     */
-    public int getOctet(int field) {
-        Integer octet = (Integer) mHeaderMap.get(field);
-        if (null == octet) {
-            return 0;
-        }
-
-        return octet;
-    }
-
-    /**
-     * Set octet value to pdu header by header field.
-     *
-     * @param value the value
-     * @param field the field
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setOctet(int value, int field)
-            throws InvalidHeaderValueException{
-        /**
-         * Check whether this field can be set for specific
-         * header and check validity of the field.
-         */
-        switch (field) {
-            case REPORT_ALLOWED:
-            case ADAPTATION_ALLOWED:
-            case DELIVERY_REPORT:
-            case DRM_CONTENT:
-            case DISTRIBUTION_INDICATOR:
-            case QUOTAS:
-            case READ_REPORT:
-            case STORE:
-            case STORED:
-            case TOTALS:
-            case SENDER_VISIBILITY:
-                if ((VALUE_YES != value) && (VALUE_NO != value)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case READ_STATUS:
-                if ((READ_STATUS_READ != value) &&
-                        (READ_STATUS__DELETED_WITHOUT_BEING_READ != value)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case CANCEL_STATUS:
-                if ((CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED != value) &&
-                        (CANCEL_STATUS_REQUEST_CORRUPTED != value)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case PRIORITY:
-                if ((value < PRIORITY_LOW) || (value > PRIORITY_HIGH)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case STATUS:
-                if ((value < STATUS_EXPIRED) || (value > STATUS_UNREACHABLE)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case REPLY_CHARGING:
-                if ((value < REPLY_CHARGING_REQUESTED)
-                        || (value > REPLY_CHARGING_ACCEPTED_TEXT_ONLY)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case MM_STATE:
-                if ((value < MM_STATE_DRAFT) || (value > MM_STATE_FORWARDED)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case RECOMMENDED_RETRIEVAL_MODE:
-                if (RECOMMENDED_RETRIEVAL_MODE_MANUAL != value) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case CONTENT_CLASS:
-                if ((value < CONTENT_CLASS_TEXT)
-                        || (value > CONTENT_CLASS_CONTENT_RICH)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            case RETRIEVE_STATUS:
-                // According to oma-ts-mms-enc-v1_3, section 7.3.50, we modify the invalid value.
-                if ((value > RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) &&
-                        (value < RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE)) {
-                    value = RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE;
-                } else if ((value > RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED) &&
-                        (value <= RETRIEVE_STATUS_ERROR_END)) {
-                    value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE;
-                } else if ((value < RETRIEVE_STATUS_OK) ||
-                        ((value > RETRIEVE_STATUS_OK) &&
-                                (value < RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE)) ||
-                                (value > RETRIEVE_STATUS_ERROR_END)) {
-                    value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE;
-                }
-                break;
-            case STORE_STATUS:
-                // According to oma-ts-mms-enc-v1_3, section 7.3.58, we modify the invalid value.
-                if ((value > STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) &&
-                        (value < STORE_STATUS_ERROR_PERMANENT_FAILURE)) {
-                    value = STORE_STATUS_ERROR_TRANSIENT_FAILURE;
-                } else if ((value > STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL) &&
-                        (value <= STORE_STATUS_ERROR_END)) {
-                    value = STORE_STATUS_ERROR_PERMANENT_FAILURE;
-                } else if ((value < STORE_STATUS_SUCCESS) ||
-                        ((value > STORE_STATUS_SUCCESS) &&
-                                (value < STORE_STATUS_ERROR_TRANSIENT_FAILURE)) ||
-                                (value > STORE_STATUS_ERROR_END)) {
-                    value = STORE_STATUS_ERROR_PERMANENT_FAILURE;
-                }
-                break;
-            case RESPONSE_STATUS:
-                // According to oma-ts-mms-enc-v1_3, section 7.3.48, we modify the invalid value.
-                if ((value > RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS) &&
-                        (value < RESPONSE_STATUS_ERROR_PERMANENT_FAILURE)) {
-                    value = RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE;
-                } else if (((value > RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID) &&
-                        (value <= RESPONSE_STATUS_ERROR_PERMANENT_END)) ||
-                        (value < RESPONSE_STATUS_OK) ||
-                        ((value > RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE) &&
-                                (value < RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE)) ||
-                                (value > RESPONSE_STATUS_ERROR_PERMANENT_END)) {
-                    value = RESPONSE_STATUS_ERROR_PERMANENT_FAILURE;
-                }
-                break;
-            case MMS_VERSION:
-                if ((value < MMS_VERSION_1_0)|| (value > MMS_VERSION_1_3)) {
-                    value = CURRENT_MMS_VERSION; // Current version is the default value.
-                }
-                break;
-            case MESSAGE_TYPE:
-                if ((value < MESSAGE_TYPE_SEND_REQ) || (value > MESSAGE_TYPE_CANCEL_CONF)) {
-                    // Invalid value.
-                    throw new InvalidHeaderValueException("Invalid Octet value!");
-                }
-                break;
-            default:
-                // This header value should not be Octect.
-                throw new RuntimeException("Invalid header field!");
-        }
-        mHeaderMap.put(field, value);
-    }
-
-    /**
-     * Get TextString value by header field.
-     *
-     * @param field the field
-     * @return the TextString value of the pdu header
-     *          with specified header field
-     */
-    public byte[] getTextString(int field) {
-        return (byte[]) mHeaderMap.get(field);
-    }
-
-    /**
-     * Set TextString value to pdu header by header field.
-     *
-     * @param value the value
-     * @param field the field
-     * @return the TextString value of the pdu header
-     *          with specified header field
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTextString(byte[] value, int field) {
-        /**
-         * Check whether this field can be set for specific
-         * header and check validity of the field.
-         */
-        if (null == value) {
-            throw new NullPointerException();
-        }
-
-        switch (field) {
-            case TRANSACTION_ID:
-            case REPLY_CHARGING_ID:
-            case AUX_APPLIC_ID:
-            case APPLIC_ID:
-            case REPLY_APPLIC_ID:
-            case MESSAGE_ID:
-            case REPLACE_ID:
-            case CANCEL_ID:
-            case CONTENT_LOCATION:
-            case MESSAGE_CLASS:
-            case CONTENT_TYPE:
-                break;
-            default:
-                // This header value should not be Text-String.
-                throw new RuntimeException("Invalid header field!");
-        }
-        mHeaderMap.put(field, value);
-    }
-
-    /**
-     * Get EncodedStringValue value by header field.
-     *
-     * @param field the field
-     * @return the EncodedStringValue value of the pdu header
-     *          with specified header field
-     */
-    public EncodedStringValue getEncodedStringValue(int field) {
-        return (EncodedStringValue) mHeaderMap.get(field);
-    }
-
-    /**
-     * Get TO, CC or BCC header value.
-     *
-     * @param field the field
-     * @return the EncodeStringValue array of the pdu header
-     *          with specified header field
-     */
-    public EncodedStringValue[] getEncodedStringValues(int field) {
-        ArrayList<EncodedStringValue> list =
-                (ArrayList<EncodedStringValue>) mHeaderMap.get(field);
-        if (null == list) {
-            return null;
-        }
-        EncodedStringValue[] values = new EncodedStringValue[list.size()];
-        return list.toArray(values);
-    }
-
-    /**
-     * Set EncodedStringValue value to pdu header by header field.
-     *
-     * @param value the value
-     * @param field the field
-     * @return the EncodedStringValue value of the pdu header
-     *          with specified header field
-     * @throws NullPointerException if the value is null.
-     */
-    public void setEncodedStringValue(EncodedStringValue value, int field) {
-        /**
-         * Check whether this field can be set for specific
-         * header and check validity of the field.
-         */
-        if (null == value) {
-            throw new NullPointerException();
-        }
-
-        switch (field) {
-            case SUBJECT:
-            case RECOMMENDED_RETRIEVAL_MODE_TEXT:
-            case RETRIEVE_TEXT:
-            case STATUS_TEXT:
-            case STORE_STATUS_TEXT:
-            case RESPONSE_TEXT:
-            case FROM:
-            case PREVIOUSLY_SENT_BY:
-            case MM_FLAGS:
-                break;
-            default:
-                // This header value should not be Encoded-String-Value.
-                throw new RuntimeException("Invalid header field!");
-        }
-
-        mHeaderMap.put(field, value);
-    }
-
-    /**
-     * Set TO, CC or BCC header value.
-     *
-     * @param value the value
-     * @param field the field
-     * @return the EncodedStringValue value array of the pdu header
-     *          with specified header field
-     * @throws NullPointerException if the value is null.
-     */
-    public void setEncodedStringValues(EncodedStringValue[] value, int field) {
-        /**
-         * Check whether this field can be set for specific
-         * header and check validity of the field.
-         */
-        if (null == value) {
-            throw new NullPointerException();
-        }
-
-        switch (field) {
-            case BCC:
-            case CC:
-            case TO:
-                break;
-            default:
-                // This header value should not be Encoded-String-Value.
-                throw new RuntimeException("Invalid header field!");
-        }
-
-        ArrayList<EncodedStringValue> list = new ArrayList<EncodedStringValue>();
-        for (int i = 0; i < value.length; i++) {
-            list.add(value[i]);
-        }
-        mHeaderMap.put(field, list);
-    }
-
-    /**
-     * Append one EncodedStringValue to another.
-     *
-     * @param value the EncodedStringValue to append
-     * @param field the field
-     * @throws NullPointerException if the value is null.
-     */
-    public void appendEncodedStringValue(EncodedStringValue value,
-                                    int field) {
-        if (null == value) {
-            throw new NullPointerException();
-        }
-
-        switch (field) {
-            case BCC:
-            case CC:
-            case TO:
-                break;
-            default:
-                throw new RuntimeException("Invalid header field!");
-        }
-
-        ArrayList<EncodedStringValue> list =
-            (ArrayList<EncodedStringValue>) mHeaderMap.get(field);
-        if (null == list) {
-            list  = new ArrayList<EncodedStringValue>();
-        }
-        list.add(value);
-        mHeaderMap.put(field, list);
-    }
-
-    /**
-     * Get LongInteger value by header field.
-     *
-     * @param field the field
-     * @return the LongInteger value of the pdu header
-     *          with specified header field. if return -1, the
-     *          field is not existed in pdu header.
-     */
-    public long getLongInteger(int field) {
-        Long longInteger = (Long) mHeaderMap.get(field);
-        if (null == longInteger) {
-            return -1;
-        }
-
-        return longInteger.longValue();
-    }
-
-    /**
-     * Set LongInteger value to pdu header by header field.
-     *
-     * @param value the value
-     * @param field the field
-     */
-    public void setLongInteger(long value, int field) {
-        /**
-         * Check whether this field can be set for specific
-         * header and check validity of the field.
-         */
-        switch (field) {
-            case DATE:
-            case REPLY_CHARGING_SIZE:
-            case MESSAGE_SIZE:
-            case MESSAGE_COUNT:
-            case START:
-            case LIMIT:
-            case DELIVERY_TIME:
-            case EXPIRY:
-            case REPLY_CHARGING_DEADLINE:
-            case PREVIOUSLY_SENT_DATE:
-                break;
-            default:
-                // This header value should not be LongInteger.
-                throw new RuntimeException("Invalid header field!");
-        }
-        mHeaderMap.put(field, value);
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/ContentType.java b/mms-common/java/com/android/mmscommon/mms/ContentType.java
deleted file mode 100644
index f21eba8..0000000
--- a/mms-common/java/com/android/mmscommon/mms/ContentType.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 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 com.android.mmscommon.mms;
-
-import java.util.ArrayList;
-
-public class ContentType {
-    public static final String MMS_MESSAGE       = "application/vnd.wap.mms-message";
-    // The phony content type for generic PDUs (e.g. ReadOrig.ind,
-    // Notification.ind, Delivery.ind).
-    public static final String MMS_GENERIC       = "application/vnd.wap.mms-generic";
-    public static final String MULTIPART_MIXED   = "application/vnd.wap.multipart.mixed";
-    public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related";
-    public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative";
-
-    public static final String TEXT_PLAIN        = "text/plain";
-    public static final String TEXT_HTML         = "text/html";
-    public static final String TEXT_VCALENDAR    = "text/x-vCalendar";
-    public static final String TEXT_VCARD        = "text/x-vCard";
-
-    public static final String IMAGE_UNSPECIFIED = "image/*";
-    public static final String IMAGE_JPEG        = "image/jpeg";
-    public static final String IMAGE_JPG         = "image/jpg";
-    public static final String IMAGE_GIF         = "image/gif";
-    public static final String IMAGE_WBMP        = "image/vnd.wap.wbmp";
-    public static final String IMAGE_PNG         = "image/png";
-
-    public static final String AUDIO_UNSPECIFIED = "audio/*";
-    public static final String AUDIO_AAC         = "audio/aac";
-    public static final String AUDIO_AMR         = "audio/amr";
-    public static final String AUDIO_IMELODY     = "audio/imelody";
-    public static final String AUDIO_MID         = "audio/mid";
-    public static final String AUDIO_MIDI        = "audio/midi";
-    public static final String AUDIO_MP3         = "audio/mp3";
-    public static final String AUDIO_MPEG3       = "audio/mpeg3";
-    public static final String AUDIO_MPEG        = "audio/mpeg";
-    public static final String AUDIO_MPG         = "audio/mpg";
-    public static final String AUDIO_MP4         = "audio/mp4";
-    public static final String AUDIO_X_MID       = "audio/x-mid";
-    public static final String AUDIO_X_MIDI      = "audio/x-midi";
-    public static final String AUDIO_X_MP3       = "audio/x-mp3";
-    public static final String AUDIO_X_MPEG3     = "audio/x-mpeg3";
-    public static final String AUDIO_X_MPEG      = "audio/x-mpeg";
-    public static final String AUDIO_X_MPG       = "audio/x-mpg";
-    public static final String AUDIO_3GPP        = "audio/3gpp";
-    public static final String AUDIO_OGG         = "application/ogg";
-
-    public static final String VIDEO_UNSPECIFIED = "video/*";
-    public static final String VIDEO_3GPP        = "video/3gpp";
-    public static final String VIDEO_3G2         = "video/3gpp2";
-    public static final String VIDEO_H263        = "video/h263";
-    public static final String VIDEO_MP4         = "video/mp4";
-
-    public static final String APP_SMIL          = "application/smil";
-    public static final String APP_WAP_XHTML     = "application/vnd.wap.xhtml+xml";
-    public static final String APP_XHTML         = "application/xhtml+xml";
-
-    public static final String APP_DRM_CONTENT   = "application/vnd.oma.drm.content";
-    public static final String APP_DRM_MESSAGE   = "application/vnd.oma.drm.message";
-
-    private static final ArrayList<String> sSupportedContentTypes = new ArrayList<String>();
-    private static final ArrayList<String> sSupportedImageTypes = new ArrayList<String>();
-    private static final ArrayList<String> sSupportedAudioTypes = new ArrayList<String>();
-    private static final ArrayList<String> sSupportedVideoTypes = new ArrayList<String>();
-
-    static {
-        sSupportedContentTypes.add(TEXT_PLAIN);
-        sSupportedContentTypes.add(TEXT_HTML);
-        sSupportedContentTypes.add(TEXT_VCALENDAR);
-        sSupportedContentTypes.add(TEXT_VCARD);
-
-        sSupportedContentTypes.add(IMAGE_JPEG);
-        sSupportedContentTypes.add(IMAGE_GIF);
-        sSupportedContentTypes.add(IMAGE_WBMP);
-        sSupportedContentTypes.add(IMAGE_PNG);
-        sSupportedContentTypes.add(IMAGE_JPG);
-        //supportedContentTypes.add(IMAGE_SVG); not yet supported.
-
-        sSupportedContentTypes.add(AUDIO_AAC);
-        sSupportedContentTypes.add(AUDIO_AMR);
-        sSupportedContentTypes.add(AUDIO_IMELODY);
-        sSupportedContentTypes.add(AUDIO_MID);
-        sSupportedContentTypes.add(AUDIO_MIDI);
-        sSupportedContentTypes.add(AUDIO_MP3);
-        sSupportedContentTypes.add(AUDIO_MPEG3);
-        sSupportedContentTypes.add(AUDIO_MPEG);
-        sSupportedContentTypes.add(AUDIO_MPG);
-        sSupportedContentTypes.add(AUDIO_X_MID);
-        sSupportedContentTypes.add(AUDIO_X_MIDI);
-        sSupportedContentTypes.add(AUDIO_X_MP3);
-        sSupportedContentTypes.add(AUDIO_X_MPEG3);
-        sSupportedContentTypes.add(AUDIO_X_MPEG);
-        sSupportedContentTypes.add(AUDIO_X_MPG);
-        sSupportedContentTypes.add(AUDIO_3GPP);
-        sSupportedContentTypes.add(AUDIO_OGG);
-
-        sSupportedContentTypes.add(VIDEO_3GPP);
-        sSupportedContentTypes.add(VIDEO_3G2);
-        sSupportedContentTypes.add(VIDEO_H263);
-        sSupportedContentTypes.add(VIDEO_MP4);
-
-        sSupportedContentTypes.add(APP_SMIL);
-        sSupportedContentTypes.add(APP_WAP_XHTML);
-        sSupportedContentTypes.add(APP_XHTML);
-
-        sSupportedContentTypes.add(APP_DRM_CONTENT);
-        sSupportedContentTypes.add(APP_DRM_MESSAGE);
-
-        // add supported image types
-        sSupportedImageTypes.add(IMAGE_JPEG);
-        sSupportedImageTypes.add(IMAGE_GIF);
-        sSupportedImageTypes.add(IMAGE_WBMP);
-        sSupportedImageTypes.add(IMAGE_PNG);
-        sSupportedImageTypes.add(IMAGE_JPG);
-
-        // add supported audio types
-        sSupportedAudioTypes.add(AUDIO_AAC);
-        sSupportedAudioTypes.add(AUDIO_AMR);
-        sSupportedAudioTypes.add(AUDIO_IMELODY);
-        sSupportedAudioTypes.add(AUDIO_MID);
-        sSupportedAudioTypes.add(AUDIO_MIDI);
-        sSupportedAudioTypes.add(AUDIO_MP3);
-        sSupportedAudioTypes.add(AUDIO_MPEG3);
-        sSupportedAudioTypes.add(AUDIO_MPEG);
-        sSupportedAudioTypes.add(AUDIO_MPG);
-        sSupportedAudioTypes.add(AUDIO_MP4);
-        sSupportedAudioTypes.add(AUDIO_X_MID);
-        sSupportedAudioTypes.add(AUDIO_X_MIDI);
-        sSupportedAudioTypes.add(AUDIO_X_MP3);
-        sSupportedAudioTypes.add(AUDIO_X_MPEG3);
-        sSupportedAudioTypes.add(AUDIO_X_MPEG);
-        sSupportedAudioTypes.add(AUDIO_X_MPG);
-        sSupportedAudioTypes.add(AUDIO_3GPP);
-        sSupportedAudioTypes.add(AUDIO_OGG);
-
-        // add supported video types
-        sSupportedVideoTypes.add(VIDEO_3GPP);
-        sSupportedVideoTypes.add(VIDEO_3G2);
-        sSupportedVideoTypes.add(VIDEO_H263);
-        sSupportedVideoTypes.add(VIDEO_MP4);
-    }
-
-    // This class should never be instantiated.
-    private ContentType() {
-    }
-
-    public static boolean isSupportedType(String contentType) {
-        return (null != contentType) && sSupportedContentTypes.contains(contentType);
-    }
-
-    public static boolean isSupportedImageType(String contentType) {
-        return isImageType(contentType) && isSupportedType(contentType);
-    }
-
-    public static boolean isSupportedAudioType(String contentType) {
-        return isAudioType(contentType) && isSupportedType(contentType);
-    }
-
-    public static boolean isSupportedVideoType(String contentType) {
-        return isVideoType(contentType) && isSupportedType(contentType);
-    }
-
-    public static boolean isTextType(String contentType) {
-        return (null != contentType) && contentType.startsWith("text/");
-    }
-
-    public static boolean isImageType(String contentType) {
-        return (null != contentType) && contentType.startsWith("image/");
-    }
-
-    public static boolean isAudioType(String contentType) {
-        return (null != contentType) && contentType.startsWith("audio/");
-    }
-
-    public static boolean isVideoType(String contentType) {
-        return (null != contentType) && contentType.startsWith("video/");
-    }
-
-    public static boolean isDrmType(String contentType) {
-        return (null != contentType)
-                && (contentType.equals(APP_DRM_CONTENT)
-                        || contentType.equals(APP_DRM_MESSAGE));
-    }
-
-    public static boolean isUnspecified(String contentType) {
-        return (null != contentType) && contentType.endsWith("*");
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getImageTypes() {
-        return (ArrayList<String>) sSupportedImageTypes.clone();
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getAudioTypes() {
-        return (ArrayList<String>) sSupportedAudioTypes.clone();
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getVideoTypes() {
-        return (ArrayList<String>) sSupportedVideoTypes.clone();
-    }
-
-    @SuppressWarnings("unchecked")
-    public static ArrayList<String> getSupportedTypes() {
-        return (ArrayList<String>) sSupportedContentTypes.clone();
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/AcknowledgeInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/AcknowledgeInd.java
deleted file mode 100644
index d1243b2..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/AcknowledgeInd.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-/**
- * M-Acknowledge.ind PDU.
- */
-public class AcknowledgeInd extends GenericPdu {
-    /**
-     * Constructor, used when composing a M-Acknowledge.ind pdu.
-     *
-     * @param mmsVersion current viersion of mms
-     * @param transactionId the transaction-id value
-     * @throws InvalidHeaderValueException if parameters are invalid.
-     *         NullPointerException if transactionId is null.
-     */
-    public AcknowledgeInd(int mmsVersion, byte[] transactionId)
-            throws InvalidHeaderValueException {
-        super();
-
-        setMessageType(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND);
-        setMmsVersion(mmsVersion);
-        setTransactionId(transactionId);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    AcknowledgeInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get X-Mms-Report-Allowed field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public int getReportAllowed() {
-        return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED);
-    }
-
-    /**
-     * Set X-Mms-Report-Allowed field value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setReportAllowed(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id field value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTransactionId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/DeliveryInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/DeliveryInd.java
deleted file mode 100644
index e83729b..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/DeliveryInd.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-/**
- * M-Delivery.Ind Pdu.
- */
-public class DeliveryInd extends GenericPdu {
-    /**
-     * Empty constructor.
-     * Since the Pdu corresponding to this class is constructed
-     * by the Proxy-Relay server, this class is only instantiated
-     * by the Pdu Parser.
-     *
-     * @throws InvalidHeaderValueException if error occurs.
-     */
-    public DeliveryInd() throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_DELIVERY_IND);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    DeliveryInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get Date value.
-     *
-     * @return the value
-     */
-    public long getDate() {
-        return mPduHeaders.getLongInteger(PduHeaders.DATE);
-    }
-
-    /**
-     * Set Date value.
-     *
-     * @param value the value
-     */
-    public void setDate(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.DATE);
-    }
-
-    /**
-     * Get Message-ID value.
-     *
-     * @return the value
-     */
-    public byte[] getMessageId() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Set Message-ID value.
-     *
-     * @param value the value, should not be null
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Get Status value.
-     *
-     * @return the value
-     */
-    public int getStatus() {
-        return mPduHeaders.getOctet(PduHeaders.STATUS);
-    }
-
-    /**
-     * Set Status value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.STATUS);
-    }
-
-    /**
-     * Get To value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getTo() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
-    }
-
-    /**
-     * set To value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTo(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     *
-     *     public EncodedStringValue getStatusText() {return null;}
-     *     public void setStatusText(EncodedStringValue value) {}
-     */
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/GenericPdu.java b/mms-common/java/com/android/mmscommon/mms/pdu/GenericPdu.java
deleted file mode 100644
index c38e502..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/GenericPdu.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-public class GenericPdu {
-    /**
-     * The headers of pdu.
-     */
-    PduHeaders mPduHeaders = null;
-
-    /**
-     * Constructor.
-     */
-    public GenericPdu() {
-        mPduHeaders = new PduHeaders();
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param headers Headers for this PDU.
-     */
-    GenericPdu(PduHeaders headers) {
-        mPduHeaders = headers;
-    }
-
-    /**
-     * Get the headers of this PDU.
-     *
-     * @return A PduHeaders of this PDU.
-     */
-    PduHeaders getPduHeaders() {
-        return mPduHeaders;
-    }
-
-    /**
-     * Get X-Mms-Message-Type field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public int getMessageType() {
-        return mPduHeaders.getOctet(PduHeaders.MESSAGE_TYPE);
-    }
-
-    /**
-     * Set X-Mms-Message-Type field value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if field's value is not Octet.
-     */
-    public void setMessageType(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.MESSAGE_TYPE);
-    }
-
-    /**
-     * Get X-Mms-MMS-Version field value.
-     *
-     * @return the X-Mms-MMS-Version value
-     */
-    public int getMmsVersion() {
-        return mPduHeaders.getOctet(PduHeaders.MMS_VERSION);
-    }
-
-    /**
-     * Set X-Mms-MMS-Version field value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if field's value is not Octet.
-     */
-    public void setMmsVersion(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.MMS_VERSION);
-    }
-
-    /**
-     * Get From value.
-     * From-value = Value-length
-     *      (Address-present-token Encoded-string-value | Insert-address-token)
-     *
-     * @return the value
-     */
-    public EncodedStringValue getFrom() {
-       return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
-    }
-
-    /**
-     * Set From value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setFrom(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/MultimediaMessagePdu.java b/mms-common/java/com/android/mmscommon/mms/pdu/MultimediaMessagePdu.java
deleted file mode 100644
index 04fde2d..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/MultimediaMessagePdu.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-/**
- * Multimedia message PDU.
- */
-public class MultimediaMessagePdu extends GenericPdu{
-    /**
-     * The body.
-     */
-    private PduBody mMessageBody;
-
-    /**
-     * Constructor.
-     */
-    public MultimediaMessagePdu() {
-        super();
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param header the header of this PDU
-     * @param body the body of this PDU
-     */
-    public MultimediaMessagePdu(PduHeaders header, PduBody body) {
-        super(header);
-        mMessageBody = body;
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    MultimediaMessagePdu(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get body of the PDU.
-     *
-     * @return the body
-     */
-    public PduBody getBody() {
-        return mMessageBody;
-    }
-
-    /**
-     * Set body of the PDU.
-     *
-     * @param body the body
-     */
-    public void setBody(PduBody body) {
-        mMessageBody = body;
-    }
-
-    /**
-     * Get subject.
-     *
-     * @return the value
-     */
-    public EncodedStringValue getSubject() {
-        return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT);
-    }
-
-    /**
-     * Set subject.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setSubject(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT);
-    }
-
-    /**
-     * Get To value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getTo() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
-    }
-
-    /**
-     * Add a "To" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void addTo(EncodedStringValue value) {
-        mPduHeaders.appendEncodedStringValue(value, PduHeaders.TO);
-    }
-
-    /**
-     * Get X-Mms-Priority value.
-     *
-     * @return the value
-     */
-    public int getPriority() {
-        return mPduHeaders.getOctet(PduHeaders.PRIORITY);
-    }
-
-    /**
-     * Set X-Mms-Priority value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setPriority(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.PRIORITY);
-    }
-
-    /**
-     * Get Date value.
-     *
-     * @return the value
-     */
-    public long getDate() {
-        return mPduHeaders.getLongInteger(PduHeaders.DATE);
-    }
-
-    /**
-     * Set Date value in seconds.
-     *
-     * @param value the value
-     */
-    public void setDate(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.DATE);
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/NotificationInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/NotificationInd.java
deleted file mode 100644
index 24f17b0..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/NotificationInd.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-/**
- * M-Notification.ind PDU.
- */
-public class NotificationInd extends GenericPdu {
-    /**
-     * Empty constructor.
-     * Since the Pdu corresponding to this class is constructed
-     * by the Proxy-Relay server, this class is only instantiated
-     * by the Pdu Parser.
-     *
-     * @throws InvalidHeaderValueException if error occurs.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public NotificationInd() throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    NotificationInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get X-Mms-Content-Class Value.
-     *
-     * @return the value
-     */
-    public int getContentClass() {
-        return mPduHeaders.getOctet(PduHeaders.CONTENT_CLASS);
-    }
-
-    /**
-     * Set X-Mms-Content-Class Value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setContentClass(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.CONTENT_CLASS);
-    }
-
-    /**
-     * Get X-Mms-Content-Location value.
-     * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
-     * Content-location-value = Uri-value
-     *
-     * @return the value
-     */
-    public byte[] getContentLocation() {
-        return mPduHeaders.getTextString(PduHeaders.CONTENT_LOCATION);
-    }
-
-    /**
-     * Set X-Mms-Content-Location value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setContentLocation(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.CONTENT_LOCATION);
-    }
-
-    /**
-     * Get X-Mms-Expiry value.
-     *
-     * Expiry-value = Value-length
-     *      (Absolute-token Date-value | Relative-token Delta-seconds-value)
-     *
-     * @return the value
-     */
-    public long getExpiry() {
-        return mPduHeaders.getLongInteger(PduHeaders.EXPIRY);
-    }
-
-    /**
-     * Set X-Mms-Expiry value.
-     *
-     * @param value the value
-     * @throws RuntimeException if an undeclared error occurs.
-     */
-    public void setExpiry(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY);
-    }
-
-    /**
-     * Get From value.
-     * From-value = Value-length
-     *      (Address-present-token Encoded-string-value | Insert-address-token)
-     *
-     * @return the value
-     */
-    public EncodedStringValue getFrom() {
-       return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
-    }
-
-    /**
-     * Set From value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setFrom(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
-    }
-
-    /**
-     * Get X-Mms-Message-Class value.
-     * Message-class-value = Class-identifier | Token-text
-     * Class-identifier = Personal | Advertisement | Informational | Auto
-     *
-     * @return the value
-     */
-    public byte[] getMessageClass() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Set X-Mms-Message-Class value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setMessageClass(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Get X-Mms-Message-Size value.
-     * Message-size-value = Long-integer
-     *
-     * @return the value
-     */
-    public long getMessageSize() {
-        return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE);
-    }
-
-    /**
-     * Set X-Mms-Message-Size value.
-     *
-     * @param value the value
-     * @throws RuntimeException if an undeclared error occurs.
-     */
-    public void setMessageSize(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE);
-    }
-
-    /**
-     * Get subject.
-     *
-     * @return the value
-     */
-    public EncodedStringValue getSubject() {
-        return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT);
-    }
-
-    /**
-     * Set subject.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setSubject(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id.
-     *
-     * @return the value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setTransactionId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Get X-Mms-Delivery-Report Value.
-     *
-     * @return the value
-     */
-    public int getDeliveryReport() {
-        return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT);
-    }
-
-    /**
-     * Set X-Mms-Delivery-Report Value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setDeliveryReport(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte getDrmContent() {return 0x00;}
-     *     public void setDrmContent(byte value) {}
-     *
-     *     public byte getDistributionIndicator() {return 0x00;}
-     *     public void setDistributionIndicator(byte value) {}
-     *
-     *     public ElementDescriptorValue getElementDescriptor() {return null;}
-     *     public void getElementDescriptor(ElementDescriptorValue value) {}
-     *
-     *     public byte getPriority() {return 0x00;}
-     *     public void setPriority(byte value) {}
-     *
-     *     public byte getRecommendedRetrievalMode() {return 0x00;}
-     *     public void setRecommendedRetrievalMode(byte value) {}
-     *
-     *     public byte getRecommendedRetrievalModeText() {return 0x00;}
-     *     public void setRecommendedRetrievalModeText(byte value) {}
-     *
-     *     public byte[] getReplaceId() {return 0x00;}
-     *     public void setReplaceId(byte[] value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     *
-     *     public byte getReplyCharging() {return 0x00;}
-     *     public void setReplyCharging(byte value) {}
-     *
-     *     public byte getReplyChargingDeadline() {return 0x00;}
-     *     public void setReplyChargingDeadline(byte value) {}
-     *
-     *     public byte[] getReplyChargingId() {return 0x00;}
-     *     public void setReplyChargingId(byte[] value) {}
-     *
-     *     public long getReplyChargingSize() {return 0;}
-     *     public void setReplyChargingSize(long value) {}
-     *
-     *     public byte getStored() {return 0x00;}
-     *     public void setStored(byte value) {}
-     */
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/NotifyRespInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/NotifyRespInd.java
deleted file mode 100644
index c2e2b26..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/NotifyRespInd.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-/**
- * M-NofifyResp.ind PDU.
- */
-public class NotifyRespInd extends GenericPdu {
-    /**
-     * Constructor, used when composing a M-NotifyResp.ind pdu.
-     *
-     * @param mmsVersion current version of mms
-     * @param transactionId the transaction-id value
-     * @param status the status value
-     * @throws InvalidHeaderValueException if parameters are invalid.
-     *         NullPointerException if transactionId is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public NotifyRespInd(int mmsVersion,
-                         byte[] transactionId,
-                         int status) throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND);
-        setMmsVersion(mmsVersion);
-        setTransactionId(transactionId);
-        setStatus(status);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    NotifyRespInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get X-Mms-Report-Allowed field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public int getReportAllowed() {
-        return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED);
-    }
-
-    /**
-     * Set X-Mms-Report-Allowed field value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setReportAllowed(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED);
-    }
-
-    /**
-     * Set X-Mms-Status field value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.STATUS);
-    }
-
-    /**
-     * GetX-Mms-Status field value.
-     *
-     * @return the X-Mms-Status value
-     */
-    public int getStatus() {
-        return mPduHeaders.getOctet(PduHeaders.STATUS);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id field value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     *         RuntimeException if an undeclared error occurs.
-     */
-    public void setTransactionId(byte[] value) {
-            mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/PduBody.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduBody.java
deleted file mode 100644
index cc28d80..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/PduBody.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-
-public class PduBody {
-    private Vector<PduPart> mParts = null;
-
-    private Map<String, PduPart> mPartMapByContentId = null;
-    private Map<String, PduPart> mPartMapByContentLocation = null;
-    private Map<String, PduPart> mPartMapByName = null;
-    private Map<String, PduPart> mPartMapByFileName = null;
-
-    /**
-     * Constructor.
-     */
-    public PduBody() {
-        mParts = new Vector<PduPart>();
-
-        mPartMapByContentId = new HashMap<String, PduPart>();
-        mPartMapByContentLocation  = new HashMap<String, PduPart>();
-        mPartMapByName = new HashMap<String, PduPart>();
-        mPartMapByFileName = new HashMap<String, PduPart>();
-    }
-
-    private void putPartToMaps(PduPart part) {
-        // Put part to mPartMapByContentId.
-        byte[] contentId = part.getContentId();
-        if(null != contentId) {
-            mPartMapByContentId.put(new String(contentId), part);
-        }
-
-        // Put part to mPartMapByContentLocation.
-        byte[] contentLocation = part.getContentLocation();
-        if(null != contentLocation) {
-            String clc = new String(contentLocation);
-            mPartMapByContentLocation.put(clc, part);
-        }
-
-        // Put part to mPartMapByName.
-        byte[] name = part.getName();
-        if(null != name) {
-            String clc = new String(name);
-            mPartMapByName.put(clc, part);
-        }
-
-        // Put part to mPartMapByFileName.
-        byte[] fileName = part.getFilename();
-        if(null != fileName) {
-            String clc = new String(fileName);
-            mPartMapByFileName.put(clc, part);
-        }
-    }
-
-    /**
-     * Appends the specified part to the end of this body.
-     *
-     * @param part part to be appended
-     * @return true when success, false when fail
-     * @throws NullPointerException when part is null
-     */
-    public boolean addPart(PduPart part) {
-        if(null == part) {
-            throw new NullPointerException();
-        }
-
-        putPartToMaps(part);
-        return mParts.add(part);
-    }
-
-    /**
-     * Inserts the specified part at the specified position.
-     *
-     * @param index index at which the specified part is to be inserted
-     * @param part part to be inserted
-     * @throws NullPointerException when part is null
-     */
-    public void addPart(int index, PduPart part) {
-        if(null == part) {
-            throw new NullPointerException();
-        }
-
-        putPartToMaps(part);
-        mParts.add(index, part);
-    }
-
-    /**
-     * Removes the part at the specified position.
-     *
-     * @param index index of the part to return
-     * @return part at the specified index
-     */
-    public PduPart removePart(int index) {
-        return mParts.remove(index);
-    }
-
-    /**
-     * Remove all of the parts.
-     */
-    public void removeAll() {
-        mParts.clear();
-    }
-
-    /**
-     * Get the part at the specified position.
-     *
-     * @param index index of the part to return
-     * @return part at the specified index
-     */
-    public PduPart getPart(int index) {
-        return mParts.get(index);
-    }
-
-    /**
-     * Get the index of the specified part.
-     *
-     * @param part the part object
-     * @return index the index of the first occurrence of the part in this body
-     */
-    public int getPartIndex(PduPart part) {
-        return mParts.indexOf(part);
-    }
-
-    /**
-     * Get the number of parts.
-     *
-     * @return the number of parts
-     */
-    public int getPartsNum() {
-        return mParts.size();
-    }
-
-    /**
-     * Get pdu part by content id.
-     *
-     * @param cid the value of content id.
-     * @return the pdu part.
-     */
-    public PduPart getPartByContentId(String cid) {
-        return mPartMapByContentId.get(cid);
-    }
-
-    /**
-     * Get pdu part by Content-Location. Content-Location of part is
-     * the same as filename and name(param of content-type).
-     *
-     * @param fileName the value of filename.
-     * @return the pdu part.
-     */
-    public PduPart getPartByContentLocation(String contentLocation) {
-        return mPartMapByContentLocation.get(contentLocation);
-    }
-
-    /**
-     * Get pdu part by name.
-     *
-     * @param fileName the value of filename.
-     * @return the pdu part.
-     */
-    public PduPart getPartByName(String name) {
-        return mPartMapByName.get(name);
-    }
-
-    /**
-     * Get pdu part by filename.
-     *
-     * @param fileName the value of filename.
-     * @return the pdu part.
-     */
-    public PduPart getPartByFileName(String filename) {
-        return mPartMapByFileName.get(filename);
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/PduComposer.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduComposer.java
deleted file mode 100644
index bb3116d..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/PduComposer.java
+++ /dev/null
@@ -1,1184 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 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 com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.PduHeaders;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.util.Log;
-import android.text.TextUtils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.HashMap;
-
-public class PduComposer {
-    /**
-     * Address type.
-     */
-    static private final int PDU_PHONE_NUMBER_ADDRESS_TYPE = 1;
-    static private final int PDU_EMAIL_ADDRESS_TYPE = 2;
-    static private final int PDU_IPV4_ADDRESS_TYPE = 3;
-    static private final int PDU_IPV6_ADDRESS_TYPE = 4;
-    static private final int PDU_UNKNOWN_ADDRESS_TYPE = 5;
-
-    /**
-     * Address regular expression string.
-     */
-    static final String REGEXP_PHONE_NUMBER_ADDRESS_TYPE = "\\+?[0-9|\\.|\\-]+";
-    static final String REGEXP_EMAIL_ADDRESS_TYPE = "[a-zA-Z| ]*\\<{0,1}[a-zA-Z| ]+@{1}" +
-            "[a-zA-Z| ]+\\.{1}[a-zA-Z| ]+\\>{0,1}";
-    static final String REGEXP_IPV6_ADDRESS_TYPE =
-        "[a-fA-F]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" +
-        "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" +
-        "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}";
-    static final String REGEXP_IPV4_ADDRESS_TYPE = "[0-9]{1,3}\\.{1}[0-9]{1,3}\\.{1}" +
-            "[0-9]{1,3}\\.{1}[0-9]{1,3}";
-
-    /**
-     * The postfix strings of address.
-     */
-    static final String STRING_PHONE_NUMBER_ADDRESS_TYPE = "/TYPE=PLMN";
-    static final String STRING_IPV4_ADDRESS_TYPE = "/TYPE=IPV4";
-    static final String STRING_IPV6_ADDRESS_TYPE = "/TYPE=IPV6";
-
-    /**
-     * Error values.
-     */
-    static private final int PDU_COMPOSE_SUCCESS = 0;
-    static private final int PDU_COMPOSE_CONTENT_ERROR = 1;
-    static private final int PDU_COMPOSE_FIELD_NOT_SET = 2;
-    static private final int PDU_COMPOSE_FIELD_NOT_SUPPORTED = 3;
-
-    /**
-     * WAP values defined in WSP spec.
-     */
-    static private final int QUOTED_STRING_FLAG = 34;
-    static private final int END_STRING_FLAG = 0;
-    static private final int LENGTH_QUOTE = 31;
-    static private final int TEXT_MAX = 127;
-    static private final int SHORT_INTEGER_MAX = 127;
-    static private final int LONG_INTEGER_LENGTH_MAX = 8;
-
-    /**
-     * Block size when read data from InputStream.
-     */
-    static private final int PDU_COMPOSER_BLOCK_SIZE = 1024;
-
-    /**
-     * The output message.
-     */
-    protected ByteArrayOutputStream mMessage = null;
-
-    /**
-     * The PDU.
-     */
-    private GenericPdu mPdu = null;
-
-    /**
-     * Current visiting position of the mMessage.
-     */
-    protected int mPosition = 0;
-
-    /**
-     * Message compose buffer stack.
-     */
-    private BufferStack mStack = null;
-
-    /**
-     * Content resolver.
-     */
-    private final ContentResolver mResolver;
-
-    /**
-     * Header of this pdu.
-     */
-    private PduHeaders mPduHeader = null;
-
-    /**
-     * Map of all content type
-     */
-    private static HashMap<String, Integer> mContentTypeMap = null;
-
-    static {
-        mContentTypeMap = new HashMap<String, Integer>();
-
-        int i;
-        for (i = 0; i < PduContentTypes.contentTypes.length; i++) {
-            mContentTypeMap.put(PduContentTypes.contentTypes[i], i);
-        }
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param context the context
-     * @param pdu the pdu to be composed
-     */
-    public PduComposer(Context context, GenericPdu pdu) {
-        mPdu = pdu;
-        mResolver = context.getContentResolver();
-        mPduHeader = pdu.getPduHeaders();
-        mStack = new BufferStack();
-        mMessage = new ByteArrayOutputStream();
-        mPosition = 0;
-    }
-
-    /**
-     * Make the message. No need to check whether mandatory fields are set,
-     * because the constructors of outgoing pdus are taking care of this.
-     *
-     * @return OutputStream of maked message. Return null if
-     *         the PDU is invalid.
-     */
-    public byte[] make() {
-        // Get Message-type.
-        int type = mPdu.getMessageType();
-
-        /* make the message */
-        switch (type) {
-            case PduHeaders.MESSAGE_TYPE_SEND_REQ:
-                if (makeSendReqPdu() != PDU_COMPOSE_SUCCESS) {
-                    return null;
-                }
-                break;
-            case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
-                if (makeNotifyResp() != PDU_COMPOSE_SUCCESS) {
-                    return null;
-                }
-                break;
-            case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
-                if (makeAckInd() != PDU_COMPOSE_SUCCESS) {
-                    return null;
-                }
-                break;
-            case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
-                if (makeReadRecInd() != PDU_COMPOSE_SUCCESS) {
-                    return null;
-                }
-                break;
-            default:
-                return null;
-        }
-
-        return mMessage.toByteArray();
-    }
-
-    /**
-     *  Copy buf to mMessage.
-     */
-    protected void arraycopy(byte[] buf, int pos, int length) {
-        mMessage.write(buf, pos, length);
-        mPosition = mPosition + length;
-    }
-
-    /**
-     * Append a byte to mMessage.
-     */
-    protected void append(int value) {
-        mMessage.write(value);
-        mPosition ++;
-    }
-
-    /**
-     * Append short integer value to mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendShortInteger(int value) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Short-integer = OCTET
-         * ; Integers in range 0-127 shall be encoded as a one octet value
-         * ; with the most significant bit set to one (1xxx xxxx) and with
-         * ; the value in the remaining least significant bits.
-         * In our implementation, only low 7 bits are stored and otherwise
-         * bits are ignored.
-         */
-        append((value | 0x80) & 0xff);
-    }
-
-    /**
-     * Append an octet number between 128 and 255 into mMessage.
-     * NOTE:
-     * A value between 0 and 127 should be appended by using appendShortInteger.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendOctet(int number) {
-        append(number);
-    }
-
-    /**
-     * Append a short length into mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendShortLength(int value) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Short-length = <Any octet 0-30>
-         */
-        append(value);
-    }
-
-    /**
-     * Append long integer into mMessage. it's used for really long integers.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendLongInteger(long longInt) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Long-integer = Short-length Multi-octet-integer
-         * ; The Short-length indicates the length of the Multi-octet-integer
-         * Multi-octet-integer = 1*30 OCTET
-         * ; The content octets shall be an unsigned integer value with the
-         * ; most significant octet encoded first (big-endian representation).
-         * ; The minimum number of octets must be used to encode the value.
-         */
-        int size;
-        long temp = longInt;
-
-        // Count the length of the long integer.
-        for(size = 0; (temp != 0) && (size < LONG_INTEGER_LENGTH_MAX); size++) {
-            temp = (temp >>> 8);
-        }
-
-        // Set Length.
-        appendShortLength(size);
-
-        // Count and set the long integer.
-        int i;
-        int shift = (size -1) * 8;
-
-        for (i = 0; i < size; i++) {
-            append((int)((longInt >>> shift) & 0xff));
-            shift = shift - 8;
-        }
-    }
-
-    /**
-     * Append text string into mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendTextString(byte[] text) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Text-string = [Quote] *TEXT End-of-string
-         * ; If the first character in the TEXT is in the range of 128-255,
-         * ; a Quote character must precede it. Otherwise the Quote character
-         * ;must be omitted. The Quote is not part of the contents.
-         */
-        if (((text[0])&0xff) > TEXT_MAX) { // No need to check for <= 255
-            append(TEXT_MAX);
-        }
-
-        arraycopy(text, 0, text.length);
-        append(0);
-    }
-
-    /**
-     * Append text string into mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendTextString(String str) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Text-string = [Quote] *TEXT End-of-string
-         * ; If the first character in the TEXT is in the range of 128-255,
-         * ; a Quote character must precede it. Otherwise the Quote character
-         * ;must be omitted. The Quote is not part of the contents.
-         */
-        appendTextString(str.getBytes());
-    }
-
-    /**
-     * Append encoded string value to mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendEncodedString(EncodedStringValue enStr) {
-        /*
-         * From OMA-TS-MMS-ENC-V1_3-20050927-C:
-         * Encoded-string-value = Text-string | Value-length Char-set Text-string
-         */
-        assert(enStr != null);
-
-        int charset = enStr.getCharacterSet();
-        byte[] textString = enStr.getTextString();
-        if (null == textString) {
-            return;
-        }
-
-        /*
-         * In the implementation of EncodedStringValue, the charset field will
-         * never be 0. It will always be composed as
-         * Encoded-string-value = Value-length Char-set Text-string
-         */
-        mStack.newbuf();
-        PositionMarker start = mStack.mark();
-
-        appendShortInteger(charset);
-        appendTextString(textString);
-
-        int len = start.getLength();
-        mStack.pop();
-        appendValueLength(len);
-        mStack.copy();
-    }
-
-    /**
-     * Append uintvar integer into mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendUintvarInteger(long value) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * To encode a large unsigned integer, split it into 7-bit fragments
-         * and place them in the payloads of multiple octets. The most significant
-         * bits are placed in the first octets with the least significant bits
-         * ending up in the last octet. All octets MUST set the Continue bit to 1
-         * except the last octet, which MUST set the Continue bit to 0.
-         */
-        int i;
-        long max = SHORT_INTEGER_MAX;
-
-        for (i = 0; i < 5; i++) {
-            if (value < max) {
-                break;
-            }
-
-            max = (max << 7) | 0x7fl;
-        }
-
-        while(i > 0) {
-            long temp = value >>> (i * 7);
-            temp = temp & 0x7f;
-
-            append((int)((temp | 0x80) & 0xff));
-
-            i--;
-        }
-
-        append((int)(value & 0x7f));
-    }
-
-    /**
-     * Append date value into mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendDateValue(long date) {
-        /*
-         * From OMA-TS-MMS-ENC-V1_3-20050927-C:
-         * Date-value = Long-integer
-         */
-        appendLongInteger(date);
-    }
-
-    /**
-     * Append value length to mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendValueLength(long value) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Value-length = Short-length | (Length-quote Length)
-         * ; Value length is used to indicate the length of the value to follow
-         * Short-length = <Any octet 0-30>
-         * Length-quote = <Octet 31>
-         * Length = Uintvar-integer
-         */
-        if (value < LENGTH_QUOTE) {
-            appendShortLength((int) value);
-            return;
-        }
-
-        append(LENGTH_QUOTE);
-        appendUintvarInteger(value);
-    }
-
-    /**
-     * Append quoted string to mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendQuotedString(byte[] text) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Quoted-string = <Octet 34> *TEXT End-of-string
-         * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing
-         * ;quotation-marks <"> removed.
-         */
-        append(QUOTED_STRING_FLAG);
-        arraycopy(text, 0, text.length);
-        append(END_STRING_FLAG);
-    }
-
-    /**
-     * Append quoted string to mMessage.
-     * This implementation doesn't check the validity of parameter, since it
-     * assumes that the values are validated in the GenericPdu setter methods.
-     */
-    protected void appendQuotedString(String str) {
-        /*
-         * From WAP-230-WSP-20010705-a:
-         * Quoted-string = <Octet 34> *TEXT End-of-string
-         * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing
-         * ;quotation-marks <"> removed.
-         */
-        appendQuotedString(str.getBytes());
-    }
-
-    private EncodedStringValue appendAddressType(EncodedStringValue address) {
-        EncodedStringValue temp = null;
-
-        try {
-            int addressType = checkAddressType(address.getString());
-            temp = EncodedStringValue.copy(address);
-            if (PDU_PHONE_NUMBER_ADDRESS_TYPE == addressType) {
-                // Phone number.
-                temp.appendTextString(STRING_PHONE_NUMBER_ADDRESS_TYPE.getBytes());
-            } else if (PDU_IPV4_ADDRESS_TYPE == addressType) {
-                // Ipv4 address.
-                temp.appendTextString(STRING_IPV4_ADDRESS_TYPE.getBytes());
-            } else if (PDU_IPV6_ADDRESS_TYPE == addressType) {
-                // Ipv6 address.
-                temp.appendTextString(STRING_IPV6_ADDRESS_TYPE.getBytes());
-            }
-        } catch (NullPointerException e) {
-            return null;
-        }
-
-        return temp;
-    }
-
-    /**
-     * Append header to mMessage.
-     */
-    private int appendHeader(int field) {
-        switch (field) {
-            case PduHeaders.MMS_VERSION:
-                appendOctet(field);
-
-                int version = mPduHeader.getOctet(field);
-                if (0 == version) {
-                    appendShortInteger(PduHeaders.CURRENT_MMS_VERSION);
-                } else {
-                    appendShortInteger(version);
-                }
-
-                break;
-
-            case PduHeaders.MESSAGE_ID:
-            case PduHeaders.TRANSACTION_ID:
-                byte[] textString = mPduHeader.getTextString(field);
-                if (null == textString) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-                appendTextString(textString);
-                break;
-
-            case PduHeaders.TO:
-            case PduHeaders.BCC:
-            case PduHeaders.CC:
-                EncodedStringValue[] addr = mPduHeader.getEncodedStringValues(field);
-
-                if (null == addr) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                EncodedStringValue temp;
-                for (int i = 0; i < addr.length; i++) {
-                    temp = appendAddressType(addr[i]);
-                    if (temp == null) {
-                        return PDU_COMPOSE_CONTENT_ERROR;
-                    }
-
-                    appendOctet(field);
-                    appendEncodedString(temp);
-                }
-                break;
-
-            case PduHeaders.FROM:
-                // Value-length (Address-present-token Encoded-string-value | Insert-address-token)
-                appendOctet(field);
-
-                EncodedStringValue from = mPduHeader.getEncodedStringValue(field);
-                if ((from == null)
-                        || TextUtils.isEmpty(from.getString())
-                        || new String(from.getTextString()).equals(
-                                PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) {
-                    // Length of from = 1
-                    append(1);
-                    // Insert-address-token = <Octet 129>
-                    append(PduHeaders.FROM_INSERT_ADDRESS_TOKEN);
-                } else {
-                    mStack.newbuf();
-                    PositionMarker fstart = mStack.mark();
-
-                    // Address-present-token = <Octet 128>
-                    append(PduHeaders.FROM_ADDRESS_PRESENT_TOKEN);
-
-                    temp = appendAddressType(from);
-                    if (temp == null) {
-                        return PDU_COMPOSE_CONTENT_ERROR;
-                    }
-
-                    appendEncodedString(temp);
-
-                    int flen = fstart.getLength();
-                    mStack.pop();
-                    appendValueLength(flen);
-                    mStack.copy();
-                }
-                break;
-
-            case PduHeaders.READ_STATUS:
-            case PduHeaders.STATUS:
-            case PduHeaders.REPORT_ALLOWED:
-            case PduHeaders.PRIORITY:
-            case PduHeaders.DELIVERY_REPORT:
-            case PduHeaders.READ_REPORT:
-                int octet = mPduHeader.getOctet(field);
-                if (0 == octet) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-                appendOctet(octet);
-                break;
-
-            case PduHeaders.DATE:
-                long date = mPduHeader.getLongInteger(field);
-                if (-1 == date) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-                appendDateValue(date);
-                break;
-
-            case PduHeaders.SUBJECT:
-                EncodedStringValue enString =
-                    mPduHeader.getEncodedStringValue(field);
-                if (null == enString) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-                appendEncodedString(enString);
-                break;
-
-            case PduHeaders.MESSAGE_CLASS:
-                byte[] messageClass = mPduHeader.getTextString(field);
-                if (null == messageClass) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-                if (Arrays.equals(messageClass,
-                        PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes())) {
-                    appendOctet(PduHeaders.MESSAGE_CLASS_ADVERTISEMENT);
-                } else if (Arrays.equals(messageClass,
-                        PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes())) {
-                    appendOctet(PduHeaders.MESSAGE_CLASS_AUTO);
-                } else if (Arrays.equals(messageClass,
-                        PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes())) {
-                    appendOctet(PduHeaders.MESSAGE_CLASS_PERSONAL);
-                } else if (Arrays.equals(messageClass,
-                        PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes())) {
-                    appendOctet(PduHeaders.MESSAGE_CLASS_INFORMATIONAL);
-                } else {
-                    appendTextString(messageClass);
-                }
-                break;
-
-            case PduHeaders.EXPIRY:
-                long expiry = mPduHeader.getLongInteger(field);
-                if (-1 == expiry) {
-                    return PDU_COMPOSE_FIELD_NOT_SET;
-                }
-
-                appendOctet(field);
-
-                mStack.newbuf();
-                PositionMarker expiryStart = mStack.mark();
-
-                append(PduHeaders.VALUE_RELATIVE_TOKEN);
-                appendLongInteger(expiry);
-
-                int expiryLength = expiryStart.getLength();
-                mStack.pop();
-                appendValueLength(expiryLength);
-                mStack.copy();
-                break;
-
-            default:
-                return PDU_COMPOSE_FIELD_NOT_SUPPORTED;
-        }
-
-        return PDU_COMPOSE_SUCCESS;
-    }
-
-    /**
-     * Make ReadRec.Ind.
-     */
-    private int makeReadRecInd() {
-        if (mMessage == null) {
-            mMessage = new ByteArrayOutputStream();
-            mPosition = 0;
-        }
-
-        // X-Mms-Message-Type
-        appendOctet(PduHeaders.MESSAGE_TYPE);
-        appendOctet(PduHeaders.MESSAGE_TYPE_READ_REC_IND);
-
-        // X-Mms-MMS-Version
-        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // Message-ID
-        if (appendHeader(PduHeaders.MESSAGE_ID) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // To
-        if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // From
-        if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // Date Optional
-        appendHeader(PduHeaders.DATE);
-
-        // X-Mms-Read-Status
-        if (appendHeader(PduHeaders.READ_STATUS) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // X-Mms-Applic-ID Optional(not support)
-        // X-Mms-Reply-Applic-ID Optional(not support)
-        // X-Mms-Aux-Applic-Info Optional(not support)
-
-        return PDU_COMPOSE_SUCCESS;
-    }
-
-    /**
-     * Make NotifyResp.Ind.
-     */
-    private int makeNotifyResp() {
-        if (mMessage == null) {
-            mMessage = new ByteArrayOutputStream();
-            mPosition = 0;
-        }
-
-        //    X-Mms-Message-Type
-        appendOctet(PduHeaders.MESSAGE_TYPE);
-        appendOctet(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND);
-
-        // X-Mms-Transaction-ID
-        if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // X-Mms-MMS-Version
-        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        //  X-Mms-Status
-        if (appendHeader(PduHeaders.STATUS) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // X-Mms-Report-Allowed Optional (not support)
-        return PDU_COMPOSE_SUCCESS;
-    }
-
-    /**
-     * Make Acknowledge.Ind.
-     */
-    private int makeAckInd() {
-        if (mMessage == null) {
-            mMessage = new ByteArrayOutputStream();
-            mPosition = 0;
-        }
-
-        //    X-Mms-Message-Type
-        appendOctet(PduHeaders.MESSAGE_TYPE);
-        appendOctet(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND);
-
-        // X-Mms-Transaction-ID
-        if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        //     X-Mms-MMS-Version
-        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // X-Mms-Report-Allowed Optional
-        appendHeader(PduHeaders.REPORT_ALLOWED);
-
-        return PDU_COMPOSE_SUCCESS;
-    }
-
-    /**
-     * Make Send.req.
-     */
-    private int makeSendReqPdu() {
-        if (mMessage == null) {
-            mMessage = new ByteArrayOutputStream();
-            mPosition = 0;
-        }
-
-        // X-Mms-Message-Type
-        appendOctet(PduHeaders.MESSAGE_TYPE);
-        appendOctet(PduHeaders.MESSAGE_TYPE_SEND_REQ);
-
-        // X-Mms-Transaction-ID
-        appendOctet(PduHeaders.TRANSACTION_ID);
-
-        byte[] trid = mPduHeader.getTextString(PduHeaders.TRANSACTION_ID);
-        if (trid == null) {
-            // Transaction-ID should be set(by Transaction) before make().
-            throw new IllegalArgumentException("Transaction-ID is null.");
-        }
-        appendTextString(trid);
-
-        //  X-Mms-MMS-Version
-        if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // Date Date-value Optional.
-        appendHeader(PduHeaders.DATE);
-
-        // From
-        if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        boolean recipient = false;
-
-        // To
-        if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_CONTENT_ERROR) {
-            recipient = true;
-        }
-
-        // Cc
-        if (appendHeader(PduHeaders.CC) != PDU_COMPOSE_CONTENT_ERROR) {
-            recipient = true;
-        }
-
-        // Bcc
-        if (appendHeader(PduHeaders.BCC) != PDU_COMPOSE_CONTENT_ERROR) {
-            recipient = true;
-        }
-
-        // Need at least one of "cc", "bcc" and "to".
-        if (false == recipient) {
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        // Subject Optional
-        appendHeader(PduHeaders.SUBJECT);
-
-        // X-Mms-Message-Class Optional
-        // Message-class-value = Class-identifier | Token-text
-        appendHeader(PduHeaders.MESSAGE_CLASS);
-
-        // X-Mms-Expiry Optional
-        appendHeader(PduHeaders.EXPIRY);
-
-        // X-Mms-Priority Optional
-        appendHeader(PduHeaders.PRIORITY);
-
-        // X-Mms-Delivery-Report Optional
-        appendHeader(PduHeaders.DELIVERY_REPORT);
-
-        // X-Mms-Read-Report Optional
-        appendHeader(PduHeaders.READ_REPORT);
-
-        //    Content-Type
-        appendOctet(PduHeaders.CONTENT_TYPE);
-
-        //  Message body
-        makeMessageBody();
-
-        return PDU_COMPOSE_SUCCESS;  // Composing the message is OK
-    }
-
-    /**
-     * Make message body.
-     */
-    private int makeMessageBody() {
-        // 1. add body informations
-        mStack.newbuf();  // Switching buffer because we need to
-
-        PositionMarker ctStart = mStack.mark();
-
-        // This contentTypeIdentifier should be used for type of attachment...
-        String contentType = new String(mPduHeader.getTextString(PduHeaders.CONTENT_TYPE));
-        Integer contentTypeIdentifier = mContentTypeMap.get(contentType);
-        if (contentTypeIdentifier == null) {
-            // content type is mandatory
-            return PDU_COMPOSE_CONTENT_ERROR;
-        }
-
-        appendShortInteger(contentTypeIdentifier.intValue());
-
-        // content-type parameter: start
-        PduBody body = ((SendReq) mPdu).getBody();
-        if (null == body || body.getPartsNum() == 0) {
-            // empty message
-            appendUintvarInteger(0);
-            mStack.pop();
-            mStack.copy();
-            return PDU_COMPOSE_SUCCESS;
-        }
-
-        PduPart part;
-        try {
-            part = body.getPart(0);
-
-            byte[] start = part.getContentId();
-            if (start != null) {
-                appendOctet(PduPart.P_DEP_START);
-                if (('<' == start[0]) && ('>' == start[start.length - 1])) {
-                    appendTextString(start);
-                } else {
-                    appendTextString("<" + new String(start) + ">");
-                }
-            }
-
-            // content-type parameter: type
-            appendOctet(PduPart.P_CT_MR_TYPE);
-            appendTextString(part.getContentType());
-        }
-        catch (ArrayIndexOutOfBoundsException e){
-            e.printStackTrace();
-        }
-
-        int ctLength = ctStart.getLength();
-        mStack.pop();
-        appendValueLength(ctLength);
-        mStack.copy();
-
-        // 3. add content
-        int partNum = body.getPartsNum();
-        appendUintvarInteger(partNum);
-        for (int i = 0; i < partNum; i++) {
-            part = body.getPart(i);
-            mStack.newbuf();  // Leaving space for header lengh and data length
-            PositionMarker attachment = mStack.mark();
-
-            mStack.newbuf();  // Leaving space for Content-Type length
-            PositionMarker contentTypeBegin = mStack.mark();
-
-            byte[] partContentType = part.getContentType();
-
-            if (partContentType == null) {
-                // content type is mandatory
-                return PDU_COMPOSE_CONTENT_ERROR;
-            }
-
-            // content-type value
-            Integer partContentTypeIdentifier =
-                mContentTypeMap.get(new String(partContentType));
-            if (partContentTypeIdentifier == null) {
-                appendTextString(partContentType);
-            } else {
-                appendShortInteger(partContentTypeIdentifier.intValue());
-            }
-
-            /* Content-type parameter : name.
-             * The value of name, filename, content-location is the same.
-             * Just one of them is enough for this PDU.
-             */
-            byte[] name = part.getName();
-
-            if (null == name) {
-                name = part.getFilename();
-
-                if (null == name) {
-                    name = part.getContentLocation();
-
-                    if (null == name) {
-                        /* at lease one of name, filename, Content-location
-                         * should be available.
-                         */
-                        return PDU_COMPOSE_CONTENT_ERROR;
-                    }
-                }
-            }
-            appendOctet(PduPart.P_DEP_NAME);
-            appendTextString(name);
-
-            // content-type parameter : charset
-            int charset = part.getCharset();
-            if (charset != 0) {
-                appendOctet(PduPart.P_CHARSET);
-                appendShortInteger(charset);
-            }
-
-            int contentTypeLength = contentTypeBegin.getLength();
-            mStack.pop();
-            appendValueLength(contentTypeLength);
-            mStack.copy();
-
-            // content id
-            byte[] contentId = part.getContentId();
-
-            if (null != contentId) {
-                appendOctet(PduPart.P_CONTENT_ID);
-                if (('<' == contentId[0]) && ('>' == contentId[contentId.length - 1])) {
-                    appendQuotedString(contentId);
-                } else {
-                    appendQuotedString("<" + new String(contentId) + ">");
-                }
-            }
-
-            // content-location
-            byte[] contentLocation = part.getContentLocation();
-            if (null != contentLocation) {
-            	appendOctet(PduPart.P_CONTENT_LOCATION);
-            	appendTextString(contentLocation);
-            }
-
-            // content
-            int headerLength = attachment.getLength();
-
-            int dataLength = 0; // Just for safety...
-            byte[] partData = part.getData();
-
-            if (partData != null) {
-                arraycopy(partData, 0, partData.length);
-                dataLength = partData.length;
-            } else {
-                InputStream cr;
-                try {
-                    byte[] buffer = new byte[PDU_COMPOSER_BLOCK_SIZE];
-                    cr = mResolver.openInputStream(part.getDataUri());
-                    int len = 0;
-                    while ((len = cr.read(buffer)) != -1) {
-                        mMessage.write(buffer, 0, len);
-                        mPosition += len;
-                        dataLength += len;
-                    }
-                } catch (FileNotFoundException e) {
-                    return PDU_COMPOSE_CONTENT_ERROR;
-                } catch (IOException e) {
-                    return PDU_COMPOSE_CONTENT_ERROR;
-                } catch (RuntimeException e) {
-                    return PDU_COMPOSE_CONTENT_ERROR;
-                }
-            }
-
-            if (dataLength != (attachment.getLength() - headerLength)) {
-                throw new RuntimeException("BUG: Length sanity check failed");
-            }
-
-            mStack.pop();
-            appendUintvarInteger(headerLength);
-            appendUintvarInteger(dataLength);
-            mStack.copy();
-        }
-
-        return PDU_COMPOSE_SUCCESS;
-    }
-
-    /**
-     *  Record current message informations.
-     */
-    static private class LengthRecordNode {
-        ByteArrayOutputStream currentMessage = null;
-        public int currentPosition = 0;
-
-        public LengthRecordNode next = null;
-    }
-
-    /**
-     * Mark current message position and stact size.
-     */
-    private class PositionMarker {
-        private int c_pos;   // Current position
-        private int currentStackSize;  // Current stack size
-
-        int getLength() {
-            // If these assert fails, likely that you are finding the
-            // size of buffer that is deep in BufferStack you can only
-            // find the length of the buffer that is on top
-            if (currentStackSize != mStack.stackSize) {
-                throw new RuntimeException("BUG: Invalid call to getLength()");
-            }
-
-            return mPosition - c_pos;
-        }
-    }
-
-    /**
-     * This implementation can be OPTIMIZED to use only
-     * 2 buffers. This optimization involves changing BufferStack
-     * only... Its usage (interface) will not change.
-     */
-    private class BufferStack {
-        private LengthRecordNode stack = null;
-        private LengthRecordNode toCopy = null;
-
-        int stackSize = 0;
-
-        /**
-         *  Create a new message buffer and push it into the stack.
-         */
-        void newbuf() {
-            // You can't create a new buff when toCopy != null
-            // That is after calling pop() and before calling copy()
-            // If you do, it is a bug
-            if (toCopy != null) {
-                throw new RuntimeException("BUG: Invalid newbuf() before copy()");
-            }
-
-            LengthRecordNode temp = new LengthRecordNode();
-
-            temp.currentMessage = mMessage;
-            temp.currentPosition = mPosition;
-
-            temp.next = stack;
-            stack = temp;
-
-            stackSize = stackSize + 1;
-
-            mMessage = new ByteArrayOutputStream();
-            mPosition = 0;
-        }
-
-        /**
-         *  Pop the message before and record current message in the stack.
-         */
-        void pop() {
-            ByteArrayOutputStream currentMessage = mMessage;
-            int currentPosition = mPosition;
-
-            mMessage = stack.currentMessage;
-            mPosition = stack.currentPosition;
-
-            toCopy = stack;
-            // Re using the top element of the stack to avoid memory allocation
-
-            stack = stack.next;
-            stackSize = stackSize - 1;
-
-            toCopy.currentMessage = currentMessage;
-            toCopy.currentPosition = currentPosition;
-        }
-
-        /**
-         *  Append current message to the message before.
-         */
-        void copy() {
-            arraycopy(toCopy.currentMessage.toByteArray(), 0,
-                    toCopy.currentPosition);
-
-            toCopy = null;
-        }
-
-        /**
-         *  Mark current message position
-         */
-        PositionMarker mark() {
-            PositionMarker m = new PositionMarker();
-
-            m.c_pos = mPosition;
-            m.currentStackSize = stackSize;
-
-            return m;
-        }
-    }
-
-    /**
-     * Check address type.
-     *
-     * @param address address string without the postfix stinng type,
-     *        such as "/TYPE=PLMN", "/TYPE=IPv6" and "/TYPE=IPv4"
-     * @return PDU_PHONE_NUMBER_ADDRESS_TYPE if it is phone number,
-     *         PDU_EMAIL_ADDRESS_TYPE if it is email address,
-     *         PDU_IPV4_ADDRESS_TYPE if it is ipv4 address,
-     *         PDU_IPV6_ADDRESS_TYPE if it is ipv6 address,
-     *         PDU_UNKNOWN_ADDRESS_TYPE if it is unknown.
-     */
-    protected static int checkAddressType(String address) {
-        /**
-         * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf, section 8.
-         * address = ( e-mail / device-address / alphanum-shortcode / num-shortcode)
-         * e-mail = mailbox; to the definition of mailbox as described in
-         * section 3.4 of [RFC2822], but excluding the
-         * obsolete definitions as indicated by the "obs-" prefix.
-         * device-address = ( global-phone-number "/TYPE=PLMN" )
-         * / ( ipv4 "/TYPE=IPv4" ) / ( ipv6 "/TYPE=IPv6" )
-         * / ( escaped-value "/TYPE=" address-type )
-         *
-         * global-phone-number = ["+"] 1*( DIGIT / written-sep )
-         * written-sep =("-"/".")
-         *
-         * ipv4 = 1*3DIGIT 3( "." 1*3DIGIT ) ; IPv4 address value
-         *
-         * ipv6 = 4HEXDIG 7( ":" 4HEXDIG ) ; IPv6 address per RFC 2373
-         */
-
-        if (null == address) {
-            return PDU_UNKNOWN_ADDRESS_TYPE;
-        }
-
-        if (address.matches(REGEXP_IPV4_ADDRESS_TYPE)) {
-            // Ipv4 address.
-            return PDU_IPV4_ADDRESS_TYPE;
-        }else if (address.matches(REGEXP_PHONE_NUMBER_ADDRESS_TYPE)) {
-            // Phone number.
-            return PDU_PHONE_NUMBER_ADDRESS_TYPE;
-        } else if (address.matches(REGEXP_EMAIL_ADDRESS_TYPE)) {
-            // Email address.
-            return PDU_EMAIL_ADDRESS_TYPE;
-        } else if (address.matches(REGEXP_IPV6_ADDRESS_TYPE)) {
-            // Ipv6 address.
-            return PDU_IPV6_ADDRESS_TYPE;
-        } else {
-            // Unknown address.
-            return PDU_UNKNOWN_ADDRESS_TYPE;
-        }
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/PduContentTypes.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduContentTypes.java
deleted file mode 100644
index 3f971fd..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/PduContentTypes.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-public class PduContentTypes {
-    /**
-     * All content types. From:
-     * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.htm
-     */
-    static final String[] contentTypes = {
-        "*/*",                                        /* 0x00 */
-        "text/*",                                     /* 0x01 */
-        "text/html",                                  /* 0x02 */
-        "text/plain",                                 /* 0x03 */
-        "text/x-hdml",                                /* 0x04 */
-        "text/x-ttml",                                /* 0x05 */
-        "text/x-vCalendar",                           /* 0x06 */
-        "text/x-vCard",                               /* 0x07 */
-        "text/vnd.wap.wml",                           /* 0x08 */
-        "text/vnd.wap.wmlscript",                     /* 0x09 */
-        "text/vnd.wap.wta-event",                     /* 0x0A */
-        "multipart/*",                                /* 0x0B */
-        "multipart/mixed",                            /* 0x0C */
-        "multipart/form-data",                        /* 0x0D */
-        "multipart/byterantes",                       /* 0x0E */
-        "multipart/alternative",                      /* 0x0F */
-        "application/*",                              /* 0x10 */
-        "application/java-vm",                        /* 0x11 */
-        "application/x-www-form-urlencoded",          /* 0x12 */
-        "application/x-hdmlc",                        /* 0x13 */
-        "application/vnd.wap.wmlc",                   /* 0x14 */
-        "application/vnd.wap.wmlscriptc",             /* 0x15 */
-        "application/vnd.wap.wta-eventc",             /* 0x16 */
-        "application/vnd.wap.uaprof",                 /* 0x17 */
-        "application/vnd.wap.wtls-ca-certificate",    /* 0x18 */
-        "application/vnd.wap.wtls-user-certificate",  /* 0x19 */
-        "application/x-x509-ca-cert",                 /* 0x1A */
-        "application/x-x509-user-cert",               /* 0x1B */
-        "image/*",                                    /* 0x1C */
-        "image/gif",                                  /* 0x1D */
-        "image/jpeg",                                 /* 0x1E */
-        "image/tiff",                                 /* 0x1F */
-        "image/png",                                  /* 0x20 */
-        "image/vnd.wap.wbmp",                         /* 0x21 */
-        "application/vnd.wap.multipart.*",            /* 0x22 */
-        "application/vnd.wap.multipart.mixed",        /* 0x23 */
-        "application/vnd.wap.multipart.form-data",    /* 0x24 */
-        "application/vnd.wap.multipart.byteranges",   /* 0x25 */
-        "application/vnd.wap.multipart.alternative",  /* 0x26 */
-        "application/xml",                            /* 0x27 */
-        "text/xml",                                   /* 0x28 */
-        "application/vnd.wap.wbxml",                  /* 0x29 */
-        "application/x-x968-cross-cert",              /* 0x2A */
-        "application/x-x968-ca-cert",                 /* 0x2B */
-        "application/x-x968-user-cert",               /* 0x2C */
-        "text/vnd.wap.si",                            /* 0x2D */
-        "application/vnd.wap.sic",                    /* 0x2E */
-        "text/vnd.wap.sl",                            /* 0x2F */
-        "application/vnd.wap.slc",                    /* 0x30 */
-        "text/vnd.wap.co",                            /* 0x31 */
-        "application/vnd.wap.coc",                    /* 0x32 */
-        "application/vnd.wap.multipart.related",      /* 0x33 */
-        "application/vnd.wap.sia",                    /* 0x34 */
-        "text/vnd.wap.connectivity-xml",              /* 0x35 */
-        "application/vnd.wap.connectivity-wbxml",     /* 0x36 */
-        "application/pkcs7-mime",                     /* 0x37 */
-        "application/vnd.wap.hashed-certificate",     /* 0x38 */
-        "application/vnd.wap.signed-certificate",     /* 0x39 */
-        "application/vnd.wap.cert-response",          /* 0x3A */
-        "application/xhtml+xml",                      /* 0x3B */
-        "application/wml+xml",                        /* 0x3C */
-        "text/css",                                   /* 0x3D */
-        "application/vnd.wap.mms-message",            /* 0x3E */
-        "application/vnd.wap.rollover-certificate",   /* 0x3F */
-        "application/vnd.wap.locc+wbxml",             /* 0x40 */
-        "application/vnd.wap.loc+xml",                /* 0x41 */
-        "application/vnd.syncml.dm+wbxml",            /* 0x42 */
-        "application/vnd.syncml.dm+xml",              /* 0x43 */
-        "application/vnd.syncml.notification",        /* 0x44 */
-        "application/vnd.wap.xhtml+xml",              /* 0x45 */
-        "application/vnd.wv.csp.cir",                 /* 0x46 */
-        "application/vnd.oma.dd+xml",                 /* 0x47 */
-        "application/vnd.oma.drm.message",            /* 0x48 */
-        "application/vnd.oma.drm.content",            /* 0x49 */
-        "application/vnd.oma.drm.rights+xml",         /* 0x4A */
-        "application/vnd.oma.drm.rights+wbxml",       /* 0x4B */
-        "application/vnd.wv.csp+xml",                 /* 0x4C */
-        "application/vnd.wv.csp+wbxml",               /* 0x4D */
-        "application/vnd.syncml.ds.notification",     /* 0x4E */
-        "audio/*",                                    /* 0x4F */
-        "video/*",                                    /* 0x50 */
-        "application/vnd.oma.dd2+xml",                /* 0x51 */
-        "application/mikey"                           /* 0x52 */
-    };
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java
deleted file mode 100644
index 6a58ba6..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java
+++ /dev/null
@@ -1,1874 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 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 com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.CharacterSets;
-import com.android.mmscommon.ContentType;
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-import android.util.Config;
-import android.util.Log;
-import android.util.base64.Base64;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.HashMap;
-
-public class PduParser {
-    /**
-     *  The next are WAP values defined in WSP specification.
-     */
-    private static final int QUOTE = 127;
-    private static final int LENGTH_QUOTE = 31;
-    private static final int TEXT_MIN = 32;
-    private static final int TEXT_MAX = 127;
-    private static final int SHORT_INTEGER_MAX = 127;
-    private static final int SHORT_LENGTH_MAX = 30;
-    private static final int LONG_INTEGER_LENGTH_MAX = 8;
-    private static final int QUOTED_STRING_FLAG = 34;
-    private static final int END_STRING_FLAG = 0x00;
-    //The next two are used by the interface "parseWapString" to
-    //distinguish Text-String and Quoted-String.
-    private static final int TYPE_TEXT_STRING = 0;
-    private static final int TYPE_QUOTED_STRING = 1;
-    private static final int TYPE_TOKEN_STRING = 2;
-
-    /**
-     * Specify the part position.
-     */
-    private static final int THE_FIRST_PART = 0;
-    private static final int THE_LAST_PART = 1;
-
-    /**
-     * The pdu data.
-     */
-    private ByteArrayInputStream mPduDataStream = null;
-
-    /**
-     * Store pdu headers
-     */
-    private PduHeaders mHeaders = null;
-
-    /**
-     * Store pdu parts.
-     */
-    private PduBody mBody = null;
-
-    /**
-     * Store the "type" parameter in "Content-Type" header field.
-     */
-    private static byte[] mTypeParam = null;
-
-    /**
-     * Store the "start" parameter in "Content-Type" header field.
-     */
-    private static byte[] mStartParam = null;
-
-    /**
-     * The log tag.
-     */
-    private static final String LOG_TAG = "PduParser";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
-
-    /**
-     * Constructor.
-     *
-     * @param pduDataStream pdu data to be parsed
-     */
-    public PduParser(byte[] pduDataStream) {
-        mPduDataStream = new ByteArrayInputStream(pduDataStream);
-    }
-
-    /**
-     * Parse the pdu.
-     *
-     * @return the pdu structure if parsing successfully.
-     *         null if parsing error happened or mandatory fields are not set.
-     */
-    public GenericPdu parse(){
-        if (mPduDataStream == null) {
-            return null;
-        }
-
-        /* parse headers */
-        mHeaders = parseHeaders(mPduDataStream);
-        if (null == mHeaders) {
-            // Parse headers failed.
-            return null;
-        }
-
-        /* get the message type */
-        int messageType = mHeaders.getOctet(PduHeaders.MESSAGE_TYPE);
-
-        /* check mandatory header fields */
-        if (false == checkMandatoryHeader(mHeaders)) {
-            log("check mandatory headers failed!");
-            return null;
-        }
-
-        if ((PduHeaders.MESSAGE_TYPE_SEND_REQ == messageType) ||
-                (PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF == messageType)) {
-            /* need to parse the parts */
-            mBody = parseParts(mPduDataStream);
-            if (null == mBody) {
-                // Parse parts failed.
-                return null;
-            }
-        }
-
-        switch (messageType) {
-            case PduHeaders.MESSAGE_TYPE_SEND_REQ:
-                SendReq sendReq = new SendReq(mHeaders, mBody);
-                return sendReq;
-            case PduHeaders.MESSAGE_TYPE_SEND_CONF:
-                SendConf sendConf = new SendConf(mHeaders);
-                return sendConf;
-            case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
-                NotificationInd notificationInd =
-                    new NotificationInd(mHeaders);
-                return notificationInd;
-            case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
-                NotifyRespInd notifyRespInd =
-                    new NotifyRespInd(mHeaders);
-                return notifyRespInd;
-            case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
-                RetrieveConf retrieveConf =
-                    new RetrieveConf(mHeaders, mBody);
-
-                byte[] contentType = retrieveConf.getContentType();
-                if (null == contentType) {
-                    return null;
-                }
-                String ctTypeStr = new String(contentType);
-                if (ctTypeStr.equals(ContentType.MULTIPART_MIXED)
-                        || ctTypeStr.equals(ContentType.MULTIPART_RELATED)
-                        || ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) {
-                    // The MMS content type must be "application/vnd.wap.multipart.mixed"
-                    // or "application/vnd.wap.multipart.related"
-                    // or "application/vnd.wap.multipart.alternative"
-                    return retrieveConf;
-                }
-                return null;
-            case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
-                DeliveryInd deliveryInd =
-                    new DeliveryInd(mHeaders);
-                return deliveryInd;
-            case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
-                AcknowledgeInd acknowledgeInd =
-                    new AcknowledgeInd(mHeaders);
-                return acknowledgeInd;
-            case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND:
-                ReadOrigInd readOrigInd =
-                    new ReadOrigInd(mHeaders);
-                return readOrigInd;
-            case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
-                ReadRecInd readRecInd =
-                    new ReadRecInd(mHeaders);
-                return readRecInd;
-            default:
-                log("Parser doesn't support this message type in this version!");
-            return null;
-        }
-    }
-
-    /**
-     * Parse pdu headers.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return headers in PduHeaders structure, null when parse fail
-     */
-    protected PduHeaders parseHeaders(ByteArrayInputStream pduDataStream){
-        if (pduDataStream == null) {
-            return null;
-        }
-
-        boolean keepParsing = true;
-        PduHeaders headers = new PduHeaders();
-
-        while (keepParsing && (pduDataStream.available() > 0)) {
-            int headerField = extractByteValue(pduDataStream);
-            switch (headerField) {
-                case PduHeaders.MESSAGE_TYPE:
-                {
-                    int messageType = extractByteValue(pduDataStream);
-                    switch (messageType) {
-                        // We don't support these kind of messages now.
-                        case PduHeaders.MESSAGE_TYPE_FORWARD_REQ:
-                        case PduHeaders.MESSAGE_TYPE_FORWARD_CONF:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF:
-                        case PduHeaders.MESSAGE_TYPE_MBOX_DESCR:
-                        case PduHeaders.MESSAGE_TYPE_DELETE_REQ:
-                        case PduHeaders.MESSAGE_TYPE_DELETE_CONF:
-                        case PduHeaders.MESSAGE_TYPE_CANCEL_REQ:
-                        case PduHeaders.MESSAGE_TYPE_CANCEL_CONF:
-                            return null;
-                    }
-                    try {
-                        headers.setOctet(messageType, headerField);
-                    } catch(InvalidHeaderValueException e) {
-                        log("Set invalid Octet value: " + messageType +
-                                " into the header filed: " + headerField);
-                        return null;
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Octet header field!");
-                        return null;
-                    }
-                    break;
-                }
-                /* Octect value */
-                case PduHeaders.REPORT_ALLOWED:
-                case PduHeaders.ADAPTATION_ALLOWED:
-                case PduHeaders.DELIVERY_REPORT:
-                case PduHeaders.DRM_CONTENT:
-                case PduHeaders.DISTRIBUTION_INDICATOR:
-                case PduHeaders.QUOTAS:
-                case PduHeaders.READ_REPORT:
-                case PduHeaders.STORE:
-                case PduHeaders.STORED:
-                case PduHeaders.TOTALS:
-                case PduHeaders.SENDER_VISIBILITY:
-                case PduHeaders.READ_STATUS:
-                case PduHeaders.CANCEL_STATUS:
-                case PduHeaders.PRIORITY:
-                case PduHeaders.STATUS:
-                case PduHeaders.REPLY_CHARGING:
-                case PduHeaders.MM_STATE:
-                case PduHeaders.RECOMMENDED_RETRIEVAL_MODE:
-                case PduHeaders.CONTENT_CLASS:
-                case PduHeaders.RETRIEVE_STATUS:
-                case PduHeaders.STORE_STATUS:
-                    /**
-                     * The following field has a different value when
-                     * used in the M-Mbox-Delete.conf and M-Delete.conf PDU.
-                     * For now we ignore this fact, since we do not support these PDUs
-                     */
-                case PduHeaders.RESPONSE_STATUS:
-                {
-                    int value = extractByteValue(pduDataStream);
-
-                    try {
-                        headers.setOctet(value, headerField);
-                    } catch(InvalidHeaderValueException e) {
-                        log("Set invalid Octet value: " + value +
-                                " into the header filed: " + headerField);
-                        return null;
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Octet header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                /* Long-Integer */
-                case PduHeaders.DATE:
-                case PduHeaders.REPLY_CHARGING_SIZE:
-                case PduHeaders.MESSAGE_SIZE:
-                {
-                    try {
-                        long value = parseLongInteger(pduDataStream);
-                        headers.setLongInteger(value, headerField);
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Long-Integer header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                /* Integer-Value */
-                case PduHeaders.MESSAGE_COUNT:
-                case PduHeaders.START:
-                case PduHeaders.LIMIT:
-                {
-                    try {
-                        long value = parseIntegerValue(pduDataStream);
-                        headers.setLongInteger(value, headerField);
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Long-Integer header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                /* Text-String */
-                case PduHeaders.TRANSACTION_ID:
-                case PduHeaders.REPLY_CHARGING_ID:
-                case PduHeaders.AUX_APPLIC_ID:
-                case PduHeaders.APPLIC_ID:
-                case PduHeaders.REPLY_APPLIC_ID:
-                    /**
-                     * The next three header fields are email addresses
-                     * as defined in RFC2822,
-                     * not including the characters "<" and ">"
-                     */
-                case PduHeaders.MESSAGE_ID:
-                case PduHeaders.REPLACE_ID:
-                case PduHeaders.CANCEL_ID:
-                    /**
-                     * The following field has a different value when
-                     * used in the M-Mbox-Delete.conf and M-Delete.conf PDU.
-                     * For now we ignore this fact, since we do not support these PDUs
-                     */
-                case PduHeaders.CONTENT_LOCATION:
-                {
-                    byte[] value = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                    if (null != value) {
-                        try {
-                            headers.setTextString(value, headerField);
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch(RuntimeException e) {
-                            log(headerField + "is not Text-String header field!");
-                            return null;
-                        }
-                    }
-                    break;
-                }
-
-                /* Encoded-string-value */
-                case PduHeaders.SUBJECT:
-                case PduHeaders.RECOMMENDED_RETRIEVAL_MODE_TEXT:
-                case PduHeaders.RETRIEVE_TEXT:
-                case PduHeaders.STATUS_TEXT:
-                case PduHeaders.STORE_STATUS_TEXT:
-                    /* the next one is not support
-                     * M-Mbox-Delete.conf and M-Delete.conf now */
-                case PduHeaders.RESPONSE_TEXT:
-                {
-                    EncodedStringValue value =
-                        parseEncodedStringValue(pduDataStream);
-                    if (null != value) {
-                        try {
-                            headers.setEncodedStringValue(value, headerField);
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch (RuntimeException e) {
-                            log(headerField + "is not Encoded-String-Value header field!");
-                            return null;
-                        }
-                    }
-                    break;
-                }
-
-                /* Addressing model */
-                case PduHeaders.BCC:
-                case PduHeaders.CC:
-                case PduHeaders.TO:
-                {
-                    EncodedStringValue value =
-                        parseEncodedStringValue(pduDataStream);
-                    if (null != value) {
-                        byte[] address = value.getTextString();
-                        if (null != address) {
-                            String str = new String(address);
-                            int endIndex = str.indexOf("/");
-                            if (endIndex > 0) {
-                                str = str.substring(0, endIndex);
-                            }
-                            try {
-                                value.setTextString(str.getBytes());
-                            } catch(NullPointerException e) {
-                                log("null pointer error!");
-                                return null;
-                            }
-                        }
-
-                        try {
-                            headers.appendEncodedStringValue(value, headerField);
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch(RuntimeException e) {
-                            log(headerField + "is not Encoded-String-Value header field!");
-                            return null;
-                        }
-                    }
-                    break;
-                }
-
-                /* Value-length
-                 * (Absolute-token Date-value | Relative-token Delta-seconds-value) */
-                case PduHeaders.DELIVERY_TIME:
-                case PduHeaders.EXPIRY:
-                case PduHeaders.REPLY_CHARGING_DEADLINE:
-                {
-                    /* parse Value-length */
-                    parseValueLength(pduDataStream);
-
-                    /* Absolute-token or Relative-token */
-                    int token = extractByteValue(pduDataStream);
-
-                    /* Date-value or Delta-seconds-value */
-                    long timeValue;
-                    try {
-                        timeValue = parseLongInteger(pduDataStream);
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Long-Integer header field!");
-                        return null;
-                    }
-                    if (PduHeaders.VALUE_RELATIVE_TOKEN == token) {
-                        /* need to convert the Delta-seconds-value
-                         * into Date-value */
-                        timeValue = System.currentTimeMillis()/1000 + timeValue;
-                    }
-
-                    try {
-                        headers.setLongInteger(timeValue, headerField);
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Long-Integer header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                case PduHeaders.FROM: {
-                    /* From-value =
-                     * Value-length
-                     * (Address-present-token Encoded-string-value | Insert-address-token)
-                     */
-                    EncodedStringValue from = null;
-                    parseValueLength(pduDataStream); /* parse value-length */
-
-                    /* Address-present-token or Insert-address-token */
-                    int fromToken = extractByteValue(pduDataStream);
-
-                    /* Address-present-token or Insert-address-token */
-                    if (PduHeaders.FROM_ADDRESS_PRESENT_TOKEN == fromToken) {
-                        /* Encoded-string-value */
-                        from = parseEncodedStringValue(pduDataStream);
-                        if (null != from) {
-                            byte[] address = from.getTextString();
-                            if (null != address) {
-                                String str = new String(address);
-                                int endIndex = str.indexOf("/");
-                                if (endIndex > 0) {
-                                    str = str.substring(0, endIndex);
-                                }
-                                try {
-                                    from.setTextString(str.getBytes());
-                                } catch(NullPointerException e) {
-                                    log("null pointer error!");
-                                    return null;
-                                }
-                            }
-                        }
-                    } else {
-                        try {
-                            from = new EncodedStringValue(
-                                    PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes());
-                        } catch(NullPointerException e) {
-                            log(headerField + "is not Encoded-String-Value header field!");
-                            return null;
-                        }
-                    }
-
-                    try {
-                        headers.setEncodedStringValue(from, PduHeaders.FROM);
-                    } catch(NullPointerException e) {
-                        log("null pointer error!");
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Encoded-String-Value header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                case PduHeaders.MESSAGE_CLASS: {
-                    /* Message-class-value = Class-identifier | Token-text */
-                    pduDataStream.mark(1);
-                    int messageClass = extractByteValue(pduDataStream);
-
-                    if (messageClass >= PduHeaders.MESSAGE_CLASS_PERSONAL) {
-                        /* Class-identifier */
-                        try {
-                            if (PduHeaders.MESSAGE_CLASS_PERSONAL == messageClass) {
-                                headers.setTextString(
-                                        PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes(),
-                                        PduHeaders.MESSAGE_CLASS);
-                            } else if (PduHeaders.MESSAGE_CLASS_ADVERTISEMENT == messageClass) {
-                                headers.setTextString(
-                                        PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes(),
-                                        PduHeaders.MESSAGE_CLASS);
-                            } else if (PduHeaders.MESSAGE_CLASS_INFORMATIONAL == messageClass) {
-                                headers.setTextString(
-                                        PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes(),
-                                        PduHeaders.MESSAGE_CLASS);
-                            } else if (PduHeaders.MESSAGE_CLASS_AUTO == messageClass) {
-                                headers.setTextString(
-                                        PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes(),
-                                        PduHeaders.MESSAGE_CLASS);
-                            }
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch(RuntimeException e) {
-                            log(headerField + "is not Text-String header field!");
-                            return null;
-                        }
-                    } else {
-                        /* Token-text */
-                        pduDataStream.reset();
-                        byte[] messageClassString = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                        if (null != messageClassString) {
-                            try {
-                                headers.setTextString(messageClassString, PduHeaders.MESSAGE_CLASS);
-                            } catch(NullPointerException e) {
-                                log("null pointer error!");
-                            } catch(RuntimeException e) {
-                                log(headerField + "is not Text-String header field!");
-                                return null;
-                            }
-                        }
-                    }
-                    break;
-                }
-
-                case PduHeaders.MMS_VERSION: {
-                    int version = parseShortInteger(pduDataStream);
-
-                    try {
-                        headers.setOctet(version, PduHeaders.MMS_VERSION);
-                    } catch(InvalidHeaderValueException e) {
-                        log("Set invalid Octet value: " + version +
-                                " into the header filed: " + headerField);
-                        return null;
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Octet header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                case PduHeaders.PREVIOUSLY_SENT_BY: {
-                    /* Previously-sent-by-value =
-                     * Value-length Forwarded-count-value Encoded-string-value */
-                    /* parse value-length */
-                    parseValueLength(pduDataStream);
-
-                    /* parse Forwarded-count-value */
-                    try {
-                        parseIntegerValue(pduDataStream);
-                    } catch(RuntimeException e) {
-                        log(headerField + " is not Integer-Value");
-                        return null;
-                    }
-
-                    /* parse Encoded-string-value */
-                    EncodedStringValue previouslySentBy =
-                        parseEncodedStringValue(pduDataStream);
-                    if (null != previouslySentBy) {
-                        try {
-                            headers.setEncodedStringValue(previouslySentBy,
-                                    PduHeaders.PREVIOUSLY_SENT_BY);
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch(RuntimeException e) {
-                            log(headerField + "is not Encoded-String-Value header field!");
-                            return null;
-                        }
-                    }
-                    break;
-                }
-
-                case PduHeaders.PREVIOUSLY_SENT_DATE: {
-                    /* Previously-sent-date-value =
-                     * Value-length Forwarded-count-value Date-value */
-                    /* parse value-length */
-                    parseValueLength(pduDataStream);
-
-                    /* parse Forwarded-count-value */
-                    try {
-                        parseIntegerValue(pduDataStream);
-                    } catch(RuntimeException e) {
-                        log(headerField + " is not Integer-Value");
-                        return null;
-                    }
-
-                    /* Date-value */
-                    try {
-                        long perviouslySentDate = parseLongInteger(pduDataStream);
-                        headers.setLongInteger(perviouslySentDate,
-                                PduHeaders.PREVIOUSLY_SENT_DATE);
-                    } catch(RuntimeException e) {
-                        log(headerField + "is not Long-Integer header field!");
-                        return null;
-                    }
-                    break;
-                }
-
-                case PduHeaders.MM_FLAGS: {
-                    /* MM-flags-value =
-                     * Value-length
-                     * ( Add-token | Remove-token | Filter-token )
-                     * Encoded-string-value
-                     */
-
-                    /* parse Value-length */
-                    parseValueLength(pduDataStream);
-
-                    /* Add-token | Remove-token | Filter-token */
-                    extractByteValue(pduDataStream);
-
-                    /* Encoded-string-value */
-                    parseEncodedStringValue(pduDataStream);
-
-                    /* not store this header filed in "headers",
-                     * because now PduHeaders doesn't support it */
-                    break;
-                }
-
-                /* Value-length
-                 * (Message-total-token | Size-total-token) Integer-Value */
-                case PduHeaders.MBOX_TOTALS:
-                case PduHeaders.MBOX_QUOTAS:
-                {
-                    /* Value-length */
-                    parseValueLength(pduDataStream);
-
-                    /* Message-total-token | Size-total-token */
-                    extractByteValue(pduDataStream);
-
-                    /*Integer-Value*/
-                    try {
-                        parseIntegerValue(pduDataStream);
-                    } catch(RuntimeException e) {
-                        log(headerField + " is not Integer-Value");
-                        return null;
-                    }
-
-                    /* not store these headers filed in "headers",
-                    because now PduHeaders doesn't support them */
-                    break;
-                }
-
-                case PduHeaders.ELEMENT_DESCRIPTOR: {
-                    parseContentType(pduDataStream, null);
-
-                    /* not store this header filed in "headers",
-                    because now PduHeaders doesn't support it */
-                    break;
-                }
-
-                case PduHeaders.CONTENT_TYPE: {
-                    HashMap<Integer, Object> map =
-                        new HashMap<Integer, Object>();
-                    byte[] contentType =
-                        parseContentType(pduDataStream, map);
-
-                    if (null != contentType) {
-                        try {
-                            headers.setTextString(contentType, PduHeaders.CONTENT_TYPE);
-                        } catch(NullPointerException e) {
-                            log("null pointer error!");
-                        } catch(RuntimeException e) {
-                            log(headerField + "is not Text-String header field!");
-                            return null;
-                        }
-                    }
-
-                    /* get start parameter */
-                    mStartParam = (byte[]) map.get(PduPart.P_START);
-
-                    /* get charset parameter */
-                    mTypeParam= (byte[]) map.get(PduPart.P_TYPE);
-
-                    keepParsing = false;
-                    break;
-                }
-
-                case PduHeaders.CONTENT:
-                case PduHeaders.ADDITIONAL_HEADERS:
-                case PduHeaders.ATTRIBUTES:
-                default: {
-                    log("Unknown header");
-                }
-            }
-        }
-
-        return headers;
-    }
-
-    /**
-     * Parse pdu parts.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return parts in PduBody structure
-     */
-    protected static PduBody parseParts(ByteArrayInputStream pduDataStream) {
-        if (pduDataStream == null) {
-            return null;
-        }
-
-        int count = parseUnsignedInt(pduDataStream); // get the number of parts
-        PduBody body = new PduBody();
-
-        for (int i = 0 ; i < count ; i++) {
-            int headerLength = parseUnsignedInt(pduDataStream);
-            int dataLength = parseUnsignedInt(pduDataStream);
-            PduPart part = new PduPart();
-            int startPos = pduDataStream.available();
-            if (startPos <= 0) {
-                // Invalid part.
-                return null;
-            }
-
-            /* parse part's content-type */
-            HashMap<Integer, Object> map = new HashMap<Integer, Object>();
-            byte[] contentType = parseContentType(pduDataStream, map);
-            if (null != contentType) {
-                part.setContentType(contentType);
-            } else {
-                part.setContentType((PduContentTypes.contentTypes[0]).getBytes()); //"*/*"
-            }
-
-            /* get name parameter */
-            byte[] name = (byte[]) map.get(PduPart.P_NAME);
-            if (null != name) {
-                part.setName(name);
-            }
-
-            /* get charset parameter */
-            Integer charset = (Integer) map.get(PduPart.P_CHARSET);
-            if (null != charset) {
-                part.setCharset(charset);
-            }
-
-            /* parse part's headers */
-            int endPos = pduDataStream.available();
-            int partHeaderLen = headerLength - (startPos - endPos);
-            if (partHeaderLen > 0) {
-                if (false == parsePartHeaders(pduDataStream, part, partHeaderLen)) {
-                    // Parse part header faild.
-                    return null;
-                }
-            } else if (partHeaderLen < 0) {
-                // Invalid length of content-type.
-                return null;
-            }
-
-            /* FIXME: check content-id, name, filename and content location,
-             * if not set anyone of them, generate a default content-location
-             */
-            if ((null == part.getContentLocation())
-                    && (null == part.getName())
-                    && (null == part.getFilename())
-                    && (null == part.getContentId())) {
-                part.setContentLocation(Long.toOctalString(
-                        System.currentTimeMillis()).getBytes());
-            }
-
-            /* get part's data */
-            if (dataLength > 0) {
-                byte[] partData = new byte[dataLength];
-                pduDataStream.read(partData, 0, dataLength);
-                // Check Content-Transfer-Encoding.
-                byte[] partDataEncoding = part.getContentTransferEncoding();
-                if (null != partDataEncoding) {
-                    String encoding = new String(partDataEncoding);
-                    if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) {
-                        // Decode "base64" into "binary".
-                        partData = Base64.decode(partData, Base64.DEFAULT);
-                    } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) {
-                        // Decode "quoted-printable" into "binary".
-                        partData = QuotedPrintable.decodeQuotedPrintable(partData);
-                    } else {
-                        // "binary" is the default encoding.
-                    }
-                }
-                if (null == partData) {
-                    log("Decode part data error!");
-                    return null;
-                }
-                part.setData(partData);
-            }
-
-            /* add this part to body */
-            if (THE_FIRST_PART == checkPartPosition(part)) {
-                /* this is the first part */
-                body.addPart(0, part);
-            } else {
-                /* add the part to the end */
-                body.addPart(part);
-            }
-        }
-
-        return body;
-    }
-
-    /**
-     * Log status.
-     *
-     * @param text log information
-     */
-    private static void log(String text) {
-        if (LOCAL_LOGV) {
-            Log.v(LOG_TAG, text);
-        }
-    }
-
-    /**
-     * Parse unsigned integer.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return the integer, -1 when failed
-     */
-    protected static int parseUnsignedInt(ByteArrayInputStream pduDataStream) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * The maximum size of a uintvar is 32 bits.
-         * So it will be encoded in no more than 5 octets.
-         */
-        assert(null != pduDataStream);
-        int result = 0;
-        int temp = pduDataStream.read();
-        if (temp == -1) {
-            return temp;
-        }
-
-        while((temp & 0x80) != 0) {
-            result = result << 7;
-            result |= temp & 0x7F;
-            temp = pduDataStream.read();
-            if (temp == -1) {
-                return temp;
-            }
-        }
-
-        result = result << 7;
-        result |= temp & 0x7F;
-
-        return result;
-    }
-
-    /**
-     * Parse value length.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return the integer
-     */
-    protected static int parseValueLength(ByteArrayInputStream pduDataStream) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Value-length = Short-length | (Length-quote Length)
-         * Short-length = <Any octet 0-30>
-         * Length-quote = <Octet 31>
-         * Length = Uintvar-integer
-         * Uintvar-integer = 1*5 OCTET
-         */
-        assert(null != pduDataStream);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        int first = temp & 0xFF;
-
-        if (first <= SHORT_LENGTH_MAX) {
-            return first;
-        } else if (first == LENGTH_QUOTE) {
-            return parseUnsignedInt(pduDataStream);
-        }
-
-        throw new RuntimeException ("Value length > LENGTH_QUOTE!");
-    }
-
-    /**
-     * Parse encoded string value.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return the EncodedStringValue
-     */
-    protected static EncodedStringValue parseEncodedStringValue(ByteArrayInputStream pduDataStream){
-        /**
-         * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf
-         * Encoded-string-value = Text-string | Value-length Char-set Text-string
-         */
-        assert(null != pduDataStream);
-        pduDataStream.mark(1);
-        EncodedStringValue returnValue = null;
-        int charset = 0;
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        int first = temp & 0xFF;
-
-        pduDataStream.reset();
-        if (first < TEXT_MIN) {
-            parseValueLength(pduDataStream);
-
-            charset = parseShortInteger(pduDataStream); //get the "Charset"
-        }
-
-        byte[] textString = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-
-        try {
-            if (0 != charset) {
-                returnValue = new EncodedStringValue(charset, textString);
-            } else {
-                returnValue = new EncodedStringValue(textString);
-            }
-        } catch(Exception e) {
-            return null;
-        }
-
-        return returnValue;
-    }
-
-    /**
-     * Parse Text-String or Quoted-String.
-     *
-     * @param pduDataStream pdu data input stream
-     * @param stringType TYPE_TEXT_STRING or TYPE_QUOTED_STRING
-     * @return the string without End-of-string in byte array
-     */
-    protected static byte[] parseWapString(ByteArrayInputStream pduDataStream,
-            int stringType) {
-        assert(null != pduDataStream);
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Text-string = [Quote] *TEXT End-of-string
-         * If the first character in the TEXT is in the range of 128-255,
-         * a Quote character must precede it.
-         * Otherwise the Quote character must be omitted.
-         * The Quote is not part of the contents.
-         * Quote = <Octet 127>
-         * End-of-string = <Octet 0>
-         *
-         * Quoted-string = <Octet 34> *TEXT End-of-string
-         *
-         * Token-text = Token End-of-string
-         */
-
-        // Mark supposed beginning of Text-string
-        // We will have to mark again if first char is QUOTE or QUOTED_STRING_FLAG
-        pduDataStream.mark(1);
-
-        // Check first char
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        if ((TYPE_QUOTED_STRING == stringType) &&
-                (QUOTED_STRING_FLAG == temp)) {
-            // Mark again if QUOTED_STRING_FLAG and ignore it
-            pduDataStream.mark(1);
-        } else if ((TYPE_TEXT_STRING == stringType) &&
-                (QUOTE == temp)) {
-            // Mark again if QUOTE and ignore it
-            pduDataStream.mark(1);
-        } else {
-            // Otherwise go back to origin
-            pduDataStream.reset();
-        }
-
-        // We are now definitely at the beginning of string
-        /**
-         * Return *TOKEN or *TEXT (Text-String without QUOTE,
-         * Quoted-String without QUOTED_STRING_FLAG and without End-of-string)
-         */
-        return getWapString(pduDataStream, stringType);
-    }
-
-    /**
-     * Check TOKEN data defined in RFC2616.
-     * @param ch checking data
-     * @return true when ch is TOKEN, false when ch is not TOKEN
-     */
-    protected static boolean isTokenCharacter(int ch) {
-        /**
-         * Token      = 1*<any CHAR except CTLs or separators>
-         * separators = "("(40) | ")"(41) | "<"(60) | ">"(62) | "@"(64)
-         *            | ","(44) | ";"(59) | ":"(58) | "\"(92) | <">(34)
-         *            | "/"(47) | "["(91) | "]"(93) | "?"(63) | "="(61)
-         *            | "{"(123) | "}"(125) | SP(32) | HT(9)
-         * CHAR       = <any US-ASCII character (octets 0 - 127)>
-         * CTL        = <any US-ASCII control character
-         *            (octets 0 - 31) and DEL (127)>
-         * SP         = <US-ASCII SP, space (32)>
-         * HT         = <US-ASCII HT, horizontal-tab (9)>
-         */
-        if((ch < 33) || (ch > 126)) {
-            return false;
-        }
-
-        switch(ch) {
-            case '"': /* '"' */
-            case '(': /* '(' */
-            case ')': /* ')' */
-            case ',': /* ',' */
-            case '/': /* '/' */
-            case ':': /* ':' */
-            case ';': /* ';' */
-            case '<': /* '<' */
-            case '=': /* '=' */
-            case '>': /* '>' */
-            case '?': /* '?' */
-            case '@': /* '@' */
-            case '[': /* '[' */
-            case '\\': /* '\' */
-            case ']': /* ']' */
-            case '{': /* '{' */
-            case '}': /* '}' */
-                return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check TEXT data defined in RFC2616.
-     * @param ch checking data
-     * @return true when ch is TEXT, false when ch is not TEXT
-     */
-    protected static boolean isText(int ch) {
-        /**
-         * TEXT = <any OCTET except CTLs,
-         *      but including LWS>
-         * CTL  = <any US-ASCII control character
-         *      (octets 0 - 31) and DEL (127)>
-         * LWS  = [CRLF] 1*( SP | HT )
-         * CRLF = CR LF
-         * CR   = <US-ASCII CR, carriage return (13)>
-         * LF   = <US-ASCII LF, linefeed (10)>
-         */
-        if(((ch >= 32) && (ch <= 126)) || ((ch >= 128) && (ch <= 255))) {
-            return true;
-        }
-
-        switch(ch) {
-            case '\t': /* '\t' */
-            case '\n': /* '\n' */
-            case '\r': /* '\r' */
-                return true;
-        }
-
-        return false;
-    }
-
-    protected static byte[] getWapString(ByteArrayInputStream pduDataStream,
-            int stringType) {
-        assert(null != pduDataStream);
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        while((-1 != temp) && ('\0' != temp)) {
-            // check each of the character
-            if (stringType == TYPE_TOKEN_STRING) {
-                if (isTokenCharacter(temp)) {
-                    out.write(temp);
-                }
-            } else {
-                if (isText(temp)) {
-                    out.write(temp);
-                }
-            }
-
-            temp = pduDataStream.read();
-            assert(-1 != temp);
-        }
-
-        if (out.size() > 0) {
-            return out.toByteArray();
-        }
-
-        return null;
-    }
-
-    /**
-     * Extract a byte value from the input stream.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return the byte
-     */
-    protected static int extractByteValue(ByteArrayInputStream pduDataStream) {
-        assert(null != pduDataStream);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        return temp & 0xFF;
-    }
-
-    /**
-     * Parse Short-Integer.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return the byte
-     */
-    protected static int parseShortInteger(ByteArrayInputStream pduDataStream) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Short-integer = OCTET
-         * Integers in range 0-127 shall be encoded as a one
-         * octet value with the most significant bit set to one (1xxx xxxx)
-         * and with the value in the remaining least significant bits.
-         */
-        assert(null != pduDataStream);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        return temp & 0x7F;
-    }
-
-    /**
-     * Parse Long-Integer.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return long integer
-     */
-    protected static long parseLongInteger(ByteArrayInputStream pduDataStream) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Long-integer = Short-length Multi-octet-integer
-         * The Short-length indicates the length of the Multi-octet-integer
-         * Multi-octet-integer = 1*30 OCTET
-         * The content octets shall be an unsigned integer value
-         * with the most significant octet encoded first (big-endian representation).
-         * The minimum number of octets must be used to encode the value.
-         * Short-length = <Any octet 0-30>
-         */
-        assert(null != pduDataStream);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        int count = temp & 0xFF;
-
-        if (count > LONG_INTEGER_LENGTH_MAX) {
-            throw new RuntimeException("Octet count greater than 8 and I can't represent that!");
-        }
-
-        long result = 0;
-
-        for (int i = 0 ; i < count ; i++) {
-            temp = pduDataStream.read();
-            assert(-1 != temp);
-            result <<= 8;
-            result += (temp & 0xFF);
-        }
-
-        return result;
-    }
-
-    /**
-     * Parse Integer-Value.
-     *
-     * @param pduDataStream pdu data input stream
-     * @return long integer
-     */
-    protected static long parseIntegerValue(ByteArrayInputStream pduDataStream) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Integer-Value = Short-integer | Long-integer
-         */
-        assert(null != pduDataStream);
-        pduDataStream.mark(1);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        pduDataStream.reset();
-        if (temp > SHORT_INTEGER_MAX) {
-            return parseShortInteger(pduDataStream);
-        } else {
-            return parseLongInteger(pduDataStream);
-        }
-    }
-
-    /**
-     * To skip length of the wap value.
-     *
-     * @param pduDataStream pdu data input stream
-     * @param length area size
-     * @return the values in this area
-     */
-    protected static int skipWapValue(ByteArrayInputStream pduDataStream, int length) {
-        assert(null != pduDataStream);
-        byte[] area = new byte[length];
-        int readLen = pduDataStream.read(area, 0, length);
-        if (readLen < length) { //The actually read length is lower than the length
-            return -1;
-        } else {
-            return readLen;
-        }
-    }
-
-    /**
-     * Parse content type parameters. For now we just support
-     * four parameters used in mms: "type", "start", "name", "charset".
-     *
-     * @param pduDataStream pdu data input stream
-     * @param map to store parameters of Content-Type field
-     * @param length length of all the parameters
-     */
-    protected static void parseContentTypeParams(ByteArrayInputStream pduDataStream,
-            HashMap<Integer, Object> map, Integer length) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Parameter = Typed-parameter | Untyped-parameter
-         * Typed-parameter = Well-known-parameter-token Typed-value
-         * the actual expected type of the value is implied by the well-known parameter
-         * Well-known-parameter-token = Integer-value
-         * the code values used for parameters are specified in the Assigned Numbers appendix
-         * Typed-value = Compact-value | Text-value
-         * In addition to the expected type, there may be no value.
-         * If the value cannot be encoded using the expected type, it shall be encoded as text.
-         * Compact-value = Integer-value |
-         * Date-value | Delta-seconds-value | Q-value | Version-value |
-         * Uri-value
-         * Untyped-parameter = Token-text Untyped-value
-         * the type of the value is unknown, but it shall be encoded as an integer,
-         * if that is possible.
-         * Untyped-value = Integer-value | Text-value
-         */
-        assert(null != pduDataStream);
-        assert(length > 0);
-
-        int startPos = pduDataStream.available();
-        int tempPos = 0;
-        int lastLen = length;
-        while(0 < lastLen) {
-            int param = pduDataStream.read();
-            assert(-1 != param);
-            lastLen--;
-
-            switch (param) {
-                /**
-                 * From rfc2387, chapter 3.1
-                 * The type parameter must be specified and its value is the MIME media
-                 * type of the "root" body part. It permits a MIME user agent to
-                 * determine the content-type without reference to the enclosed body
-                 * part. If the value of the type parameter and the root body part's
-                 * content-type differ then the User Agent's behavior is undefined.
-                 *
-                 * From wap-230-wsp-20010705-a.pdf
-                 * type = Constrained-encoding
-                 * Constrained-encoding = Extension-Media | Short-integer
-                 * Extension-media = *TEXT End-of-string
-                 */
-                case PduPart.P_TYPE:
-                case PduPart.P_CT_MR_TYPE:
-                    pduDataStream.mark(1);
-                    int first = extractByteValue(pduDataStream);
-                    pduDataStream.reset();
-                    if (first > TEXT_MAX) {
-                        // Short-integer (well-known type)
-                        int index = parseShortInteger(pduDataStream);
-
-                        if (index < PduContentTypes.contentTypes.length) {
-                            byte[] type = (PduContentTypes.contentTypes[index]).getBytes();
-                            map.put(PduPart.P_TYPE, type);
-                        } else {
-                            //not support this type, ignore it.
-                        }
-                    } else {
-                        // Text-String (extension-media)
-                        byte[] type = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                        if ((null != type) && (null != map)) {
-                            map.put(PduPart.P_TYPE, type);
-                        }
-                    }
-
-                    tempPos = pduDataStream.available();
-                    lastLen = length - (startPos - tempPos);
-                    break;
-
-                    /**
-                     * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.3.
-                     * Start Parameter Referring to Presentation
-                     *
-                     * From rfc2387, chapter 3.2
-                     * The start parameter, if given, is the content-ID of the compound
-                     * object's "root". If not present the "root" is the first body part in
-                     * the Multipart/Related entity. The "root" is the element the
-                     * applications processes first.
-                     *
-                     * From wap-230-wsp-20010705-a.pdf
-                     * start = Text-String
-                     */
-                case PduPart.P_START:
-                case PduPart.P_DEP_START:
-                    byte[] start = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                    if ((null != start) && (null != map)) {
-                        map.put(PduPart.P_START, start);
-                    }
-
-                    tempPos = pduDataStream.available();
-                    lastLen = length - (startPos - tempPos);
-                    break;
-
-                    /**
-                     * From oma-ts-mms-conf-v1_3.pdf
-                     * In creation, the character set SHALL be either us-ascii
-                     * (IANA MIBenum 3) or utf-8 (IANA MIBenum 106)[Unicode].
-                     * In retrieval, both us-ascii and utf-8 SHALL be supported.
-                     *
-                     * From wap-230-wsp-20010705-a.pdf
-                     * charset = Well-known-charset|Text-String
-                     * Well-known-charset = Any-charset | Integer-value
-                     * Both are encoded using values from Character Set
-                     * Assignments table in Assigned Numbers
-                     * Any-charset = <Octet 128>
-                     * Equivalent to the special RFC2616 charset value "*"
-                     */
-                case PduPart.P_CHARSET:
-                    pduDataStream.mark(1);
-                    int firstValue = extractByteValue(pduDataStream);
-                    pduDataStream.reset();
-                    //Check first char
-                    if (((firstValue > TEXT_MIN) && (firstValue < TEXT_MAX)) ||
-                            (END_STRING_FLAG == firstValue)) {
-                        //Text-String (extension-charset)
-                        byte[] charsetStr = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                        try {
-                            int charsetInt = CharacterSets.getMibEnumValue(
-                                    new String(charsetStr));
-                            map.put(PduPart.P_CHARSET, charsetInt);
-                        } catch (UnsupportedEncodingException e) {
-                            // Not a well-known charset, use "*".
-                            Log.e(LOG_TAG, Arrays.toString(charsetStr), e);
-                            map.put(PduPart.P_CHARSET, CharacterSets.ANY_CHARSET);
-                        }
-                    } else {
-                        //Well-known-charset
-                        int charset = (int) parseIntegerValue(pduDataStream);
-                        if (map != null) {
-                            map.put(PduPart.P_CHARSET, charset);
-                        }
-                    }
-
-                    tempPos = pduDataStream.available();
-                    lastLen = length - (startPos - tempPos);
-                    break;
-
-                    /**
-                     * From oma-ts-mms-conf-v1_3.pdf
-                     * A name for multipart object SHALL be encoded using name-parameter
-                     * for Content-Type header in WSP multipart headers.
-                     *
-                     * From wap-230-wsp-20010705-a.pdf
-                     * name = Text-String
-                     */
-                case PduPart.P_DEP_NAME:
-                case PduPart.P_NAME:
-                    byte[] name = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                    if ((null != name) && (null != map)) {
-                        map.put(PduPart.P_NAME, name);
-                    }
-
-                    tempPos = pduDataStream.available();
-                    lastLen = length - (startPos - tempPos);
-                    break;
-                default:
-                    if (LOCAL_LOGV) {
-                        Log.v(LOG_TAG, "Not supported Content-Type parameter");
-                    }
-                if (-1 == skipWapValue(pduDataStream, lastLen)) {
-                    Log.e(LOG_TAG, "Corrupt Content-Type");
-                } else {
-                    lastLen = 0;
-                }
-                break;
-            }
-        }
-
-        if (0 != lastLen) {
-            Log.e(LOG_TAG, "Corrupt Content-Type");
-        }
-    }
-
-    /**
-     * Parse content type.
-     *
-     * @param pduDataStream pdu data input stream
-     * @param map to store parameters in Content-Type header field
-     * @return Content-Type value
-     */
-    protected static byte[] parseContentType(ByteArrayInputStream pduDataStream,
-            HashMap<Integer, Object> map) {
-        /**
-         * From wap-230-wsp-20010705-a.pdf
-         * Content-type-value = Constrained-media | Content-general-form
-         * Content-general-form = Value-length Media-type
-         * Media-type = (Well-known-media | Extension-Media) *(Parameter)
-         */
-        assert(null != pduDataStream);
-
-        byte[] contentType = null;
-        pduDataStream.mark(1);
-        int temp = pduDataStream.read();
-        assert(-1 != temp);
-        pduDataStream.reset();
-
-        int cur = (temp & 0xFF);
-
-        if (cur < TEXT_MIN) {
-            int length = parseValueLength(pduDataStream);
-            int startPos = pduDataStream.available();
-            pduDataStream.mark(1);
-            temp = pduDataStream.read();
-            assert(-1 != temp);
-            pduDataStream.reset();
-            int first = (temp & 0xFF);
-
-            if ((first >= TEXT_MIN) && (first <= TEXT_MAX)) {
-                contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-            } else if (first > TEXT_MAX) {
-                int index = parseShortInteger(pduDataStream);
-
-                if (index < PduContentTypes.contentTypes.length) { //well-known type
-                    contentType = (PduContentTypes.contentTypes[index]).getBytes();
-                } else {
-                    pduDataStream.reset();
-                    contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                }
-            } else {
-                Log.e(LOG_TAG, "Corrupt content-type");
-                return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*"
-            }
-
-            int endPos = pduDataStream.available();
-            int parameterLen = length - (startPos - endPos);
-            if (parameterLen > 0) {//have parameters
-                parseContentTypeParams(pduDataStream, map, parameterLen);
-            }
-
-            if (parameterLen < 0) {
-                Log.e(LOG_TAG, "Corrupt MMS message");
-                return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*"
-            }
-        } else if (cur <= TEXT_MAX) {
-            contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-        } else {
-            contentType =
-                (PduContentTypes.contentTypes[parseShortInteger(pduDataStream)]).getBytes();
-        }
-
-        return contentType;
-    }
-
-    /**
-     * Parse part's headers.
-     *
-     * @param pduDataStream pdu data input stream
-     * @param part to store the header informations of the part
-     * @param length length of the headers
-     * @return true if parse successfully, false otherwise
-     */
-    protected static boolean parsePartHeaders(ByteArrayInputStream pduDataStream,
-            PduPart part, int length) {
-        assert(null != pduDataStream);
-        assert(null != part);
-        assert(length > 0);
-
-        /**
-         * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.
-         * A name for multipart object SHALL be encoded using name-parameter
-         * for Content-Type header in WSP multipart headers.
-         * In decoding, name-parameter of Content-Type SHALL be used if available.
-         * If name-parameter of Content-Type is not available,
-         * filename parameter of Content-Disposition header SHALL be used if available.
-         * If neither name-parameter of Content-Type header nor filename parameter
-         * of Content-Disposition header is available,
-         * Content-Location header SHALL be used if available.
-         *
-         * Within SMIL part the reference to the media object parts SHALL use
-         * either Content-ID or Content-Location mechanism [RFC2557]
-         * and the corresponding WSP part headers in media object parts
-         * contain the corresponding definitions.
-         */
-        int startPos = pduDataStream.available();
-        int tempPos = 0;
-        int lastLen = length;
-        while(0 < lastLen) {
-            int header = pduDataStream.read();
-            assert(-1 != header);
-            lastLen--;
-
-            if (header > TEXT_MAX) {
-                // Number assigned headers.
-                switch (header) {
-                    case PduPart.P_CONTENT_LOCATION:
-                        /**
-                         * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21
-                         * Content-location-value = Uri-value
-                         */
-                        byte[] contentLocation = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                        if (null != contentLocation) {
-                            part.setContentLocation(contentLocation);
-                        }
-
-                        tempPos = pduDataStream.available();
-                        lastLen = length - (startPos - tempPos);
-                        break;
-                    case PduPart.P_CONTENT_ID:
-                        /**
-                         * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21
-                         * Content-ID-value = Quoted-string
-                         */
-                        byte[] contentId = parseWapString(pduDataStream, TYPE_QUOTED_STRING);
-                        if (null != contentId) {
-                            part.setContentId(contentId);
-                        }
-
-                        tempPos = pduDataStream.available();
-                        lastLen = length - (startPos - tempPos);
-                        break;
-                    case PduPart.P_DEP_CONTENT_DISPOSITION:
-                    case PduPart.P_CONTENT_DISPOSITION:
-                        /**
-                         * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21
-                         * Content-disposition-value = Value-length Disposition *(Parameter)
-                         * Disposition = Form-data | Attachment | Inline | Token-text
-                         * Form-data = <Octet 128>
-                         * Attachment = <Octet 129>
-                         * Inline = <Octet 130>
-                         */
-                        int len = parseValueLength(pduDataStream);
-                        pduDataStream.mark(1);
-                        int thisStartPos = pduDataStream.available();
-                        int thisEndPos = 0;
-                        int value = pduDataStream.read();
-
-                        if (value == PduPart.P_DISPOSITION_FROM_DATA ) {
-                            part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA);
-                        } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) {
-                            part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT);
-                        } else if (value == PduPart.P_DISPOSITION_INLINE) {
-                            part.setContentDisposition(PduPart.DISPOSITION_INLINE);
-                        } else {
-                            pduDataStream.reset();
-                            /* Token-text */
-                            part.setContentDisposition(parseWapString(pduDataStream, TYPE_TEXT_STRING));
-                        }
-
-                        /* get filename parameter and skip other parameters */
-                        thisEndPos = pduDataStream.available();
-                        if (thisStartPos - thisEndPos < len) {
-                            value = pduDataStream.read();
-                            if (value == PduPart.P_FILENAME) { //filename is text-string
-                                part.setFilename(parseWapString(pduDataStream, TYPE_TEXT_STRING));
-                            }
-
-                            /* skip other parameters */
-                            thisEndPos = pduDataStream.available();
-                            if (thisStartPos - thisEndPos < len) {
-                                int last = len - (thisStartPos - thisEndPos);
-                                byte[] temp = new byte[last];
-                                pduDataStream.read(temp, 0, last);
-                            }
-                        }
-
-                        tempPos = pduDataStream.available();
-                        lastLen = length - (startPos - tempPos);
-                        break;
-                    default:
-                        if (LOCAL_LOGV) {
-                            Log.v(LOG_TAG, "Not supported Part headers: " + header);
-                        }
-                    if (-1 == skipWapValue(pduDataStream, lastLen)) {
-                        Log.e(LOG_TAG, "Corrupt Part headers");
-                        return false;
-                    }
-                    lastLen = 0;
-                    break;
-                }
-            } else if ((header >= TEXT_MIN) && (header <= TEXT_MAX)) {
-                // Not assigned header.
-                byte[] tempHeader = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-                byte[] tempValue = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-
-                // Check the header whether it is "Content-Transfer-Encoding".
-                if (true ==
-                    PduPart.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(new String(tempHeader))) {
-                    part.setContentTransferEncoding(tempValue);
-                }
-
-                tempPos = pduDataStream.available();
-                lastLen = length - (startPos - tempPos);
-            } else {
-                if (LOCAL_LOGV) {
-                    Log.v(LOG_TAG, "Not supported Part headers: " + header);
-                }
-                // Skip all headers of this part.
-                if (-1 == skipWapValue(pduDataStream, lastLen)) {
-                    Log.e(LOG_TAG, "Corrupt Part headers");
-                    return false;
-                }
-                lastLen = 0;
-            }
-        }
-
-        if (0 != lastLen) {
-            Log.e(LOG_TAG, "Corrupt Part headers");
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check the position of a specified part.
-     *
-     * @param part the part to be checked
-     * @return part position, THE_FIRST_PART when it's the
-     * first one, THE_LAST_PART when it's the last one.
-     */
-    private static int checkPartPosition(PduPart part) {
-        assert(null != part);
-        if ((null == mTypeParam) &&
-                (null == mStartParam)) {
-            return THE_LAST_PART;
-        }
-
-        /* check part's content-id */
-        if (null != mStartParam) {
-            byte[] contentId = part.getContentId();
-            if (null != contentId) {
-                if (true == Arrays.equals(mStartParam, contentId)) {
-                    return THE_FIRST_PART;
-                }
-            }
-        }
-
-        /* check part's content-type */
-        if (null != mTypeParam) {
-            byte[] contentType = part.getContentType();
-            if (null != contentType) {
-                if (true == Arrays.equals(mTypeParam, contentType)) {
-                    return THE_FIRST_PART;
-                }
-            }
-        }
-
-        return THE_LAST_PART;
-    }
-
-    /**
-     * Check mandatory headers of a pdu.
-     *
-     * @param headers pdu headers
-     * @return true if the pdu has all of the mandatory headers, false otherwise.
-     */
-    protected static boolean checkMandatoryHeader(PduHeaders headers) {
-        if (null == headers) {
-            return false;
-        }
-
-        /* get message type */
-        int messageType = headers.getOctet(PduHeaders.MESSAGE_TYPE);
-
-        /* check Mms-Version field */
-        int mmsVersion = headers.getOctet(PduHeaders.MMS_VERSION);
-        if (0 == mmsVersion) {
-            // Every message should have Mms-Version field.
-            return false;
-        }
-
-        /* check mandatory header fields */
-        switch (messageType) {
-            case PduHeaders.MESSAGE_TYPE_SEND_REQ:
-                // Content-Type field.
-                byte[] srContentType = headers.getTextString(PduHeaders.CONTENT_TYPE);
-                if (null == srContentType) {
-                    return false;
-                }
-
-                // From field.
-                EncodedStringValue srFrom = headers.getEncodedStringValue(PduHeaders.FROM);
-                if (null == srFrom) {
-                    return false;
-                }
-
-                // Transaction-Id field.
-                byte[] srTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
-                if (null == srTransactionId) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_SEND_CONF:
-                // Response-Status field.
-                int scResponseStatus = headers.getOctet(PduHeaders.RESPONSE_STATUS);
-                if (0 == scResponseStatus) {
-                    return false;
-                }
-
-                // Transaction-Id field.
-                byte[] scTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
-                if (null == scTransactionId) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
-                // Content-Location field.
-                byte[] niContentLocation = headers.getTextString(PduHeaders.CONTENT_LOCATION);
-                if (null == niContentLocation) {
-                    return false;
-                }
-
-                // Expiry field.
-                long niExpiry = headers.getLongInteger(PduHeaders.EXPIRY);
-                if (-1 == niExpiry) {
-                    return false;
-                }
-
-                // Message-Class field.
-                byte[] niMessageClass = headers.getTextString(PduHeaders.MESSAGE_CLASS);
-                if (null == niMessageClass) {
-                    return false;
-                }
-
-                // Message-Size field.
-                long niMessageSize = headers.getLongInteger(PduHeaders.MESSAGE_SIZE);
-                if (-1 == niMessageSize) {
-                    return false;
-                }
-
-                // Transaction-Id field.
-                byte[] niTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
-                if (null == niTransactionId) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
-                // Status field.
-                int nriStatus = headers.getOctet(PduHeaders.STATUS);
-                if (0 == nriStatus) {
-                    return false;
-                }
-
-                // Transaction-Id field.
-                byte[] nriTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
-                if (null == nriTransactionId) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
-                // Content-Type field.
-                byte[] rcContentType = headers.getTextString(PduHeaders.CONTENT_TYPE);
-                if (null == rcContentType) {
-                    return false;
-                }
-
-                // Date field.
-                long rcDate = headers.getLongInteger(PduHeaders.DATE);
-                if (-1 == rcDate) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
-                // Date field.
-                long diDate = headers.getLongInteger(PduHeaders.DATE);
-                if (-1 == diDate) {
-                    return false;
-                }
-
-                // Message-Id field.
-                byte[] diMessageId = headers.getTextString(PduHeaders.MESSAGE_ID);
-                if (null == diMessageId) {
-                    return false;
-                }
-
-                // Status field.
-                int diStatus = headers.getOctet(PduHeaders.STATUS);
-                if (0 == diStatus) {
-                    return false;
-                }
-
-                // To field.
-                EncodedStringValue[] diTo = headers.getEncodedStringValues(PduHeaders.TO);
-                if (null == diTo) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
-                // Transaction-Id field.
-                byte[] aiTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
-                if (null == aiTransactionId) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND:
-                // Date field.
-                long roDate = headers.getLongInteger(PduHeaders.DATE);
-                if (-1 == roDate) {
-                    return false;
-                }
-
-                // From field.
-                EncodedStringValue roFrom = headers.getEncodedStringValue(PduHeaders.FROM);
-                if (null == roFrom) {
-                    return false;
-                }
-
-                // Message-Id field.
-                byte[] roMessageId = headers.getTextString(PduHeaders.MESSAGE_ID);
-                if (null == roMessageId) {
-                    return false;
-                }
-
-                // Read-Status field.
-                int roReadStatus = headers.getOctet(PduHeaders.READ_STATUS);
-                if (0 == roReadStatus) {
-                    return false;
-                }
-
-                // To field.
-                EncodedStringValue[] roTo = headers.getEncodedStringValues(PduHeaders.TO);
-                if (null == roTo) {
-                    return false;
-                }
-
-                break;
-            case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
-                // From field.
-                EncodedStringValue rrFrom = headers.getEncodedStringValue(PduHeaders.FROM);
-                if (null == rrFrom) {
-                    return false;
-                }
-
-                // Message-Id field.
-                byte[] rrMessageId = headers.getTextString(PduHeaders.MESSAGE_ID);
-                if (null == rrMessageId) {
-                    return false;
-                }
-
-                // Read-Status field.
-                int rrReadStatus = headers.getOctet(PduHeaders.READ_STATUS);
-                if (0 == rrReadStatus) {
-                    return false;
-                }
-
-                // To field.
-                EncodedStringValue[] rrTo = headers.getEncodedStringValues(PduHeaders.TO);
-                if (null == rrTo) {
-                    return false;
-                }
-
-                break;
-            default:
-                // Parser doesn't support this message type in this version.
-                return false;
-        }
-
-        return true;
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/PduPart.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduPart.java
deleted file mode 100644
index 7d51b86..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/PduPart.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 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 com.android.mmscommon.mms.pdu;
-
-import android.net.Uri;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The pdu part.
- */
-public class PduPart {
-    /**
-     * Well-Known Parameters.
-     */
-    public static final int P_Q                  = 0x80;
-    public static final int P_CHARSET            = 0x81;
-    public static final int P_LEVEL              = 0x82;
-    public static final int P_TYPE               = 0x83;
-    public static final int P_DEP_NAME           = 0x85;
-    public static final int P_DEP_FILENAME       = 0x86;
-    public static final int P_DIFFERENCES        = 0x87;
-    public static final int P_PADDING            = 0x88;
-    // This value of "TYPE" s used with Content-Type: multipart/related
-    public static final int P_CT_MR_TYPE         = 0x89;
-    public static final int P_DEP_START          = 0x8A;
-    public static final int P_DEP_START_INFO     = 0x8B;
-    public static final int P_DEP_COMMENT        = 0x8C;
-    public static final int P_DEP_DOMAIN         = 0x8D;
-    public static final int P_MAX_AGE            = 0x8E;
-    public static final int P_DEP_PATH           = 0x8F;
-    public static final int P_SECURE             = 0x90;
-    public static final int P_SEC                = 0x91;
-    public static final int P_MAC                = 0x92;
-    public static final int P_CREATION_DATE      = 0x93;
-    public static final int P_MODIFICATION_DATE  = 0x94;
-    public static final int P_READ_DATE          = 0x95;
-    public static final int P_SIZE               = 0x96;
-    public static final int P_NAME               = 0x97;
-    public static final int P_FILENAME           = 0x98;
-    public static final int P_START              = 0x99;
-    public static final int P_START_INFO         = 0x9A;
-    public static final int P_COMMENT            = 0x9B;
-    public static final int P_DOMAIN             = 0x9C;
-    public static final int P_PATH               = 0x9D;
-
-    /**
-     *  Header field names.
-     */
-     public static final int P_CONTENT_TYPE       = 0x91;
-     public static final int P_CONTENT_LOCATION   = 0x8E;
-     public static final int P_CONTENT_ID         = 0xC0;
-     public static final int P_DEP_CONTENT_DISPOSITION = 0xAE;
-     public static final int P_CONTENT_DISPOSITION = 0xC5;
-    // The next header is unassigned header, use reserved header(0x48) value.
-     public static final int P_CONTENT_TRANSFER_ENCODING = 0xC8;
-
-     /**
-      * Content=Transfer-Encoding string.
-      */
-     public static final String CONTENT_TRANSFER_ENCODING =
-             "Content-Transfer-Encoding";
-
-     /**
-      * Value of Content-Transfer-Encoding.
-      */
-     public static final String P_BINARY = "binary";
-     public static final String P_7BIT = "7bit";
-     public static final String P_8BIT = "8bit";
-     public static final String P_BASE64 = "base64";
-     public static final String P_QUOTED_PRINTABLE = "quoted-printable";
-
-     /**
-      * Value of disposition can be set to PduPart when the value is octet in
-      * the PDU.
-      * "from-data" instead of Form-data<Octet 128>.
-      * "attachment" instead of Attachment<Octet 129>.
-      * "inline" instead of Inline<Octet 130>.
-      */
-     static final byte[] DISPOSITION_FROM_DATA = "from-data".getBytes();
-     static final byte[] DISPOSITION_ATTACHMENT = "attachment".getBytes();
-     static final byte[] DISPOSITION_INLINE = "inline".getBytes();
-
-     /**
-      * Content-Disposition value.
-      */
-     public static final int P_DISPOSITION_FROM_DATA  = 0x80;
-     public static final int P_DISPOSITION_ATTACHMENT = 0x81;
-     public static final int P_DISPOSITION_INLINE     = 0x82;
-
-     /**
-      * Header of part.
-      */
-     private Map<Integer, Object> mPartHeader = null;
-
-     /**
-      * Data uri.
-      */
-     private Uri mUri = null;
-
-     /**
-      * Part data.
-      */
-     private byte[] mPartData = null;
-
-     private static final String TAG = "PduPart";
-
-     /**
-      * Empty Constructor.
-      */
-     public PduPart() {
-         mPartHeader = new HashMap<Integer, Object>();
-     }
-
-     /**
-      * Set part data. The data are stored as byte array.
-      *
-      * @param data the data
-      */
-     public void setData(byte[] data) {
-         if(data == null) {
-            return;
-        }
-
-         mPartData = new byte[data.length];
-         System.arraycopy(data, 0, mPartData, 0, data.length);
-     }
-
-     /**
-      * @return A copy of the part data or null if the data wasn't set or
-      *         the data is stored as Uri.
-      * @see #getDataUri
-      */
-     public byte[] getData() {
-         if(mPartData == null) {
-            return null;
-         }
-
-         byte[] byteArray = new byte[mPartData.length];
-         System.arraycopy(mPartData, 0, byteArray, 0, mPartData.length);
-         return byteArray;
-     }
-
-     /**
-      * Set data uri. The data are stored as Uri.
-      *
-      * @param uri the uri
-      */
-     public void setDataUri(Uri uri) {
-         mUri = uri;
-     }
-
-     /**
-      * @return The Uri of the part data or null if the data wasn't set or
-      *         the data is stored as byte array.
-      * @see #getData
-      */
-     public Uri getDataUri() {
-         return mUri;
-     }
-
-     /**
-      * Set Content-id value
-      *
-      * @param contentId the content-id value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setContentId(byte[] contentId) {
-         if((contentId == null) || (contentId.length == 0)) {
-             throw new IllegalArgumentException(
-                     "Content-Id may not be null or empty.");
-         }
-
-         if ((contentId.length > 1)
-                 && ((char) contentId[0] == '<')
-                 && ((char) contentId[contentId.length - 1] == '>')) {
-             mPartHeader.put(P_CONTENT_ID, contentId);
-             return;
-         }
-
-         // Insert beginning '<' and trailing '>' for Content-Id.
-         byte[] buffer = new byte[contentId.length + 2];
-         buffer[0] = (byte) (0xff & '<');
-         buffer[buffer.length - 1] = (byte) (0xff & '>');
-         System.arraycopy(contentId, 0, buffer, 1, contentId.length);
-         mPartHeader.put(P_CONTENT_ID, buffer);
-     }
-
-     /**
-      * Get Content-id value.
-      *
-      * @return the value
-      */
-     public byte[] getContentId() {
-         return (byte[]) mPartHeader.get(P_CONTENT_ID);
-     }
-
-     /**
-      * Set Char-set value.
-      *
-      * @param charset the value
-      */
-     public void setCharset(int charset) {
-         mPartHeader.put(P_CHARSET, charset);
-     }
-
-     /**
-      * Get Char-set value
-      *
-      * @return the charset value. Return 0 if charset was not set.
-      */
-     public int getCharset() {
-         Integer charset = (Integer) mPartHeader.get(P_CHARSET);
-         if(charset == null) {
-             return 0;
-         } else {
-             return charset.intValue();
-         }
-     }
-
-     /**
-      * Set Content-Location value.
-      *
-      * @param contentLocation the value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setContentLocation(byte[] contentLocation) {
-         if(contentLocation == null) {
-             throw new NullPointerException("null content-location");
-         }
-
-         mPartHeader.put(P_CONTENT_LOCATION, contentLocation);
-     }
-
-     /**
-      * Get Content-Location value.
-      *
-      * @return the value
-      *     return PduPart.disposition[0] instead of <Octet 128> (Form-data).
-      *     return PduPart.disposition[1] instead of <Octet 129> (Attachment).
-      *     return PduPart.disposition[2] instead of <Octet 130> (Inline).
-      */
-     public byte[] getContentLocation() {
-         return (byte[]) mPartHeader.get(P_CONTENT_LOCATION);
-     }
-
-     /**
-      * Set Content-Disposition value.
-      * Use PduPart.disposition[0] instead of <Octet 128> (Form-data).
-      * Use PduPart.disposition[1] instead of <Octet 129> (Attachment).
-      * Use PduPart.disposition[2] instead of <Octet 130> (Inline).
-      *
-      * @param contentDisposition the value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setContentDisposition(byte[] contentDisposition) {
-         if(contentDisposition == null) {
-             throw new NullPointerException("null content-disposition");
-         }
-
-         mPartHeader.put(P_CONTENT_DISPOSITION, contentDisposition);
-     }
-
-     /**
-      * Get Content-Disposition value.
-      *
-      * @return the value
-      */
-     public byte[] getContentDisposition() {
-         return (byte[]) mPartHeader.get(P_CONTENT_DISPOSITION);
-     }
-
-     /**
-      *  Set Content-Type value.
-      *
-      *  @param value the value
-      *  @throws NullPointerException if the value is null.
-      */
-     public void setContentType(byte[] contentType) {
-         if(contentType == null) {
-             throw new NullPointerException("null content-type");
-         }
-
-         mPartHeader.put(P_CONTENT_TYPE, contentType);
-     }
-
-     /**
-      * Get Content-Type value of part.
-      *
-      * @return the value
-      */
-     public byte[] getContentType() {
-         return (byte[]) mPartHeader.get(P_CONTENT_TYPE);
-     }
-
-     /**
-      * Set Content-Transfer-Encoding value
-      *
-      * @param contentId the content-id value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setContentTransferEncoding(byte[] contentTransferEncoding) {
-         if(contentTransferEncoding == null) {
-             throw new NullPointerException("null content-transfer-encoding");
-         }
-
-         mPartHeader.put(P_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
-     }
-
-     /**
-      * Get Content-Transfer-Encoding value.
-      *
-      * @return the value
-      */
-     public byte[] getContentTransferEncoding() {
-         return (byte[]) mPartHeader.get(P_CONTENT_TRANSFER_ENCODING);
-     }
-
-     /**
-      * Set Content-type parameter: name.
-      *
-      * @param name the name value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setName(byte[] name) {
-         if(null == name) {
-             throw new NullPointerException("null content-id");
-         }
-
-         mPartHeader.put(P_NAME, name);
-     }
-
-     /**
-      *  Get content-type parameter: name.
-      *
-      *  @return the name
-      */
-     public byte[] getName() {
-         return (byte[]) mPartHeader.get(P_NAME);
-     }
-
-     /**
-      * Get Content-disposition parameter: filename
-      *
-      * @param fileName the filename value
-      * @throws NullPointerException if the value is null.
-      */
-     public void setFilename(byte[] fileName) {
-         if(null == fileName) {
-             throw new NullPointerException("null content-id");
-         }
-
-         mPartHeader.put(P_FILENAME, fileName);
-     }
-
-     /**
-      * Set Content-disposition parameter: filename
-      *
-      * @return the filename
-      */
-     public byte[] getFilename() {
-         return (byte[]) mPartHeader.get(P_FILENAME);
-     }
-
-    public String generateLocation() {
-        // Assumption: At least one of the content-location / name / filename
-        // or content-id should be set. This is guaranteed by the PduParser
-        // for incoming messages and by MM composer for outgoing messages.
-        byte[] location = (byte[]) mPartHeader.get(P_NAME);
-        if(null == location) {
-            location = (byte[]) mPartHeader.get(P_FILENAME);
-
-            if (null == location) {
-                location = (byte[]) mPartHeader.get(P_CONTENT_LOCATION);
-            }
-        }
-
-        if (null == location) {
-            byte[] contentId = (byte[]) mPartHeader.get(P_CONTENT_ID);
-            return "cid:" + new String(contentId);
-        } else {
-            return new String(location);
-        }
-    }
-}
-
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/PduPersister.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduPersister.java
deleted file mode 100644
index d92f0e1..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/PduPersister.java
+++ /dev/null
@@ -1,1270 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 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 com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.mms.pdu.PduPersister;
-
-import com.android.mmscommon.ContentType;
-import com.android.mmscommon.CharacterSets;
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.MmsException;
-import com.android.mmscommon.PduHeaders;
-import com.android.mmscommon.mms.util.PduCache;
-import com.android.mmscommon.mms.util.PduCacheEntry;
-import android.database.sqlite.SqliteWrapper;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.net.Uri;
-import com.android.mmscommon.telephony.TelephonyProvider;
-import com.android.mmscommon.telephony.TelephonyProvider.Mms;
-import com.android.mmscommon.telephony.TelephonyProvider.MmsSms;
-import com.android.mmscommon.telephony.TelephonyProvider.Threads;
-import com.android.mmscommon.telephony.TelephonyProvider.Mms.Addr;
-import com.android.mmscommon.telephony.TelephonyProvider.Mms.Part;
-import com.android.mmscommon.telephony.TelephonyProvider.MmsSms.PendingMessages;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-
-/**
- * This class is the high-level manager of PDU storage.
- */
-public class PduPersister {
-    private static final String TAG = "PduPersister";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
-
-    private static final long DUMMY_THREAD_ID = Long.MAX_VALUE;
-
-    /**
-     * The uri of temporary drm objects.
-     */
-    public static final String TEMPORARY_DRM_OBJECT_URI =
-        "content://mms/" + Long.MAX_VALUE + "/part";
-    /**
-     * Indicate that we transiently failed to process a MM.
-     */
-    public static final int PROC_STATUS_TRANSIENT_FAILURE   = 1;
-    /**
-     * Indicate that we permanently failed to process a MM.
-     */
-    public static final int PROC_STATUS_PERMANENTLY_FAILURE = 2;
-    /**
-     * Indicate that we have successfully processed a MM.
-     */
-    public static final int PROC_STATUS_COMPLETED           = 3;
-
-    private static PduPersister sPersister;
-    private static final PduCache PDU_CACHE_INSTANCE;
-
-    private static final int[] ADDRESS_FIELDS = new int[] {
-            PduHeaders.BCC,
-            PduHeaders.CC,
-            PduHeaders.FROM,
-            PduHeaders.TO
-    };
-
-    private static final String[] PDU_PROJECTION = new String[] {
-        Mms._ID,
-        Mms.MESSAGE_BOX,
-        Mms.THREAD_ID,
-        Mms.RETRIEVE_TEXT,
-        Mms.SUBJECT,
-        Mms.CONTENT_LOCATION,
-        Mms.CONTENT_TYPE,
-        Mms.MESSAGE_CLASS,
-        Mms.MESSAGE_ID,
-        Mms.RESPONSE_TEXT,
-        Mms.TRANSACTION_ID,
-        Mms.CONTENT_CLASS,
-        Mms.DELIVERY_REPORT,
-        Mms.MESSAGE_TYPE,
-        Mms.MMS_VERSION,
-        Mms.PRIORITY,
-        Mms.READ_REPORT,
-        Mms.READ_STATUS,
-        Mms.REPORT_ALLOWED,
-        Mms.RETRIEVE_STATUS,
-        Mms.STATUS,
-        Mms.DATE,
-        Mms.DELIVERY_TIME,
-        Mms.EXPIRY,
-        Mms.MESSAGE_SIZE,
-        Mms.SUBJECT_CHARSET,
-        Mms.RETRIEVE_TEXT_CHARSET,
-    };
-
-    private static final int PDU_COLUMN_ID                    = 0;
-    private static final int PDU_COLUMN_MESSAGE_BOX           = 1;
-    private static final int PDU_COLUMN_THREAD_ID             = 2;
-    private static final int PDU_COLUMN_RETRIEVE_TEXT         = 3;
-    private static final int PDU_COLUMN_SUBJECT               = 4;
-    private static final int PDU_COLUMN_CONTENT_LOCATION      = 5;
-    private static final int PDU_COLUMN_CONTENT_TYPE          = 6;
-    private static final int PDU_COLUMN_MESSAGE_CLASS         = 7;
-    private static final int PDU_COLUMN_MESSAGE_ID            = 8;
-    private static final int PDU_COLUMN_RESPONSE_TEXT         = 9;
-    private static final int PDU_COLUMN_TRANSACTION_ID        = 10;
-    private static final int PDU_COLUMN_CONTENT_CLASS         = 11;
-    private static final int PDU_COLUMN_DELIVERY_REPORT       = 12;
-    private static final int PDU_COLUMN_MESSAGE_TYPE          = 13;
-    private static final int PDU_COLUMN_MMS_VERSION           = 14;
-    private static final int PDU_COLUMN_PRIORITY              = 15;
-    private static final int PDU_COLUMN_READ_REPORT           = 16;
-    private static final int PDU_COLUMN_READ_STATUS           = 17;
-    private static final int PDU_COLUMN_REPORT_ALLOWED        = 18;
-    private static final int PDU_COLUMN_RETRIEVE_STATUS       = 19;
-    private static final int PDU_COLUMN_STATUS                = 20;
-    private static final int PDU_COLUMN_DATE                  = 21;
-    private static final int PDU_COLUMN_DELIVERY_TIME         = 22;
-    private static final int PDU_COLUMN_EXPIRY                = 23;
-    private static final int PDU_COLUMN_MESSAGE_SIZE          = 24;
-    private static final int PDU_COLUMN_SUBJECT_CHARSET       = 25;
-    private static final int PDU_COLUMN_RETRIEVE_TEXT_CHARSET = 26;
-
-    private static final String[] PART_PROJECTION = new String[] {
-        Part._ID,
-        Part.CHARSET,
-        Part.CONTENT_DISPOSITION,
-        Part.CONTENT_ID,
-        Part.CONTENT_LOCATION,
-        Part.CONTENT_TYPE,
-        Part.FILENAME,
-        Part.NAME,
-        Part.TEXT
-    };
-
-    private static final int PART_COLUMN_ID                  = 0;
-    private static final int PART_COLUMN_CHARSET             = 1;
-    private static final int PART_COLUMN_CONTENT_DISPOSITION = 2;
-    private static final int PART_COLUMN_CONTENT_ID          = 3;
-    private static final int PART_COLUMN_CONTENT_LOCATION    = 4;
-    private static final int PART_COLUMN_CONTENT_TYPE        = 5;
-    private static final int PART_COLUMN_FILENAME            = 6;
-    private static final int PART_COLUMN_NAME                = 7;
-    private static final int PART_COLUMN_TEXT                = 8;
-
-    private static final HashMap<Uri, Integer> MESSAGE_BOX_MAP;
-    // These map are used for convenience in persist() and load().
-    private static final HashMap<Integer, Integer> CHARSET_COLUMN_INDEX_MAP;
-    private static final HashMap<Integer, Integer> ENCODED_STRING_COLUMN_INDEX_MAP;
-    private static final HashMap<Integer, Integer> TEXT_STRING_COLUMN_INDEX_MAP;
-    private static final HashMap<Integer, Integer> OCTET_COLUMN_INDEX_MAP;
-    private static final HashMap<Integer, Integer> LONG_COLUMN_INDEX_MAP;
-    private static final HashMap<Integer, String> CHARSET_COLUMN_NAME_MAP;
-    private static final HashMap<Integer, String> ENCODED_STRING_COLUMN_NAME_MAP;
-    private static final HashMap<Integer, String> TEXT_STRING_COLUMN_NAME_MAP;
-    private static final HashMap<Integer, String> OCTET_COLUMN_NAME_MAP;
-    private static final HashMap<Integer, String> LONG_COLUMN_NAME_MAP;
-
-    static {
-        MESSAGE_BOX_MAP = new HashMap<Uri, Integer>();
-        MESSAGE_BOX_MAP.put(Mms.Inbox.CONTENT_URI,  Mms.MESSAGE_BOX_INBOX);
-        MESSAGE_BOX_MAP.put(Mms.Sent.CONTENT_URI,   Mms.MESSAGE_BOX_SENT);
-        MESSAGE_BOX_MAP.put(Mms.Draft.CONTENT_URI,  Mms.MESSAGE_BOX_DRAFTS);
-        MESSAGE_BOX_MAP.put(Mms.Outbox.CONTENT_URI, Mms.MESSAGE_BOX_OUTBOX);
-
-        CHARSET_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
-        CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT_CHARSET);
-        CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT_CHARSET);
-
-        CHARSET_COLUMN_NAME_MAP = new HashMap<Integer, String>();
-        CHARSET_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT_CHARSET);
-        CHARSET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT_CHARSET);
-
-        // Encoded string field code -> column index/name map.
-        ENCODED_STRING_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
-        ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT);
-        ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT);
-
-        ENCODED_STRING_COLUMN_NAME_MAP = new HashMap<Integer, String>();
-        ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT);
-        ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT);
-
-        // Text string field code -> column index/name map.
-        TEXT_STRING_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_LOCATION, PDU_COLUMN_CONTENT_LOCATION);
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_TYPE, PDU_COLUMN_CONTENT_TYPE);
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_CLASS, PDU_COLUMN_MESSAGE_CLASS);
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_ID, PDU_COLUMN_MESSAGE_ID);
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RESPONSE_TEXT, PDU_COLUMN_RESPONSE_TEXT);
-        TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.TRANSACTION_ID, PDU_COLUMN_TRANSACTION_ID);
-
-        TEXT_STRING_COLUMN_NAME_MAP = new HashMap<Integer, String>();
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_LOCATION, Mms.CONTENT_LOCATION);
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_TYPE, Mms.CONTENT_TYPE);
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_CLASS, Mms.MESSAGE_CLASS);
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_ID, Mms.MESSAGE_ID);
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.RESPONSE_TEXT, Mms.RESPONSE_TEXT);
-        TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.TRANSACTION_ID, Mms.TRANSACTION_ID);
-
-        // Octet field code -> column index/name map.
-        OCTET_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_CLASS, PDU_COLUMN_CONTENT_CLASS);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_REPORT, PDU_COLUMN_DELIVERY_REPORT);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_TYPE, PDU_COLUMN_MESSAGE_TYPE);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MMS_VERSION, PDU_COLUMN_MMS_VERSION);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.PRIORITY, PDU_COLUMN_PRIORITY);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_REPORT, PDU_COLUMN_READ_REPORT);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_STATUS, PDU_COLUMN_READ_STATUS);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.REPORT_ALLOWED, PDU_COLUMN_REPORT_ALLOWED);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_STATUS, PDU_COLUMN_RETRIEVE_STATUS);
-        OCTET_COLUMN_INDEX_MAP.put(PduHeaders.STATUS, PDU_COLUMN_STATUS);
-
-        OCTET_COLUMN_NAME_MAP = new HashMap<Integer, String>();
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_CLASS, Mms.CONTENT_CLASS);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_REPORT, Mms.DELIVERY_REPORT);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_TYPE, Mms.MESSAGE_TYPE);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.MMS_VERSION, Mms.MMS_VERSION);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.PRIORITY, Mms.PRIORITY);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_REPORT, Mms.READ_REPORT);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_STATUS, Mms.READ_STATUS);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.REPORT_ALLOWED, Mms.REPORT_ALLOWED);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_STATUS, Mms.RETRIEVE_STATUS);
-        OCTET_COLUMN_NAME_MAP.put(PduHeaders.STATUS, Mms.STATUS);
-
-        // Long field code -> column index/name map.
-        LONG_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
-        LONG_COLUMN_INDEX_MAP.put(PduHeaders.DATE, PDU_COLUMN_DATE);
-        LONG_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_TIME, PDU_COLUMN_DELIVERY_TIME);
-        LONG_COLUMN_INDEX_MAP.put(PduHeaders.EXPIRY, PDU_COLUMN_EXPIRY);
-        LONG_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_SIZE, PDU_COLUMN_MESSAGE_SIZE);
-
-        LONG_COLUMN_NAME_MAP = new HashMap<Integer, String>();
-        LONG_COLUMN_NAME_MAP.put(PduHeaders.DATE, Mms.DATE);
-        LONG_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_TIME, Mms.DELIVERY_TIME);
-        LONG_COLUMN_NAME_MAP.put(PduHeaders.EXPIRY, Mms.EXPIRY);
-        LONG_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_SIZE, Mms.MESSAGE_SIZE);
-
-        PDU_CACHE_INSTANCE = PduCache.getInstance();
-     }
-
-    private final Context mContext;
-    private final ContentResolver mContentResolver;
-
-    private PduPersister(Context context) {
-        mContext = context;
-        mContentResolver = context.getContentResolver();
-     }
-
-    /** Get(or create if not exist) an instance of PduPersister */
-    public static PduPersister getPduPersister(Context context) {
-        if ((sPersister == null) || !context.equals(sPersister.mContext)) {
-            sPersister = new PduPersister(context);
-        }
-
-        return sPersister;
-    }
-
-    private void setEncodedStringValueToHeaders(
-            Cursor c, int columnIndex,
-            PduHeaders headers, int mapColumn) {
-        String s = c.getString(columnIndex);
-        if ((s != null) && (s.length() > 0)) {
-            int charsetColumnIndex = CHARSET_COLUMN_INDEX_MAP.get(mapColumn);
-            int charset = c.getInt(charsetColumnIndex);
-            EncodedStringValue value = new EncodedStringValue(
-                    charset, getBytes(s));
-            headers.setEncodedStringValue(value, mapColumn);
-        }
-    }
-
-    private void setTextStringToHeaders(
-            Cursor c, int columnIndex,
-            PduHeaders headers, int mapColumn) {
-        String s = c.getString(columnIndex);
-        if (s != null) {
-            headers.setTextString(getBytes(s), mapColumn);
-        }
-    }
-
-    private void setOctetToHeaders(
-            Cursor c, int columnIndex,
-            PduHeaders headers, int mapColumn) throws InvalidHeaderValueException {
-        if (!c.isNull(columnIndex)) {
-            int b = c.getInt(columnIndex);
-            headers.setOctet(b, mapColumn);
-        }
-    }
-
-    private void setLongToHeaders(
-            Cursor c, int columnIndex,
-            PduHeaders headers, int mapColumn) {
-        if (!c.isNull(columnIndex)) {
-            long l = c.getLong(columnIndex);
-            headers.setLongInteger(l, mapColumn);
-        }
-    }
-
-    private Integer getIntegerFromPartColumn(Cursor c, int columnIndex) {
-        if (!c.isNull(columnIndex)) {
-            return c.getInt(columnIndex);
-        }
-        return null;
-    }
-
-    private byte[] getByteArrayFromPartColumn(Cursor c, int columnIndex) {
-        if (!c.isNull(columnIndex)) {
-            return getBytes(c.getString(columnIndex));
-        }
-        return null;
-    }
-
-    private PduPart[] loadParts(long msgId) throws MmsException {
-        Cursor c = SqliteWrapper.query(mContext, mContentResolver,
-                Uri.parse("content://mms/" + msgId + "/part"),
-                PART_PROJECTION, null, null, null);
-
-        PduPart[] parts = null;
-
-        try {
-            if ((c == null) || (c.getCount() == 0)) {
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, "loadParts(" + msgId + "): no part to load.");
-                }
-                return null;
-            }
-
-            int partCount = c.getCount();
-            int partIdx = 0;
-            parts = new PduPart[partCount];
-            while (c.moveToNext()) {
-                PduPart part = new PduPart();
-                Integer charset = getIntegerFromPartColumn(
-                        c, PART_COLUMN_CHARSET);
-                if (charset != null) {
-                    part.setCharset(charset);
-                }
-
-                byte[] contentDisposition = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_CONTENT_DISPOSITION);
-                if (contentDisposition != null) {
-                    part.setContentDisposition(contentDisposition);
-                }
-
-                byte[] contentId = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_CONTENT_ID);
-                if (contentId != null) {
-                    part.setContentId(contentId);
-                }
-
-                byte[] contentLocation = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_CONTENT_LOCATION);
-                if (contentLocation != null) {
-                    part.setContentLocation(contentLocation);
-                }
-
-                byte[] contentType = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_CONTENT_TYPE);
-                if (contentType != null) {
-                    part.setContentType(contentType);
-                } else {
-                    throw new MmsException("Content-Type must be set.");
-                }
-
-                byte[] fileName = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_FILENAME);
-                if (fileName != null) {
-                    part.setFilename(fileName);
-                }
-
-                byte[] name = getByteArrayFromPartColumn(
-                        c, PART_COLUMN_NAME);
-                if (name != null) {
-                    part.setName(name);
-                }
-
-                // Construct a Uri for this part.
-                long partId = c.getLong(PART_COLUMN_ID);
-                Uri partURI = Uri.parse("content://mms/part/" + partId);
-                part.setDataUri(partURI);
-
-                // For images/audio/video, we won't keep their data in Part
-                // because their renderer accept Uri as source.
-                String type = toIsoString(contentType);
-                if (!ContentType.isImageType(type)
-                        && !ContentType.isAudioType(type)
-                        && !ContentType.isVideoType(type)) {
-                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    InputStream is = null;
-
-                    // Store simple string values directly in the database instead of an
-                    // external file.  This makes the text searchable and retrieval slightly
-                    // faster.
-                    if (ContentType.TEXT_PLAIN.equals(type) || ContentType.APP_SMIL.equals(type)
-                            || ContentType.TEXT_HTML.equals(type)) {
-                        String text = c.getString(PART_COLUMN_TEXT);
-                        if (text == null) {
-                            text = "";
-                        }
-                        byte [] blob = new EncodedStringValue(text).getTextString();
-                        baos.write(blob, 0, blob.length);
-                    } else {
-
-                        try {
-                            is = mContentResolver.openInputStream(partURI);
-
-                            byte[] buffer = new byte[256];
-                            int len = is.read(buffer);
-                            while (len >= 0) {
-                                baos.write(buffer, 0, len);
-                                len = is.read(buffer);
-                            }
-                        } catch (IOException e) {
-                            Log.e(TAG, "Failed to load part data", e);
-                            c.close();
-                            throw new MmsException(e);
-                        } finally {
-                            if (is != null) {
-                                try {
-                                    is.close();
-                                } catch (IOException e) {
-                                    Log.e(TAG, "Failed to close stream", e);
-                                } // Ignore
-                            }
-                        }
-                    }
-                    part.setData(baos.toByteArray());
-                }
-                parts[partIdx++] = part;
-            }
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
-
-        return parts;
-    }
-
-    private void loadAddress(long msgId, PduHeaders headers) {
-        Cursor c = SqliteWrapper.query(mContext, mContentResolver,
-                Uri.parse("content://mms/" + msgId + "/addr"),
-                new String[] { Addr.ADDRESS, Addr.CHARSET, Addr.TYPE },
-                null, null, null);
-
-        if (c != null) {
-            try {
-                while (c.moveToNext()) {
-                    String addr = c.getString(0);
-                    if (!TextUtils.isEmpty(addr)) {
-                        int addrType = c.getInt(2);
-                        switch (addrType) {
-                            case PduHeaders.FROM:
-                                headers.setEncodedStringValue(
-                                        new EncodedStringValue(c.getInt(1), getBytes(addr)),
-                                        addrType);
-                                break;
-                            case PduHeaders.TO:
-                            case PduHeaders.CC:
-                            case PduHeaders.BCC:
-                                headers.appendEncodedStringValue(
-                                        new EncodedStringValue(c.getInt(1), getBytes(addr)),
-                                        addrType);
-                                break;
-                            default:
-                                Log.e(TAG, "Unknown address type: " + addrType);
-                                break;
-                        }
-                    }
-                }
-            } finally {
-                c.close();
-            }
-        }
-    }
-
-    /**
-     * Load a PDU from storage by given Uri.
-     *
-     * @param uri The Uri of the PDU to be loaded.
-     * @return A generic PDU object, it may be cast to dedicated PDU.
-     * @throws MmsException Failed to load some fields of a PDU.
-     */
-    public GenericPdu load(Uri uri) throws MmsException {
-        PduCacheEntry cacheEntry = PDU_CACHE_INSTANCE.get(uri);
-        if (cacheEntry != null) {
-            return cacheEntry.getPdu();
-        }
-
-        Cursor c = SqliteWrapper.query(mContext, mContentResolver, uri,
-                        PDU_PROJECTION, null, null, null);
-        PduHeaders headers = new PduHeaders();
-        Set<Entry<Integer, Integer>> set;
-        long msgId = ContentUris.parseId(uri);
-        int msgBox;
-        long threadId;
-
-        try {
-            if ((c == null) || (c.getCount() != 1) || !c.moveToFirst()) {
-                throw new MmsException("Bad uri: " + uri);
-            }
-
-            msgBox = c.getInt(PDU_COLUMN_MESSAGE_BOX);
-            threadId = c.getLong(PDU_COLUMN_THREAD_ID);
-
-            set = ENCODED_STRING_COLUMN_INDEX_MAP.entrySet();
-            for (Entry<Integer, Integer> e : set) {
-                setEncodedStringValueToHeaders(
-                        c, e.getValue(), headers, e.getKey());
-            }
-
-            set = TEXT_STRING_COLUMN_INDEX_MAP.entrySet();
-            for (Entry<Integer, Integer> e : set) {
-                setTextStringToHeaders(
-                        c, e.getValue(), headers, e.getKey());
-            }
-
-            set = OCTET_COLUMN_INDEX_MAP.entrySet();
-            for (Entry<Integer, Integer> e : set) {
-                setOctetToHeaders(
-                        c, e.getValue(), headers, e.getKey());
-            }
-
-            set = LONG_COLUMN_INDEX_MAP.entrySet();
-            for (Entry<Integer, Integer> e : set) {
-                setLongToHeaders(
-                        c, e.getValue(), headers, e.getKey());
-            }
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
-
-        // Check whether 'msgId' has been assigned a valid value.
-        if (msgId == -1L) {
-            throw new MmsException("Error! ID of the message: -1.");
-        }
-
-        // Load address information of the MM.
-        loadAddress(msgId, headers);
-
-        int msgType = headers.getOctet(PduHeaders.MESSAGE_TYPE);
-        PduBody body = new PduBody();
-
-        // For PDU which type is M_retrieve.conf or Send.req, we should
-        // load multiparts and put them into the body of the PDU.
-        if ((msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)
-                || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) {
-            PduPart[] parts = loadParts(msgId);
-            if (parts != null) {
-                int partsNum = parts.length;
-                for (int i = 0; i < partsNum; i++) {
-                    body.addPart(parts[i]);
-                }
-            }
-        }
-
-        GenericPdu pdu = null;
-        switch (msgType) {
-            case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
-                pdu = new NotificationInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
-                pdu = new DeliveryInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND:
-                pdu = new ReadOrigInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
-                pdu = new RetrieveConf(headers, body);
-                break;
-            case PduHeaders.MESSAGE_TYPE_SEND_REQ:
-                pdu = new SendReq(headers, body);
-                break;
-            case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
-                pdu = new AcknowledgeInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
-                pdu = new NotifyRespInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
-                pdu = new ReadRecInd(headers);
-                break;
-            case PduHeaders.MESSAGE_TYPE_SEND_CONF:
-            case PduHeaders.MESSAGE_TYPE_FORWARD_REQ:
-            case PduHeaders.MESSAGE_TYPE_FORWARD_CONF:
-            case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ:
-            case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF:
-            case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ:
-            case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF:
-            case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ:
-            case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF:
-            case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ:
-            case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF:
-            case PduHeaders.MESSAGE_TYPE_MBOX_DESCR:
-            case PduHeaders.MESSAGE_TYPE_DELETE_REQ:
-            case PduHeaders.MESSAGE_TYPE_DELETE_CONF:
-            case PduHeaders.MESSAGE_TYPE_CANCEL_REQ:
-            case PduHeaders.MESSAGE_TYPE_CANCEL_CONF:
-                throw new MmsException(
-                        "Unsupported PDU type: " + Integer.toHexString(msgType));
-
-            default:
-                throw new MmsException(
-                        "Unrecognized PDU type: " + Integer.toHexString(msgType));
-        }
-
-        cacheEntry = new PduCacheEntry(pdu, msgBox, threadId);
-        PDU_CACHE_INSTANCE.put(uri, cacheEntry);
-        return pdu;
-    }
-
-    private void persistAddress(
-            long msgId, int type, EncodedStringValue[] array) {
-        ContentValues values = new ContentValues(3);
-
-        for (EncodedStringValue addr : array) {
-            values.clear(); // Clear all values first.
-            values.put(Addr.ADDRESS, toIsoString(addr.getTextString()));
-            values.put(Addr.CHARSET, addr.getCharacterSet());
-            values.put(Addr.TYPE, type);
-
-            Uri uri = Uri.parse("content://mms/" + msgId + "/addr");
-            SqliteWrapper.insert(mContext, mContentResolver, uri, values);
-        }
-    }
-
-    public Uri persistPart(PduPart part, long msgId)
-            throws MmsException {
-        Uri uri = Uri.parse("content://mms/" + msgId + "/part");
-        ContentValues values = new ContentValues(8);
-
-        int charset = part.getCharset();
-        if (charset != 0 ) {
-            values.put(Part.CHARSET, charset);
-        }
-
-        String contentType = null;
-        if (part.getContentType() != null) {
-            contentType = toIsoString(part.getContentType());
-            values.put(Part.CONTENT_TYPE, contentType);
-            // To ensure the SMIL part is always the first part.
-            if (ContentType.APP_SMIL.equals(contentType)) {
-                values.put(Part.SEQ, -1);
-            }
-        } else {
-            throw new MmsException("MIME type of the part must be set.");
-        }
-
-        if (part.getFilename() != null) {
-            String fileName = new String(part.getFilename());
-            values.put(Part.FILENAME, fileName);
-        }
-
-        if (part.getName() != null) {
-            String name = new String(part.getName());
-            values.put(Part.NAME, name);
-        }
-
-        Object value = null;
-        if (part.getContentDisposition() != null) {
-            value = toIsoString(part.getContentDisposition());
-            values.put(Part.CONTENT_DISPOSITION, (String) value);
-        }
-
-        if (part.getContentId() != null) {
-            value = toIsoString(part.getContentId());
-            values.put(Part.CONTENT_ID, (String) value);
-        }
-
-        if (part.getContentLocation() != null) {
-            value = toIsoString(part.getContentLocation());
-            values.put(Part.CONTENT_LOCATION, (String) value);
-        }
-
-        Uri res = SqliteWrapper.insert(mContext, mContentResolver, uri, values);
-        if (res == null) {
-            throw new MmsException("Failed to persist part, return null.");
-        }
-
-        persistData(part, res, contentType);
-        // After successfully store the data, we should update
-        // the dataUri of the part.
-        part.setDataUri(res);
-
-        return res;
-    }
-
-    /**
-     * Save data of the part into storage. The source data may be given
-     * by a byte[] or a Uri. If it's a byte[], directly save it
-     * into storage, otherwise load source data from the dataUri and then
-     * save it. If the data is an image, we may scale down it according
-     * to user preference.
-     *
-     * @param part The PDU part which contains data to be saved.
-     * @param uri The URI of the part.
-     * @param contentType The MIME type of the part.
-     * @throws MmsException Cannot find source data or error occurred
-     *         while saving the data.
-     */
-    private void persistData(PduPart part, Uri uri,
-            String contentType)
-            throws MmsException {
-        OutputStream os = null;
-        InputStream is = null;
-
-        try {
-            byte[] data = part.getData();
-            if (ContentType.TEXT_PLAIN.equals(contentType)
-                    || ContentType.APP_SMIL.equals(contentType)
-                    || ContentType.TEXT_HTML.equals(contentType)) {
-                ContentValues cv = new ContentValues();
-                cv.put(TelephonyProvider.Mms.Part.TEXT, new EncodedStringValue(data).getString());
-                if (mContentResolver.update(uri, cv, null, null) != 1) {
-                    throw new MmsException("unable to update " + uri.toString());
-                }
-            } else {
-                os = mContentResolver.openOutputStream(uri);
-                if (data == null) {
-                    Uri dataUri = part.getDataUri();
-                    if ((dataUri == null) || (dataUri == uri)) {
-                        Log.w(TAG, "Can't find data for this part.");
-                        return;
-                    }
-                    is = mContentResolver.openInputStream(dataUri);
-
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, "Saving data to: " + uri);
-                    }
-
-                    byte[] buffer = new byte[256];
-                    for (int len = 0; (len = is.read(buffer)) != -1; ) {
-                        os.write(buffer, 0, len);
-                    }
-                } else {
-                    if (LOCAL_LOGV) {
-                        Log.v(TAG, "Saving data to: " + uri);
-                    }
-                    os.write(data);
-                }
-            }
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "Failed to open Input/Output stream.", e);
-            throw new MmsException(e);
-        } catch (IOException e) {
-            Log.e(TAG, "Failed to read/write data.", e);
-            throw new MmsException(e);
-        } finally {
-            if (os != null) {
-                try {
-                    os.close();
-                } catch (IOException e) {
-                    Log.e(TAG, "IOException while closing: " + os, e);
-                } // Ignore
-            }
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                    Log.e(TAG, "IOException while closing: " + is, e);
-                } // Ignore
-            }
-        }
-    }
-
-    private void updateAddress(
-            long msgId, int type, EncodedStringValue[] array) {
-        // Delete old address information and then insert new ones.
-        SqliteWrapper.delete(mContext, mContentResolver,
-                Uri.parse("content://mms/" + msgId + "/addr"),
-                Addr.TYPE + "=" + type, null);
-
-        persistAddress(msgId, type, array);
-    }
-
-    /**
-     * Update headers of a SendReq.
-     *
-     * @param uri The PDU which need to be updated.
-     * @param pdu New headers.
-     * @throws MmsException Bad URI or updating failed.
-     */
-    public void updateHeaders(Uri uri, SendReq sendReq) {
-        PDU_CACHE_INSTANCE.purge(uri);
-
-        ContentValues values = new ContentValues(10);
-        byte[] contentType = sendReq.getContentType();
-        if (contentType != null) {
-            values.put(Mms.CONTENT_TYPE, toIsoString(contentType));
-        }
-
-        long date = sendReq.getDate();
-        if (date != -1) {
-            values.put(Mms.DATE, date);
-        }
-
-        int deliveryReport = sendReq.getDeliveryReport();
-        if (deliveryReport != 0) {
-            values.put(Mms.DELIVERY_REPORT, deliveryReport);
-        }
-
-        long expiry = sendReq.getExpiry();
-        if (expiry != -1) {
-            values.put(Mms.EXPIRY, expiry);
-        }
-
-        byte[] msgClass = sendReq.getMessageClass();
-        if (msgClass != null) {
-            values.put(Mms.MESSAGE_CLASS, toIsoString(msgClass));
-        }
-
-        int priority = sendReq.getPriority();
-        if (priority != 0) {
-            values.put(Mms.PRIORITY, priority);
-        }
-
-        int readReport = sendReq.getReadReport();
-        if (readReport != 0) {
-            values.put(Mms.READ_REPORT, readReport);
-        }
-
-        byte[] transId = sendReq.getTransactionId();
-        if (transId != null) {
-            values.put(Mms.TRANSACTION_ID, toIsoString(transId));
-        }
-
-        EncodedStringValue subject = sendReq.getSubject();
-        if (subject != null) {
-            values.put(Mms.SUBJECT, toIsoString(subject.getTextString()));
-            values.put(Mms.SUBJECT_CHARSET, subject.getCharacterSet());
-        } else {
-            values.put(Mms.SUBJECT, "");
-        }
-
-        long messageSize = sendReq.getMessageSize();
-        if (messageSize > 0) {
-            values.put(Mms.MESSAGE_SIZE, messageSize);
-        }
-
-        PduHeaders headers = sendReq.getPduHeaders();
-        HashSet<String> recipients = new HashSet<String>();
-        for (int addrType : ADDRESS_FIELDS) {
-            EncodedStringValue[] array = null;
-            if (addrType == PduHeaders.FROM) {
-                EncodedStringValue v = headers.getEncodedStringValue(addrType);
-                if (v != null) {
-                    array = new EncodedStringValue[1];
-                    array[0] = v;
-                }
-            } else {
-                array = headers.getEncodedStringValues(addrType);
-            }
-
-            if (array != null) {
-                long msgId = ContentUris.parseId(uri);
-                updateAddress(msgId, addrType, array);
-                if (addrType == PduHeaders.TO) {
-                    for (EncodedStringValue v : array) {
-                        if (v != null) {
-                            recipients.add(v.getString());
-                        }
-                    }
-                }
-            }
-        }
-
-        long threadId = Threads.getOrCreateThreadId(mContext, recipients);
-        values.put(Mms.THREAD_ID, threadId);
-
-        SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null);
-    }
-
-    private void updatePart(Uri uri, PduPart part) throws MmsException {
-        ContentValues values = new ContentValues(7);
-
-        int charset = part.getCharset();
-        if (charset != 0 ) {
-            values.put(Part.CHARSET, charset);
-        }
-
-        String contentType = null;
-        if (part.getContentType() != null) {
-            contentType = toIsoString(part.getContentType());
-            values.put(Part.CONTENT_TYPE, contentType);
-        } else {
-            throw new MmsException("MIME type of the part must be set.");
-        }
-
-        if (part.getFilename() != null) {
-            String fileName = new String(part.getFilename());
-            values.put(Part.FILENAME, fileName);
-        }
-
-        if (part.getName() != null) {
-            String name = new String(part.getName());
-            values.put(Part.NAME, name);
-        }
-
-        Object value = null;
-        if (part.getContentDisposition() != null) {
-            value = toIsoString(part.getContentDisposition());
-            values.put(Part.CONTENT_DISPOSITION, (String) value);
-        }
-
-        if (part.getContentId() != null) {
-            value = toIsoString(part.getContentId());
-            values.put(Part.CONTENT_ID, (String) value);
-        }
-
-        if (part.getContentLocation() != null) {
-            value = toIsoString(part.getContentLocation());
-            values.put(Part.CONTENT_LOCATION, (String) value);
-        }
-
-        SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null);
-
-        // Only update the data when:
-        // 1. New binary data supplied or
-        // 2. The Uri of the part is different from the current one.
-        if ((part.getData() != null)
-                || (uri != part.getDataUri())) {
-            persistData(part, uri, contentType);
-        }
-    }
-
-    /**
-     * Update all parts of a PDU.
-     *
-     * @param uri The PDU which need to be updated.
-     * @param body New message body of the PDU.
-     * @throws MmsException Bad URI or updating failed.
-     */
-    public void updateParts(Uri uri, PduBody body)
-            throws MmsException {
-        PduCacheEntry cacheEntry = PDU_CACHE_INSTANCE.get(uri);
-        if (cacheEntry != null) {
-            ((MultimediaMessagePdu) cacheEntry.getPdu()).setBody(body);
-        }
-
-        ArrayList<PduPart> toBeCreated = new ArrayList<PduPart>();
-        HashMap<Uri, PduPart> toBeUpdated = new HashMap<Uri, PduPart>();
-
-        int partsNum = body.getPartsNum();
-        StringBuilder filter = new StringBuilder().append('(');
-        for (int i = 0; i < partsNum; i++) {
-            PduPart part = body.getPart(i);
-            Uri partUri = part.getDataUri();
-            if ((partUri == null) || !partUri.getAuthority().startsWith("mms")) {
-                toBeCreated.add(part);
-            } else {
-                toBeUpdated.put(partUri, part);
-
-                // Don't use 'i > 0' to determine whether we should append
-                // 'AND' since 'i = 0' may be skipped in another branch.
-                if (filter.length() > 1) {
-                    filter.append(" AND ");
-                }
-
-                filter.append(Part._ID);
-                filter.append("!=");
-                DatabaseUtils.appendEscapedSQLString(filter, partUri.getLastPathSegment());
-            }
-        }
-        filter.append(')');
-
-        long msgId = ContentUris.parseId(uri);
-
-        // Remove the parts which doesn't exist anymore.
-        SqliteWrapper.delete(mContext, mContentResolver,
-                Uri.parse(Mms.CONTENT_URI + "/" + msgId + "/part"),
-                filter.length() > 2 ? filter.toString() : null, null);
-
-        // Create new parts which didn't exist before.
-        for (PduPart part : toBeCreated) {
-            persistPart(part, msgId);
-        }
-
-        // Update the modified parts.
-        for (Map.Entry<Uri, PduPart> e : toBeUpdated.entrySet()) {
-            updatePart(e.getKey(), e.getValue());
-        }
-    }
-
-    /**
-     * Persist a PDU object to specific location in the storage.
-     *
-     * @param pdu The PDU object to be stored.
-     * @param uri Where to store the given PDU object.
-     * @return A Uri which can be used to access the stored PDU.
-     */
-    public Uri persist(GenericPdu pdu, Uri uri) throws MmsException {
-        if (uri == null) {
-            throw new MmsException("Uri may not be null.");
-        }
-
-        Integer msgBox = MESSAGE_BOX_MAP.get(uri);
-        if (msgBox == null) {
-            throw new MmsException(
-                    "Bad destination, must be one of "
-                    + "content://mms/inbox, content://mms/sent, "
-                    + "content://mms/drafts, content://mms/outbox, "
-                    + "content://mms/temp.");
-        }
-        PDU_CACHE_INSTANCE.purge(uri);
-
-        PduHeaders header = pdu.getPduHeaders();
-        PduBody body = null;
-        ContentValues values = new ContentValues();
-        Set<Entry<Integer, String>> set;
-
-        set = ENCODED_STRING_COLUMN_NAME_MAP.entrySet();
-        for (Entry<Integer, String> e : set) {
-            int field = e.getKey();
-            EncodedStringValue encodedString = header.getEncodedStringValue(field);
-            if (encodedString != null) {
-                String charsetColumn = CHARSET_COLUMN_NAME_MAP.get(field);
-                values.put(e.getValue(), toIsoString(encodedString.getTextString()));
-                values.put(charsetColumn, encodedString.getCharacterSet());
-            }
-        }
-
-        set = TEXT_STRING_COLUMN_NAME_MAP.entrySet();
-        for (Entry<Integer, String> e : set){
-            byte[] text = header.getTextString(e.getKey());
-            if (text != null) {
-                values.put(e.getValue(), toIsoString(text));
-            }
-        }
-
-        set = OCTET_COLUMN_NAME_MAP.entrySet();
-        for (Entry<Integer, String> e : set){
-            int b = header.getOctet(e.getKey());
-            if (b != 0) {
-                values.put(e.getValue(), b);
-            }
-        }
-
-        set = LONG_COLUMN_NAME_MAP.entrySet();
-        for (Entry<Integer, String> e : set){
-            long l = header.getLongInteger(e.getKey());
-            if (l != -1L) {
-                values.put(e.getValue(), l);
-            }
-        }
-
-        HashMap<Integer, EncodedStringValue[]> addressMap =
-                new HashMap<Integer, EncodedStringValue[]>(ADDRESS_FIELDS.length);
-        // Save address information.
-        for (int addrType : ADDRESS_FIELDS) {
-            EncodedStringValue[] array = null;
-            if (addrType == PduHeaders.FROM) {
-                EncodedStringValue v = header.getEncodedStringValue(addrType);
-                if (v != null) {
-                    array = new EncodedStringValue[1];
-                    array[0] = v;
-                }
-            } else {
-                array = header.getEncodedStringValues(addrType);
-            }
-            addressMap.put(addrType, array);
-        }
-
-        HashSet<String> recipients = new HashSet<String>();
-        long threadId = DUMMY_THREAD_ID;
-        int msgType = pdu.getMessageType();
-        // Here we only allocate thread ID for M-Notification.ind,
-        // M-Retrieve.conf and M-Send.req.
-        // Some of other PDU types may be allocated a thread ID outside
-        // this scope.
-        if ((msgType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND)
-                || (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)
-                || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) {
-            EncodedStringValue[] array = null;
-            switch (msgType) {
-                case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
-                case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
-                    array = addressMap.get(PduHeaders.FROM);
-                    break;
-                case PduHeaders.MESSAGE_TYPE_SEND_REQ:
-                    array = addressMap.get(PduHeaders.TO);
-                    break;
-            }
-
-            if (array != null) {
-                for (EncodedStringValue v : array) {
-                    if (v != null) {
-                        recipients.add(v.getString());
-                    }
-                }
-            }
-            threadId = Threads.getOrCreateThreadId(mContext, recipients);
-        }
-        values.put(Mms.THREAD_ID, threadId);
-
-        // Save parts first to avoid inconsistent message is loaded
-        // while saving the parts.
-        long dummyId = System.currentTimeMillis(); // Dummy ID of the msg.
-        // Get body if the PDU is a RetrieveConf or SendReq.
-        if (pdu instanceof MultimediaMessagePdu) {
-            body = ((MultimediaMessagePdu) pdu).getBody();
-            // Start saving parts if necessary.
-            if (body != null) {
-                int partsNum = body.getPartsNum();
-                for (int i = 0; i < partsNum; i++) {
-                    PduPart part = body.getPart(i);
-                    persistPart(part, dummyId);
-                }
-            }
-        }
-
-        // mark "read" and "seen"
-        values.put(Mms.READ, 0);
-        values.put(Mms.SEEN, 0);
-
-        Uri res = SqliteWrapper.insert(mContext, mContentResolver, uri, values);
-        if (res == null) {
-            throw new MmsException("persist() failed: return null.");
-        }
-
-        // Get the real ID of the PDU and update all parts which were
-        // saved with the dummy ID.
-        long msgId = ContentUris.parseId(res);
-        values = new ContentValues(1);
-        values.put(Part.MSG_ID, msgId);
-        SqliteWrapper.update(mContext, mContentResolver,
-                             Uri.parse("content://mms/" + dummyId + "/part"),
-                             values, null, null);
-        // We should return the longest URI of the persisted PDU, for
-        // example, if input URI is "content://mms/inbox" and the _ID of
-        // persisted PDU is '8', we should return "content://mms/inbox/8"
-        // instead of "content://mms/8".
-        // FIXME: Should the MmsProvider be responsible for this???
-        res = Uri.parse(uri + "/" + msgId);
-
-        // Save address information.
-        for (int addrType : ADDRESS_FIELDS) {
-            EncodedStringValue[] array = addressMap.get(addrType);
-            if (array != null) {
-                persistAddress(msgId, addrType, array);
-            }
-        }
-
-        return res;
-    }
-
-    /**
-     * Move a PDU object from one location to another.
-     *
-     * @param from Specify the PDU object to be moved.
-     * @param to The destination location, should be one of the following:
-     *        "content://mms/inbox", "content://mms/sent",
-     *        "content://mms/drafts", "content://mms/outbox",
-     *        "content://mms/trash".
-     * @return New Uri of the moved PDU.
-     * @throws MmsException Error occurred while moving the message.
-     */
-    public Uri move(Uri from, Uri to) throws MmsException {
-        // Check whether the 'msgId' has been assigned a valid value.
-        long msgId = ContentUris.parseId(from);
-        if (msgId == -1L) {
-            throw new MmsException("Error! ID of the message: -1.");
-        }
-
-        // Get corresponding int value of destination box.
-        Integer msgBox = MESSAGE_BOX_MAP.get(to);
-        if (msgBox == null) {
-            throw new MmsException(
-                    "Bad destination, must be one of "
-                    + "content://mms/inbox, content://mms/sent, "
-                    + "content://mms/drafts, content://mms/outbox, "
-                    + "content://mms/temp.");
-        }
-
-        ContentValues values = new ContentValues(1);
-        values.put(Mms.MESSAGE_BOX, msgBox);
-        SqliteWrapper.update(mContext, mContentResolver, from, values, null, null);
-        return ContentUris.withAppendedId(to, msgId);
-    }
-
-    /**
-     * Wrap a byte[] into a String.
-     */
-    public static String toIsoString(byte[] bytes) {
-        try {
-            return new String(bytes, CharacterSets.MIMENAME_ISO_8859_1);
-        } catch (UnsupportedEncodingException e) {
-            // Impossible to reach here!
-            Log.e(TAG, "ISO_8859_1 must be supported!", e);
-            return "";
-        }
-    }
-
-    /**
-     * Unpack a given String into a byte[].
-     */
-    public static byte[] getBytes(String data) {
-        try {
-            return data.getBytes(CharacterSets.MIMENAME_ISO_8859_1);
-        } catch (UnsupportedEncodingException e) {
-            // Impossible to reach here!
-            Log.e(TAG, "ISO_8859_1 must be supported!", e);
-            return new byte[0];
-        }
-    }
-
-    /**
-     * Remove all objects in the temporary path.
-     */
-    public void release() {
-        Uri uri = Uri.parse(TEMPORARY_DRM_OBJECT_URI);
-        SqliteWrapper.delete(mContext, mContentResolver, uri, null, null);
-    }
-
-    /**
-     * Find all messages to be sent or downloaded before certain time.
-     */
-    public Cursor getPendingMessages(long dueTime) {
-        Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon();
-        uriBuilder.appendQueryParameter("protocol", "mms");
-
-        String selection = PendingMessages.ERROR_TYPE + " < ?"
-                + " AND " + PendingMessages.DUE_TIME + " <= ?";
-
-        String[] selectionArgs = new String[] {
-                String.valueOf(MmsSms.ERR_TYPE_GENERIC_PERMANENT),
-                String.valueOf(dueTime)
-        };
-
-        return SqliteWrapper.query(mContext, mContentResolver,
-                uriBuilder.build(), null, selection, selectionArgs,
-                PendingMessages.DUE_TIME);
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/QuotedPrintable.java b/mms-common/java/com/android/mmscommon/mms/pdu/QuotedPrintable.java
deleted file mode 100644
index e9da7df..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/QuotedPrintable.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import java.io.ByteArrayOutputStream;
-
-public class QuotedPrintable {
-    private static byte ESCAPE_CHAR = '=';
-
-    /**
-     * Decodes an array quoted-printable characters into an array of original bytes.
-     * Escaped characters are converted back to their original representation.
-     *
-     * <p>
-     * This function implements a subset of
-     * quoted-printable encoding specification (rule #1 and rule #2)
-     * as defined in RFC 1521.
-     * </p>
-     *
-     * @param bytes array of quoted-printable characters
-     * @return array of original bytes,
-     *         null if quoted-printable decoding is unsuccessful.
-     */
-    public static final byte[] decodeQuotedPrintable(byte[] bytes) {
-        if (bytes == null) {
-            return null;
-        }
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        for (int i = 0; i < bytes.length; i++) {
-            int b = bytes[i];
-            if (b == ESCAPE_CHAR) {
-                try {
-                    if('\r' == (char)bytes[i + 1] &&
-                            '\n' == (char)bytes[i + 2]) {
-                        i += 2;
-                        continue;
-                    }
-                    int u = Character.digit((char) bytes[++i], 16);
-                    int l = Character.digit((char) bytes[++i], 16);
-                    if (u == -1 || l == -1) {
-                        return null;
-                    }
-                    buffer.write((char) ((u << 4) + l));
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    return null;
-                }
-            } else {
-                buffer.write(b);
-            }
-        }
-        return buffer.toByteArray();
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/ReadOrigInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/ReadOrigInd.java
deleted file mode 100644
index 9678784..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/ReadOrigInd.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-public class ReadOrigInd extends GenericPdu {
-    /**
-     * Empty constructor.
-     * Since the Pdu corresponding to this class is constructed
-     * by the Proxy-Relay server, this class is only instantiated
-     * by the Pdu Parser.
-     *
-     * @throws InvalidHeaderValueException if error occurs.
-     */
-    public ReadOrigInd() throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_READ_ORIG_IND);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    ReadOrigInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get Date value.
-     *
-     * @return the value
-     */
-    public long getDate() {
-        return mPduHeaders.getLongInteger(PduHeaders.DATE);
-    }
-
-    /**
-     * Set Date value.
-     *
-     * @param value the value
-     */
-    public void setDate(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.DATE);
-    }
-
-    /**
-     * Get From value.
-     * From-value = Value-length
-     *      (Address-present-token Encoded-string-value | Insert-address-token)
-     *
-     * @return the value
-     */
-    public EncodedStringValue getFrom() {
-       return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
-    }
-
-    /**
-     * Set From value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setFrom(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
-    }
-
-    /**
-     * Get Message-ID value.
-     *
-     * @return the value
-     */
-    public byte[] getMessageId() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Set Message-ID value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Get X-MMS-Read-status value.
-     *
-     * @return the value
-     */
-    public int getReadStatus() {
-        return mPduHeaders.getOctet(PduHeaders.READ_STATUS);
-    }
-
-    /**
-     * Set X-MMS-Read-status value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setReadStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.READ_STATUS);
-    }
-
-    /**
-     * Get To value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getTo() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
-    }
-
-    /**
-     * Set To value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTo(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     */
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/ReadRecInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/ReadRecInd.java
deleted file mode 100644
index c1efbbc..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/ReadRecInd.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-public class ReadRecInd extends GenericPdu {
-    /**
-     * Constructor, used when composing a M-ReadRec.ind pdu.
-     *
-     * @param from the from value
-     * @param messageId the message ID value
-     * @param mmsVersion current viersion of mms
-     * @param readStatus the read status value
-     * @param to the to value
-     * @throws InvalidHeaderValueException if parameters are invalid.
-     *         NullPointerException if messageId or to is null.
-     */
-    public ReadRecInd(EncodedStringValue from,
-                      byte[] messageId,
-                      int mmsVersion,
-                      int readStatus,
-                      EncodedStringValue[] to) throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_READ_REC_IND);
-        setFrom(from);
-        setMessageId(messageId);
-        setMmsVersion(mmsVersion);
-        setTo(to);
-        setReadStatus(readStatus);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    ReadRecInd(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get Date value.
-     *
-     * @return the value
-     */
-    public long getDate() {
-        return mPduHeaders.getLongInteger(PduHeaders.DATE);
-    }
-
-    /**
-     * Set Date value.
-     *
-     * @param value the value
-     */
-    public void setDate(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.DATE);
-    }
-
-    /**
-     * Get Message-ID value.
-     *
-     * @return the value
-     */
-    public byte[] getMessageId() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Set Message-ID value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Get To value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getTo() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
-    }
-
-    /**
-     * Set To value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTo(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
-    }
-
-    /**
-     * Get X-MMS-Read-status value.
-     *
-     * @return the value
-     */
-    public int getReadStatus() {
-        return mPduHeaders.getOctet(PduHeaders.READ_STATUS);
-    }
-
-    /**
-     * Set X-MMS-Read-status value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setReadStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.READ_STATUS);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     */
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/RetrieveConf.java b/mms-common/java/com/android/mmscommon/mms/pdu/RetrieveConf.java
deleted file mode 100644
index 442949e..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/RetrieveConf.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-/**
- * M-Retrive.conf Pdu.
- */
-public class RetrieveConf extends MultimediaMessagePdu {
-    /**
-     * Empty constructor.
-     * Since the Pdu corresponding to this class is constructed
-     * by the Proxy-Relay server, this class is only instantiated
-     * by the Pdu Parser.
-     *
-     * @throws InvalidHeaderValueException if error occurs.
-     */
-    public RetrieveConf() throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    RetrieveConf(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Constructor with given headers and body
-     *
-     * @param headers Headers for this PDU.
-     * @param body Body of this PDu.
-     */
-    RetrieveConf(PduHeaders headers, PduBody body) {
-        super(headers, body);
-    }
-
-    /**
-     * Get CC value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getCc() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.CC);
-    }
-
-    /**
-     * Add a "CC" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void addCc(EncodedStringValue value) {
-        mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC);
-    }
-
-    /**
-     * Get Content-type value.
-     *
-     * @return the value
-     */
-    public byte[] getContentType() {
-        return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE);
-    }
-
-    /**
-     * Set Content-type value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setContentType(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE);
-    }
-
-    /**
-     * Get X-Mms-Delivery-Report value.
-     *
-     * @return the value
-     */
-    public int getDeliveryReport() {
-        return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT);
-    }
-
-    /**
-     * Set X-Mms-Delivery-Report value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setDeliveryReport(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT);
-    }
-
-    /**
-     * Get From value.
-     * From-value = Value-length
-     *      (Address-present-token Encoded-string-value | Insert-address-token)
-     *
-     * @return the value
-     */
-    public EncodedStringValue getFrom() {
-       return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
-    }
-
-    /**
-     * Set From value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setFrom(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
-    }
-
-    /**
-     * Get X-Mms-Message-Class value.
-     * Message-class-value = Class-identifier | Token-text
-     * Class-identifier = Personal | Advertisement | Informational | Auto
-     *
-     * @return the value
-     */
-    public byte[] getMessageClass() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Set X-Mms-Message-Class value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageClass(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Get Message-ID value.
-     *
-     * @return the value
-     */
-    public byte[] getMessageId() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Set Message-ID value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Get X-Mms-Read-Report value.
-     *
-     * @return the value
-     */
-    public int getReadReport() {
-        return mPduHeaders.getOctet(PduHeaders.READ_REPORT);
-    }
-
-    /**
-     * Set X-Mms-Read-Report value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setReadReport(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.READ_REPORT);
-    }
-
-    /**
-     * Get X-Mms-Retrieve-Status value.
-     *
-     * @return the value
-     */
-    public int getRetrieveStatus() {
-        return mPduHeaders.getOctet(PduHeaders.RETRIEVE_STATUS);
-    }
-
-    /**
-     * Set X-Mms-Retrieve-Status value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setRetrieveStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.RETRIEVE_STATUS);
-    }
-
-    /**
-     * Get X-Mms-Retrieve-Text value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue getRetrieveText() {
-        return mPduHeaders.getEncodedStringValue(PduHeaders.RETRIEVE_TEXT);
-    }
-
-    /**
-     * Set X-Mms-Retrieve-Text value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setRetrieveText(EncodedStringValue value) {
-        mPduHeaders.setEncodedStringValue(value, PduHeaders.RETRIEVE_TEXT);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id.
-     *
-     * @return the value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTransactionId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte getContentClass() {return 0x00;}
-     *     public void setApplicId(byte value) {}
-     *
-     *     public byte getDrmContent() {return 0x00;}
-     *     public void setDrmContent(byte value) {}
-     *
-     *     public byte getDistributionIndicator() {return 0x00;}
-     *     public void setDistributionIndicator(byte value) {}
-     *
-     *     public PreviouslySentByValue getPreviouslySentBy() {return null;}
-     *     public void setPreviouslySentBy(PreviouslySentByValue value) {}
-     *
-     *     public PreviouslySentDateValue getPreviouslySentDate() {}
-     *     public void setPreviouslySentDate(PreviouslySentDateValue value) {}
-     *
-     *     public MmFlagsValue getMmFlags() {return null;}
-     *     public void setMmFlags(MmFlagsValue value) {}
-     *
-     *     public MmStateValue getMmState() {return null;}
-     *     public void getMmState(MmStateValue value) {}
-     *
-     *     public byte[] getReplaceId() {return 0x00;}
-     *     public void setReplaceId(byte[] value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     *
-     *     public byte getReplyCharging() {return 0x00;}
-     *     public void setReplyCharging(byte value) {}
-     *
-     *     public byte getReplyChargingDeadline() {return 0x00;}
-     *     public void setReplyChargingDeadline(byte value) {}
-     *
-     *     public byte[] getReplyChargingId() {return 0x00;}
-     *     public void setReplyChargingId(byte[] value) {}
-     *
-     *     public long getReplyChargingSize() {return 0;}
-     *     public void setReplyChargingSize(long value) {}
-     */
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/SendConf.java b/mms-common/java/com/android/mmscommon/mms/pdu/SendConf.java
deleted file mode 100644
index 0a57b6b..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/SendConf.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-public class SendConf extends GenericPdu {
-    /**
-     * Empty constructor.
-     * Since the Pdu corresponding to this class is constructed
-     * by the Proxy-Relay server, this class is only instantiated
-     * by the Pdu Parser.
-     *
-     * @throws InvalidHeaderValueException if error occurs.
-     */
-    public SendConf() throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_SEND_CONF);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    SendConf(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Get Message-ID value.
-     *
-     * @return the value
-     */
-    public byte[] getMessageId() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Set Message-ID value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
-    }
-
-    /**
-     * Get X-Mms-Response-Status.
-     *
-     * @return the value
-     */
-    public int getResponseStatus() {
-        return mPduHeaders.getOctet(PduHeaders.RESPONSE_STATUS);
-    }
-
-    /**
-     * Set X-Mms-Response-Status.
-     *
-     * @param value the values
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setResponseStatus(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.RESPONSE_STATUS);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id field value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTransactionId(byte[] value) {
-            mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *    public byte[] getContentLocation() {return null;}
-     *    public void setContentLocation(byte[] value) {}
-     *
-     *    public EncodedStringValue getResponseText() {return null;}
-     *    public void setResponseText(EncodedStringValue value) {}
-     *
-     *    public byte getStoreStatus() {return 0x00;}
-     *    public void setStoreStatus(byte value) {}
-     *
-     *    public byte[] getStoreStatusText() {return null;}
-     *    public void setStoreStatusText(byte[] value) {}
-     */
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/SendReq.java b/mms-common/java/com/android/mmscommon/mms/pdu/SendReq.java
deleted file mode 100644
index 5da4719..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/SendReq.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 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 com.android.mmscommon.mms.pdu;
-
-import android.util.Log;
-
-import com.android.mmscommon.EncodedStringValue;
-import com.android.mmscommon.InvalidHeaderValueException;
-import com.android.mmscommon.PduHeaders;
-
-public class SendReq extends MultimediaMessagePdu {
-    private static final String TAG = "SendReq";
-
-    public SendReq() {
-        super();
-
-        try {
-            setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ);
-            setMmsVersion(PduHeaders.CURRENT_MMS_VERSION);
-            // FIXME: Content-type must be decided according to whether
-            // SMIL part present.
-            setContentType("application/vnd.wap.multipart.related".getBytes());
-            setFrom(new EncodedStringValue(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes()));
-            setTransactionId(generateTransactionId());
-        } catch (InvalidHeaderValueException e) {
-            // Impossible to reach here since all headers we set above are valid.
-            Log.e(TAG, "Unexpected InvalidHeaderValueException.", e);
-            throw new RuntimeException(e);
-        }
-    }
-
-    private byte[] generateTransactionId() {
-        String transactionId = "T" + Long.toHexString(System.currentTimeMillis());
-        return transactionId.getBytes();
-    }
-
-    /**
-     * Constructor, used when composing a M-Send.req pdu.
-     *
-     * @param contentType the content type value
-     * @param from the from value
-     * @param mmsVersion current viersion of mms
-     * @param transactionId the transaction-id value
-     * @throws InvalidHeaderValueException if parameters are invalid.
-     *         NullPointerException if contentType, form or transactionId is null.
-     */
-    public SendReq(byte[] contentType,
-                   EncodedStringValue from,
-                   int mmsVersion,
-                   byte[] transactionId) throws InvalidHeaderValueException {
-        super();
-        setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ);
-        setContentType(contentType);
-        setFrom(from);
-        setMmsVersion(mmsVersion);
-        setTransactionId(transactionId);
-    }
-
-    /**
-     * Constructor with given headers.
-     *
-     * @param headers Headers for this PDU.
-     */
-    SendReq(PduHeaders headers) {
-        super(headers);
-    }
-
-    /**
-     * Constructor with given headers and body
-     *
-     * @param headers Headers for this PDU.
-     * @param body Body of this PDu.
-     */
-    SendReq(PduHeaders headers, PduBody body) {
-        super(headers, body);
-    }
-
-    /**
-     * Get Bcc value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getBcc() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.BCC);
-    }
-
-    /**
-     * Add a "BCC" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void addBcc(EncodedStringValue value) {
-        mPduHeaders.appendEncodedStringValue(value, PduHeaders.BCC);
-    }
-
-    /**
-     * Set "BCC" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setBcc(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.BCC);
-    }
-
-    /**
-     * Get CC value.
-     *
-     * @return the value
-     */
-    public EncodedStringValue[] getCc() {
-        return mPduHeaders.getEncodedStringValues(PduHeaders.CC);
-    }
-
-    /**
-     * Add a "CC" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void addCc(EncodedStringValue value) {
-        mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC);
-    }
-
-    /**
-     * Set "CC" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setCc(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.CC);
-    }
-
-    /**
-     * Get Content-type value.
-     *
-     * @return the value
-     */
-    public byte[] getContentType() {
-        return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE);
-    }
-
-    /**
-     * Set Content-type value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setContentType(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE);
-    }
-
-    /**
-     * Get X-Mms-Delivery-Report value.
-     *
-     * @return the value
-     */
-    public int getDeliveryReport() {
-        return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT);
-    }
-
-    /**
-     * Set X-Mms-Delivery-Report value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setDeliveryReport(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT);
-    }
-
-    /**
-     * Get X-Mms-Expiry value.
-     *
-     * Expiry-value = Value-length
-     *      (Absolute-token Date-value | Relative-token Delta-seconds-value)
-     *
-     * @return the value
-     */
-    public long getExpiry() {
-        return mPduHeaders.getLongInteger(PduHeaders.EXPIRY);
-    }
-
-    /**
-     * Set X-Mms-Expiry value.
-     *
-     * @param value the value
-     */
-    public void setExpiry(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY);
-    }
-
-    /**
-     * Get X-Mms-MessageSize value.
-     *
-     * Expiry-value = size of message
-     *
-     * @return the value
-     */
-    public long getMessageSize() {
-        return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE);
-    }
-
-    /**
-     * Set X-Mms-MessageSize value.
-     *
-     * @param value the value
-     */
-    public void setMessageSize(long value) {
-        mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE);
-    }
-
-    /**
-     * Get X-Mms-Message-Class value.
-     * Message-class-value = Class-identifier | Token-text
-     * Class-identifier = Personal | Advertisement | Informational | Auto
-     *
-     * @return the value
-     */
-    public byte[] getMessageClass() {
-        return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Set X-Mms-Message-Class value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setMessageClass(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS);
-    }
-
-    /**
-     * Get X-Mms-Read-Report value.
-     *
-     * @return the value
-     */
-    public int getReadReport() {
-        return mPduHeaders.getOctet(PduHeaders.READ_REPORT);
-    }
-
-    /**
-     * Set X-Mms-Read-Report value.
-     *
-     * @param value the value
-     * @throws InvalidHeaderValueException if the value is invalid.
-     */
-    public void setReadReport(int value) throws InvalidHeaderValueException {
-        mPduHeaders.setOctet(value, PduHeaders.READ_REPORT);
-    }
-
-    /**
-     * Set "To" value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTo(EncodedStringValue[] value) {
-        mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
-    }
-
-    /**
-     * Get X-Mms-Transaction-Id field value.
-     *
-     * @return the X-Mms-Report-Allowed value
-     */
-    public byte[] getTransactionId() {
-        return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
-    }
-
-    /**
-     * Set X-Mms-Transaction-Id field value.
-     *
-     * @param value the value
-     * @throws NullPointerException if the value is null.
-     */
-    public void setTransactionId(byte[] value) {
-        mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
-    }
-
-    /*
-     * Optional, not supported header fields:
-     *
-     *     public byte getAdaptationAllowed() {return 0};
-     *     public void setAdaptationAllowed(btye value) {};
-     *
-     *     public byte[] getApplicId() {return null;}
-     *     public void setApplicId(byte[] value) {}
-     *
-     *     public byte[] getAuxApplicId() {return null;}
-     *     public void getAuxApplicId(byte[] value) {}
-     *
-     *     public byte getContentClass() {return 0x00;}
-     *     public void setApplicId(byte value) {}
-     *
-     *     public long getDeliveryTime() {return 0};
-     *     public void setDeliveryTime(long value) {};
-     *
-     *     public byte getDrmContent() {return 0x00;}
-     *     public void setDrmContent(byte value) {}
-     *
-     *     public MmFlagsValue getMmFlags() {return null;}
-     *     public void setMmFlags(MmFlagsValue value) {}
-     *
-     *     public MmStateValue getMmState() {return null;}
-     *     public void getMmState(MmStateValue value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     *
-     *     public byte getReplyCharging() {return 0x00;}
-     *     public void setReplyCharging(byte value) {}
-     *
-     *     public byte getReplyChargingDeadline() {return 0x00;}
-     *     public void setReplyChargingDeadline(byte value) {}
-     *
-     *     public byte[] getReplyChargingId() {return 0x00;}
-     *     public void setReplyChargingId(byte[] value) {}
-     *
-     *     public long getReplyChargingSize() {return 0;}
-     *     public void setReplyChargingSize(long value) {}
-     *
-     *     public byte[] getReplyApplicId() {return 0x00;}
-     *     public void setReplyApplicId(byte[] value) {}
-     *
-     *     public byte getStore() {return 0x00;}
-     *     public void setStore(byte value) {}
-     */
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/util/AbstractCache.java b/mms-common/java/com/android/mmscommon/mms/util/AbstractCache.java
deleted file mode 100644
index 10a6fce..0000000
--- a/mms-common/java/com/android/mmscommon/mms/util/AbstractCache.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 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 com.android.mmscommon.mms.util;
-
-import android.util.Config;
-import android.util.Log;
-
-import java.util.HashMap;
-
-public abstract class AbstractCache<K, V> {
-    private static final String TAG = "AbstractCache";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
-
-    private static final int MAX_CACHED_ITEMS  = 500;
-
-    private final HashMap<K, CacheEntry<V>> mCacheMap;
-
-    protected AbstractCache() {
-        mCacheMap = new HashMap<K, CacheEntry<V>>();
-    }
-
-    public boolean put(K key, V value) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Trying to put " + key + " into cache.");
-        }
-
-        if (mCacheMap.size() >= MAX_CACHED_ITEMS) {
-            // TODO Should remove the oldest or least hit cached entry
-            // and then cache the new one.
-            if (LOCAL_LOGV) {
-                Log.v(TAG, "Failed! size limitation reached.");
-            }
-            return false;
-        }
-
-        if (key != null) {
-            CacheEntry<V> cacheEntry = new CacheEntry<V>();
-            cacheEntry.value = value;
-            mCacheMap.put(key, cacheEntry);
-
-            if (LOCAL_LOGV) {
-                Log.v(TAG, key + " cached, " + mCacheMap.size() + " items total.");
-            }
-            return true;
-        }
-        return false;
-    }
-
-    public V get(K key) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Trying to get " + key + " from cache.");
-        }
-
-        if (key != null) {
-            CacheEntry<V> cacheEntry = mCacheMap.get(key);
-            if (cacheEntry != null) {
-                cacheEntry.hit++;
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, key + " hit " + cacheEntry.hit + " times.");
-                }
-                return cacheEntry.value;
-            }
-        }
-        return null;
-    }
-
-    public V purge(K key) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Trying to purge " + key);
-        }
-
-        CacheEntry<V> v = mCacheMap.remove(key);
-
-        if (LOCAL_LOGV) {
-            Log.v(TAG, mCacheMap.size() + " items cached.");
-        }
-
-        return v != null ? v.value : null;
-    }
-
-    public void purgeAll() {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Purging cache, " + mCacheMap.size()
-                    + " items dropped.");
-        }
-        mCacheMap.clear();
-    }
-
-    public int size() {
-        return mCacheMap.size();
-    }
-
-    private static class CacheEntry<V> {
-        int hit;
-        V value;
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/util/PduCache.java b/mms-common/java/com/android/mmscommon/mms/util/PduCache.java
deleted file mode 100644
index ca5432f..0000000
--- a/mms-common/java/com/android/mmscommon/mms/util/PduCache.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 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 com.android.mmscommon.mms.util;
-
-import android.content.ContentUris;
-import android.content.UriMatcher;
-import android.net.Uri;
-import com.android.mmscommon.telephony.TelephonyProvider.Mms;
-import android.util.Config;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.HashSet;
-
-public final class PduCache extends AbstractCache<Uri, PduCacheEntry> {
-    private static final String TAG = "PduCache";
-    private static final boolean DEBUG = false;
-    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
-
-    private static final int MMS_ALL             = 0;
-    private static final int MMS_ALL_ID          = 1;
-    private static final int MMS_INBOX           = 2;
-    private static final int MMS_INBOX_ID        = 3;
-    private static final int MMS_SENT            = 4;
-    private static final int MMS_SENT_ID         = 5;
-    private static final int MMS_DRAFTS          = 6;
-    private static final int MMS_DRAFTS_ID       = 7;
-    private static final int MMS_OUTBOX          = 8;
-    private static final int MMS_OUTBOX_ID       = 9;
-    private static final int MMS_CONVERSATION    = 10;
-    private static final int MMS_CONVERSATION_ID = 11;
-
-    private static final UriMatcher URI_MATCHER;
-    private static final HashMap<Integer, Integer> MATCH_TO_MSGBOX_ID_MAP;
-
-    private static PduCache sInstance;
-
-    static {
-        URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
-        URI_MATCHER.addURI("mms", null,         MMS_ALL);
-        URI_MATCHER.addURI("mms", "#",          MMS_ALL_ID);
-        URI_MATCHER.addURI("mms", "inbox",      MMS_INBOX);
-        URI_MATCHER.addURI("mms", "inbox/#",    MMS_INBOX_ID);
-        URI_MATCHER.addURI("mms", "sent",       MMS_SENT);
-        URI_MATCHER.addURI("mms", "sent/#",     MMS_SENT_ID);
-        URI_MATCHER.addURI("mms", "drafts",     MMS_DRAFTS);
-        URI_MATCHER.addURI("mms", "drafts/#",   MMS_DRAFTS_ID);
-        URI_MATCHER.addURI("mms", "outbox",     MMS_OUTBOX);
-        URI_MATCHER.addURI("mms", "outbox/#",   MMS_OUTBOX_ID);
-        URI_MATCHER.addURI("mms-sms", "conversations",   MMS_CONVERSATION);
-        URI_MATCHER.addURI("mms-sms", "conversations/#", MMS_CONVERSATION_ID);
-
-        MATCH_TO_MSGBOX_ID_MAP = new HashMap<Integer, Integer>();
-        MATCH_TO_MSGBOX_ID_MAP.put(MMS_INBOX,  Mms.MESSAGE_BOX_INBOX);
-        MATCH_TO_MSGBOX_ID_MAP.put(MMS_SENT,   Mms.MESSAGE_BOX_SENT);
-        MATCH_TO_MSGBOX_ID_MAP.put(MMS_DRAFTS, Mms.MESSAGE_BOX_DRAFTS);
-        MATCH_TO_MSGBOX_ID_MAP.put(MMS_OUTBOX, Mms.MESSAGE_BOX_OUTBOX);
-    }
-
-    private final HashMap<Integer, HashSet<Uri>> mMessageBoxes;
-    private final HashMap<Long, HashSet<Uri>> mThreads;
-
-    private PduCache() {
-        mMessageBoxes = new HashMap<Integer, HashSet<Uri>>();
-        mThreads = new HashMap<Long, HashSet<Uri>>();
-    }
-
-    synchronized public static final PduCache getInstance() {
-        if (sInstance == null) {
-            if (LOCAL_LOGV) {
-                Log.v(TAG, "Constructing new PduCache instance.");
-            }
-            sInstance = new PduCache();
-        }
-        return sInstance;
-    }
-
-    @Override
-    synchronized public boolean put(Uri uri, PduCacheEntry entry) {
-        int msgBoxId = entry.getMessageBox();
-        HashSet<Uri> msgBox = mMessageBoxes.get(msgBoxId);
-        if (msgBox == null) {
-            msgBox = new HashSet<Uri>();
-            mMessageBoxes.put(msgBoxId, msgBox);
-        }
-
-        long threadId = entry.getThreadId();
-        HashSet<Uri> thread = mThreads.get(threadId);
-        if (thread == null) {
-            thread = new HashSet<Uri>();
-            mThreads.put(threadId, thread);
-        }
-
-        Uri finalKey = normalizeKey(uri);
-        boolean result = super.put(finalKey, entry);
-        if (result) {
-            msgBox.add(finalKey);
-            thread.add(finalKey);
-        }
-        return result;
-    }
-
-    @Override
-    synchronized public PduCacheEntry purge(Uri uri) {
-        int match = URI_MATCHER.match(uri);
-        switch (match) {
-            case MMS_ALL_ID:
-                return purgeSingleEntry(uri);
-            case MMS_INBOX_ID:
-            case MMS_SENT_ID:
-            case MMS_DRAFTS_ID:
-            case MMS_OUTBOX_ID:
-                String msgId = uri.getLastPathSegment();
-                return purgeSingleEntry(Uri.withAppendedPath(Mms.CONTENT_URI, msgId));
-            // Implicit batch of purge, return null.
-            case MMS_ALL:
-            case MMS_CONVERSATION:
-                purgeAll();
-                return null;
-            case MMS_INBOX:
-            case MMS_SENT:
-            case MMS_DRAFTS:
-            case MMS_OUTBOX:
-                purgeByMessageBox(MATCH_TO_MSGBOX_ID_MAP.get(match));
-                return null;
-            case MMS_CONVERSATION_ID:
-                purgeByThreadId(ContentUris.parseId(uri));
-                return null;
-            default:
-                return null;
-        }
-    }
-
-    private PduCacheEntry purgeSingleEntry(Uri key) {
-        PduCacheEntry entry = super.purge(key);
-        if (entry != null) {
-            removeFromThreads(key, entry);
-            removeFromMessageBoxes(key, entry);
-            return entry;
-        }
-        return null;
-    }
-
-    @Override
-    synchronized public void purgeAll() {
-        super.purgeAll();
-
-        mMessageBoxes.clear();
-        mThreads.clear();
-    }
-
-    /**
-     * @param uri The Uri to be normalized.
-     * @return Uri The normalized key of cached entry.
-     */
-    private Uri normalizeKey(Uri uri) {
-        int match = URI_MATCHER.match(uri);
-        Uri normalizedKey = null;
-
-        switch (match) {
-            case MMS_ALL_ID:
-                normalizedKey = uri;
-                break;
-            case MMS_INBOX_ID:
-            case MMS_SENT_ID:
-            case MMS_DRAFTS_ID:
-            case MMS_OUTBOX_ID:
-                String msgId = uri.getLastPathSegment();
-                normalizedKey = Uri.withAppendedPath(Mms.CONTENT_URI, msgId);
-                break;
-            default:
-                return null;
-        }
-
-        if (LOCAL_LOGV) {
-            Log.v(TAG, uri + " -> " + normalizedKey);
-        }
-        return normalizedKey;
-    }
-
-    private void purgeByMessageBox(Integer msgBoxId) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Purge cache in message box: " + msgBoxId);
-        }
-
-        if (msgBoxId != null) {
-            HashSet<Uri> msgBox = mMessageBoxes.remove(msgBoxId);
-            if (msgBox != null) {
-                for (Uri key : msgBox) {
-                    PduCacheEntry entry = super.purge(key);
-                    if (entry != null) {
-                        removeFromThreads(key, entry);
-                    }
-                }
-            }
-        }
-    }
-
-    private void removeFromThreads(Uri key, PduCacheEntry entry) {
-        HashSet<Uri> thread = mThreads.get(entry.getThreadId());
-        if (thread != null) {
-            thread.remove(key);
-        }
-    }
-
-    private void purgeByThreadId(long threadId) {
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Purge cache in thread: " + threadId);
-        }
-
-        HashSet<Uri> thread = mThreads.remove(threadId);
-        if (thread != null) {
-            for (Uri key : thread) {
-                PduCacheEntry entry = super.purge(key);
-                if (entry != null) {
-                    removeFromMessageBoxes(key, entry);
-                }
-            }
-        }
-    }
-
-    private void removeFromMessageBoxes(Uri key, PduCacheEntry entry) {
-        HashSet<Uri> msgBox = mThreads.get(entry.getMessageBox());
-        if (msgBox != null) {
-            msgBox.remove(key);
-        }
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/util/PduCacheEntry.java b/mms-common/java/com/android/mmscommon/mms/util/PduCacheEntry.java
deleted file mode 100644
index aed741d..0000000
--- a/mms-common/java/com/android/mmscommon/mms/util/PduCacheEntry.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 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 com.android.mmscommon.mms.util;
-
-import com.android.mmscommon.mms.pdu.GenericPdu;
-
-public final class PduCacheEntry {
-    private final GenericPdu mPdu;
-    private final int mMessageBox;
-    private final long mThreadId;
-
-    public PduCacheEntry(GenericPdu pdu, int msgBox, long threadId) {
-        mPdu = pdu;
-        mMessageBox = msgBox;
-        mThreadId = threadId;
-    }
-
-    public GenericPdu getPdu() {
-        return mPdu;
-    }
-
-    public int getMessageBox() {
-        return mMessageBox;
-    }
-
-    public long getThreadId() {
-        return mThreadId;
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java b/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
deleted file mode 100644
index cfc9231..0000000
--- a/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
+++ /dev/null
@@ -1,1779 +0,0 @@
-/*
- * Copyright (C) 2006 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 com.android.mmscommon.telephony;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.BaseColumns;
-import android.telephony.SmsMessage;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-import android.util.Patterns;
-
-import android.database.sqlite.SqliteWrapper;
-
-/**
- * The Telephony provider contains data related to phone operation.
- *
- * @hide
- */
-
-// This is a copy of the private TelephoneProvider.java file found in:
-//      com.android.providers.telephony
-// TODO: keep these files in sync.
-
-public final class TelephonyProvider {
-    private static final String TAG = "Telephony";
-    private static final boolean DEBUG = true;
-    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
-
-    // Constructor
-    public TelephonyProvider() {
-    }
-
-    /**
-     * Base columns for tables that contain text based SMSs.
-     */
-    public interface TextBasedSmsColumns {
-        /**
-         * The type of the message
-         * <P>Type: INTEGER</P>
-         */
-        public static final String TYPE = "type";
-
-        public static final int MESSAGE_TYPE_ALL    = 0;
-        public static final int MESSAGE_TYPE_INBOX  = 1;
-        public static final int MESSAGE_TYPE_SENT   = 2;
-        public static final int MESSAGE_TYPE_DRAFT  = 3;
-        public static final int MESSAGE_TYPE_OUTBOX = 4;
-        public static final int MESSAGE_TYPE_FAILED = 5; // for failed outgoing messages
-        public static final int MESSAGE_TYPE_QUEUED = 6; // for messages to send later
-
-
-        /**
-         * The thread ID of the message
-         * <P>Type: INTEGER</P>
-         */
-        public static final String THREAD_ID = "thread_id";
-
-        /**
-         * The address of the other party
-         * <P>Type: TEXT</P>
-         */
-        public static final String ADDRESS = "address";
-
-        /**
-         * The person ID of the sender
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String PERSON_ID = "person";
-
-        /**
-         * The date the message was sent
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String DATE = "date";
-
-        /**
-         * Has the message been read
-         * <P>Type: INTEGER (boolean)</P>
-         */
-        public static final String READ = "read";
-
-        /**
-         * Indicates whether this message has been seen by the user. The "seen" flag will be
-         * used to figure out whether we need to throw up a statusbar notification or not.
-         */
-        public static final String SEEN = "seen";
-
-        /**
-         * The TP-Status value for the message, or -1 if no status has
-         * been received
-         */
-        public static final String STATUS = "status";
-
-        public static final int STATUS_NONE = -1;
-        public static final int STATUS_COMPLETE = 0;
-        public static final int STATUS_PENDING = 64;
-        public static final int STATUS_FAILED = 128;
-
-        /**
-         * The subject of the message, if present
-         * <P>Type: TEXT</P>
-         */
-        public static final String SUBJECT = "subject";
-
-        /**
-         * The body of the message
-         * <P>Type: TEXT</P>
-         */
-        public static final String BODY = "body";
-
-        /**
-         * The id of the sender of the conversation, if present
-         * <P>Type: INTEGER (reference to item in content://contacts/people)</P>
-         */
-        public static final String PERSON = "person";
-
-        /**
-         * The protocol identifier code
-         * <P>Type: INTEGER</P>
-         */
-        public static final String PROTOCOL = "protocol";
-
-        /**
-         * Whether the <code>TP-Reply-Path</code> bit was set on this message
-         * <P>Type: BOOLEAN</P>
-         */
-        public static final String REPLY_PATH_PRESENT = "reply_path_present";
-
-        /**
-         * The service center (SC) through which to send the message, if present
-         * <P>Type: TEXT</P>
-         */
-        public static final String SERVICE_CENTER = "service_center";
-
-        /**
-         * Has the message been locked?
-         * <P>Type: INTEGER (boolean)</P>
-         */
-        public static final String LOCKED = "locked";
-
-        /**
-         * Error code associated with sending or receiving this message
-         * <P>Type: INTEGER</P>
-         */
-        public static final String ERROR_CODE = "error_code";
-}
-
-    /**
-     * Contains all text based SMS messages.
-     */
-    public static final class Sms implements BaseColumns, TextBasedSmsColumns {
-        public static final Cursor query(ContentResolver cr, String[] projection) {
-            return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
-        }
-
-        public static final Cursor query(ContentResolver cr, String[] projection,
-                String where, String orderBy) {
-            return cr.query(CONTENT_URI, projection, where,
-                                         null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
-        }
-
-        /**
-         * The content:// style URL for this table
-         */
-        public static final Uri CONTENT_URI =
-            Uri.parse("content://sms");
-
-        /**
-         * The default sort order for this table
-         */
-        public static final String DEFAULT_SORT_ORDER = "date DESC";
-
-        /**
-         * Add an SMS to the given URI.
-         *
-         * @param resolver the content resolver to use
-         * @param uri the URI to add the message to
-         * @param address the address of the sender
-         * @param body the body of the message
-         * @param subject the psuedo-subject of the message
-         * @param date the timestamp for the message
-         * @param read true if the message has been read, false if not
-         * @param deliveryReport true if a delivery report was requested, false if not
-         * @return the URI for the new message
-         */
-        public static Uri addMessageToUri(ContentResolver resolver,
-                Uri uri, String address, String body, String subject,
-                Long date, boolean read, boolean deliveryReport) {
-            return addMessageToUri(resolver, uri, address, body, subject,
-                    date, read, deliveryReport, -1L);
-        }
-
-        /**
-         * Add an SMS to the given URI with thread_id specified.
-         *
-         * @param resolver the content resolver to use
-         * @param uri the URI to add the message to
-         * @param address the address of the sender
-         * @param body the body of the message
-         * @param subject the psuedo-subject of the message
-         * @param date the timestamp for the message
-         * @param read true if the message has been read, false if not
-         * @param deliveryReport true if a delivery report was requested, false if not
-         * @param threadId the thread_id of the message
-         * @return the URI for the new message
-         */
-        public static Uri addMessageToUri(ContentResolver resolver,
-                Uri uri, String address, String body, String subject,
-                Long date, boolean read, boolean deliveryReport, long threadId) {
-            ContentValues values = new ContentValues(7);
-
-            values.put(ADDRESS, address);
-            if (date != null) {
-                values.put(DATE, date);
-            }
-            values.put(READ, read ? Integer.valueOf(1) : Integer.valueOf(0));
-            values.put(SUBJECT, subject);
-            values.put(BODY, body);
-            if (deliveryReport) {
-                values.put(STATUS, STATUS_PENDING);
-            }
-            if (threadId != -1L) {
-                values.put(THREAD_ID, threadId);
-            }
-            return resolver.insert(uri, values);
-        }
-
-        /**
-         * Move a message to the given folder.
-         *
-         * @param context the context to use
-         * @param uri the message to move
-         * @param folder the folder to move to
-         * @return true if the operation succeeded
-         */
-        public static boolean moveMessageToFolder(Context context,
-                Uri uri, int folder, int error) {
-            if (uri == null) {
-                return false;
-            }
-
-            boolean markAsUnread = false;
-            boolean markAsRead = false;
-            switch(folder) {
-            case MESSAGE_TYPE_INBOX:
-            case MESSAGE_TYPE_DRAFT:
-                break;
-            case MESSAGE_TYPE_OUTBOX:
-            case MESSAGE_TYPE_SENT:
-                markAsRead = true;
-                break;
-            case MESSAGE_TYPE_FAILED:
-            case MESSAGE_TYPE_QUEUED:
-                markAsUnread = true;
-                break;
-            default:
-                return false;
-            }
-
-            ContentValues values = new ContentValues(3);
-
-            values.put(TYPE, folder);
-            if (markAsUnread) {
-                values.put(READ, Integer.valueOf(0));
-            } else if (markAsRead) {
-                values.put(READ, Integer.valueOf(1));
-            }
-            values.put(ERROR_CODE, error);
-
-            return 1 == SqliteWrapper.update(context, context.getContentResolver(),
-                            uri, values, null, null);
-        }
-
-        /**
-         * Returns true iff the folder (message type) identifies an
-         * outgoing message.
-         */
-        public static boolean isOutgoingFolder(int messageType) {
-            return  (messageType == MESSAGE_TYPE_FAILED)
-                    || (messageType == MESSAGE_TYPE_OUTBOX)
-                    || (messageType == MESSAGE_TYPE_SENT)
-                    || (messageType == MESSAGE_TYPE_QUEUED);
-        }
-
-        /**
-         * Contains all text based SMS messages in the SMS app's inbox.
-         */
-        public static final class Inbox implements BaseColumns, TextBasedSmsColumns {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri CONTENT_URI =
-                Uri.parse("content://sms/inbox");
-
-            /**
-             * The default sort order for this table
-             */
-            public static final String DEFAULT_SORT_ORDER = "date DESC";
-
-            /**
-             * Add an SMS to the Draft box.
-             *
-             * @param resolver the content resolver to use
-             * @param address the address of the sender
-             * @param body the body of the message
-             * @param subject the psuedo-subject of the message
-             * @param date the timestamp for the message
-             * @param read true if the message has been read, false if not
-             * @return the URI for the new message
-             */
-            public static Uri addMessage(ContentResolver resolver,
-                    String address, String body, String subject, Long date,
-                    boolean read) {
-                return addMessageToUri(resolver, CONTENT_URI, address, body,
-                        subject, date, read, false);
-            }
-        }
-
-        /**
-         * Contains all sent text based SMS messages in the SMS app's.
-         */
-        public static final class Sent implements BaseColumns, TextBasedSmsColumns {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri CONTENT_URI =
-                    Uri.parse("content://sms/sent");
-
-            /**
-             * The default sort order for this table
-             */
-            public static final String DEFAULT_SORT_ORDER = "date DESC";
-
-            /**
-             * Add an SMS to the Draft box.
-             *
-             * @param resolver the content resolver to use
-             * @param address the address of the sender
-             * @param body the body of the message
-             * @param subject the psuedo-subject of the message
-             * @param date the timestamp for the message
-             * @return the URI for the new message
-             */
-            public static Uri addMessage(ContentResolver resolver,
-                    String address, String body, String subject, Long date) {
-                return addMessageToUri(resolver, CONTENT_URI, address, body,
-                        subject, date, true, false);
-            }
-        }
-
-        /**
-         * Contains all sent text based SMS messages in the SMS app's.
-         */
-        public static final class Draft implements BaseColumns, TextBasedSmsColumns {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri CONTENT_URI =
-                    Uri.parse("content://sms/draft");
-
-            /**
-             * The default sort order for this table
-             */
-            public static final String DEFAULT_SORT_ORDER = "date DESC";
-
-            /**
-             * Add an SMS to the Draft box.
-             *
-             * @param resolver the content resolver to use
-             * @param address the address of the sender
-             * @param body the body of the message
-             * @param subject the psuedo-subject of the message
-             * @param date the timestamp for the message
-             * @return the URI for the new message
-             */
-            public static Uri addMessage(ContentResolver resolver,
-                    String address, String body, String subject, Long date) {
-                return addMessageToUri(resolver, CONTENT_URI, address, body,
-                        subject, date, true, false);
-            }
-
-            /**
-             * Save over an existing draft message.
-             *
-             * @param resolver the content resolver to use
-             * @param uri of existing message
-             * @param body the new body for the draft message
-             * @return true is successful, false otherwise
-             */
-            public static boolean saveMessage(ContentResolver resolver,
-                    Uri uri, String body) {
-                ContentValues values = new ContentValues(2);
-                values.put(BODY, body);
-                values.put(DATE, System.currentTimeMillis());
-                return resolver.update(uri, values, null, null) == 1;
-            }
-        }
-
-        /**
-         * Contains all pending outgoing text based SMS messages.
-         */
-        public static final class Outbox implements BaseColumns, TextBasedSmsColumns {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri CONTENT_URI =
-                Uri.parse("content://sms/outbox");
-
-            /**
-             * The default sort order for this table
-             */
-            public static final String DEFAULT_SORT_ORDER = "date DESC";
-
-            /**
-             * Add an SMS to the Out box.
-             *
-             * @param resolver the content resolver to use
-             * @param address the address of the sender
-             * @param body the body of the message
-             * @param subject the psuedo-subject of the message
-             * @param date the timestamp for the message
-             * @param deliveryReport whether a delivery report was requested for the message
-             * @return the URI for the new message
-             */
-            public static Uri addMessage(ContentResolver resolver,
-                    String address, String body, String subject, Long date,
-                    boolean deliveryReport, long threadId) {
-                return addMessageToUri(resolver, CONTENT_URI, address, body,
-                        subject, date, true, deliveryReport, threadId);
-            }
-        }
-
-        /**
-         * Contains all sent text-based SMS messages in the SMS app's.
-         */
-        public static final class Conversations
-                implements BaseColumns, TextBasedSmsColumns {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri CONTENT_URI =
-                Uri.parse("content://sms/conversations");
-
-            /**
-             * The default sort order for this table
-             */
-            public static final String DEFAULT_SORT_ORDER = "date DESC";
-
-            /**
-             * The first 45 characters of the body of the message
-             * <P>Type: TEXT</P>
-             */
-            public static final String SNIPPET = "snippet";
-
-            /**
-             * The number of messages in the conversation
-             * <P>Type: INTEGER</P>
-             */
-            public static final String MESSAGE_COUNT = "msg_count";
-        }
-
-        /**
-         * Contains info about SMS related Intents that are broadcast.
-         */
-        public static final class Intents {
-            /**
-             * Set by BroadcastReceiver. Indicates the message was handled
-             * successfully.
-             */
-            public static final int RESULT_SMS_HANDLED = 1;
-
-            /**
-             * Set by BroadcastReceiver. Indicates a generic error while
-             * processing the message.
-             */
-            public static final int RESULT_SMS_GENERIC_ERROR = 2;
-
-            /**
-             * Set by BroadcastReceiver. Indicates insufficient memory to store
-             * the message.
-             */
-            public static final int RESULT_SMS_OUT_OF_MEMORY = 3;
-
-            /**
-             * Set by BroadcastReceiver. Indicates the message, while
-             * possibly valid, is of a format or encoding that is not
-             * supported.
-             */
-            public static final int RESULT_SMS_UNSUPPORTED = 4;
-
-            /**
-             * Broadcast Action: A new text based SMS message has been received
-             * by the device. The intent will have the following extra
-             * values:</p>
-             *
-             * <ul>
-             *   <li><em>pdus</em> - An Object[] od byte[]s containing the PDUs
-             *   that make up the message.</li>
-             * </ul>
-             *
-             * <p>The extra values can be extracted using
-             * {@link #getMessagesFromIntent(Intent)}.</p>
-             *
-             * <p>If a BroadcastReceiver encounters an error while processing
-             * this intent it should set the result code appropriately.</p>
-             */
-            public static final String SMS_RECEIVED_ACTION =
-                    "android.provider.Telephony.SMS_RECEIVED";
-
-            /**
-             * Broadcast Action: A new data based SMS message has been received
-             * by the device. The intent will have the following extra
-             * values:</p>
-             *
-             * <ul>
-             *   <li><em>pdus</em> - An Object[] od byte[]s containing the PDUs
-             *   that make up the message.</li>
-             * </ul>
-             *
-             * <p>The extra values can be extracted using
-             * {@link #getMessagesFromIntent(Intent)}.</p>
-             *
-             * <p>If a BroadcastReceiver encounters an error while processing
-             * this intent it should set the result code appropriately.</p>
-             */
-            public static final String DATA_SMS_RECEIVED_ACTION =
-                    "android.intent.action.DATA_SMS_RECEIVED";
-
-            /**
-             * Broadcast Action: A new WAP PUSH message has been received by the
-             * device. The intent will have the following extra
-             * values:</p>
-             *
-             * <ul>
-             *   <li><em>transactionId (Integer)</em> - The WAP transaction
-             *    ID</li>
-             *   <li><em>pduType (Integer)</em> - The WAP PDU type</li>
-             *   <li><em>header (byte[])</em> - The header of the message</li>
-             *   <li><em>data (byte[])</em> - The data payload of the message</li>
-             * </ul>
-             *
-             * <p>If a BroadcastReceiver encounters an error while processing
-             * this intent it should set the result code appropriately.</p>
-             */
-            public static final String WAP_PUSH_RECEIVED_ACTION =
-                    "android.provider.Telephony.WAP_PUSH_RECEIVED";
-
-            /**
-             * Broadcast Action: The SIM storage for SMS messages is full.  If
-             * space is not freed, messages targeted for the SIM (class 2) may
-             * not be saved.
-             */
-            public static final String SIM_FULL_ACTION =
-                "android.provider.Telephony.SIM_FULL";
-
-            /**
-             * Broadcast Action: An incoming SMS has been rejected by the
-             * telephony framework.  This intent is sent in lieu of any
-             * of the RECEIVED_ACTION intents.  The intent will have the
-             * following extra value:</p>
-             *
-             * <ul>
-             *   <li><em>result</em> - An int result code, eg,
-             *   <code>{@link #RESULT_SMS_OUT_OF_MEMORY}</code>,
-             *   indicating the error returned to the network.</li>
-             * </ul>
-
-             */
-            public static final String SMS_REJECTED_ACTION =
-                "android.provider.Telephony.SMS_REJECTED";
-
-            /**
-             * Broadcast Action: The phone service state has changed. The intent will have the following
-             * extra values:</p>
-             * <ul>
-             *   <li><em>state</em> - An int with one of the following values:
-             *          {@link android.telephony.ServiceState#STATE_IN_SERVICE},
-             *          {@link android.telephony.ServiceState#STATE_OUT_OF_SERVICE},
-             *          {@link android.telephony.ServiceState#STATE_EMERGENCY_ONLY}
-             *          or {@link android.telephony.ServiceState#STATE_POWER_OFF}
-             *   <li><em>roaming</em> - A boolean value indicating whether the phone is roaming.</li>
-             *   <li><em>operator-alpha-long</em> - The carrier name as a string.</li>
-             *   <li><em>operator-alpha-short</em> - A potentially shortened version of the carrier name,
-             *          as a string.</li>
-             *   <li><em>operator-numeric</em> - A number representing the carrier, as a string. This is
-             *          a five or six digit number consisting of the MCC (Mobile Country Code, 3 digits)
-             *          and MNC (Mobile Network code, 2-3 digits).</li>
-             *   <li><em>manual</em> - A boolean, where true indicates that the user has chosen to select
-             *          the network manually, and false indicates that network selection is handled by the
-             *          phone.</li>
-             * </ul>
-             *
-             * <p class="note">
-             * Requires the READ_PHONE_STATE permission.
-             *
-             * <p class="note">This is a protected intent that can only be sent
-             * by the system.
-             */
-            public static final String ACTION_SERVICE_STATE_CHANGED =
-                "android.intent.action.SERVICE_STATE";
-
-            /**
-             * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
-             * {@link #DATA_SMS_RECEIVED_ACTION} intent.
-             *
-             * @param intent the intent to read from
-             * @return an array of SmsMessages for the PDUs
-             */
-            public static final SmsMessage[] getMessagesFromIntent(
-                    Intent intent) {
-                Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
-                byte[][] pduObjs = new byte[messages.length][];
-
-                for (int i = 0; i < messages.length; i++) {
-                    pduObjs[i] = (byte[]) messages[i];
-                }
-                byte[][] pdus = new byte[pduObjs.length][];
-                int pduCount = pdus.length;
-                SmsMessage[] msgs = new SmsMessage[pduCount];
-                for (int i = 0; i < pduCount; i++) {
-                    pdus[i] = pduObjs[i];
-                    msgs[i] = SmsMessage.createFromPdu(pdus[i]);
-                }
-                return msgs;
-            }
-        }
-    }
-
-    /**
-     * Base columns for tables that contain MMSs.
-     */
-    public interface BaseMmsColumns extends BaseColumns {
-
-        public static final int MESSAGE_BOX_ALL    = 0;
-        public static final int MESSAGE_BOX_INBOX  = 1;
-        public static final int MESSAGE_BOX_SENT   = 2;
-        public static final int MESSAGE_BOX_DRAFTS = 3;
-        public static final int MESSAGE_BOX_OUTBOX = 4;
-
-        /**
-         * The date the message was sent.
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String DATE = "date";
-
-        /**
-         * The box which the message belong to, for example, MESSAGE_BOX_INBOX.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MESSAGE_BOX = "msg_box";
-
-        /**
-         * Has the message been read.
-         * <P>Type: INTEGER (boolean)</P>
-         */
-        public static final String READ = "read";
-
-        /**
-         * Indicates whether this message has been seen by the user. The "seen" flag will be
-         * used to figure out whether we need to throw up a statusbar notification or not.
-         */
-        public static final String SEEN = "seen";
-
-        /**
-         * The Message-ID of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String MESSAGE_ID = "m_id";
-
-        /**
-         * The subject of the message, if present.
-         * <P>Type: TEXT</P>
-         */
-        public static final String SUBJECT = "sub";
-
-        /**
-         * The character set of the subject, if present.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String SUBJECT_CHARSET = "sub_cs";
-
-        /**
-         * The Content-Type of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String CONTENT_TYPE = "ct_t";
-
-        /**
-         * The Content-Location of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String CONTENT_LOCATION = "ct_l";
-
-        /**
-         * The address of the sender.
-         * <P>Type: TEXT</P>
-         */
-        public static final String FROM = "from";
-
-        /**
-         * The address of the recipients.
-         * <P>Type: TEXT</P>
-         */
-        public static final String TO = "to";
-
-        /**
-         * The address of the cc. recipients.
-         * <P>Type: TEXT</P>
-         */
-        public static final String CC = "cc";
-
-        /**
-         * The address of the bcc. recipients.
-         * <P>Type: TEXT</P>
-         */
-        public static final String BCC = "bcc";
-
-        /**
-         * The expiry time of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String EXPIRY = "exp";
-
-        /**
-         * The class of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String MESSAGE_CLASS = "m_cls";
-
-        /**
-         * The type of the message defined by MMS spec.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MESSAGE_TYPE = "m_type";
-
-        /**
-         * The version of specification that this message conform.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MMS_VERSION = "v";
-
-        /**
-         * The size of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MESSAGE_SIZE = "m_size";
-
-        /**
-         * The priority of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String PRIORITY = "pri";
-
-        /**
-         * The read-report of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String READ_REPORT = "rr";
-
-        /**
-         * Whether the report is allowed.
-         * <P>Type: TEXT</P>
-         */
-        public static final String REPORT_ALLOWED = "rpt_a";
-
-        /**
-         * The response-status of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String RESPONSE_STATUS = "resp_st";
-
-        /**
-         * The status of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String STATUS = "st";
-
-        /**
-         * The transaction-id of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String TRANSACTION_ID = "tr_id";
-
-        /**
-         * The retrieve-status of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String RETRIEVE_STATUS = "retr_st";
-
-        /**
-         * The retrieve-text of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String RETRIEVE_TEXT = "retr_txt";
-
-        /**
-         * The character set of the retrieve-text.
-         * <P>Type: TEXT</P>
-         */
-        public static final String RETRIEVE_TEXT_CHARSET = "retr_txt_cs";
-
-        /**
-         * The read-status of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String READ_STATUS = "read_status";
-
-        /**
-         * The content-class of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String CONTENT_CLASS = "ct_cls";
-
-        /**
-         * The delivery-report of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String DELIVERY_REPORT = "d_rpt";
-
-        /**
-         * The delivery-time-token of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String DELIVERY_TIME_TOKEN = "d_tm_tok";
-
-        /**
-         * The delivery-time of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String DELIVERY_TIME = "d_tm";
-
-        /**
-         * The response-text of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String RESPONSE_TEXT = "resp_txt";
-
-        /**
-         * The sender-visibility of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String SENDER_VISIBILITY = "s_vis";
-
-        /**
-         * The reply-charging of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String REPLY_CHARGING = "r_chg";
-
-        /**
-         * The reply-charging-deadline-token of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String REPLY_CHARGING_DEADLINE_TOKEN = "r_chg_dl_tok";
-
-        /**
-         * The reply-charging-deadline of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String REPLY_CHARGING_DEADLINE = "r_chg_dl";
-
-        /**
-         * The reply-charging-id of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String REPLY_CHARGING_ID = "r_chg_id";
-
-        /**
-         * The reply-charging-size of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String REPLY_CHARGING_SIZE = "r_chg_sz";
-
-        /**
-         * The previously-sent-by of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String PREVIOUSLY_SENT_BY = "p_s_by";
-
-        /**
-         * The previously-sent-date of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String PREVIOUSLY_SENT_DATE = "p_s_d";
-
-        /**
-         * The store of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String STORE = "store";
-
-        /**
-         * The mm-state of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MM_STATE = "mm_st";
-
-        /**
-         * The mm-flags-token of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MM_FLAGS_TOKEN = "mm_flg_tok";
-
-        /**
-         * The mm-flags of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String MM_FLAGS = "mm_flg";
-
-        /**
-         * The store-status of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String STORE_STATUS = "store_st";
-
-        /**
-         * The store-status-text of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String STORE_STATUS_TEXT = "store_st_txt";
-
-        /**
-         * The stored of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String STORED = "stored";
-
-        /**
-         * The totals of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String TOTALS = "totals";
-
-        /**
-         * The mbox-totals of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String MBOX_TOTALS = "mb_t";
-
-        /**
-         * The mbox-totals-token of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MBOX_TOTALS_TOKEN = "mb_t_tok";
-
-        /**
-         * The quotas of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String QUOTAS = "qt";
-
-        /**
-         * The mbox-quotas of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String MBOX_QUOTAS = "mb_qt";
-
-        /**
-         * The mbox-quotas-token of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MBOX_QUOTAS_TOKEN = "mb_qt_tok";
-
-        /**
-         * The message-count of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MESSAGE_COUNT = "m_cnt";
-
-        /**
-         * The start of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String START = "start";
-
-        /**
-         * The distribution-indicator of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String DISTRIBUTION_INDICATOR = "d_ind";
-
-        /**
-         * The element-descriptor of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String ELEMENT_DESCRIPTOR = "e_des";
-
-        /**
-         * The limit of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String LIMIT = "limit";
-
-        /**
-         * The recommended-retrieval-mode of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String RECOMMENDED_RETRIEVAL_MODE = "r_r_mod";
-
-        /**
-         * The recommended-retrieval-mode-text of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String RECOMMENDED_RETRIEVAL_MODE_TEXT = "r_r_mod_txt";
-
-        /**
-         * The status-text of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String STATUS_TEXT = "st_txt";
-
-        /**
-         * The applic-id of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String APPLIC_ID = "apl_id";
-
-        /**
-         * The reply-applic-id of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String REPLY_APPLIC_ID = "r_apl_id";
-
-        /**
-         * The aux-applic-id of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String AUX_APPLIC_ID = "aux_apl_id";
-
-        /**
-         * The drm-content of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String DRM_CONTENT = "drm_c";
-
-        /**
-         * The adaptation-allowed of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String ADAPTATION_ALLOWED = "adp_a";
-
-        /**
-         * The replace-id of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String REPLACE_ID = "repl_id";
-
-        /**
-         * The cancel-id of the message.
-         * <P>Type: TEXT</P>
-         */
-        public static final String CANCEL_ID = "cl_id";
-
-        /**
-         * The cancel-status of the message.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String CANCEL_STATUS = "cl_st";
-
-        /**
-         * The thread ID of the message
-         * <P>Type: INTEGER</P>
-         */
-        public static final String THREAD_ID = "thread_id";
-
-        /**
-         * Has the message been locked?
-         * <P>Type: INTEGER (boolean)</P>
-         */
-        public static final String LOCKED = "locked";
-    }
-
-    /**
-     * Columns for the "canonical_addresses" table used by MMS and
-     * SMS."
-     */
-    public interface CanonicalAddressesColumns extends BaseColumns {
-        /**
-         * An address used in MMS or SMS.  Email addresses are
-         * converted to lower case and are compared by string
-         * equality.  Other addresses are compared using
-         * PHONE_NUMBERS_EQUAL.
-         * <P>Type: TEXT</P>
-         */
-        public static final String ADDRESS = "address";
-    }
-
-    /**
-     * Columns for the "threads" table used by MMS and SMS.
-     */
-    public interface ThreadsColumns extends BaseColumns {
-        /**
-         * The date at which the thread was created.
-         *
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String DATE = "date";
-
-        /**
-         * A string encoding of the recipient IDs of the recipients of
-         * the message, in numerical order and separated by spaces.
-         * <P>Type: TEXT</P>
-         */
-        public static final String RECIPIENT_IDS = "recipient_ids";
-
-        /**
-         * The message count of the thread.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String MESSAGE_COUNT = "message_count";
-        /**
-         * Indicates whether all messages of the thread have been read.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String READ = "read";
-
-        /**
-         * The snippet of the latest message in the thread.
-         * <P>Type: TEXT</P>
-         */
-        public static final String SNIPPET = "snippet";
-        /**
-         * The charset of the snippet.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String SNIPPET_CHARSET = "snippet_cs";
-        /**
-         * Type of the thread, either Threads.COMMON_THREAD or
-         * Threads.BROADCAST_THREAD.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String TYPE = "type";
-        /**
-         * Indicates whether there is a transmission error in the thread.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String ERROR = "error";
-        /**
-         * Indicates whether this thread contains any attachments.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String HAS_ATTACHMENT = "has_attachment";
-    }
-
-    /**
-     * Helper functions for the "threads" table used by MMS and SMS.
-     */
-    public static final class Threads implements ThreadsColumns {
-        private static final String[] ID_PROJECTION = { BaseColumns._ID };
-        private static final String STANDARD_ENCODING = "UTF-8";
-        private static final Uri THREAD_ID_CONTENT_URI = Uri.parse(
-                "content://mms-sms/threadID");
-        public static final Uri CONTENT_URI = Uri.withAppendedPath(
-                MmsSms.CONTENT_URI, "conversations");
-        public static final Uri OBSOLETE_THREADS_URI = Uri.withAppendedPath(
-                CONTENT_URI, "obsolete");
-
-        public static final int COMMON_THREAD    = 0;
-        public static final int BROADCAST_THREAD = 1;
-
-        // No one should construct an instance of this class.
-        private Threads() {
-        }
-
-        /**
-         * This is a single-recipient version of
-         * getOrCreateThreadId.  It's convenient for use with SMS
-         * messages.
-         */
-        public static long getOrCreateThreadId(Context context, String recipient) {
-            Set<String> recipients = new HashSet<String>();
-
-            recipients.add(recipient);
-            return getOrCreateThreadId(context, recipients);
-        }
-
-        /**
-         * Given the recipients list and subject of an unsaved message,
-         * return its thread ID.  If the message starts a new thread,
-         * allocate a new thread ID.  Otherwise, use the appropriate
-         * existing thread ID.
-         *
-         * Find the thread ID of the same set of recipients (in
-         * any order, without any additions). If one
-         * is found, return it.  Otherwise, return a unique thread ID.
-         */
-        public static long getOrCreateThreadId(
-                Context context, Set<String> recipients) {
-            Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon();
-
-            for (String recipient : recipients) {
-                if (Mms.isEmailAddress(recipient)) {
-                    recipient = Mms.extractAddrSpec(recipient);
-                }
-
-                uriBuilder.appendQueryParameter("recipient", recipient);
-            }
-
-            Uri uri = uriBuilder.build();
-            if (DEBUG) {
-                Log.v(TAG, "getOrCreateThreadId uri: " + uri);
-            }
-            Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
-                    uri, ID_PROJECTION, null, null, null);
-            if (DEBUG) {
-                Log.v(TAG, "getOrCreateThreadId cursor cnt: " + cursor.getCount());
-            }
-            if (cursor != null) {
-                try {
-                    if (cursor.moveToFirst()) {
-                        return cursor.getLong(0);
-                    } else {
-                        Log.e(TAG, "getOrCreateThreadId returned no rows!");
-                    }
-                } finally {
-                    cursor.close();
-                }
-            }
-
-            Log.e(TAG, "getOrCreateThreadId failed with uri " + uri.toString());
-            throw new IllegalArgumentException("Unable to find or allocate a thread ID.");
-        }
-    }
-
-    /**
-     * Contains all MMS messages.
-     */
-    public static final class Mms implements BaseMmsColumns {
-        /**
-         * The content:// style URL for this table
-         */
-        public static final Uri CONTENT_URI = Uri.parse("content://mms");
-
-        public static final Uri REPORT_REQUEST_URI = Uri.withAppendedPath(
-                                            CONTENT_URI, "report-request");
-
-        public static final Uri REPORT_STATUS_URI = Uri.withAppendedPath(
-                                            CONTENT_URI, "report-status");
-
-        /**
-         * The default sort order for this table
-         */
-        public static final String DEFAULT_SORT_ORDER = "date DESC";
-
-        /**
-         * mailbox         =       name-addr
-         * name-addr       =       [display-name] angle-addr
-         * angle-addr      =       [CFWS] "<" addr-spec ">" [CFWS]
-         */
-        public static final Pattern NAME_ADDR_EMAIL_PATTERN =
-                Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*");
-
-        /**
-         * quoted-string   =       [CFWS]
-         *                         DQUOTE *([FWS] qcontent) [FWS] DQUOTE
-         *                         [CFWS]
-         */
-        public static final Pattern QUOTED_STRING_PATTERN =
-                Pattern.compile("\\s*\"([^\"]*)\"\\s*");
-
-        public static final Cursor query(
-                ContentResolver cr, String[] projection) {
-            return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
-        }
-
-        public static final Cursor query(
-                ContentResolver cr, String[] projection,
-                String where, String orderBy) {
-            return cr.query(CONTENT_URI, projection,
-                    where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
-        }
-
-        public static final String getMessageBoxName(int msgBox) {
-            switch (msgBox) {
-                case MESSAGE_BOX_ALL:
-                    return "all";
-                case MESSAGE_BOX_INBOX:
-                    return "inbox";
-                case MESSAGE_BOX_SENT:
-                    return "sent";
-                case MESSAGE_BOX_DRAFTS:
-                    return "drafts";
-                case MESSAGE_BOX_OUTBOX:
-                    return "outbox";
-                default:
-                    throw new IllegalArgumentException("Invalid message box: " + msgBox);
-            }
-        }
-
-        public static String extractAddrSpec(String address) {
-            Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address);
-
-            if (match.matches()) {
-                return match.group(2);
-            }
-            return address;
-        }
-
-        /**
-         * Returns true if the address is an email address
-         *
-         * @param address the input address to be tested
-         * @return true if address is an email address
-         */
-        public static boolean isEmailAddress(String address) {
-            if (TextUtils.isEmpty(address)) {
-                return false;
-            }
-
-            String s = extractAddrSpec(address);
-            Matcher match = Patterns.EMAIL_ADDRESS.matcher(s);
-            return match.matches();
-        }
-
-        /**
-         * Returns true if the number is a Phone number
-         *
-         * @param number the input number to be tested
-         * @return true if number is a Phone number
-         */
-        public static boolean isPhoneNumber(String number) {
-            if (TextUtils.isEmpty(number)) {
-                return false;
-            }
-
-            Matcher match = Patterns.PHONE.matcher(number);
-            return match.matches();
-        }
-
-        /**
-         * Contains all MMS messages in the MMS app's inbox.
-         */
-        public static final class Inbox implements BaseMmsColumns {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri
-                    CONTENT_URI = Uri.parse("content://mms/inbox");
-
-            /**
-             * The default sort order for this table
-             */
-            public static final String DEFAULT_SORT_ORDER = "date DESC";
-        }
-
-        /**
-         * Contains all MMS messages in the MMS app's sent box.
-         */
-        public static final class Sent implements BaseMmsColumns {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri
-                    CONTENT_URI = Uri.parse("content://mms/sent");
-
-            /**
-             * The default sort order for this table
-             */
-            public static final String DEFAULT_SORT_ORDER = "date DESC";
-        }
-
-        /**
-         * Contains all MMS messages in the MMS app's drafts box.
-         */
-        public static final class Draft implements BaseMmsColumns {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri
-                    CONTENT_URI = Uri.parse("content://mms/drafts");
-
-            /**
-             * The default sort order for this table
-             */
-            public static final String DEFAULT_SORT_ORDER = "date DESC";
-        }
-
-        /**
-         * Contains all MMS messages in the MMS app's outbox.
-         */
-        public static final class Outbox implements BaseMmsColumns {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri
-                    CONTENT_URI = Uri.parse("content://mms/outbox");
-
-            /**
-             * The default sort order for this table
-             */
-            public static final String DEFAULT_SORT_ORDER = "date DESC";
-        }
-
-        public static final class Addr implements BaseColumns {
-            /**
-             * The ID of MM which this address entry belongs to.
-             */
-            public static final String MSG_ID = "msg_id";
-
-            /**
-             * The ID of contact entry in Phone Book.
-             */
-            public static final String CONTACT_ID = "contact_id";
-
-            /**
-             * The address text.
-             */
-            public static final String ADDRESS = "address";
-
-            /**
-             * Type of address, must be one of PduHeaders.BCC,
-             * PduHeaders.CC, PduHeaders.FROM, PduHeaders.TO.
-             */
-            public static final String TYPE = "type";
-
-            /**
-             * Character set of this entry.
-             */
-            public static final String CHARSET = "charset";
-        }
-
-        public static final class Part implements BaseColumns {
-            /**
-             * The identifier of the message which this part belongs to.
-             * <P>Type: INTEGER</P>
-             */
-            public static final String MSG_ID = "mid";
-
-            /**
-             * The order of the part.
-             * <P>Type: INTEGER</P>
-             */
-            public static final String SEQ = "seq";
-
-            /**
-             * The content type of the part.
-             * <P>Type: TEXT</P>
-             */
-            public static final String CONTENT_TYPE = "ct";
-
-            /**
-             * The name of the part.
-             * <P>Type: TEXT</P>
-             */
-            public static final String NAME = "name";
-
-            /**
-             * The charset of the part.
-             * <P>Type: TEXT</P>
-             */
-            public static final String CHARSET = "chset";
-
-            /**
-             * The file name of the part.
-             * <P>Type: TEXT</P>
-             */
-            public static final String FILENAME = "fn";
-
-            /**
-             * The content disposition of the part.
-             * <P>Type: TEXT</P>
-             */
-            public static final String CONTENT_DISPOSITION = "cd";
-
-            /**
-             * The content ID of the part.
-             * <P>Type: INTEGER</P>
-             */
-            public static final String CONTENT_ID = "cid";
-
-            /**
-             * The content location of the part.
-             * <P>Type: INTEGER</P>
-             */
-            public static final String CONTENT_LOCATION = "cl";
-
-            /**
-             * The start of content-type of the message.
-             * <P>Type: INTEGER</P>
-             */
-            public static final String CT_START = "ctt_s";
-
-            /**
-             * The type of content-type of the message.
-             * <P>Type: TEXT</P>
-             */
-            public static final String CT_TYPE = "ctt_t";
-
-            /**
-             * The location(on filesystem) of the binary data of the part.
-             * <P>Type: INTEGER</P>
-             */
-            public static final String _DATA = "_data";
-
-            public static final String TEXT = "text";
-
-        }
-
-        public static final class Rate {
-            public static final Uri CONTENT_URI = Uri.withAppendedPath(
-                    Mms.CONTENT_URI, "rate");
-            /**
-             * When a message was successfully sent.
-             * <P>Type: INTEGER</P>
-             */
-            public static final String SENT_TIME = "sent_time";
-        }
-
-        public static final class ScrapSpace {
-            /**
-             * The content:// style URL for this table
-             */
-            public static final Uri CONTENT_URI = Uri.parse("content://mms/scrapSpace");
-
-            /**
-             * This is the scrap file we use to store the media attachment when the user
-             * chooses to capture a photo to be attached . We pass {#link@Uri} to the Camera app,
-             * which streams the captured image to the uri. Internally we write the media content
-             * to this file. It's named '.temp.jpg' so Gallery won't pick it up.
-             */
-            public static final String SCRAP_FILE_PATH = "/sdcard/mms/scrapSpace/.temp.jpg";
-        }
-
-        public static final class Intents {
-            private Intents() {
-                // Non-instantiatable.
-            }
-
-            /**
-             * The extra field to store the contents of the Intent,
-             * which should be an array of Uri.
-             */
-            public static final String EXTRA_CONTENTS = "contents";
-            /**
-             * The extra field to store the type of the contents,
-             * which should be an array of String.
-             */
-            public static final String EXTRA_TYPES    = "types";
-            /**
-             * The extra field to store the 'Cc' addresses.
-             */
-            public static final String EXTRA_CC       = "cc";
-            /**
-             * The extra field to store the 'Bcc' addresses;
-             */
-            public static final String EXTRA_BCC      = "bcc";
-            /**
-             * The extra field to store the 'Subject'.
-             */
-            public static final String EXTRA_SUBJECT  = "subject";
-            /**
-             * Indicates that the contents of specified URIs were changed.
-             * The application which is showing or caching these contents
-             * should be updated.
-             */
-            public static final String
-            CONTENT_CHANGED_ACTION = "android.intent.action.CONTENT_CHANGED";
-            /**
-             * An extra field which stores the URI of deleted contents.
-             */
-            public static final String DELETED_CONTENTS = "deleted_contents";
-        }
-    }
-
-    /**
-     * Contains all MMS and SMS messages.
-     */
-    public static final class MmsSms implements BaseColumns {
-        /**
-         * The column to distinguish SMS &amp; MMS messages in query results.
-         */
-        public static final String TYPE_DISCRIMINATOR_COLUMN =
-                "transport_type";
-
-        public static final Uri CONTENT_URI = Uri.parse("content://mms-sms/");
-
-        public static final Uri CONTENT_CONVERSATIONS_URI = Uri.parse(
-                "content://mms-sms/conversations");
-
-        public static final Uri CONTENT_FILTER_BYPHONE_URI = Uri.parse(
-                "content://mms-sms/messages/byphone");
-
-        public static final Uri CONTENT_UNDELIVERED_URI = Uri.parse(
-                "content://mms-sms/undelivered");
-
-        public static final Uri CONTENT_DRAFT_URI = Uri.parse(
-                "content://mms-sms/draft");
-
-        public static final Uri CONTENT_LOCKED_URI = Uri.parse(
-                "content://mms-sms/locked");
-
-        /***
-         * Pass in a query parameter called "pattern" which is the text
-         * to search for.
-         * The sort order is fixed to be thread_id ASC,date DESC.
-         */
-        public static final Uri SEARCH_URI = Uri.parse(
-                "content://mms-sms/search");
-
-        // Constants for message protocol types.
-        public static final int SMS_PROTO = 0;
-        public static final int MMS_PROTO = 1;
-
-        // Constants for error types of pending messages.
-        public static final int NO_ERROR                      = 0;
-        public static final int ERR_TYPE_GENERIC              = 1;
-        public static final int ERR_TYPE_SMS_PROTO_TRANSIENT  = 2;
-        public static final int ERR_TYPE_MMS_PROTO_TRANSIENT  = 3;
-        public static final int ERR_TYPE_TRANSPORT_FAILURE    = 4;
-        public static final int ERR_TYPE_GENERIC_PERMANENT    = 10;
-        public static final int ERR_TYPE_SMS_PROTO_PERMANENT  = 11;
-        public static final int ERR_TYPE_MMS_PROTO_PERMANENT  = 12;
-
-        public static final class PendingMessages implements BaseColumns {
-            public static final Uri CONTENT_URI = Uri.withAppendedPath(
-                    MmsSms.CONTENT_URI, "pending");
-            /**
-             * The type of transport protocol(MMS or SMS).
-             * <P>Type: INTEGER</P>
-             */
-            public static final String PROTO_TYPE = "proto_type";
-            /**
-             * The ID of the message to be sent or downloaded.
-             * <P>Type: INTEGER</P>
-             */
-            public static final String MSG_ID = "msg_id";
-            /**
-             * The type of the message to be sent or downloaded.
-             * This field is only valid for MM. For SM, its value is always
-             * set to 0.
-             */
-            public static final String MSG_TYPE = "msg_type";
-            /**
-             * The type of the error code.
-             * <P>Type: INTEGER</P>
-             */
-            public static final String ERROR_TYPE = "err_type";
-            /**
-             * The error code of sending/retrieving process.
-             * <P>Type:  INTEGER</P>
-             */
-            public static final String ERROR_CODE = "err_code";
-            /**
-             * How many times we tried to send or download the message.
-             * <P>Type:  INTEGER</P>
-             */
-            public static final String RETRY_INDEX = "retry_index";
-            /**
-             * The time to do next retry.
-             */
-            public static final String DUE_TIME = "due_time";
-            /**
-             * The time we last tried to send or download the message.
-             */
-            public static final String LAST_TRY = "last_try";
-        }
-
-        public static final class WordsTable {
-            public static final String ID = "_id";
-            public static final String SOURCE_ROW_ID = "source_id";
-            public static final String TABLE_ID = "table_to_use";
-            public static final String INDEXED_TEXT = "index_text";
-        }
-    }
-
-    public static final class Carriers implements BaseColumns {
-        /**
-         * The content:// style URL for this table
-         */
-        public static final Uri CONTENT_URI =
-            Uri.parse("content://telephony/carriers");
-
-        /**
-         * The default sort order for this table
-         */
-        public static final String DEFAULT_SORT_ORDER = "name ASC";
-
-        public static final String NAME = "name";
-
-        public static final String APN = "apn";
-
-        public static final String PROXY = "proxy";
-
-        public static final String PORT = "port";
-
-        public static final String MMSPROXY = "mmsproxy";
-
-        public static final String MMSPORT = "mmsport";
-
-        public static final String SERVER = "server";
-
-        public static final String USER = "user";
-
-        public static final String PASSWORD = "password";
-
-        public static final String MMSC = "mmsc";
-
-        public static final String MCC = "mcc";
-
-        public static final String MNC = "mnc";
-
-        public static final String NUMERIC = "numeric";
-
-        public static final String AUTH_TYPE = "authtype";
-
-        public static final String TYPE = "type";
-
-        public static final String CURRENT = "current";
-    }
-
-    public static final class Intents {
-        private Intents() {
-            // Not instantiable
-        }
-
-        /**
-         * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are
-         * of the form *#*#<code>#*#*. The intent will have the data URI:</p>
-         *
-         * <p><code>android_secret_code://&lt;code&gt;</code></p>
-         */
-        public static final String SECRET_CODE_ACTION =
-                "android.provider.Telephony.SECRET_CODE";
-
-        /**
-         * Broadcast Action: The Service Provider string(s) have been updated.  Activities or
-         * services that use these strings should update their display.
-         * The intent will have the following extra values:</p>
-         * <ul>
-         *   <li><em>showPlmn</em> - Boolean that indicates whether the PLMN should be shown.</li>
-         *   <li><em>plmn</em> - The operator name of the registered network, as a string.</li>
-         *   <li><em>showSpn</em> - Boolean that indicates whether the SPN should be shown.</li>
-         *   <li><em>spn</em> - The service provider name, as a string.</li>
-         * </ul>
-         * Note that <em>showPlmn</em> may indicate that <em>plmn</em> should be displayed, even
-         * though the value for <em>plmn</em> is null.  This can happen, for example, if the phone
-         * has not registered to a network yet.  In this case the receiver may substitute an
-         * appropriate placeholder string (eg, "No service").
-         *
-         * It is recommended to display <em>plmn</em> before / above <em>spn</em> if
-         * both are displayed.
-         *
-         * <p>Note this is a protected intent that can only be sent
-         * by the system.
-         */
-        public static final String SPN_STRINGS_UPDATED_ACTION =
-                "android.provider.Telephony.SPN_STRINGS_UPDATED";
-
-        public static final String EXTRA_SHOW_PLMN  = "showPlmn";
-        public static final String EXTRA_PLMN       = "plmn";
-        public static final String EXTRA_SHOW_SPN   = "showSpn";
-        public static final String EXTRA_SPN        = "spn";
-    }
-}
